You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by ma...@apache.org on 2019/07/11 08:51:20 UTC

[commons-dbcp] branch master updated: Convert files using Windows line endings to unix line endings

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

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


The following commit(s) were added to refs/heads/master by this push:
     new 6a80bb8  Convert files using Windows line endings to unix line endings
6a80bb8 is described below

commit 6a80bb8910244fce92165887ff9dbf3fcce8beda
Author: Mark Thomas <ma...@apache.org>
AuthorDate: Thu Jul 11 09:51:09 2019 +0100

    Convert files using Windows line endings to unix line endings
    
    The significant majority of the files in the repo use unix line-endings.
    Mixed line endings cause large diffs when line endings change making the
    true change harder to see. Therefore, switch all the files to a single
    line ending - unix.
    Common / recommended practice is to use unix line endings in the repo
    and use native line endings locally.
---
 .travis.yml                                        |   52 +-
 CONTRIBUTING.md                                    |  230 +-
 NOTICE.txt                                         |   10 +-
 README.md                                          |  210 +-
 pom.xml                                            | 1026 ++--
 src/changes/changes.xml                            | 2082 ++++----
 .../org/apache/commons/dbcp2/BasicDataSource.java  | 5443 ++++++++++----------
 .../commons/dbcp2/managed/ManagedDataSource.java   |  186 +-
 src/site/site.xml                                  |  120 +-
 src/site/xdoc/download_dbcp.xml                    |  492 +-
 src/site/xdoc/index.xml                            |  208 +-
 src/site/xdoc/issue-tracking.xml                   |  204 +-
 src/site/xdoc/mail-lists.xml                       |  410 +-
 .../dbcp2/TestParallelCreationWithNoIdle.java      |  320 +-
 14 files changed, 5628 insertions(+), 5365 deletions(-)

diff --git a/.travis.yml b/.travis.yml
index 1cf4ffb..96216a2 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,27 +1,27 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You under the Apache License, Version 2.0
-# (the "License"); you may not use this file except in compliance with
-# the License.  You may obtain a copy of the License at
-#
-#     http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-language: java
-sudo: false
-
-jdk:
-  - oraclejdk8
-  - oraclejdk11
-  - openjdk8
-  - openjdk11
-  - openjdk12
-  - openjdk-ea
-
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License.  You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+language: java
+sudo: false
+
+jdk:
+  - oraclejdk8
+  - oraclejdk11
+  - openjdk8
+  - openjdk11
+  - openjdk12
+  - openjdk-ea
+
   
\ No newline at end of file
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 91d3583..e12b0b6 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -1,115 +1,115 @@
-<!---
- Licensed to the Apache Software Foundation (ASF) under one or more
- contributor license agreements.  See the NOTICE file distributed with
- this work for additional information regarding copyright ownership.
- The ASF licenses this file to You under the Apache License, Version 2.0
- (the "License"); you may not use this file except in compliance with
- the License.  You may obtain a copy of the License at
-
-      http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-<!---
- +======================================================================+
- |****                                                              ****|
- |****      THIS FILE IS GENERATED BY THE COMMONS BUILD PLUGIN      ****|
- |****                    DO NOT EDIT DIRECTLY                      ****|
- |****                                                              ****|
- +======================================================================+
- | TEMPLATE FILE: contributing-md-template.md                           |
- | commons-build-plugin/trunk/src/main/resources/commons-xdoc-templates |
- +======================================================================+
- |                                                                      |
- | 1) Re-generate using: mvn commons-build:contributing-md              |
- |                                                                      |
- | 2) Set the following properties in the component's pom:              |
- |    - commons.jira.id  (required, alphabetic, upper case)             |
- |                                                                      |
- | 3) Example Properties                                                |
- |                                                                      |
- |  <properties>                                                        |
- |    <commons.jira.id>MATH</commons.jira.id>                           |
- |  </properties>                                                       |
- |                                                                      |
- +======================================================================+
---->
-Contributing to Apache Commons DBCP
-======================
-
-You have found a bug or you have an idea for a cool new feature? Contributing code is a great way to give something back to
-the open source community. Before you dig right into the code there are a few guidelines that we need contributors to
-follow so that we can have a chance of keeping on top of things.
-
-Getting Started
----------------
-
-+ Make sure you have a [JIRA account](https://issues.apache.org/jira/).
-+ Make sure you have a [GitHub account](https://github.com/signup/free).
-+ If you're planning to implement a new feature it makes sense to discuss your changes on the [dev list](https://commons.apache.org/mail-lists.html) first. This way you can make sure you're not wasting your time on something that isn't considered to be in Apache Commons DBCP's scope.
-+ Submit a [Jira Ticket][jira] for your issue, assuming one does not already exist.
-  + Clearly describe the issue including steps to reproduce when it is a bug.
-  + Make sure you fill in the earliest version that you know has the issue.
-+ Find the corresponding [repository on GitHub](https://github.com/apache/?query=commons-),
-[fork](https://help.github.com/articles/fork-a-repo/) and check out your forked repository.
-
-Making Changes
---------------
-
-+ Create a _topic branch_ for your isolated work.
-  * Usually you should base your branch on the `master` or `trunk` branch.
-  * A good topic branch name can be the JIRA bug id plus a keyword, e.g. `DBCP-123-InputStream`.
-  * If you have submitted multiple JIRA issues, try to maintain separate branches and pull requests.
-+ Make commits of logical units.
-  * Make sure your commit messages are meaningful and in the proper format. Your commit message should contain the key of the JIRA issue.
-  * e.g. `DBCP-123: Close input stream earlier`
-+ Respect the original code style:
-  + Only use spaces for indentation.
-  + Create minimal diffs - disable _On Save_ actions like _Reformat Source Code_ or _Organize Imports_. If you feel the source code should be reformatted create a separate PR for this change first.
-  + Check for unnecessary whitespace with `git diff` -- check before committing.
-+ Make sure you have added the necessary tests for your changes, typically in `src/test/java`.
-+ Run all the tests with `mvn clean verify` to assure nothing else was accidentally broken.
-
-Making Trivial Changes
-----------------------
-
-The JIRA tickets are used to generate the changelog for the next release.
-
-For changes of a trivial nature to comments and documentation, it is not always necessary to create a new ticket in JIRA.
-In this case, it is appropriate to start the first line of a commit with '(doc)' instead of a ticket number.
-
-
-Submitting Changes
-------------------
-
-+ Sign and submit the Apache [Contributor License Agreement][cla] if you haven't already.
-  * Note that small patches & typical bug fixes do not require a CLA as
-    clause 5 of the [Apache License](https://www.apache.org/licenses/LICENSE-2.0.html#contributions)
-    covers them.
-+ Push your changes to a topic branch in your fork of the repository.
-+ Submit a _Pull Request_ to the corresponding repository in the `apache` organization.
-  * Verify _Files Changed_ shows only your intended changes and does not
-  include additional files like `target/*.class`
-+ Update your JIRA ticket and include a link to the pull request in the ticket.
-
-If you prefer to not use GitHub, then you can instead use
-`git format-patch` (or `svn diff`) and attach the patch file to the JIRA issue.
-
-
-Additional Resources
---------------------
-
-+ [Contributing patches](https://commons.apache.org/patches.html)
-+ [Apache Commons DBCP JIRA project page][jira]
-+ [Contributor License Agreement][cla]
-+ [General GitHub documentation](https://help.github.com/)
-+ [GitHub pull request documentation](https://help.github.com/articles/creating-a-pull-request/)
-+ [Apache Commons Twitter Account](https://twitter.com/ApacheCommons)
-+ `#apache-commons` IRC channel on `irc.freenode.net`
-
-[cla]:https://www.apache.org/licenses/#clas
-[jira]:https://issues.apache.org/jira/browse/DBCP
+<!---
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements.  See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License.  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<!---
+ +======================================================================+
+ |****                                                              ****|
+ |****      THIS FILE IS GENERATED BY THE COMMONS BUILD PLUGIN      ****|
+ |****                    DO NOT EDIT DIRECTLY                      ****|
+ |****                                                              ****|
+ +======================================================================+
+ | TEMPLATE FILE: contributing-md-template.md                           |
+ | commons-build-plugin/trunk/src/main/resources/commons-xdoc-templates |
+ +======================================================================+
+ |                                                                      |
+ | 1) Re-generate using: mvn commons-build:contributing-md              |
+ |                                                                      |
+ | 2) Set the following properties in the component's pom:              |
+ |    - commons.jira.id  (required, alphabetic, upper case)             |
+ |                                                                      |
+ | 3) Example Properties                                                |
+ |                                                                      |
+ |  <properties>                                                        |
+ |    <commons.jira.id>MATH</commons.jira.id>                           |
+ |  </properties>                                                       |
+ |                                                                      |
+ +======================================================================+
+--->
+Contributing to Apache Commons DBCP
+======================
+
+You have found a bug or you have an idea for a cool new feature? Contributing code is a great way to give something back to
+the open source community. Before you dig right into the code there are a few guidelines that we need contributors to
+follow so that we can have a chance of keeping on top of things.
+
+Getting Started
+---------------
+
++ Make sure you have a [JIRA account](https://issues.apache.org/jira/).
++ Make sure you have a [GitHub account](https://github.com/signup/free).
++ If you're planning to implement a new feature it makes sense to discuss your changes on the [dev list](https://commons.apache.org/mail-lists.html) first. This way you can make sure you're not wasting your time on something that isn't considered to be in Apache Commons DBCP's scope.
++ Submit a [Jira Ticket][jira] for your issue, assuming one does not already exist.
+  + Clearly describe the issue including steps to reproduce when it is a bug.
+  + Make sure you fill in the earliest version that you know has the issue.
++ Find the corresponding [repository on GitHub](https://github.com/apache/?query=commons-),
+[fork](https://help.github.com/articles/fork-a-repo/) and check out your forked repository.
+
+Making Changes
+--------------
+
++ Create a _topic branch_ for your isolated work.
+  * Usually you should base your branch on the `master` or `trunk` branch.
+  * A good topic branch name can be the JIRA bug id plus a keyword, e.g. `DBCP-123-InputStream`.
+  * If you have submitted multiple JIRA issues, try to maintain separate branches and pull requests.
++ Make commits of logical units.
+  * Make sure your commit messages are meaningful and in the proper format. Your commit message should contain the key of the JIRA issue.
+  * e.g. `DBCP-123: Close input stream earlier`
++ Respect the original code style:
+  + Only use spaces for indentation.
+  + Create minimal diffs - disable _On Save_ actions like _Reformat Source Code_ or _Organize Imports_. If you feel the source code should be reformatted create a separate PR for this change first.
+  + Check for unnecessary whitespace with `git diff` -- check before committing.
++ Make sure you have added the necessary tests for your changes, typically in `src/test/java`.
++ Run all the tests with `mvn clean verify` to assure nothing else was accidentally broken.
+
+Making Trivial Changes
+----------------------
+
+The JIRA tickets are used to generate the changelog for the next release.
+
+For changes of a trivial nature to comments and documentation, it is not always necessary to create a new ticket in JIRA.
+In this case, it is appropriate to start the first line of a commit with '(doc)' instead of a ticket number.
+
+
+Submitting Changes
+------------------
+
++ Sign and submit the Apache [Contributor License Agreement][cla] if you haven't already.
+  * Note that small patches & typical bug fixes do not require a CLA as
+    clause 5 of the [Apache License](https://www.apache.org/licenses/LICENSE-2.0.html#contributions)
+    covers them.
++ Push your changes to a topic branch in your fork of the repository.
++ Submit a _Pull Request_ to the corresponding repository in the `apache` organization.
+  * Verify _Files Changed_ shows only your intended changes and does not
+  include additional files like `target/*.class`
++ Update your JIRA ticket and include a link to the pull request in the ticket.
+
+If you prefer to not use GitHub, then you can instead use
+`git format-patch` (or `svn diff`) and attach the patch file to the JIRA issue.
+
+
+Additional Resources
+--------------------
+
++ [Contributing patches](https://commons.apache.org/patches.html)
++ [Apache Commons DBCP JIRA project page][jira]
++ [Contributor License Agreement][cla]
++ [General GitHub documentation](https://help.github.com/)
++ [GitHub pull request documentation](https://help.github.com/articles/creating-a-pull-request/)
++ [Apache Commons Twitter Account](https://twitter.com/ApacheCommons)
++ `#apache-commons` IRC channel on `irc.freenode.net`
+
+[cla]:https://www.apache.org/licenses/#clas
+[jira]:https://issues.apache.org/jira/browse/DBCP
diff --git a/NOTICE.txt b/NOTICE.txt
index 91fd3fc..392bb6e 100644
--- a/NOTICE.txt
+++ b/NOTICE.txt
@@ -1,5 +1,5 @@
-Apache Commons DBCP
-Copyright 2001-2019 The Apache Software Foundation
-
-This product includes software developed at
-The Apache Software Foundation (http://www.apache.org/).
+Apache Commons DBCP
+Copyright 2001-2019 The Apache Software Foundation
+
+This product includes software developed at
+The Apache Software Foundation (http://www.apache.org/).
diff --git a/README.md b/README.md
index effd1dd..89d6f1e 100644
--- a/README.md
+++ b/README.md
@@ -1,105 +1,105 @@
-<!---
- Licensed to the Apache Software Foundation (ASF) under one or more
- contributor license agreements.  See the NOTICE file distributed with
- this work for additional information regarding copyright ownership.
- The ASF licenses this file to You under the Apache License, Version 2.0
- (the "License"); you may not use this file except in compliance with
- the License.  You may obtain a copy of the License at
-
-      http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-<!---
- +======================================================================+
- |****                                                              ****|
- |****      THIS FILE IS GENERATED BY THE COMMONS BUILD PLUGIN      ****|
- |****                    DO NOT EDIT DIRECTLY                      ****|
- |****                                                              ****|
- +======================================================================+
- | TEMPLATE FILE: readme-md-template.md                                 |
- | commons-build-plugin/trunk/src/main/resources/commons-xdoc-templates |
- +======================================================================+
- |                                                                      |
- | 1) Re-generate using: mvn commons-build:readme-md                    |
- |                                                                      |
- | 2) Set the following properties in the component's pom:              |
- |    - commons.componentid (required, alphabetic, lower case)          |
- |    - commons.release.version (required)                              |
- |                                                                      |
- | 3) Example Properties                                                |
- |                                                                      |
- |  <properties>                                                        |
- |    <commons.componentid>math</commons.componentid>                   |
- |    <commons.release.version>1.2</commons.release.version>            |
- |  </properties>                                                       |
- |                                                                      |
- +======================================================================+
---->
-Apache Commons DBCP
-===================
-
-[![Build Status](https://travis-ci.org/apache/commons-dbcp.svg)](https://travis-ci.org/apache/commons-dbcp)
-[![Coverage Status](https://coveralls.io/repos/apache/commons-dbcp/badge.svg)](https://coveralls.io/r/apache/commons-dbcp)
-[![Maven Central](https://maven-badges.herokuapp.com/maven-central/org.apache.commons/commons-dbcp2/badge.svg)](https://maven-badges.herokuapp.com/maven-central/org.apache.commons/commons-dbcp2/)
-[![Javadocs](https://javadoc.io/badge/org.apache.commons/commons-dbcp2/2.6.0.svg)](https://javadoc.io/doc/org.apache.commons/commons-dbcp2/2.6.0)
-
-Apache Commons DBCP software implements Database Connection Pooling
-
-Documentation
--------------
-
-More information can be found on the [Apache Commons DBCP homepage](https://commons.apache.org/proper/commons-dbcp).
-The [Javadoc](https://commons.apache.org/proper/commons-dbcp/apidocs) can be browsed.
-Questions related to the usage of Apache Commons DBCP should be posted to the [user mailing list][ml].
-
-Where can I get the latest release?
------------------------------------
-You can download source and binaries from our [download page](https://commons.apache.org/proper/commons-dbcp/download_dbcp.cgi).
-
-Alternatively you can pull it from the central Maven repositories:
-
-```xml
-<dependency>
-  <groupId>org.apache.commons</groupId>
-  <artifactId>commons-dbcp2</artifactId>
-  <version>2.6.0</version>
-</dependency>
-```
-
-Contributing
-------------
-
-We accept Pull Requests via GitHub. The [developer mailing list][ml] is the main channel of communication for contributors.
-There are some guidelines which will make applying PRs easier for us:
-+ No tabs! Please use spaces for indentation.
-+ Respect the code style.
-+ Create minimal diffs - disable on save actions like reformat source code or organize imports. If you feel the source code should be reformatted create a separate PR for this change.
-+ Provide JUnit tests for your changes and make sure your changes don't break any existing tests by running ```mvn clean test```.
-
-If you plan to contribute on a regular basis, please consider filing a [contributor license agreement](https://www.apache.org/licenses/#clas).
-You can learn more about contributing via GitHub in our [contribution guidelines](CONTRIBUTING.md).
-
-License
--------
-This code is under the [Apache Licence v2](https://www.apache.org/licenses/LICENSE-2.0).
-
-See the `NOTICE.txt` file for required notices and attributions.
-
-Donations
----------
-You like Apache Commons DBCP? Then [donate back to the ASF](https://www.apache.org/foundation/contributing.html) to support the development.
-
-Additional Resources
---------------------
-
-+ [Apache Commons Homepage](https://commons.apache.org/)
-+ [Apache Issue Tracker (JIRA)](https://issues.apache.org/jira/browse/DBCP)
-+ [Apache Commons Twitter Account](https://twitter.com/ApacheCommons)
-+ `#apache-commons` IRC channel on `irc.freenode.org`
-
-[ml]:https://commons.apache.org/mail-lists.html
+<!---
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements.  See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License.  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<!---
+ +======================================================================+
+ |****                                                              ****|
+ |****      THIS FILE IS GENERATED BY THE COMMONS BUILD PLUGIN      ****|
+ |****                    DO NOT EDIT DIRECTLY                      ****|
+ |****                                                              ****|
+ +======================================================================+
+ | TEMPLATE FILE: readme-md-template.md                                 |
+ | commons-build-plugin/trunk/src/main/resources/commons-xdoc-templates |
+ +======================================================================+
+ |                                                                      |
+ | 1) Re-generate using: mvn commons-build:readme-md                    |
+ |                                                                      |
+ | 2) Set the following properties in the component's pom:              |
+ |    - commons.componentid (required, alphabetic, lower case)          |
+ |    - commons.release.version (required)                              |
+ |                                                                      |
+ | 3) Example Properties                                                |
+ |                                                                      |
+ |  <properties>                                                        |
+ |    <commons.componentid>math</commons.componentid>                   |
+ |    <commons.release.version>1.2</commons.release.version>            |
+ |  </properties>                                                       |
+ |                                                                      |
+ +======================================================================+
+--->
+Apache Commons DBCP
+===================
+
+[![Build Status](https://travis-ci.org/apache/commons-dbcp.svg)](https://travis-ci.org/apache/commons-dbcp)
+[![Coverage Status](https://coveralls.io/repos/apache/commons-dbcp/badge.svg)](https://coveralls.io/r/apache/commons-dbcp)
+[![Maven Central](https://maven-badges.herokuapp.com/maven-central/org.apache.commons/commons-dbcp2/badge.svg)](https://maven-badges.herokuapp.com/maven-central/org.apache.commons/commons-dbcp2/)
+[![Javadocs](https://javadoc.io/badge/org.apache.commons/commons-dbcp2/2.6.0.svg)](https://javadoc.io/doc/org.apache.commons/commons-dbcp2/2.6.0)
+
+Apache Commons DBCP software implements Database Connection Pooling
+
+Documentation
+-------------
+
+More information can be found on the [Apache Commons DBCP homepage](https://commons.apache.org/proper/commons-dbcp).
+The [Javadoc](https://commons.apache.org/proper/commons-dbcp/apidocs) can be browsed.
+Questions related to the usage of Apache Commons DBCP should be posted to the [user mailing list][ml].
+
+Where can I get the latest release?
+-----------------------------------
+You can download source and binaries from our [download page](https://commons.apache.org/proper/commons-dbcp/download_dbcp.cgi).
+
+Alternatively you can pull it from the central Maven repositories:
+
+```xml
+<dependency>
+  <groupId>org.apache.commons</groupId>
+  <artifactId>commons-dbcp2</artifactId>
+  <version>2.6.0</version>
+</dependency>
+```
+
+Contributing
+------------
+
+We accept Pull Requests via GitHub. The [developer mailing list][ml] is the main channel of communication for contributors.
+There are some guidelines which will make applying PRs easier for us:
++ No tabs! Please use spaces for indentation.
++ Respect the code style.
++ Create minimal diffs - disable on save actions like reformat source code or organize imports. If you feel the source code should be reformatted create a separate PR for this change.
++ Provide JUnit tests for your changes and make sure your changes don't break any existing tests by running ```mvn clean test```.
+
+If you plan to contribute on a regular basis, please consider filing a [contributor license agreement](https://www.apache.org/licenses/#clas).
+You can learn more about contributing via GitHub in our [contribution guidelines](CONTRIBUTING.md).
+
+License
+-------
+This code is under the [Apache Licence v2](https://www.apache.org/licenses/LICENSE-2.0).
+
+See the `NOTICE.txt` file for required notices and attributions.
+
+Donations
+---------
+You like Apache Commons DBCP? Then [donate back to the ASF](https://www.apache.org/foundation/contributing.html) to support the development.
+
+Additional Resources
+--------------------
+
++ [Apache Commons Homepage](https://commons.apache.org/)
++ [Apache Issue Tracker (JIRA)](https://issues.apache.org/jira/browse/DBCP)
++ [Apache Commons Twitter Account](https://twitter.com/ApacheCommons)
++ `#apache-commons` IRC channel on `irc.freenode.org`
+
+[ml]:https://commons.apache.org/mail-lists.html
diff --git a/pom.xml b/pom.xml
index 3d9b8f8..56afc69 100644
--- a/pom.xml
+++ b/pom.xml
@@ -1,513 +1,513 @@
-<?xml version="1.0"?>
-<!--
-   Licensed to the Apache Software Foundation (ASF) under one or more
-   contributor license agreements.  See the NOTICE file distributed with
-   this work for additional information regarding copyright ownership.
-   The ASF licenses this file to You under the Apache License, Version 2.0
-   (the "License"); you may not use this file except in compliance with
-   the License.  You may obtain a copy of the License at
-
-       http://www.apache.org/licenses/LICENSE-2.0
-
-   Unless required by applicable law or agreed to in writing, software
-   distributed under the License is distributed on an "AS IS" BASIS,
-   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-   See the License for the specific language governing permissions and
-   limitations under the License.
--->
-<project
-    xmlns="http://maven.apache.org/POM/4.0.0"
-    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
-  <parent>
-    <groupId>org.apache.commons</groupId>
-    <artifactId>commons-parent</artifactId>
-    <version>48</version>
-  </parent>
-  <modelVersion>4.0.0</modelVersion>
-  <artifactId>commons-dbcp2</artifactId>
-  <version>2.7.0-SNAPSHOT</version>
-  <name>Apache Commons DBCP</name>
-
-  <inceptionYear>2001</inceptionYear>
-  <description>Apache Commons DBCP software implements Database Connection Pooling</description>
-  <url>https://commons.apache.org/dbcp/</url>
-
-  <distributionManagement>
-    <!-- Cannot define in parent ATM, see COMMONSSITE-26 -->
-    <site>
-      <id>apache.website</id>
-      <name>Apache Commons Site</name>
-      <url>scm:svn:https://svn.apache.org/repos/infra/websites/production/commons/content/proper/commons-dbcp/</url>
-    </site>
-  </distributionManagement>
-
-  <issueManagement>
-    <system>jira</system>
-    <url>https://issues.apache.org/jira/browse/DBCP</url>
-  </issueManagement>
-
-  <scm>
-    <connection>scm:git:http://git-wip-us.apache.org/repos/asf/commons-dbcp.git</connection>
-    <developerConnection>scm:git:https://git-wip-us.apache.org/repos/asf/commons-dbcp.git</developerConnection>
-    <url>https://git-wip-us.apache.org/repos/asf?p=commons-dbcp.git</url>
-  </scm>
-
-  <developers>
-    <developer>
-      <name>Morgan Delagrange</name>
-      <id>morgand</id>
-      <email></email>
-      <organization></organization>
-    </developer>
-    <developer>
-      <name>Geir Magnusson</name>
-      <id>geirm</id>
-      <email></email>
-      <organization></organization>
-    </developer>
-    <developer>
-      <name>Craig McClanahan</name>
-      <id>craigmcc</id>
-      <email></email>
-      <organization></organization>
-    </developer>
-    <developer>
-      <name>John McNally</name>
-      <id>jmcnally</id>
-      <email></email>
-      <organization></organization>
-    </developer>
-    <developer>
-      <name>Martin Poeschl</name>
-      <id>mpoeschl</id>
-      <email>mpoeschl@marmot.at</email>
-      <organization>tucana.at</organization>
-    </developer>
-    <developer>
-      <name>Rodney Waldhoff</name>
-      <id>rwaldhoff</id>
-      <email></email>
-      <organization></organization>
-    </developer>
-    <developer>
-      <name>David Weinrich</name>
-      <id>dweinr1</id>
-      <email></email>
-      <organization></organization>
-    </developer>
-    <developer>
-      <name>Dirk Verbeeck</name>
-      <id>dirkv</id>
-      <email></email>
-      <organization></organization>
-    </developer>
-    <developer>
-      <name>Yoav Shapira</name>
-      <id>yoavs</id>
-      <email>yoavs@apache.org</email>
-      <organization>The Apache Software Foundation</organization>
-    </developer>
-    <developer>
-      <name>J&#x00f6;rg Schaible</name>
-      <id>joehni</id>
-      <email>joerg.schaible@gmx.de</email>
-      <organization></organization>
-      <timezone>+1</timezone>
-    </developer>
-    <developer>
-      <name>Mark Thomas</name>
-      <id>markt</id>
-      <email>markt@apache.org</email>
-      <organization>The Apache Software Foundation</organization>
-    </developer>
-    <developer>
-      <name>Gary Gregory</name>
-      <id>ggregory</id>
-      <email>ggregory@apache.org</email>
-      <organization>The Apache Software Foundation</organization>
-    </developer>
-    <developer>
-      <name>Ignacio J. Ortega</name>
-      <id>nacho</id>
-    </developer>
-    <developer>
-      <name>Sean C. Sullivan</name>
-      <id>sullis</id>
-    </developer>
-  </developers>
-  <contributors>
-    <contributor>
-      <name>Todd Carmichael</name>
-      <email>toddc@concur.com</email>
-    </contributor>
-    <contributor>
-      <name>Wayne Woodfield</name>
-    </contributor>
-    <contributor>
-      <name>Dain Sundstrom</name>
-      <email>dain@apache.org</email>
-    </contributor>
-    <contributor>
-      <name>Philippe Mouawad</name>
-    </contributor>
-    <contributor>
-      <name>Glenn L. Nielsen</name>
-    </contributor>
-    <contributor>
-      <name>James House</name>
-    </contributor>
-    <contributor>
-      <name>James Ring</name>
-    </contributor>
-    <contributor>
-      <name>Peter Wicks</name>
-       <email>pwicks@apache.org</email>
-    </contributor>
-  </contributors>
-
-  <dependencies>
-    <dependency>
-      <groupId>org.apache.commons</groupId>
-      <artifactId>commons-pool2</artifactId>
-      <version>${commons.pool.version}</version>
-    </dependency>
-
-    <dependency>
-      <groupId>commons-logging</groupId>
-      <artifactId>commons-logging</artifactId>
-      <version>1.2</version>
-    </dependency>
-
-    <dependency>
-      <groupId>org.junit.jupiter</groupId>
-      <artifactId>junit-jupiter</artifactId>
-      <version>5.4.2</version>
-      <scope>test</scope>
-    </dependency>
-
-    <dependency>
-      <groupId>org.hamcrest</groupId>
-      <artifactId>hamcrest-all</artifactId>
-      <version>1.3</version>
-      <scope>test</scope>
-    </dependency>
-
-    <dependency>
-      <groupId>org.mockito</groupId>
-      <artifactId>mockito-core</artifactId>
-      <version>2.27.0</version>
-      <scope>test</scope>
-    </dependency>
-
-    <!-- For managed connections -->
-    <dependency>
-      <groupId>org.apache.geronimo.specs</groupId>
-      <artifactId>geronimo-jta_1.1_spec</artifactId>
-      <version>1.1.1</version>
-      <optional>true</optional>
-    </dependency>
-
-    <!-- tomcat naming jars for jndi reference tests -->
-    <dependency>
-      <groupId>tomcat</groupId>
-      <artifactId>naming-common</artifactId>
-      <version>5.0.28</version>
-      <scope>test</scope>
-    </dependency>
-
-    <dependency>
-      <groupId>tomcat</groupId>
-      <artifactId>naming-java</artifactId>
-      <version>5.0.28</version>
-      <scope>test</scope>
-    </dependency>
-
-    <!-- for testing of managed connections -->
-    <dependency>
-      <groupId>org.apache.geronimo.modules</groupId>
-      <artifactId>geronimo-transaction</artifactId>
-      <version>2.2.1</version>
-      <scope>test</scope>
-      <exclusions>
-        <exclusion>
-          <artifactId>org.junit.jupiter</artifactId>
-          <groupId>junit-jupiter</groupId>
-        </exclusion>
-        <exclusion>
-          <artifactId>commons-logging</artifactId>
-          <groupId>commons-logging</groupId>
-        </exclusion>
-      </exclusions>
-    </dependency>
-    <dependency>
-      <groupId>org.slf4j</groupId>
-      <artifactId>slf4j-simple</artifactId>
-      <version>1.7.26</version>
-      <scope>test</scope>
-    </dependency>
-    <dependency>
-      <groupId>com.h2database</groupId>
-      <artifactId>h2</artifactId>
-      <version>1.4.199</version>
-      <scope>test</scope>
-    </dependency>
-    <dependency>
-      <groupId>org.jboss.narayana.jta</groupId>
-      <artifactId>narayana-jta</artifactId>
-      <version>5.9.5.Final</version>
-      <scope>test</scope>
-    </dependency>
-    <dependency>
-      <groupId>org.jboss.spec.javax.transaction</groupId>
-      <artifactId>jboss-transaction-api_1.2_spec</artifactId>
-      <version>1.1.1.Final</version>
-      <scope>test</scope>
-    </dependency>
-    <dependency>
-      <groupId>org.jboss</groupId>
-      <artifactId>jboss-transaction-spi</artifactId>
-      <version>7.6.0.Final</version>
-      <exclusions>
-        <exclusion>
-          <groupId>org.jboss.logging</groupId>
-          <artifactId>jboss-logging-spi</artifactId>
-        </exclusion>
-      </exclusions>
-      <scope>test</scope>
-    </dependency>
-    <dependency>
-      <groupId>org.jboss.logging</groupId>
-      <artifactId>jboss-logging</artifactId>
-      <version>3.3.2.Final</version>
-      <scope>test</scope>
-    </dependency>
-  </dependencies>
-
-  <properties>
-    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
-    <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
-    <maven.compiler.source>1.8</maven.compiler.source>
-    <maven.compiler.target>1.8</maven.compiler.target>
-    <commons.componentid>dbcp</commons.componentid>
-    <commons.rc.version>RC1</commons.rc.version>
-    <commons.module.name>org.apache.commons.dbcp2</commons.module.name>
-    
-    <commons.release.version>2.7.0</commons.release.version>
-    <commons.release.desc>for JDBC 4.2 on Java 8</commons.release.desc>
-    
-    <commons.release.2.version>2.4.0</commons.release.2.version>
-    <commons.release.2.desc>for JDBC 4.1 on Java 7</commons.release.2.desc>
-    
-    <!-- override parent name, because 1.x uses different artifactId -->
-    <commons.release.3.name>commons-dbcp-${commons.release.3.version}</commons.release.3.name>
-    <commons.release.3.version>1.4</commons.release.3.version>
-    <commons.release.3.desc>for JDBC 4 on Java 6</commons.release.3.desc>
-    
-    <!-- override parent name, because 1.x uses different artifactId -->
-    <commons.release.4.name>commons-dbcp-${commons.release.4.version}</commons.release.4.name>
-    <commons.release.4.version>1.3</commons.release.4.version>
-    <commons.release.4.desc>for JDBC 3 on Java 1.4 or 5</commons.release.4.desc>
-    
-    <commons.site.path>dbcp</commons.site.path>
-    <commons.scmPubUrl>https://svn.apache.org/repos/infra/websites/production/commons/content/proper/commons-dbcp</commons.scmPubUrl>
-    <commons.scmPubCheckoutDirectory>site-content</commons.scmPubCheckoutDirectory>
-    <commons.jira.id>DBCP</commons.jira.id>
-    <commons.jira.pid>12310469</commons.jira.pid>
-    <!-- Override CP version until that is updated -->
-    <commons.checkstyle.version>3.0.0</commons.checkstyle.version>
-    <!-- Constant for Commons Pool version (used in multiple places) -->
-    <commons.pool.version>2.6.2</commons.pool.version>
-    <commons.japicmp.version>0.13.1</commons.japicmp.version>
-    <!-- See DBCP-445 and DBCP-454 -->
-    <commons.osgi.import>javax.transaction;version="1.1.0",javax.transaction.xa;version="1.1.0";partial=true;mandatory:=partial,*</commons.osgi.import>
-    <commons.japicmp.ignoreMissingClasses>true</commons.japicmp.ignoreMissingClasses>
-    <!-- Commons Release Plugin -->
-    <commons.bc.version>2.6.0</commons.bc.version>
-    <commons.release.isDistModule>true</commons.release.isDistModule>
-    <commons.releaseManagerName>Gary Gregory</commons.releaseManagerName>    
-    <commons.releaseManagerKey>86fdc7e2a11262cb</commons.releaseManagerKey>
-
-    <japicmp.skip>false</japicmp.skip>
-  </properties>
-
-  <build>
-    <pluginManagement>
-      <plugins>
-        <plugin>
-          <groupId>org.apache.maven.plugins</groupId>
-          <artifactId>maven-scm-publish-plugin</artifactId>
-          <version>${commons.scm-publish.version}</version>
-          <configuration>
-            <ignorePathsToDelete>
-              <ignorePathToDelete>javadocs</ignorePathToDelete>
-            </ignorePathsToDelete>
-          </configuration>
-        </plugin>
-        <!-- Allow use of "mvn checkstyle:checkstyle" -->
-        <plugin>
-          <groupId>org.apache.maven.plugins</groupId>
-          <artifactId>maven-checkstyle-plugin</artifactId>
-          <version>${commons.checkstyle.version}</version>
-          <configuration>
-            <configLocation>${basedir}/checkstyle.xml</configLocation>
-            <enableRulesSummary>false</enableRulesSummary>
-          </configuration>
-        </plugin>
-      </plugins>
-    </pluginManagement>
-    <plugins>
-      <plugin>
-        <groupId>org.apache.maven.plugins</groupId>
-        <artifactId>maven-surefire-plugin</artifactId>
-        <configuration>
-          <systemPropertyVariables>
-            <!-- Ensure that logging messages can be inspected -->
-            <org.apache.commons.logging.Log>org.apache.commons.dbcp2.StackMessageLog</org.apache.commons.logging.Log>
-          </systemPropertyVariables>
-          <excludes>
-            <!-- Test support files -->
-            <exclude>**/Tester*.java</exclude>
-            <!-- Exclude nested classes which Surefire cannot handle -->
-            <exclude>**/Test*$*.java</exclude>
-          </excludes>
-        </configuration>
-      </plugin>
-      <plugin>
-        <artifactId>maven-assembly-plugin</artifactId>
-        <configuration>
-          <descriptors>
-            <descriptor>src/main/assembly/bin.xml</descriptor>
-            <descriptor>src/main/assembly/src-tar-gz.xml</descriptor>
-            <descriptor>src/main/assembly/src-zip.xml</descriptor>
-          </descriptors>
-          <tarLongFileMode>gnu</tarLongFileMode>
-        </configuration>
-      </plugin>
-      <plugin>
-        <groupId>org.apache.maven.plugins</groupId>
-        <artifactId>maven-scm-publish-plugin</artifactId>
-        <configuration>
-          <ignorePathsToDelete>
-            <ignorePathToDelete>api-*</ignorePathToDelete>
-          </ignorePathsToDelete>
-        </configuration>
-      </plugin>
-      <plugin>
-        <groupId>org.apache.maven.plugins</groupId>
-        <artifactId>maven-javadoc-plugin</artifactId>
-        <version>${commons.javadoc.version}</version>
-        <configuration>
-          <links>
-            <link>http://docs.oracle.com/javase/7/docs/api</link>
-            <link>https://commons.apache.org/proper/commons-pool/api-${commons.pool.version}</link>
-            <link>http://docs.oracle.com/javaee/7/api/</link>
-          </links>
-        </configuration>
-      </plugin>
-    </plugins>
-  </build>
-  <reporting>
-    <plugins>
-      <plugin>
-        <groupId>com.github.siom79.japicmp</groupId>
-        <artifactId>japicmp-maven-plugin</artifactId>
-        <version>${commons.japicmp.version}</version>
-        <reportSets>
-          <reportSet>
-            <reports>
-              <report>cmp-report</report>
-            </reports>
-          </reportSet>
-        </reportSets>
-        <configuration>
-          <parameter>
-            <onlyModified>true</onlyModified>
-            <breakBuildOnBinaryIncompatibleModifications>${commons.japicmp.breakBuildOnBinaryIncompatibleModifications}</breakBuildOnBinaryIncompatibleModifications>
-            <!-- skip japicmp on "mvn site" - use "mvn package site" to include report -->
-            <ignoreMissingNewVersion>true</ignoreMissingNewVersion>
-            <reportOnlyFilename>true</reportOnlyFilename>
-            <skipPomModules>true</skipPomModules>
-            <ignoreMissingClasses>${commons.japicmp.ignoreMissingClasses}</ignoreMissingClasses>
-            <oldVersionPattern>${commons.bc.version}</oldVersionPattern>
-          </parameter>
-          <dependencies>
-            <dependency>
-              <groupId>org.apache.geronimo.specs</groupId>
-              <artifactId>geronimo-jta_1.1_spec</artifactId>
-              <version>1.1.1</version>
-            </dependency>
-          </dependencies>
-        </configuration>
-      </plugin>    
-      <plugin>
-        <groupId>org.codehaus.mojo</groupId>
-        <artifactId>findbugs-maven-plugin</artifactId>
-        <version>3.0.5</version>
-        <configuration>
-          <threshold>Normal</threshold>
-          <effort>Default</effort>
-          <excludeFilterFile>${basedir}/findbugs-exclude-filter.xml</excludeFilterFile>
-        </configuration>
-      </plugin>
-      <plugin>
-        <groupId>org.apache.maven.plugins</groupId>
-        <artifactId>maven-javadoc-plugin</artifactId>
-        <version>${commons.javadoc.version}</version>
-        <configuration>
-          <links>
-            <link>http://docs.oracle.com/javase/7/docs/api</link>
-            <link>https://commons.apache.org/proper/commons-pool/api-${commons.pool.version}</link>
-            <link>http://docs.oracle.com/javaee/7/api/</link>
-          </links>
-        </configuration>
-      </plugin>
-      <plugin>
-        <groupId>org.apache.maven.plugins</groupId>
-        <artifactId>maven-changes-plugin</artifactId>
-        <version>${commons.changes.version}</version>
-        <configuration>
-          <template>release-notes.vm</template>
-          <templateDirectory>src/changes</templateDirectory>
-          <!-- Limit this to released, supported versions else there are -->
-          <!-- to many issues in the report -->
-          <fixVersionIds>12313721,12326766,12328750</fixVersionIds>
-        </configuration>
-      </plugin>
-      <plugin>
-        <groupId>org.apache.maven.plugins</groupId>
-        <artifactId>maven-checkstyle-plugin</artifactId>
-        <version>${commons.checkstyle.version}</version>
-        <configuration>
-          <configLocation>${basedir}/checkstyle.xml</configLocation>
-          <enableRulesSummary>false</enableRulesSummary>
-        </configuration>
-      </plugin>
-      <plugin>
-        <groupId>org.codehaus.mojo</groupId>
-        <artifactId>clirr-maven-plugin</artifactId>
-        <version>${commons.clirr.version}</version>
-        <configuration>
-          <minSeverity>info</minSeverity>
-        </configuration>
-      </plugin>
-      <plugin>
-        <artifactId>maven-pmd-plugin</artifactId>
-        <version>3.12.0</version>
-        <configuration>
-          <targetJdk>${maven.compiler.target}</targetJdk>
-        </configuration>
-        <reportSets>
-          <reportSet>
-            <reports>
-              <report>pmd</report>
-              <report>cpd</report>
-            </reports>
-          </reportSet>
-        </reportSets>
-      </plugin>
-    </plugins>
-  </reporting>
-  <profiles>
-  </profiles>
-</project>
+<?xml version="1.0"?>
+<!--
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You under the Apache License, Version 2.0
+   (the "License"); you may not use this file except in compliance with
+   the License.  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+<project
+    xmlns="http://maven.apache.org/POM/4.0.0"
+    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+  <parent>
+    <groupId>org.apache.commons</groupId>
+    <artifactId>commons-parent</artifactId>
+    <version>48</version>
+  </parent>
+  <modelVersion>4.0.0</modelVersion>
+  <artifactId>commons-dbcp2</artifactId>
+  <version>2.7.0-SNAPSHOT</version>
+  <name>Apache Commons DBCP</name>
+
+  <inceptionYear>2001</inceptionYear>
+  <description>Apache Commons DBCP software implements Database Connection Pooling</description>
+  <url>https://commons.apache.org/dbcp/</url>
+
+  <distributionManagement>
+    <!-- Cannot define in parent ATM, see COMMONSSITE-26 -->
+    <site>
+      <id>apache.website</id>
+      <name>Apache Commons Site</name>
+      <url>scm:svn:https://svn.apache.org/repos/infra/websites/production/commons/content/proper/commons-dbcp/</url>
+    </site>
+  </distributionManagement>
+
+  <issueManagement>
+    <system>jira</system>
+    <url>https://issues.apache.org/jira/browse/DBCP</url>
+  </issueManagement>
+
+  <scm>
+    <connection>scm:git:http://git-wip-us.apache.org/repos/asf/commons-dbcp.git</connection>
+    <developerConnection>scm:git:https://git-wip-us.apache.org/repos/asf/commons-dbcp.git</developerConnection>
+    <url>https://git-wip-us.apache.org/repos/asf?p=commons-dbcp.git</url>
+  </scm>
+
+  <developers>
+    <developer>
+      <name>Morgan Delagrange</name>
+      <id>morgand</id>
+      <email></email>
+      <organization></organization>
+    </developer>
+    <developer>
+      <name>Geir Magnusson</name>
+      <id>geirm</id>
+      <email></email>
+      <organization></organization>
+    </developer>
+    <developer>
+      <name>Craig McClanahan</name>
+      <id>craigmcc</id>
+      <email></email>
+      <organization></organization>
+    </developer>
+    <developer>
+      <name>John McNally</name>
+      <id>jmcnally</id>
+      <email></email>
+      <organization></organization>
+    </developer>
+    <developer>
+      <name>Martin Poeschl</name>
+      <id>mpoeschl</id>
+      <email>mpoeschl@marmot.at</email>
+      <organization>tucana.at</organization>
+    </developer>
+    <developer>
+      <name>Rodney Waldhoff</name>
+      <id>rwaldhoff</id>
+      <email></email>
+      <organization></organization>
+    </developer>
+    <developer>
+      <name>David Weinrich</name>
+      <id>dweinr1</id>
+      <email></email>
+      <organization></organization>
+    </developer>
+    <developer>
+      <name>Dirk Verbeeck</name>
+      <id>dirkv</id>
+      <email></email>
+      <organization></organization>
+    </developer>
+    <developer>
+      <name>Yoav Shapira</name>
+      <id>yoavs</id>
+      <email>yoavs@apache.org</email>
+      <organization>The Apache Software Foundation</organization>
+    </developer>
+    <developer>
+      <name>J&#x00f6;rg Schaible</name>
+      <id>joehni</id>
+      <email>joerg.schaible@gmx.de</email>
+      <organization></organization>
+      <timezone>+1</timezone>
+    </developer>
+    <developer>
+      <name>Mark Thomas</name>
+      <id>markt</id>
+      <email>markt@apache.org</email>
+      <organization>The Apache Software Foundation</organization>
+    </developer>
+    <developer>
+      <name>Gary Gregory</name>
+      <id>ggregory</id>
+      <email>ggregory@apache.org</email>
+      <organization>The Apache Software Foundation</organization>
+    </developer>
+    <developer>
+      <name>Ignacio J. Ortega</name>
+      <id>nacho</id>
+    </developer>
+    <developer>
+      <name>Sean C. Sullivan</name>
+      <id>sullis</id>
+    </developer>
+  </developers>
+  <contributors>
+    <contributor>
+      <name>Todd Carmichael</name>
+      <email>toddc@concur.com</email>
+    </contributor>
+    <contributor>
+      <name>Wayne Woodfield</name>
+    </contributor>
+    <contributor>
+      <name>Dain Sundstrom</name>
+      <email>dain@apache.org</email>
+    </contributor>
+    <contributor>
+      <name>Philippe Mouawad</name>
+    </contributor>
+    <contributor>
+      <name>Glenn L. Nielsen</name>
+    </contributor>
+    <contributor>
+      <name>James House</name>
+    </contributor>
+    <contributor>
+      <name>James Ring</name>
+    </contributor>
+    <contributor>
+      <name>Peter Wicks</name>
+       <email>pwicks@apache.org</email>
+    </contributor>
+  </contributors>
+
+  <dependencies>
+    <dependency>
+      <groupId>org.apache.commons</groupId>
+      <artifactId>commons-pool2</artifactId>
+      <version>${commons.pool.version}</version>
+    </dependency>
+
+    <dependency>
+      <groupId>commons-logging</groupId>
+      <artifactId>commons-logging</artifactId>
+      <version>1.2</version>
+    </dependency>
+
+    <dependency>
+      <groupId>org.junit.jupiter</groupId>
+      <artifactId>junit-jupiter</artifactId>
+      <version>5.4.2</version>
+      <scope>test</scope>
+    </dependency>
+
+    <dependency>
+      <groupId>org.hamcrest</groupId>
+      <artifactId>hamcrest-all</artifactId>
+      <version>1.3</version>
+      <scope>test</scope>
+    </dependency>
+
+    <dependency>
+      <groupId>org.mockito</groupId>
+      <artifactId>mockito-core</artifactId>
+      <version>2.27.0</version>
+      <scope>test</scope>
+    </dependency>
+
+    <!-- For managed connections -->
+    <dependency>
+      <groupId>org.apache.geronimo.specs</groupId>
+      <artifactId>geronimo-jta_1.1_spec</artifactId>
+      <version>1.1.1</version>
+      <optional>true</optional>
+    </dependency>
+
+    <!-- tomcat naming jars for jndi reference tests -->
+    <dependency>
+      <groupId>tomcat</groupId>
+      <artifactId>naming-common</artifactId>
+      <version>5.0.28</version>
+      <scope>test</scope>
+    </dependency>
+
+    <dependency>
+      <groupId>tomcat</groupId>
+      <artifactId>naming-java</artifactId>
+      <version>5.0.28</version>
+      <scope>test</scope>
+    </dependency>
+
+    <!-- for testing of managed connections -->
+    <dependency>
+      <groupId>org.apache.geronimo.modules</groupId>
+      <artifactId>geronimo-transaction</artifactId>
+      <version>2.2.1</version>
+      <scope>test</scope>
+      <exclusions>
+        <exclusion>
+          <artifactId>org.junit.jupiter</artifactId>
+          <groupId>junit-jupiter</groupId>
+        </exclusion>
+        <exclusion>
+          <artifactId>commons-logging</artifactId>
+          <groupId>commons-logging</groupId>
+        </exclusion>
+      </exclusions>
+    </dependency>
+    <dependency>
+      <groupId>org.slf4j</groupId>
+      <artifactId>slf4j-simple</artifactId>
+      <version>1.7.26</version>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>com.h2database</groupId>
+      <artifactId>h2</artifactId>
+      <version>1.4.199</version>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.jboss.narayana.jta</groupId>
+      <artifactId>narayana-jta</artifactId>
+      <version>5.9.5.Final</version>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.jboss.spec.javax.transaction</groupId>
+      <artifactId>jboss-transaction-api_1.2_spec</artifactId>
+      <version>1.1.1.Final</version>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.jboss</groupId>
+      <artifactId>jboss-transaction-spi</artifactId>
+      <version>7.6.0.Final</version>
+      <exclusions>
+        <exclusion>
+          <groupId>org.jboss.logging</groupId>
+          <artifactId>jboss-logging-spi</artifactId>
+        </exclusion>
+      </exclusions>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.jboss.logging</groupId>
+      <artifactId>jboss-logging</artifactId>
+      <version>3.3.2.Final</version>
+      <scope>test</scope>
+    </dependency>
+  </dependencies>
+
+  <properties>
+    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+    <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
+    <maven.compiler.source>1.8</maven.compiler.source>
+    <maven.compiler.target>1.8</maven.compiler.target>
+    <commons.componentid>dbcp</commons.componentid>
+    <commons.rc.version>RC1</commons.rc.version>
+    <commons.module.name>org.apache.commons.dbcp2</commons.module.name>
+    
+    <commons.release.version>2.7.0</commons.release.version>
+    <commons.release.desc>for JDBC 4.2 on Java 8</commons.release.desc>
+    
+    <commons.release.2.version>2.4.0</commons.release.2.version>
+    <commons.release.2.desc>for JDBC 4.1 on Java 7</commons.release.2.desc>
+    
+    <!-- override parent name, because 1.x uses different artifactId -->
+    <commons.release.3.name>commons-dbcp-${commons.release.3.version}</commons.release.3.name>
+    <commons.release.3.version>1.4</commons.release.3.version>
+    <commons.release.3.desc>for JDBC 4 on Java 6</commons.release.3.desc>
+    
+    <!-- override parent name, because 1.x uses different artifactId -->
+    <commons.release.4.name>commons-dbcp-${commons.release.4.version}</commons.release.4.name>
+    <commons.release.4.version>1.3</commons.release.4.version>
+    <commons.release.4.desc>for JDBC 3 on Java 1.4 or 5</commons.release.4.desc>
+    
+    <commons.site.path>dbcp</commons.site.path>
+    <commons.scmPubUrl>https://svn.apache.org/repos/infra/websites/production/commons/content/proper/commons-dbcp</commons.scmPubUrl>
+    <commons.scmPubCheckoutDirectory>site-content</commons.scmPubCheckoutDirectory>
+    <commons.jira.id>DBCP</commons.jira.id>
+    <commons.jira.pid>12310469</commons.jira.pid>
+    <!-- Override CP version until that is updated -->
+    <commons.checkstyle.version>3.0.0</commons.checkstyle.version>
+    <!-- Constant for Commons Pool version (used in multiple places) -->
+    <commons.pool.version>2.6.2</commons.pool.version>
+    <commons.japicmp.version>0.13.1</commons.japicmp.version>
+    <!-- See DBCP-445 and DBCP-454 -->
+    <commons.osgi.import>javax.transaction;version="1.1.0",javax.transaction.xa;version="1.1.0";partial=true;mandatory:=partial,*</commons.osgi.import>
+    <commons.japicmp.ignoreMissingClasses>true</commons.japicmp.ignoreMissingClasses>
+    <!-- Commons Release Plugin -->
+    <commons.bc.version>2.6.0</commons.bc.version>
+    <commons.release.isDistModule>true</commons.release.isDistModule>
+    <commons.releaseManagerName>Gary Gregory</commons.releaseManagerName>    
+    <commons.releaseManagerKey>86fdc7e2a11262cb</commons.releaseManagerKey>
+
+    <japicmp.skip>false</japicmp.skip>
+  </properties>
+
+  <build>
+    <pluginManagement>
+      <plugins>
+        <plugin>
+          <groupId>org.apache.maven.plugins</groupId>
+          <artifactId>maven-scm-publish-plugin</artifactId>
+          <version>${commons.scm-publish.version}</version>
+          <configuration>
+            <ignorePathsToDelete>
+              <ignorePathToDelete>javadocs</ignorePathToDelete>
+            </ignorePathsToDelete>
+          </configuration>
+        </plugin>
+        <!-- Allow use of "mvn checkstyle:checkstyle" -->
+        <plugin>
+          <groupId>org.apache.maven.plugins</groupId>
+          <artifactId>maven-checkstyle-plugin</artifactId>
+          <version>${commons.checkstyle.version}</version>
+          <configuration>
+            <configLocation>${basedir}/checkstyle.xml</configLocation>
+            <enableRulesSummary>false</enableRulesSummary>
+          </configuration>
+        </plugin>
+      </plugins>
+    </pluginManagement>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-surefire-plugin</artifactId>
+        <configuration>
+          <systemPropertyVariables>
+            <!-- Ensure that logging messages can be inspected -->
+            <org.apache.commons.logging.Log>org.apache.commons.dbcp2.StackMessageLog</org.apache.commons.logging.Log>
+          </systemPropertyVariables>
+          <excludes>
+            <!-- Test support files -->
+            <exclude>**/Tester*.java</exclude>
+            <!-- Exclude nested classes which Surefire cannot handle -->
+            <exclude>**/Test*$*.java</exclude>
+          </excludes>
+        </configuration>
+      </plugin>
+      <plugin>
+        <artifactId>maven-assembly-plugin</artifactId>
+        <configuration>
+          <descriptors>
+            <descriptor>src/main/assembly/bin.xml</descriptor>
+            <descriptor>src/main/assembly/src-tar-gz.xml</descriptor>
+            <descriptor>src/main/assembly/src-zip.xml</descriptor>
+          </descriptors>
+          <tarLongFileMode>gnu</tarLongFileMode>
+        </configuration>
+      </plugin>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-scm-publish-plugin</artifactId>
+        <configuration>
+          <ignorePathsToDelete>
+            <ignorePathToDelete>api-*</ignorePathToDelete>
+          </ignorePathsToDelete>
+        </configuration>
+      </plugin>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-javadoc-plugin</artifactId>
+        <version>${commons.javadoc.version}</version>
+        <configuration>
+          <links>
+            <link>http://docs.oracle.com/javase/7/docs/api</link>
+            <link>https://commons.apache.org/proper/commons-pool/api-${commons.pool.version}</link>
+            <link>http://docs.oracle.com/javaee/7/api/</link>
+          </links>
+        </configuration>
+      </plugin>
+    </plugins>
+  </build>
+  <reporting>
+    <plugins>
+      <plugin>
+        <groupId>com.github.siom79.japicmp</groupId>
+        <artifactId>japicmp-maven-plugin</artifactId>
+        <version>${commons.japicmp.version}</version>
+        <reportSets>
+          <reportSet>
+            <reports>
+              <report>cmp-report</report>
+            </reports>
+          </reportSet>
+        </reportSets>
+        <configuration>
+          <parameter>
+            <onlyModified>true</onlyModified>
+            <breakBuildOnBinaryIncompatibleModifications>${commons.japicmp.breakBuildOnBinaryIncompatibleModifications}</breakBuildOnBinaryIncompatibleModifications>
+            <!-- skip japicmp on "mvn site" - use "mvn package site" to include report -->
+            <ignoreMissingNewVersion>true</ignoreMissingNewVersion>
+            <reportOnlyFilename>true</reportOnlyFilename>
+            <skipPomModules>true</skipPomModules>
+            <ignoreMissingClasses>${commons.japicmp.ignoreMissingClasses}</ignoreMissingClasses>
+            <oldVersionPattern>${commons.bc.version}</oldVersionPattern>
+          </parameter>
+          <dependencies>
+            <dependency>
+              <groupId>org.apache.geronimo.specs</groupId>
+              <artifactId>geronimo-jta_1.1_spec</artifactId>
+              <version>1.1.1</version>
+            </dependency>
+          </dependencies>
+        </configuration>
+      </plugin>    
+      <plugin>
+        <groupId>org.codehaus.mojo</groupId>
+        <artifactId>findbugs-maven-plugin</artifactId>
+        <version>3.0.5</version>
+        <configuration>
+          <threshold>Normal</threshold>
+          <effort>Default</effort>
+          <excludeFilterFile>${basedir}/findbugs-exclude-filter.xml</excludeFilterFile>
+        </configuration>
+      </plugin>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-javadoc-plugin</artifactId>
+        <version>${commons.javadoc.version}</version>
+        <configuration>
+          <links>
+            <link>http://docs.oracle.com/javase/7/docs/api</link>
+            <link>https://commons.apache.org/proper/commons-pool/api-${commons.pool.version}</link>
+            <link>http://docs.oracle.com/javaee/7/api/</link>
+          </links>
+        </configuration>
+      </plugin>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-changes-plugin</artifactId>
+        <version>${commons.changes.version}</version>
+        <configuration>
+          <template>release-notes.vm</template>
+          <templateDirectory>src/changes</templateDirectory>
+          <!-- Limit this to released, supported versions else there are -->
+          <!-- to many issues in the report -->
+          <fixVersionIds>12313721,12326766,12328750</fixVersionIds>
+        </configuration>
+      </plugin>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-checkstyle-plugin</artifactId>
+        <version>${commons.checkstyle.version}</version>
+        <configuration>
+          <configLocation>${basedir}/checkstyle.xml</configLocation>
+          <enableRulesSummary>false</enableRulesSummary>
+        </configuration>
+      </plugin>
+      <plugin>
+        <groupId>org.codehaus.mojo</groupId>
+        <artifactId>clirr-maven-plugin</artifactId>
+        <version>${commons.clirr.version}</version>
+        <configuration>
+          <minSeverity>info</minSeverity>
+        </configuration>
+      </plugin>
+      <plugin>
+        <artifactId>maven-pmd-plugin</artifactId>
+        <version>3.12.0</version>
+        <configuration>
+          <targetJdk>${maven.compiler.target}</targetJdk>
+        </configuration>
+        <reportSets>
+          <reportSet>
+            <reports>
+              <report>pmd</report>
+              <report>cpd</report>
+            </reports>
+          </reportSet>
+        </reportSets>
+      </plugin>
+    </plugins>
+  </reporting>
+  <profiles>
+  </profiles>
+</project>
diff --git a/src/changes/changes.xml b/src/changes/changes.xml
index d431bed..3444883 100644
--- a/src/changes/changes.xml
+++ b/src/changes/changes.xml
@@ -1,1041 +1,1041 @@
-<?xml version="1.0"?>
-<!--
-   Licensed to the Apache Software Foundation (ASF) under one or more
-  contributor license agreements.  See the NOTICE file distributed with
-  this work for additional information regarding copyright ownership.
-  The ASF licenses this file to You under the Apache License, Version 2.0
-  (the "License"); you may not use this file except in compliance with
-  the License.  You may obtain a copy of the License at
-
-       http://www.apache.org/licenses/LICENSE-2.0
-
-   Unless required by applicable law or agreed to in writing, software
-   distributed under the License is distributed on an "AS IS" BASIS,
-   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-   See the License for the specific language governing permissions and
-   limitations under the License.
--->
-
-<!--
-This file is used by the maven-changes-plugin to generate the release notes.
-Useful ways of finding items to add to this file are:
-
-1.  Add items when you fix a bug or add a feature (this makes the
-release process easy :-).
-
-2.  Do a bugzilla search for tickets closed since the previous release.
-
-3.  Use the report generated by the maven-changelog-plugin to see all
-SVN commits.  Set the project.properties' maven.changelog.range
-property to the number of days since the last release.
-
-To generate the release notes from this file:
-
-mvn changes:announcement-generate -Prelease-notes [-Dchanges.version=nnn]
-
-then tweak the formatting if necessary
-and commit
-
-The <action> type attribute can be add,update,fix,remove.
--->
-
-<document>
-  <properties>
-    <title>Apache Commons DBCP Release Notes</title>
-  </properties>
-    <!-- NOTE:
-    The description below is specially formatted so as to improve the layout of the generated release notes:
-    The parsing process removes all line feeds, replacing them with a single space.
-    The Velocity template in src/changes has been enhanced to replace pairs of adjacent spaces
-    with a new-line in the release notes. (These spaces are ignored when displaying HTML).
-    If the output is not quite correct, check for invisible trailing spaces!
-
-    N.B. The release notes template groups actions by type, and only extracts data for the current release.
-    The changes report outputs actions in the order they appear in this file.
-
-    To regenerate the release notes:
-    mvn changes:announcement-generate -Prelease-notes [-Dchanges.version=nnn]
-
-    Defining changes.version allows one to create the RN without first removing the SNAPSHOT suffix.
-     -->
-
-  <body>
-    <release version="2.7.0" date="2019-MM-DD" description="This is a minor release, including bug fixes and enhancements.">
-      <action dev="jleroux" type="add" issue="DBCP-539" due-to="Jacques Le Roux">
-        ManagedDataSource#close() should declare used exceptions.
-      </action>
-      <action dev="ggregory" type="add" issue="DBCP-538" due-to="Ragnar Haugan, Gary Gregory">
-        Wrong JMX base name derived in BasicDataSource#updateJmxName.
-      </action>
-      <action dev="ggregory" type="update" due-to="Gary Gregory">
-        Update tests from H2 1.4.198 to 1.4.199.
-      </action>
-      <action dev="ggregory" type="update" issue="DBCP-540" due-to="emopers">
-        Close ObjectOutputStream before calling toByteArray() on underlying ByteArrayOutputStream #28.
-      </action>
-      <action dev="ggregory" type="update" issue="DBCP-541" due-to="Allon Murienik">
-        Upgrade to JUnit Jupiter #19.
-      </action>
-      <action dev="ggregory" type="update" issue="DBCP-542" due-to="Zheng Feng, Gary Gregory">
-        Fix tests on Java 11.
-      </action>
-      <action dev="ggregory" type="update" issue="DBCP-543" due-to="Gary Gregory">
-        Update Apache Commons Pool from 2.6.1 to 2.6.2.
-      </action>
-      <action dev="ggregory" type="update" issue="DBCP-546" due-to="Sergey Chupov">
-        Avoid NPE when calling DriverAdapterCPDS.toString().
-      </action>
-      <action dev="ggregory" type="update" issue="DBCP-547" due-to="leechoongyon, Gary Gregory">
-        Add a ConnectionFactory class name setting for BasicDataSource.createConnectionFactory() #33.
-      </action>
-      <action dev="ggregory" type="update" due-to="LichKing-lee">
-        Fix Javadoc link in README.md #21.
-      </action>
-      <action dev="ggregory" type="update" issue="DBCP-529" due-to="Yuri">
-        Add 'jmxName' property to web configuration parameters listing.
-      </action>
-    </release>
-    <release version="2.6.0" date="2019-02-14" description="This is a minor release, including bug fixes and enhancements.">
-      <action dev="chtompki" type="add" issue="DBCP-534" due-to="Peter Wicks">
-        Allow for manual connection eviction.
-      </action>
-      <action dev="ggregory" type="add" issue="DBCP-514" due-to="Tom Jenkinson, Gary Gregory">
-        Allow DBCP to register with a TransactionSynchronizationRegistry for XA cases.
-      </action>
-      <action dev="ggregory" type="update" issue="DBCP-517" due-to="Gary Gregory">
-        Make defensive copies of char[] passwords.
-      </action>
-      <action dev="ggregory" type="update" issue="DBCP-515" due-to="Tom Jenkinson, Gary Gregory">
-        Do not try to register synchronization when the transaction is no longer active.
-      </action>
-      <action dev="ggregory" type="update" issue="DBCP-516" due-to="Tom Jenkinson, Gary Gregory">
-        Do not double returnObject back to the pool if there is a transaction context with a shared connection.
-      </action>
-      <action dev="ggregory" type="fix" issue="DBCP-518" due-to="Gary Gregory">
-        Allow DBCP to work with old Java 6/JDBC drivers without throwing AbstractMethodError.
-      </action>
-      <action dev="ggregory" type="add" issue="DBCP-519" due-to="Gary Gregory">
-        Add some toString() methods for debugging (never printing passwords.)
-      </action>
-      <action dev="ggregory" type="update" issue="DBCP-520" due-to="Zheng Feng">
-        BasicManagedDataSource needs to pass the TSR with creating DataSourceXAConnectionFactory.
-      </action>
-      <action dev="ggregory" type="add" issue="DBCP-527" due-to="Gary Gregory">
-        Add getters to some classes.
-      </action>
-      <action dev="ggregory" type="add" issue="DBCP-528" due-to="Gary Gregory">
-        org.apache.commons.dbcp2.DriverManagerConnectionFactory should use a char[] instead of a String to store passwords.
-      </action>
-      <action dev="ggregory" type="update" issue="DBCP-537" due-to="Gary Gregory">
-        Update Apache Commons Pool from 2.6.0 to 2.6.1.
-      </action>
-    </release>
-    <release version="2.5.0" date="2018-07-15" description="This is a minor release, including bug fixes and enhancements.">
-      <action dev="ggregory" type="update" issue="DBCP-505" due-to="Gary Gregory">
-        Update Java requirement from version 7 to 8.
-      </action>
-      <action dev="ggregory" type="add" issue="DBCP-506" due-to="Gary Gregory">
-        Support JDBC 4.2.
-      </action>
-      <action dev="ggregory" type="add" issue="DBCP-479" due-to="Guillaume Husta, Gary Gregory">
-        Support default schema in configuration.
-      </action>
-       <action dev="ggregory" type="update" issue="DBCP-427" due-to="Vladimir Konkov, Phil Steitz, Gary Gregory">
-        Examines 'SQLException's thrown by underlying connections or statements for fatal (disconnection) errors.
-      </action>
-       <action dev="ggregory" type="update" issue="DBCP-507" due-to="Vladimir Konkov, Phil Steitz, Gary Gregory">
-        Change default for fail-fast connections from false to true.
-      </action>
-      <action dev="ggregory" type="fix" issue="DBCP-508" due-to="Gary Gregory">
-        Prepared statement keys should take a Connection's schema into account.
-      </action>
-      <action dev="ggregory" type="update" issue="DBCP-504" due-to="Bruno P. Kinoshita">
-        Increase test coverage.
-      </action>
-      <action dev="ggregory" type="update" issue="DBCP-510" due-to="Gary Gregory">
-        Update Apache Commons Pool from 2.5.0 to 2.6.0.
-      </action>
-      <action dev="ggregory" type="fix" issue="DBCP-512" due-to="Gary Gregory">
-        Avoid exceptions when closing a connection in mutli-threaded use case.
-      </action>
-    </release>
-    <release version="2.4.0" date="2018-06-12" description="This is a minor release, including bug fixes and enhancements.">
-      <action dev="ggregory" type="fix" issue="DBCP-484" due-to="Emanuel Freitas">
-        Connection leak during XATransaction in high load.
-      </action>
-      <action dev="ggregory" type="update" issue="DBCP-492" due-to="Gary Gregory">
-        Drop Ant build.
-      </action>
-      <action dev="ggregory" type="update" issue="DBCP-491" due-to="Zheng Feng, Gary Gregory">
-        Ensure DBCP ConnectionListener can deal with transaction managers which invoke rollback in a separate thread.
-      </action>
-      <action dev="ggregory" type="update" issue="DBCP-494" due-to="Gary Gregory">
-        org.apache.commons.dbcp2.PStmtKey should make copies of given arrays in constructors.
-      </action>
-      <action dev="ggregory" type="update" issue="DBCP-495" due-to="Gary Gregory">
-        Remove duplicate code in org.apache.commons.dbcp2.cpdsadapter.PStmtKeyCPDS.
-      </action>
-      <action dev="ggregory" type="fix" issue="DBCP-496" due-to="Gary Gregory">
-        Add support for pooling CallableStatements to the org.apache.commons.dbcp2.cpdsadapter package.
-      </action>
-      <action dev="ggregory" type="update" issue="DBCP-497" due-to="Gary Gregory">
-        Deprecate use of PStmtKeyCPDS in favor of PStmtKey.
-      </action>
-      <action dev="ggregory" type="update" issue="DBCP-498" due-to="Gary Gregory">
-        org.apache.commons.dbcp2.DataSourceConnectionFactory should use a char[] instead of a String to store passwords.
-      </action>
-      <action dev="ggregory" type="update" issue="DBCP-499" due-to="Gary Gregory">
-        org.apache.commons.dbcp2.managed.DataSourceXAConnectionFactory should use a char[] instead of a String to store passwords.
-      </action>
-      <action dev="ggregory" type="update" issue="DBCP-500" due-to="Gary Gregory">
-        org.apache.commons.dbcp2.cpdsadapter.DriverAdapterCPDS should use a char[] instead of a String to store passwords.
-      </action>
-      <action dev="ggregory" type="update" issue="DBCP-501" due-to="Gary Gregory">
-        org.apache.commons.dbcp2.datasources.CPDSConnectionFactory should use a char[] instead of a String to store passwords.
-      </action>
-      <action dev="ggregory" type="update" issue="DBCP-502" due-to="Gary Gregory">
-        org.apache.commons.dbcp2.datasources internals should use a char[] instead of a String to store passwords.
-      </action>
-      <action dev="ggregory" type="update" issue="DBCP-503" due-to="Gary Gregory">
-        org.apache.commons.dbcp2.datasources.InstanceKeyDataSourceFactory.closeAll() does not close all.
-      </action>
-    </release>
-    <release version="2.3.0" date="2018-05-12" description="This is a minor release, including bug fixes and enhancements.">
-      <action dev="pschumacher" type="fix" issue="DBCP-476" due-to="Gary Evesson, Richard Cordova">
-        AbandonedTrace.getTrace() contains race condition.
-      </action>
-      <action dev="ggregory" type="fix" issue="DBCP-482" due-to="Dennis Lloyd, Gary Gregory">
-        Avoid javax.management.InstanceNotFoundException on shutdown when a bean is not registered. Closes #9.
-      </action>
-      <action dev="ggregory" type="update" issue="DBCP-483" due-to="Gary Gregory">
-        Make constant public: org.apache.commons.dbcp2.PoolingDriver.URL_PREFIX.
-      </action>
-      <action dev="ggregory" type="update" issue="DBCP-486" due-to="Gary Gregory">
-        DriverAdapterCPDS.setUser(), setPassword(), and getPooledConnection() with null arguments throw NullPointerExceptions when connection properties are set.
-      </action>
-      <action dev="ggregory" type="update" issue="DBCP-487" due-to="Gary Gregory">
-        Add API org.apache.commons.dbcp2.datasources.PerUserPoolDataSource.clear().
-      </action>
-      <action dev="ggregory" type="update" issue="DBCP-488" due-to="Gary Gregory">
-        NPE for org.apache.commons.dbcp2.cpdsadapter.DriverAdapterCPDS.setConnectionProperties(null).
-      </action>
-      <action dev="ggregory" type="update" issue="DBCP-490" due-to="Gary Gregory">
-        The method org.apache.commons.dbcp2.PoolingDriver.getConnectionPool(String) does not tell you which pool name is not registered when it throws an exception.
-      </action>
-    </release>
-    <release version="2.2.0" date="2017-12-27" description="This is a minor release, including bug fixes and enhancements.">
-      <action dev="ggregory" type="fix" issue="DBCP-481" due-to="Gary Gregory">
-        Update Apache Commons Pool from 2.4.2 to 2.5.0.
-      </action>
-      <action dev="mattsicker" type="fix" issue="DBCP-454" due-to="Philipp Marx, Matt Sicker">
-        OSGi declarations contain multiple import headers for javax.transaction.
-      </action>
-      <action dev="ggregory" type="fix" issue="DBCP-478" due-to="nicola mele">
-        Wrong parameter name in site documentation for BasicDataSource Configuration Parameters.
-      </action>
-      <action dev="psteitz" type="fix" issue="DBCP-452">
-        Add jmxName to properties set by BasicDataSourceFactory.  This
-        enables container-managed pools created from JNDI Resource
-        definitions to enable JMX by supplying a valid root JMX name.
-      </action>
-      <action dev="ggregory" type="fix" issue="DBCP-446" due-to="Gary Gregory, feng yang, Euclides M, Phil Steitz">
-        NullPointerException thrown when calling ManagedConnection.isClosed().
-      </action>
-      <action dev="psteitz" type="fix" issue="DBCP-444">
-        InvalidateConnection can result in closed connection returned by getConnection.
-      </action>
-      <action dev="ggregory" type="fix" issue="DBCP-449" due-to="Grzegorz D.">
-        Complete the fix for DBCP-418, enabling PoolableConnection class to load in environments
-        (such as GAE) where the JMX ManagementFactory is not available.
-      </action>
-      <action dev="ggregory" type="add" issue="DBCP-451">
-        Add constructor DriverManagerConnectionFactory(String).
-      </action>
-      <action dev="markt" type="fix" issue="DBCP-455" due-to="Kyohei Nakamura">
-        Ensure that the cacheState setting is used when statement pooling is
-        disabled.
-      </action>
-      <action dev="markt" type="fix" issue="DBCP-453" due-to="Philipp Marx">
-        Ensure that setSoftMinEvictableIdleTimeMillis is used when working with
-        BasicDataSource.
-      </action>
-      <action dev="markt" type="fix" issue="DBCP-456" due-to="Kyohei Nakamura">
-        Correct the name of the configuration attribute
-        softMinEvictableIdleTimeMillis.
-      </action>
-      <action dev="markt" type="fix" issue="DBCP-472">
-        Avoid potential infinite loops when checking if an SQLException is fatal
-        for a connection or not.
-      </action>
-      <action dev="markt" type="fix" issue="DBCP-468">
-        Expand the fail-fast for fatal connection errors feature to include
-        managed connections.
-      </action>
-      <action dev="markt" type="fix" issue="DBCP-463">
-        Correct a typo in the method name
-        PoolableConnectionFactory#setMaxOpenPreparedStatements. The old method
-        remains but is deprecated so not to break clients currently using the
-        incorrect name.
-      </action>
-       <action dev="markt" type="add" issue="DBCP-462" due-to="Keiichi Fujino">
-         Refactoring to prepare for a future patch to enable pooling of all
-         prepared and callable statements in PoolingConnection.
-       </action>
-       <action dev="markt" type="fix" issue="DBCP-459">
-         Ensure that a thread's interrupt status is visible to the caller if the
-         thread is interrupted during a call to
-         PoolingDataSource.getConnection().
-       </action>
-       <action dev="markt" type="add" issue="DBCP-458" due-to="Adrian Tarau">
-         Make it simpler to extend BasicDataSource to allow sub-classes to
-         provide custom GenericObjectPool implementations.
-       </action>
-       <action dev="markt" type="fix" issue="DBCP-457">
-         When using a BasicDataSource, pass changes related to the handling of
-         abandoned connections to the underlying pool so that the pool
-         configuration may be updated dynamically.
-       </action>
-       <action dev="markt" type="add" issue="DBCP-474" due-to="Keiichi Fujino">
-         Enable pooling of all prepared and callable statements
-         inPoolingConnection.
-       </action>
-    </release>
-    <release version="2.1.1" date="6 Aug 2015" description=
-"This is a patch release, including bug fixes only.">
-      <action dev="psteitz" type="update">
-        Updated pool version to 2.4.2.  The fix for POOL-300 may cause DBCP
-        users to see more reports of abandoned connections (if removal and logging
-        are configured).  Prior to the fix for POOL-300, the PrintWriter used to log
-        abandoned connection stack traces was not being flushed on each log event.
-      </action>
-      <action issue="DBCP-441" dev="psteitz" type="fix">
-        Added BasicDataSource abandonedUsageTracking property missing from BasicDataSourceFactory.
-      </action>
-      <action issue="DBCP-442" dev="psteitz" type="fix">
-        SharedPoolDataSource getConnection fails when testOnBorrow is set with
-        a null validation query.
-      </action>
-      <action issue="DBCP-438" dev="psteitz" type="fix" due-to="Raihan Kibria">
-        Nested connections in a transaction (local) throws null pointer.
-      </action>
-      <action issue="DBCP-437" dev="psteitz" type="fix">
-        BasicDataSource does not set disconnectionSql properties on its PoolableConnectionFactory.
-      </action>
-    </release>
-    <release version="2.1" date="23 Feb 2015" description=
- "This is minor release, including bug fixes and enhancements. Note that
-  one of the enhancements (DBCP-423) is to implement AutoCloseable in
-  BasicDataSource, PoolingDataSource and the InstanceKeyDataSource
-  implementations.
-      ">
-      <action issue="DBCP-420" dev="sebb" type="fix">
-        InstanceKeyDataSource discards native SQLException when given password does not match
-        password used to create the connection.
-      </action>
-      <action issue="DBCP-422" dev="ggregory" type="update">
-        Update Apache Commons Logging to 1.2 from 1.1.3.
-      </action>
-      <action dev="markt" type="fix">
-        Correct some Javadoc references to Apache Commons Pool 2 classes that
-        have changed names since Pool 1.x.
-      </action>
-      <action dev="markt" type="fix">
-        Do not ignore the configured custom eviction policy when creating a
-        BasicDataSource.
-      </action>
-      <action dev="psteitz" type="add" issue="DBCP-426" due-to="Kasper Sørensen">
-        Added invalidateConnection method to BasicDataSource.
-      </action>
-      <action issue="DBCP-428" dev="psteitz" type="fix" due-to="Vladimir Konkov">
-        Unsuccessful Connection enlistment in XA Transaction ignored by TransactionContext.
-      </action>
-      <action issue="DBCP-424" dev="psteitz" type="update">
-        Made expired connection logging configurable in BasicDataSource.  Setting
-        logExpiredConnections to false suppresses expired connection log messages.
-      </action>
-      <action issue="DBCP-423" dev="psteitz" type="update">
-        Made Datasources implement AutoCloseable.
-      </action>
-      <action issue="DBCP-427" dev="psteitz" type="add" due-to="Vladimir Konkov">
-        Added fastFailValidation property to PoolableConnection, configurable in
-        BasicDataSource.  When set to true, connections that have previously thrown
-        fatal disconnection errors will fail validation immediately (no driver calls).
-      </action>
-      <action issue="DBCP-432" dev="psteitz" type="fix">
-        Changed BasicDataSource createDataSource method to ensure that initialization
-        completes before clients get reference to newly created instances.
-      </action>
-      <action issue="DBCP-433" dev="psteitz" type="fix" due-to="Vladimir Konkov">
-        Fixed connection leak when SQLException is thrown while enlisting an XA
-        transaction.
-      </action>
-      <action issue="DBCP-434" dev="psteitz" type="fix">
-        Setting jmxName to null should suppress JMX registration of connection
-        and statement pools.
-      </action>
-      <action dev="psteitz" type="update">
-        Eliminated synchronization in BasicDataSource getNumActive, getNumIdle methods.
-      </action>
-      <action issue="DBCP-435" type="update" due-to="Denixx Baykin">
-        Added property name verification to BasicDataSourceFactory. References including
-        obsolete or unrecognized properties now generate log messages.
-      </action>
-    </release>
-    <release version="2.0.1" date="24 May 2014" description="This is a bug fix release.">
-      <action dev="markt" type="fix">
-        Small performance improvements when returning connections to the pool.
-      </action>
-      <action issue="DBCP-414" dev="markt" type="fix" due-to="Pasi Eronen">
-        Fixed DelegatingStatement close to ensure closed statements do not retain references
-        to pooled prepared statements. Due to finalization code added in 2.0, this was causing
-        pooled prepared statements to be closed by GC while in use by clients.
-      </action>
-      <action issue="DBCP-412" dev="psteitz" type="update">
-        Added check in PoolingDataSource constructor to ensure that the connection factory
-        and pool are properly linked.
-      </action>
-      <action issue="DBCP-417" dev="psteitz" type="fix">
-        Fixed connection leak when managed connections are closed during transactions.
-      </action>
-      <action issue="DBCP-418" dev="psteitz" type="fix">
-        Enable PoolableConnection class to load without JMX.
-      </action>
-    </release>
-    <release version="2.0" date="3 March 2014" description=
-"This release includes new features as well as bug fixes and enhancements.
- Version 2.0.x supports JDBC 4.1, so requires Java 7.
-
- The Java package name has been changed from 'org.apache.commons.dbcp' to 'org.apache.commons.dbcp2'.
- Also the Maven groupId is now 'org.apache.commons' and the artifactId is 'commons-dbcp2'
- These changes are necessary because the API is not strictly binary compatible with the 1.x releases.
- To convert from the earlier releases, update the package name in imports, update the dependencies and recompile.
- There may be a few other changes to be made.
-
- Applications running under Java 7 should use DBCP 2.0.x.
- Java 6 users should use DBCP 1.4.x which supports JDBC 4.
- Java 1.4 and Java 5 users should use DBCP 1.3.x which supports JDBC 3.
-      ">
-      <action issue="DBCP-411" dev="sebb" type="fix">
-        BasicManagedDataSource - unregister from JMX on close().
-      </action>
-        <action issue="DBCP-154" dev="markt" type="fix">
-        Log validation failures of poolable connections.
-      </action>
-      <action issue="DBCP-403" dev="sebb" type="fix">
-        DelegatingStatement.close() fails with NPE if statement is null
-      </action>
-      <action issue="DBCP-322" dev="sebb" type="fix">
-        CPDSConnectionFactory.validateObject(Object) ignores Throwable.
-      </action>
-      <action dev="markt" type="add">
-        Provide a new option (cacheState) to cache current values of autoCommit
-        and readOnly so database queries are not required for every call to the
-        associated getters. This option is enabled by default.
-      </action>
-      <action dev="markt" issue="DBCP-300" type="fix">
-        Removed unnecessary synchronisation in BasicDataSource#createDataSource.
-      </action>
-      <action dev="markt" type="update">
-        The Java package name has been changed from org.apache.commons.dbcp to
-        org.apache.commons.dbcp2.
-      </action>
-      <action dev="markt" type="update">
-        Update to Commons Pool 2 (based on java.util.concurrent) to provide
-        pooling functionality.
-      </action>
-      <action dev="markt" type="update">
-        Updated source code for Java 1.6 (added @Override &amp; @Deprecated
-        annotations).
-      </action>
-      <action dev="markt" type="update">
-        Removed JOCL support.
-      </action>
-      <action dev="markt" issue="DBCP-143" type="update">
-        Remove deprecated SQLNestedException.
-      </action>
-      <action dev="markt" issue="DBCP-384" type="fix">
-        Fix threading issues with accessToUnderlyingConnectionAllowed attribute
-        of PoolingDriver which is used to support unit testing.
-      </action>
-      <action dev="markt" issue="DBCP-292" type="add">
-        BasicDataSource instances are now exposed via JMX. All the configuration
-        properties are available as is the connection pool and the statement
-        pools (if statement pooling is enabled).
-      </action>
-      <action dev="markt" issue="DBCP-376" type="fix" due-to="Dave Oxley">
-        Fix thread safety issues in the SharedPoolDataSource and the
-        PerUserPoolDataSource.
-      </action>
-      <action dev="markt" issue="DBCP-382" type="fix" due-to="Stefan Rempfer">
-        Allow accessToUnderlyingConnectionAllowed to be configured when
-        configuration takes place via JNDI in a JavaEE container.
-      </action>
-      <action dev="markt" issue="DBCP-369" type="fix" due-to="Michael Pradel">
-        Fix threading issue when using multiple instances of the
-        SharedPoolDataSource concurrently.
-      </action>
-      <action dev="markt" issue="DBCP-391" type="fix">
-        Ensure that the close state of a pooled connection and the underlying
-        connection is consistent when the underlying connection is closed as a
-        result of an error condition.
-      </action>
-      <action dev="markt" issue="DBCP-404" type="fix">
-        Make all mutable fields private.
-      </action>
-      <action dev="markt" issue="DBCP-364" type="fix">
-        Return BasicDataSource rather than DataSource from
-        BasicDataSourceFactory so a cast is not required to use BasicDataSource
-        specific methods.
-      </action>
-      <action dev="markt" issue="DBCP-358" type="fix">
-        The equals() implementations of the DelegatingXxx classes are now
-        symmetric. There are some important API changes underlying this fix.
-        Firstly, two DelegatingXxx instances are no longer considered equal if
-        they have the same innermost delegate. Secondly, a DelegatingXxx
-        instance is not considered equal to its innermost delegate. The
-        getInnermostDelegateInternal() method has been made public (but remains
-        part of the internal API) to allow classes extending this implementation
-        to access the innermost delegate when required.
-      </action>
-      <action dev="markt" issue="DBCP-368" type="add">
-        Expose the new Pool 2 property evictionPolicyClassName to enable more
-        sophisticated eviction strategies to be used.
-      </action>
-      <action dev="markt" issue="DBCP-406" type="add" due-to="Steeve Beroard">
-        Add support for pooling PreparedStatements that use auto-generated keys.
-      </action>
-      <action dev="markt" issue="DBCP-180" type="fix">
-        Enable JDBC resources that are no longer referenced by client code to be
-        eligible for garbage collection.
-      </action>
-      <action dev="markt" issue="DBCP-177" type="add">
-        Enable DBCP to work with a SecurityManager such that only DBCP needs to
-        be granted the necessary permissions to communicate with the database.
-      </action>
-      <action dev="markt" issue="DBCP-410" type="fix" due-to="Andreas Sturmlechner">
-        Correct path to Javadoc overview in build.xml.
-      </action>
-      <action dev="markt" issue="DBCP-234" type="fix">
-        The default values for readOnly, autoCommit and transactionIsolation are
-        now taken from the JDBC driver. No calls to setReadOnly(),
-        setAutoCommit() or setTransactionIsolation() will be made for a newly
-        borrowed connection unless a default is explicitly configured and the
-        connection is currently using a different setting.
-      </action>
-      <action dev="markt" issue="DBCP-219" type="add">
-        Register pooled connections with JMX so that they may be forcibly closed
-        via JMX if required.
-      </action>
-      <action dev="markt" issue="DBCP-373" type="add">
-        Modify SharedPoolDataSource and PerUserPoolDataSource to expose all of
-        the configuration properties of the underlying connection pool(s). This
-        represents a significant refactoring of these classes and a number of
-        property names have changed as a result.
-      </action>
-      <action dev="markt" issue="DBCP-351" type="add">
-        Provide an option to control if autoCommit is always set to true when a
-        connection is returned to the connection pool.
-      </action>
-      <action dev="markt" issue="DBCP-399" type="add">
-        Provide an option to control if rollback is called when a connection is
-        returned to the poll with autoCommit disabled.
-      </action>
-      <action dev="markt" issue="DBCP-340" type="add">
-        Provide an option to set the default query timeout.
-      </action>
-      <action dev="markt" type="fix">
-        Connection.isValid() should not throw an SQLException if the connection
-        is closed.
-      </action>
-      <action dev="markt" issue="DBCP-357" type="fix">
-        Use Connection.isValid() to validate connections unless a validation
-        query is explicitly configured. Note that this means it is no longer
-        necessary for a validation query to be specified in order for validation
-        to take place. When testing with Oracle, this resulted in database
-        validation being approximately 7 times faster.
-      </action>
-      <action dev="markt" issue="DBCP-249" type="add">
-        Add support for validation testing database connections on creation.
-      </action>
-    </release>
-    <release version="1.5.1" date="not yet released" description="TBD">
-      <action dev="markt" issue="DBCP-400" type="fix">
-        Correct the documentation for the maxOpenPreparedStatements parameter
-        and review the use of the phrase non-positive throughout the
-        documentation and javadoc, replacing it with negative where that is the
-        correct definition to use.
-      </action>
-      <action dev="markt" issue="DBCP-405" type="fix">
-        Avoid multiple calls to Connection.getAutoCommit() in
-        PoolableConnectionFactory.passivateObject() as it could be an expensive
-        call.
-      </action>
-      <action dev="markt" issue="DBCP-392" type="fix">
-        Use one line per statement for methods with multiple statements rather
-        than using a single line.
-      </action>
-      <action dev="markt" issue="DBCP-396" type="fix">
-        Expose all of the AbandonedConfig properties through a BasicDataSource.
-      </action>
-      <action dev="markt" issue="DBCP-380" type="fix" due-to="Balazs Zsoldos">
-        Correct implementation of DelegatingConnection.isWrapperFor() so it
-        works correctly with older JDBC drivers.
-      </action>
-      <action dev="markt" issue="DBCP-347" type="fix" due-to="Robert Poskrobek">
-        Correct implementation of DelegatingStatement.isWrapperFor(). Also fix
-        DelegatingDatabaseMetaData.isWrapperFor() and
-        DelegatingResultSet.isWrapperFor() that had the same problem.
-      </action>
-      <action dev="markt" issue="DBCP-341" type="fix" due-to="Ioannis Canellos">
-        LocalXAConnectionFactory does not properly check if Xid is equal to
-        currentXid when resuming which may result in an XAException.
-      </action>
-      <action dev="markt" issue="DBCP-355" type="fix" due-to="Florent Guillaume">
-        Ensure that the XAConnection is closed when the associated Connection is
-        closed.
-      </action>
-      <action dev="markt" issue="DBCP-398" type="fix">
-        Clarify Jaavdoc for isClosed() method of PoolableConnection.
-      </action>
-      <action dev="markt" issue="DBCP-383" type="fix">
-        Avoid NullPointerException and throw an XAException if an attempt is
-        made to commit the current transaction for a connection when no
-        transaction has been started.
-      </action>
-      <action dev="markt" issue="DBCP-372" type="fix">
-        Using batchUpdate() should not invalidate the PreparedStatement when it
-        is returned to the pool.
-      </action>
-      <action dev="markt" issue="DBCP-309" type="fix">
-        Improve documentation for JNDI example using BasicDataSource.
-      </action>
-    </release>
-    <release version="1.4.1" date="not yet released" description="TBD">
-      <action dev="psteitz" issue="DBCP-334" type="update" due-to="Alberto Mozzone">
-        Exposed GenericObjectPool's softMinEvictableIdleTimeMillis property for
-        configuration and use by BasicDataSource.
-      </action>
-      <action dev="psteitz" issue="DBCP-337" type="fix" due-to="Rob Gansevles">
-        Made equals reflexive in DelegatingStatement (and subclasses), DelegatingMetaData,
-        DelegatingResultSet and PoolingDriver#PoolGuardConnectionWrapper.
-      </action>
-      <action dev="psteitz" issue="DBCP-342" type="fix" due-to="Byungchol Kim">
-        Modified createDataSource method in BasicDataSource to ensure that GenericObjectPool
-        Evictor tasks are not started and orphaned when BasicDataSource encounters errors on
-        initialization.  Prior to this fix, when minIdle and timeBetweenEvictionRunsMillis
-        are both positive, Evictors orphaned by failed initialization can continue to
-        generate database connection requests.  This issue is duplicated by DBCP-339
-        and DBCP-93.
-      </action>
-      <action dev="psteitz" issue="DBCP-330" type="fix">
-        Changed DelegatingDatabaseMetaData to no longer add itself to the AbandonedTrace
-        of its parent connection.  This was causing excessive memory consumption and was
-        not necessary, as resultsets created by DelegatingDatabaseMetaData instances are
-        attached to the parent connection's trace on creation.  Also fixes DBCP-352.
-      </action>
-      <action dev="psteitz" issue="DBCP-343" type="fix">
-        Modified execute methods of Statement objects to ensure that whenever
-        a statement is used, the lastUsed property of its parent connection is
-        updated.
-      </action>
-      <action dev="markt" issue="DBCP-333" type="fix">
-        Correctly implemented the option to configure the class loader used to load
-        the JDBC driver.
-      </action>
-      <action dev="psteitz" issue="DBCP-346" type="update" due-to="Ken Tatsushita">
-        LIFO configuration option has been added to BasicDataSource.  When set
-        to true (the default), the pool acts as a LIFO queue; setting to false
-        causes connections to enter and exit to pool in FIFO order.
-      </action>
-      <action dev="psteitz" issue="DBCP-344" type="fix" due-to="Jeremy Whiting">
-        Test transitive dependencies brought in by geronimo-transaction created
-        version conflicts (commons logging and junit).  These have been explicitly
-        excluded in the POM.
-      </action>
-      <action dev="psteitz" issue="DBCP-348" type="fix" due-to="Eiji Takahashi">
-        BasicDataSourceFactory incorrectly used "initConnectSqls" in versions
-        1.3 and 1.4 of DBCP as the property name for connectionInitSqls.
-        Online docs for 1.3/1/4 have been updated to reflect this inconsistency.
-        The BasicDataSourceFactory property name has been changed to "connectInitSqls"
-        to match the online docs and the BasicDataSource property name.
-      </action>
-    </release>
-    <release version="1.4" date="2010-02-14" description="This release includes
-     new features as well as bug fixes and enhancements.  Some bug fixes
-     change semantics (e.g. connection close is now idempotent).  The 1.3
-     and 1.4 releases of DBCP are built from the same sources.  Version 1.4
-     supports JDBC 4, so requires JDK 1.6. Applications running under
-     JDK 1.4-1.5 must use DBCP 1.3. Applications running under JDK 1.6
-     should use DBCP 1.4. Other than support for the added methods in JDBC 4,
-     there is nothing new or different in DBCP 1.4 vs. DBCP 1.3.   The list of
-     changes below since 1.2.2 applies to both the 1.3 and 1.4 release.  Other than
-     the one issue related to adding JDBC 4 support (DBCP-191), all bug fixes
-     or new features are included in both DBCP 1.3 and 1.4 ">
-      <action dev="psteitz" type="fix" issue="DBCP-320">
-        Eliminated poolKeys cache from PerUserPoolDataSource.
-      </action>
-      <action dev="sebb" type="fix" issue="DBCP-321">
-        Eliminated userKeys LRUMap cache from SharedPoolDataSource.
-      </action>
-      <action dev="psteitz" type="fix" issue="DBCP-319" due-to="Sebastian Bazley">
-        Made private fields final where possible.
-      </action>
-      <action dev="sebb" type="fix" issue="DBCP-318" due-to="Sebastian Bazley">
-        PerUserPoolDataSource.getPooledConnectionAndInfo multi-threading bug.
-      </action>
-      <action dev="sebb" type="fix" issue="DBCP-315" due-to="Sebastian Bazley">
-        Remove throws clause from method that does not throw an exception.
-      </action>
-      <action dev="sebb" type="fix" issue="DBCP-313" due-to="Sebastian Bazley">
-        Remove code that catches and ignores Exceptions when calling
-        PooledConnection.removeConnectionEventListener(ConnectionEventListener)
-        as the method does not throw any Exceptions.
-      </action>
-      <action dev="sebb" type="fix" issue="DBCP-316" due-to="Sebastian Bazley">
-        Remove impossible null check.
-      </action>
-      <action dev="sebb" type="update" issue="DBCP-314" due-to="Sebastian Bazley">
-        Renamed variables with duplicate names in different scopes.
-      </action>
-      <action dev="psteitz" type="update" issue="DBCP-312" due-to="Glen Mazza">
-        Clarified javadoc for BasicDataSource close() method.
-      </action>
-      <action dev="psteitz" type="add" issue="DBCP-204" due-to="Wei Chen">
-        Made PoolingConnection pool CallableStatements. When BasicDataSource's
-        poolPreparedStatements property is true, CallableStatements are now
-        pooled along with PreparedStatements. The maxOpenPreparedStatements
-        property limits the combined number of Callable and Prepared statements
-        that can be in use at a given time.
-      </action>
-      <action dev="markt" type="update" issue="DBCP-305" due-to="Christopher Schultz">
-        Use an API specific exception for logging abandoned objects to make
-        scanning the logs for these exceptions simpler and to provide a better
-        message that includes the creation time of the abandoned object.
-      </action>
-      <action dev="markt" type="fix" issue="DBCP-303" due-to="Dave Oxley">
-        Ensure Statement.getGeneratedKeys() works correctly with the CPDS
-        adapter.
-      </action>
-      <action dev="psteitz" type="fix" issue="DBCP-302" due-to="Sebastian Bazley">
-        Removed incorrectly advertised ClassNotFoundException from
-        JOCLContentHandler.ConstructorDetails.createObject().
-      </action>
-      <action dev="markt" type="update" issue="DBCP-203" due-to="Mark Grand">
-        Make the class loader used to load the JDBC driver configurable for the
-        BasicDatasource.
-      </action>
-      <action dev="markt" type="fix" issue="DBCP-8">
-        Handle user password changes for InstanceKeyDataSources.
-      </action>
-      <action dev="psteitz" type="update" issue="DBCP-289" due-to="Marc Kannegießer">
-        Made XADataSource configurable in BasicManagedDataSource.
-      </action>
-      <action dev="psteitz" type="fix" issue="DBCP-294" due-to="Philippe Mouawad">
-        Added PoolableManagedConnection and PoolableManagedConnectionFactory so that
-        pooled managed connections can unregister themselves from transaction registries,
-        avoiding resource leaks.
-      </action>
-      <action dev="psteitz" type="update" issue="DBCP-276">
-        Added connectionProperties property to DriverAdapterCPDS.
-      </action>
-      <action dev="psteitz" type="add" issue="DBCP-226">
-        Added a validationQueryTimeout configuration parameter to BasicDataSource
-        allowing the user to specify a timeout value (in seconds) for connection
-        validation queries.
-      </action>
-      <action dev="psteitz" type="add" issue="DBCP-175" due-to="Jiri Melichna and Jerome Lacoste">
-        Added a connectionInitSqls configuration parameter to BasicDataSource
-        allowing the user to specify a collection of SQL statements to execute
-        one time when a physical database connection is first opened.
-      </action>
-      <action dev="markt" type="fix" issue="DBCP-212">
-        PoolableConnectionFactory.makeObject() is no longer synchronized. This
-        provides improved response times when load spikes at the cost of a
-        faster rise in database server load. This change was made as a partial
-        fix for DBCP-212.  The synchronization changes in Commons Pool 1.5 complete
-        the fix for this issue.
-      </action>
-      <action dev="psteitz" type="fix" issue="DBCP-242">
-        Reverted DelegatingConnection close to 1.2.2 version to ensure
-        open statements are closed before the underlying connection is closed.
-      </action>
-      <action dev="markt" type="fix" issue="DBCP-235">
-        Refactor DelegatingConnection and ManagedConnection enable overridden
-        equals() and hashcode() to work correctly.
-      </action>
-      <action dev="markt" type="update" issue="DBCP-265">
-        Add a DelegatingDatabaseMetaData to track ResultSets returned from
-        DatabaseMetaData objects.
-      </action>
-      <action dev="markt" type="fix" issue="DBCP-215">
-        Modified BasicDataSourceFactory to complete initialization of the pool
-        by creating initialSize connections rather than leaving this to lazy
-        initialization when the pool is used.
-      </action>
-      <action dev="markt" type="fix" issue="DBCP-253">
-        Eliminated masked _stmt field in descendents of DelegatingStatement.
-       </action>
-      <action dev="markt" type="fix" issue="DBCP-191" due-to="Michael Heuer and J. David Beutel" >
-        Modified DBCP sources to support compilation under JDK 1.4-1.6
-        using Ant flags to do conditional compilation.
-      </action>
-      <action dev="markt" type="fix" issue="DBCP-272">
-        Added a static initializer to BasicDatasource that calls
-        DriverManager.getDrivers() to force initialization before we ever do
-        anything that might use Class.forName() to load (and register) a JDBC
-        driver.
-      </action>
-      <action dev="markt" type="fix" issue="DBCP-4">
-        Eliminated direct System.out calls in AbandonedTrace.
-      </action>
-      <action dev="niallp" type="fix" issue="DBCP-264">
-        Modified DelegatingStatement close to clear open batches.
-      </action>
-      <action dev="psteitz" type="fix" issue="DBCP-255">
-        Eliminated unused private "parent" field in AbandonedTrace.
-      </action>
-      <action dev="psteitz" type="fix" issue="DBCP-273" due-to="Mark Lin">
-        Fixed errors handling boolean-valued Reference properties in
-        InstanceKeyObjectFactory, DriverAdapterCPDS that were causing
-        testOnBorrow and poolPreparedStatements properties to be incorrectly
-        set when creating objects from javax.naming.Reference instances.
-      </action>
-      <action dev="psteitz" type="fix" issue="DBCP-271" due-to="Sebastian Bazley">
-        Made private instance fields of AbandonedTrace volatile (parent,
-        createdBy, lastUsed, createdTime) or final (trace).
-      </action>
-      <action dev="psteitz" type="fix" issue="DBCP-270" due-to="Filip Hanik">
-        Narrowed synchronization in AbandonedTrace to resolve an Evictor deadlock.
-      </action>
-      <action dev="bayard" type="fix" issue="DBCP-218">
-        Corrected Javadoc to state that getLoginTimeout and setLoginTimeout are
-        NOT supported by BasicDataSource.
-      </action>
-      <action dev="bayard" type="update" issue="DBCP-211">
-        Added Maven 2 pom.xml. Removed a block of code from TestJOCLed that set
-        the Xerces parser manually. This was to support early JDKs. The 1.3
-        version of DBCP requires JDK 1.4+.
-      </action>
-      <action dev="psteitz" type="add" issue="DBCP-228" due-to="Dain Sundstrom">
-        Added support for pooling managed connections.
-      </action>
-      <action dev="psteitz" type="add" issue="DBCP-230" due-to="Dain Sundstrom">
-        Added BasicManagedDataSource, extending BasicDataSource.
-        Also improved extensibility of BasicDataSource by encapsulating
-        methods to create object pool, connection factory and datasource
-        instance previously embedded in createDataSource.
-      </action>
-      <action dev="psteitz" type="update" issue="DBCP-233" due-to="Dain Sundstrom">
-        Changed behavior to allow Connection, Statement, PreparedStatement,
-        CallableStatement and ResultSet to be closed multiple times. The first
-        time close is called the resource is closed and any subsequent calls
-        have no effect. This behavior is required as per the Javadocs for these
-        classes. Also added tests for closing all types multiple times and
-        updated any tests that incorrectly assert that a resource can not be
-        closed more then once.  Fixes DBCP-3, DBCP-5, DBCP-23 and DBCP-134.
-      </action>
-      <action dev="psteitz" type="update" issue="DBCP-11" due-to="Dain Sundstrom">
-        Modified PoolingDataSource, PoolingDriver and DelegatingStatement to
-        assure that all returned Statements, PreparedStatements,
-        CallableStatements and ResultSets are wrapped with a delegating object,
-        which already properly handle the back pointers for Connection and
-        Statement.  Also added tests to to assure that the *same* object used
-        to create the statement or result set is returned  from either
-        getConnection() or getStatement().
-      </action>
-      <action dev="dain" type="update" issue="DBCP-143">
-        SQLNestedException has been deprecated and will be replaced in DBCP 2.0 with
-        SQLException and standard Java exception chaining.
-      </action>
-      <action dev="dain" type="fix" issue="DBCP-221">
-        BasicDataSource.close() now permanently marks the data source as closed,
-        and no new connections can be obtained from the data source. At close all
-        idle connections are destroyed and the method returns.  As the remaining
-        active connections are closed, they are destroyed.
-      </action>
-      <action dev="psteitz" type="fix" issue="DBCP-241">
-        Eliminated potential sources of NullPointerExceptions in
-        PoolingConnection.
-      </action>
-      <action dev="psteitz" type="fix" issue="DBCP-216" due-to="Marcos Sanz">
-        Improved error recovery and listener cleanup in
-        KeyedCPDSConnectionFactory. Substituted calls to destroyObject with
-         _pool.invalidateObject on error to ensure pool active count is
-        decremented on error events. Ensured that events from closed or invalid
-        connections are ignored and listeners are cleaned up.
-      </action>
-      <action dev="psteitz" type="fix" issue="DBCP-245" due-to="Michael Drechsel">
-        Fixed error in SharedPoolDataSource causing incorrect passwords to be
-        stored under certain conditions.
-      </action>
-      <action dev="psteitz" type="fix" issue="DBCP-237" due-to="Oliver Matz">
-        Added exception handler to ensure that PooledConnections are not
-        orphaned when an exception occurs in setUpDefaults or clearWarnings in
-        InstanceKeyDataSource.getConnection.
-      </action>
-      <action dev="psteitz" type="fix" issue="DBCP-252" due-to="FindBugs">
-        Made getPool synchronized in PoolableConnectionFactory.
-        Fixes inconsistent synchronization accessing _pool.
-      </action>
-      <action dev="psteitz" type="fix" issue="DBCP-252" due-to="FindBugs">
-        Fixed inconsistent synchronization on _rollbackAfterValidation,
-        _validationQuery and _pool in CPDSConnectionFactory and
-        KeyedCPDSConnectionFactory by making the first two volatile and making
-        both getter and setter for _pool synchronized.
-      </action>
-    </release>
-    <release version="1.3" date="2010-02-14" description="Compatability release for JDBC 3.
-      See version 1.4 description and change log.">
-     <action type="update">
-        See &lt;a href="changes-report.html#a1.4"&gt;DBCP 1.4 Changes &lt;/a&gt; for details. Version
-        1.3 is identical to 1.4, other than JDBC 4 methods being filtered out of the DBCP 1.3 sources. Changes
-        Since 1.2.2 are the same for 1.3 and 1.4.
-      </action>
-    </release>
-    <release version="1.2.2" date="2007-04-04"
-      description="This is a maintenance release containing bug fixes
-      and enhancements. All API changes are binary compatible with version 1.2.1.">
-      <action dev="dirkv " type="add">
-        Add a &lt;i&gt;JNDI How To&lt;/i&gt; to the User Guide.
-      </action>
-      <action dev="dirkv " type="fix" issue="DBCP-108" due-to="Maxwell Grender-Jones">
-        DriverManagerConnectionFactory: blank user name and password handling.
-      </action>
-      <action dev="dirkv " type="fix" issue="DBCP-113" due-to="Rohan Lenard">
-        Broken behaviour for BasicDataSource.setMaxActive(0).
-      </action>
-      <action dev="dirkv " type="fix" issue="DBCP-36" due-to="Jonathan Whitall">
-        BasicDataSource does not work with getConnection(String, String).
-      </action>
-      <action dev="dirkv " type="update" issue="DBCP-164" due-to="Todd Carmichael">
-        Enhancements to prepared statement in DriverAdapterCPDS.
-      </action>
-      <action dev="yoavs" type="update" issue="DBCP-186" due-to="Ralf Hauser">
-        Better messages and docs for LoginTimeout UnsupportedOperationException.
-      </action>
-      <action dev="yoavs" type="fix" issue="DBCP-50" due-to="Nicky Nicolson">
-        Error in JOCL snippet in org.apache.commons.dbcp package javadoc.
-      </action>
-      <action dev="yoavs" type="update" issue="DBCP-165" due-to="QM">
-        Added toString() methods to DelegatingPreparedStatement and DelegatingStatement
-      </action>
-      <action dev="yoavs" type="fix">
-        Changes to make DBCP compile on JDK 1.5 by adding source="1.4" to compiler
-        arguments (there are compiler errors in JDK 5.0 without this source switch
-        that cannot be fixed without JDK 5.0-specific syntax).
-      </action>
-      <action dev="dirkv " type="fix" issue="DBCP-20" due-to="Chris Nappin">
-        Per-user pooling with Oracle driver and default isolation settings.
-      </action>
-      <action dev="dirkv " type="fix" issue="DBCP-9" due-to="Adrian Baker">
-        Error in JOCL document in javadoc.
-      </action>
-      <action dev="sullis" type="update">
-        Added toString() method to DelegatingConnection.
-      </action>
-      <action dev="dirkv " type="update" issue="DBCP-181" due-to="Meikel Bisping">
-        Add DriverManager.invalidateConnection().
-      </action>
-      <action dev="dirkv " type="fix" issue="DBCP-184" due-to="Meikel Bisping">
-        Improved Exception nesting in ConnectionPool.
-      </action>
-      <action dev="dennisl" type="fix" issue="DBCP-144" due-to="Sebb">
-        Fix broken website links for examples.
-      </action>
-      <action dev="psteitz" type="fix" issue="DBCP-28"
-        due-to="Huw Lewis, James Ring">
-        Modified PoolableConnection close method to invalidate instance
-        when invoked on an already closed connection.
-      </action>
-      <action dev="joehni" type="fix" issue="DBCP-81">
-        Inserted null checks to avoid NPE in close operations.
-      </action>
-      <action dev="psteitz" type="fix" issue="DBCP-105"
-        due-to="Sandy McArthur, Thomas Fischer">
-        Changed getReference method in InstanceKeyDataSource to return a
-        concrete factory and added implementations of getReference in concrete
-        subclasses.
-      </action>
-      <action dev="psteitz" type="fix" issue="DBCP-39" due-to="Jindrich Vimr">
-        Inserted null check in close method of SharedPoolDataSource to avoid
-        NPE when invoked on non-initialized pool.
-      </action>
-      <action dev="psteitz" type="fix" issue="DBCP-71" due-to="Douglas Squirrel">
-        Document fact that true values for testOnBorrow, testOnReturn, testWhileIdle
-        only have effect when validationQuery is set to a non-null string.
-      </action>
-      <action dev="psteitz" type="fix" issue="DBCP-102">
-        Modified activateObject in PoolableConnection to test connection
-        properties before resetting to defaults.
-      </action>
-      <action dev="sandymac" type="fix" issue="DBCP-188">
-        Corrected maxActive documentation in configuration.html.
-      </action>
-      <action dev="psteitz"  type="update">
-        Upgraded dependency to Pool 1.3.
-      </action>
-      <action dev="psteitz" type="update" issue="DBCP-187" due-to="Ralf Hauser">
-        Added connection info to SQLException messages when closed connections
-        (resp stmts) are accessed in DelegatingConnection, DelegatingStatement.
-      </action>
-      <action dev="psteitz" type="fix" issue="DBCP-41" due-to="Anton Tagunov">
-        Fixed errors in pool parameter documentation and made
-        0 value for _maxPreparedStatements in DriverAdapterCPDS behave
-        like a negative value, to be consistent with documentation
-        and pool behavior.
-      </action>
-      <action dev="psteitz" type="fix" issue="DBCP-100">
-        Made userKeys an instance variable (i.e., not static)
-        in SharedPoolDataSource.
-      </action>
-      <action dev="psteitz" type="fix" issue="DBCP-198">
-        Changed implementation of equals in
-        PoolingDataSource.PoolGuardConnectionWrapper
-        to ensure it is reflexive, even when wrapped connections are not
-        DelegatingConnections.
-      </action>
-      <action dev="psteitz" type="update" issue="DBCP-116" due-to="Thomas Fischer">
-        Added rollbackAfterValidation property and code to issue a rollback on a
-        connection after validation when this property is set to true to eliminate
-        Oracle driver exceptions. Default property value is false.
-      </action>
-      <action dev="psteitz" type="update" issue="DBCP-68">
-        Removed dependency on Commons Collections by adding collections
-        2.1 sources for LRUMap and SequencedHashMap with package scope to
-        datasources package.
-      </action>
-      <action dev="psteitz" type="fix" issue="DBCP-65">
-        Removed synchronization from prepareStatement methods in
-        PoolingConnection. Synchronization in these methods was causing
-        deadlocks. No resources other than the prepared statement pool are
-        accessed by these methods, and the pool methods are synchronized.
-        Also fixes DBCP-202.
-      </action>
-    </release>
-
-    <release version="1.2.1" date="2004-06-12" description="Maintenance Release to restore JDK 1.3 compatibility">
-      <action type="fix">
-        See &lt;a href="release-notes-1.2.1.html"&gt;DBCP 1.2.1 Release Notes&lt;/a&gt; for details.
-      </action>
-    </release>
-
-    <release version="1.2" date="2004-06-07">
-      <action type="update">
-        See &lt;a href="release-notes-1.2.html"&gt;DBCP 1.2 Release Notes&lt;/a&gt; for details.
-      </action>
-    </release>
-
-    <release version="1.1" date="2003-10-20">
-      <action type="update">
-        See &lt;a href="release-notes-1.1.html"&gt;DBCP 1.1 Release Notes&lt;/a&gt; for details.
-      </action>
-    </release>
-
-   <release version="1.0" date="2002-08-12" description="Initial Release">
-      <action type="add">
-        Initial Release
-      </action>
-    </release>
-
-  </body>
-</document>
+<?xml version="1.0"?>
+<!--
+   Licensed to the Apache Software Foundation (ASF) under one or more
+  contributor license agreements.  See the NOTICE file distributed with
+  this work for additional information regarding copyright ownership.
+  The ASF licenses this file to You under the Apache License, Version 2.0
+  (the "License"); you may not use this file except in compliance with
+  the License.  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<!--
+This file is used by the maven-changes-plugin to generate the release notes.
+Useful ways of finding items to add to this file are:
+
+1.  Add items when you fix a bug or add a feature (this makes the
+release process easy :-).
+
+2.  Do a bugzilla search for tickets closed since the previous release.
+
+3.  Use the report generated by the maven-changelog-plugin to see all
+SVN commits.  Set the project.properties' maven.changelog.range
+property to the number of days since the last release.
+
+To generate the release notes from this file:
+
+mvn changes:announcement-generate -Prelease-notes [-Dchanges.version=nnn]
+
+then tweak the formatting if necessary
+and commit
+
+The <action> type attribute can be add,update,fix,remove.
+-->
+
+<document>
+  <properties>
+    <title>Apache Commons DBCP Release Notes</title>
+  </properties>
+    <!-- NOTE:
+    The description below is specially formatted so as to improve the layout of the generated release notes:
+    The parsing process removes all line feeds, replacing them with a single space.
+    The Velocity template in src/changes has been enhanced to replace pairs of adjacent spaces
+    with a new-line in the release notes. (These spaces are ignored when displaying HTML).
+    If the output is not quite correct, check for invisible trailing spaces!
+
+    N.B. The release notes template groups actions by type, and only extracts data for the current release.
+    The changes report outputs actions in the order they appear in this file.
+
+    To regenerate the release notes:
+    mvn changes:announcement-generate -Prelease-notes [-Dchanges.version=nnn]
+
+    Defining changes.version allows one to create the RN without first removing the SNAPSHOT suffix.
+     -->
+
+  <body>
+    <release version="2.7.0" date="2019-MM-DD" description="This is a minor release, including bug fixes and enhancements.">
+      <action dev="jleroux" type="add" issue="DBCP-539" due-to="Jacques Le Roux">
+        ManagedDataSource#close() should declare used exceptions.
+      </action>
+      <action dev="ggregory" type="add" issue="DBCP-538" due-to="Ragnar Haugan, Gary Gregory">
+        Wrong JMX base name derived in BasicDataSource#updateJmxName.
+      </action>
+      <action dev="ggregory" type="update" due-to="Gary Gregory">
+        Update tests from H2 1.4.198 to 1.4.199.
+      </action>
+      <action dev="ggregory" type="update" issue="DBCP-540" due-to="emopers">
+        Close ObjectOutputStream before calling toByteArray() on underlying ByteArrayOutputStream #28.
+      </action>
+      <action dev="ggregory" type="update" issue="DBCP-541" due-to="Allon Murienik">
+        Upgrade to JUnit Jupiter #19.
+      </action>
+      <action dev="ggregory" type="update" issue="DBCP-542" due-to="Zheng Feng, Gary Gregory">
+        Fix tests on Java 11.
+      </action>
+      <action dev="ggregory" type="update" issue="DBCP-543" due-to="Gary Gregory">
+        Update Apache Commons Pool from 2.6.1 to 2.6.2.
+      </action>
+      <action dev="ggregory" type="update" issue="DBCP-546" due-to="Sergey Chupov">
+        Avoid NPE when calling DriverAdapterCPDS.toString().
+      </action>
+      <action dev="ggregory" type="update" issue="DBCP-547" due-to="leechoongyon, Gary Gregory">
+        Add a ConnectionFactory class name setting for BasicDataSource.createConnectionFactory() #33.
+      </action>
+      <action dev="ggregory" type="update" due-to="LichKing-lee">
+        Fix Javadoc link in README.md #21.
+      </action>
+      <action dev="ggregory" type="update" issue="DBCP-529" due-to="Yuri">
+        Add 'jmxName' property to web configuration parameters listing.
+      </action>
+    </release>
+    <release version="2.6.0" date="2019-02-14" description="This is a minor release, including bug fixes and enhancements.">
+      <action dev="chtompki" type="add" issue="DBCP-534" due-to="Peter Wicks">
+        Allow for manual connection eviction.
+      </action>
+      <action dev="ggregory" type="add" issue="DBCP-514" due-to="Tom Jenkinson, Gary Gregory">
+        Allow DBCP to register with a TransactionSynchronizationRegistry for XA cases.
+      </action>
+      <action dev="ggregory" type="update" issue="DBCP-517" due-to="Gary Gregory">
+        Make defensive copies of char[] passwords.
+      </action>
+      <action dev="ggregory" type="update" issue="DBCP-515" due-to="Tom Jenkinson, Gary Gregory">
+        Do not try to register synchronization when the transaction is no longer active.
+      </action>
+      <action dev="ggregory" type="update" issue="DBCP-516" due-to="Tom Jenkinson, Gary Gregory">
+        Do not double returnObject back to the pool if there is a transaction context with a shared connection.
+      </action>
+      <action dev="ggregory" type="fix" issue="DBCP-518" due-to="Gary Gregory">
+        Allow DBCP to work with old Java 6/JDBC drivers without throwing AbstractMethodError.
+      </action>
+      <action dev="ggregory" type="add" issue="DBCP-519" due-to="Gary Gregory">
+        Add some toString() methods for debugging (never printing passwords.)
+      </action>
+      <action dev="ggregory" type="update" issue="DBCP-520" due-to="Zheng Feng">
+        BasicManagedDataSource needs to pass the TSR with creating DataSourceXAConnectionFactory.
+      </action>
+      <action dev="ggregory" type="add" issue="DBCP-527" due-to="Gary Gregory">
+        Add getters to some classes.
+      </action>
+      <action dev="ggregory" type="add" issue="DBCP-528" due-to="Gary Gregory">
+        org.apache.commons.dbcp2.DriverManagerConnectionFactory should use a char[] instead of a String to store passwords.
+      </action>
+      <action dev="ggregory" type="update" issue="DBCP-537" due-to="Gary Gregory">
+        Update Apache Commons Pool from 2.6.0 to 2.6.1.
+      </action>
+    </release>
+    <release version="2.5.0" date="2018-07-15" description="This is a minor release, including bug fixes and enhancements.">
+      <action dev="ggregory" type="update" issue="DBCP-505" due-to="Gary Gregory">
+        Update Java requirement from version 7 to 8.
+      </action>
+      <action dev="ggregory" type="add" issue="DBCP-506" due-to="Gary Gregory">
+        Support JDBC 4.2.
+      </action>
+      <action dev="ggregory" type="add" issue="DBCP-479" due-to="Guillaume Husta, Gary Gregory">
+        Support default schema in configuration.
+      </action>
+       <action dev="ggregory" type="update" issue="DBCP-427" due-to="Vladimir Konkov, Phil Steitz, Gary Gregory">
+        Examines 'SQLException's thrown by underlying connections or statements for fatal (disconnection) errors.
+      </action>
+       <action dev="ggregory" type="update" issue="DBCP-507" due-to="Vladimir Konkov, Phil Steitz, Gary Gregory">
+        Change default for fail-fast connections from false to true.
+      </action>
+      <action dev="ggregory" type="fix" issue="DBCP-508" due-to="Gary Gregory">
+        Prepared statement keys should take a Connection's schema into account.
+      </action>
+      <action dev="ggregory" type="update" issue="DBCP-504" due-to="Bruno P. Kinoshita">
+        Increase test coverage.
+      </action>
+      <action dev="ggregory" type="update" issue="DBCP-510" due-to="Gary Gregory">
+        Update Apache Commons Pool from 2.5.0 to 2.6.0.
+      </action>
+      <action dev="ggregory" type="fix" issue="DBCP-512" due-to="Gary Gregory">
+        Avoid exceptions when closing a connection in mutli-threaded use case.
+      </action>
+    </release>
+    <release version="2.4.0" date="2018-06-12" description="This is a minor release, including bug fixes and enhancements.">
+      <action dev="ggregory" type="fix" issue="DBCP-484" due-to="Emanuel Freitas">
+        Connection leak during XATransaction in high load.
+      </action>
+      <action dev="ggregory" type="update" issue="DBCP-492" due-to="Gary Gregory">
+        Drop Ant build.
+      </action>
+      <action dev="ggregory" type="update" issue="DBCP-491" due-to="Zheng Feng, Gary Gregory">
+        Ensure DBCP ConnectionListener can deal with transaction managers which invoke rollback in a separate thread.
+      </action>
+      <action dev="ggregory" type="update" issue="DBCP-494" due-to="Gary Gregory">
+        org.apache.commons.dbcp2.PStmtKey should make copies of given arrays in constructors.
+      </action>
+      <action dev="ggregory" type="update" issue="DBCP-495" due-to="Gary Gregory">
+        Remove duplicate code in org.apache.commons.dbcp2.cpdsadapter.PStmtKeyCPDS.
+      </action>
+      <action dev="ggregory" type="fix" issue="DBCP-496" due-to="Gary Gregory">
+        Add support for pooling CallableStatements to the org.apache.commons.dbcp2.cpdsadapter package.
+      </action>
+      <action dev="ggregory" type="update" issue="DBCP-497" due-to="Gary Gregory">
+        Deprecate use of PStmtKeyCPDS in favor of PStmtKey.
+      </action>
+      <action dev="ggregory" type="update" issue="DBCP-498" due-to="Gary Gregory">
+        org.apache.commons.dbcp2.DataSourceConnectionFactory should use a char[] instead of a String to store passwords.
+      </action>
+      <action dev="ggregory" type="update" issue="DBCP-499" due-to="Gary Gregory">
+        org.apache.commons.dbcp2.managed.DataSourceXAConnectionFactory should use a char[] instead of a String to store passwords.
+      </action>
+      <action dev="ggregory" type="update" issue="DBCP-500" due-to="Gary Gregory">
+        org.apache.commons.dbcp2.cpdsadapter.DriverAdapterCPDS should use a char[] instead of a String to store passwords.
+      </action>
+      <action dev="ggregory" type="update" issue="DBCP-501" due-to="Gary Gregory">
+        org.apache.commons.dbcp2.datasources.CPDSConnectionFactory should use a char[] instead of a String to store passwords.
+      </action>
+      <action dev="ggregory" type="update" issue="DBCP-502" due-to="Gary Gregory">
+        org.apache.commons.dbcp2.datasources internals should use a char[] instead of a String to store passwords.
+      </action>
+      <action dev="ggregory" type="update" issue="DBCP-503" due-to="Gary Gregory">
+        org.apache.commons.dbcp2.datasources.InstanceKeyDataSourceFactory.closeAll() does not close all.
+      </action>
+    </release>
+    <release version="2.3.0" date="2018-05-12" description="This is a minor release, including bug fixes and enhancements.">
+      <action dev="pschumacher" type="fix" issue="DBCP-476" due-to="Gary Evesson, Richard Cordova">
+        AbandonedTrace.getTrace() contains race condition.
+      </action>
+      <action dev="ggregory" type="fix" issue="DBCP-482" due-to="Dennis Lloyd, Gary Gregory">
+        Avoid javax.management.InstanceNotFoundException on shutdown when a bean is not registered. Closes #9.
+      </action>
+      <action dev="ggregory" type="update" issue="DBCP-483" due-to="Gary Gregory">
+        Make constant public: org.apache.commons.dbcp2.PoolingDriver.URL_PREFIX.
+      </action>
+      <action dev="ggregory" type="update" issue="DBCP-486" due-to="Gary Gregory">
+        DriverAdapterCPDS.setUser(), setPassword(), and getPooledConnection() with null arguments throw NullPointerExceptions when connection properties are set.
+      </action>
+      <action dev="ggregory" type="update" issue="DBCP-487" due-to="Gary Gregory">
+        Add API org.apache.commons.dbcp2.datasources.PerUserPoolDataSource.clear().
+      </action>
+      <action dev="ggregory" type="update" issue="DBCP-488" due-to="Gary Gregory">
+        NPE for org.apache.commons.dbcp2.cpdsadapter.DriverAdapterCPDS.setConnectionProperties(null).
+      </action>
+      <action dev="ggregory" type="update" issue="DBCP-490" due-to="Gary Gregory">
+        The method org.apache.commons.dbcp2.PoolingDriver.getConnectionPool(String) does not tell you which pool name is not registered when it throws an exception.
+      </action>
+    </release>
+    <release version="2.2.0" date="2017-12-27" description="This is a minor release, including bug fixes and enhancements.">
+      <action dev="ggregory" type="fix" issue="DBCP-481" due-to="Gary Gregory">
+        Update Apache Commons Pool from 2.4.2 to 2.5.0.
+      </action>
+      <action dev="mattsicker" type="fix" issue="DBCP-454" due-to="Philipp Marx, Matt Sicker">
+        OSGi declarations contain multiple import headers for javax.transaction.
+      </action>
+      <action dev="ggregory" type="fix" issue="DBCP-478" due-to="nicola mele">
+        Wrong parameter name in site documentation for BasicDataSource Configuration Parameters.
+      </action>
+      <action dev="psteitz" type="fix" issue="DBCP-452">
+        Add jmxName to properties set by BasicDataSourceFactory.  This
+        enables container-managed pools created from JNDI Resource
+        definitions to enable JMX by supplying a valid root JMX name.
+      </action>
+      <action dev="ggregory" type="fix" issue="DBCP-446" due-to="Gary Gregory, feng yang, Euclides M, Phil Steitz">
+        NullPointerException thrown when calling ManagedConnection.isClosed().
+      </action>
+      <action dev="psteitz" type="fix" issue="DBCP-444">
+        InvalidateConnection can result in closed connection returned by getConnection.
+      </action>
+      <action dev="ggregory" type="fix" issue="DBCP-449" due-to="Grzegorz D.">
+        Complete the fix for DBCP-418, enabling PoolableConnection class to load in environments
+        (such as GAE) where the JMX ManagementFactory is not available.
+      </action>
+      <action dev="ggregory" type="add" issue="DBCP-451">
+        Add constructor DriverManagerConnectionFactory(String).
+      </action>
+      <action dev="markt" type="fix" issue="DBCP-455" due-to="Kyohei Nakamura">
+        Ensure that the cacheState setting is used when statement pooling is
+        disabled.
+      </action>
+      <action dev="markt" type="fix" issue="DBCP-453" due-to="Philipp Marx">
+        Ensure that setSoftMinEvictableIdleTimeMillis is used when working with
+        BasicDataSource.
+      </action>
+      <action dev="markt" type="fix" issue="DBCP-456" due-to="Kyohei Nakamura">
+        Correct the name of the configuration attribute
+        softMinEvictableIdleTimeMillis.
+      </action>
+      <action dev="markt" type="fix" issue="DBCP-472">
+        Avoid potential infinite loops when checking if an SQLException is fatal
+        for a connection or not.
+      </action>
+      <action dev="markt" type="fix" issue="DBCP-468">
+        Expand the fail-fast for fatal connection errors feature to include
+        managed connections.
+      </action>
+      <action dev="markt" type="fix" issue="DBCP-463">
+        Correct a typo in the method name
+        PoolableConnectionFactory#setMaxOpenPreparedStatements. The old method
+        remains but is deprecated so not to break clients currently using the
+        incorrect name.
+      </action>
+       <action dev="markt" type="add" issue="DBCP-462" due-to="Keiichi Fujino">
+         Refactoring to prepare for a future patch to enable pooling of all
+         prepared and callable statements in PoolingConnection.
+       </action>
+       <action dev="markt" type="fix" issue="DBCP-459">
+         Ensure that a thread's interrupt status is visible to the caller if the
+         thread is interrupted during a call to
+         PoolingDataSource.getConnection().
+       </action>
+       <action dev="markt" type="add" issue="DBCP-458" due-to="Adrian Tarau">
+         Make it simpler to extend BasicDataSource to allow sub-classes to
+         provide custom GenericObjectPool implementations.
+       </action>
+       <action dev="markt" type="fix" issue="DBCP-457">
+         When using a BasicDataSource, pass changes related to the handling of
+         abandoned connections to the underlying pool so that the pool
+         configuration may be updated dynamically.
+       </action>
+       <action dev="markt" type="add" issue="DBCP-474" due-to="Keiichi Fujino">
+         Enable pooling of all prepared and callable statements
+         inPoolingConnection.
+       </action>
+    </release>
+    <release version="2.1.1" date="6 Aug 2015" description=
+"This is a patch release, including bug fixes only.">
+      <action dev="psteitz" type="update">
+        Updated pool version to 2.4.2.  The fix for POOL-300 may cause DBCP
+        users to see more reports of abandoned connections (if removal and logging
+        are configured).  Prior to the fix for POOL-300, the PrintWriter used to log
+        abandoned connection stack traces was not being flushed on each log event.
+      </action>
+      <action issue="DBCP-441" dev="psteitz" type="fix">
+        Added BasicDataSource abandonedUsageTracking property missing from BasicDataSourceFactory.
+      </action>
+      <action issue="DBCP-442" dev="psteitz" type="fix">
+        SharedPoolDataSource getConnection fails when testOnBorrow is set with
+        a null validation query.
+      </action>
+      <action issue="DBCP-438" dev="psteitz" type="fix" due-to="Raihan Kibria">
+        Nested connections in a transaction (local) throws null pointer.
+      </action>
+      <action issue="DBCP-437" dev="psteitz" type="fix">
+        BasicDataSource does not set disconnectionSql properties on its PoolableConnectionFactory.
+      </action>
+    </release>
+    <release version="2.1" date="23 Feb 2015" description=
+ "This is minor release, including bug fixes and enhancements. Note that
+  one of the enhancements (DBCP-423) is to implement AutoCloseable in
+  BasicDataSource, PoolingDataSource and the InstanceKeyDataSource
+  implementations.
+      ">
+      <action issue="DBCP-420" dev="sebb" type="fix">
+        InstanceKeyDataSource discards native SQLException when given password does not match
+        password used to create the connection.
+      </action>
+      <action issue="DBCP-422" dev="ggregory" type="update">
+        Update Apache Commons Logging to 1.2 from 1.1.3.
+      </action>
+      <action dev="markt" type="fix">
+        Correct some Javadoc references to Apache Commons Pool 2 classes that
+        have changed names since Pool 1.x.
+      </action>
+      <action dev="markt" type="fix">
+        Do not ignore the configured custom eviction policy when creating a
+        BasicDataSource.
+      </action>
+      <action dev="psteitz" type="add" issue="DBCP-426" due-to="Kasper Sørensen">
+        Added invalidateConnection method to BasicDataSource.
+      </action>
+      <action issue="DBCP-428" dev="psteitz" type="fix" due-to="Vladimir Konkov">
+        Unsuccessful Connection enlistment in XA Transaction ignored by TransactionContext.
+      </action>
+      <action issue="DBCP-424" dev="psteitz" type="update">
+        Made expired connection logging configurable in BasicDataSource.  Setting
+        logExpiredConnections to false suppresses expired connection log messages.
+      </action>
+      <action issue="DBCP-423" dev="psteitz" type="update">
+        Made Datasources implement AutoCloseable.
+      </action>
+      <action issue="DBCP-427" dev="psteitz" type="add" due-to="Vladimir Konkov">
+        Added fastFailValidation property to PoolableConnection, configurable in
+        BasicDataSource.  When set to true, connections that have previously thrown
+        fatal disconnection errors will fail validation immediately (no driver calls).
+      </action>
+      <action issue="DBCP-432" dev="psteitz" type="fix">
+        Changed BasicDataSource createDataSource method to ensure that initialization
+        completes before clients get reference to newly created instances.
+      </action>
+      <action issue="DBCP-433" dev="psteitz" type="fix" due-to="Vladimir Konkov">
+        Fixed connection leak when SQLException is thrown while enlisting an XA
+        transaction.
+      </action>
+      <action issue="DBCP-434" dev="psteitz" type="fix">
+        Setting jmxName to null should suppress JMX registration of connection
+        and statement pools.
+      </action>
+      <action dev="psteitz" type="update">
+        Eliminated synchronization in BasicDataSource getNumActive, getNumIdle methods.
+      </action>
+      <action issue="DBCP-435" type="update" due-to="Denixx Baykin">
+        Added property name verification to BasicDataSourceFactory. References including
+        obsolete or unrecognized properties now generate log messages.
+      </action>
+    </release>
+    <release version="2.0.1" date="24 May 2014" description="This is a bug fix release.">
+      <action dev="markt" type="fix">
+        Small performance improvements when returning connections to the pool.
+      </action>
+      <action issue="DBCP-414" dev="markt" type="fix" due-to="Pasi Eronen">
+        Fixed DelegatingStatement close to ensure closed statements do not retain references
+        to pooled prepared statements. Due to finalization code added in 2.0, this was causing
+        pooled prepared statements to be closed by GC while in use by clients.
+      </action>
+      <action issue="DBCP-412" dev="psteitz" type="update">
+        Added check in PoolingDataSource constructor to ensure that the connection factory
+        and pool are properly linked.
+      </action>
+      <action issue="DBCP-417" dev="psteitz" type="fix">
+        Fixed connection leak when managed connections are closed during transactions.
+      </action>
+      <action issue="DBCP-418" dev="psteitz" type="fix">
+        Enable PoolableConnection class to load without JMX.
+      </action>
+    </release>
+    <release version="2.0" date="3 March 2014" description=
+"This release includes new features as well as bug fixes and enhancements.
+ Version 2.0.x supports JDBC 4.1, so requires Java 7.
+
+ The Java package name has been changed from 'org.apache.commons.dbcp' to 'org.apache.commons.dbcp2'.
+ Also the Maven groupId is now 'org.apache.commons' and the artifactId is 'commons-dbcp2'
+ These changes are necessary because the API is not strictly binary compatible with the 1.x releases.
+ To convert from the earlier releases, update the package name in imports, update the dependencies and recompile.
+ There may be a few other changes to be made.
+
+ Applications running under Java 7 should use DBCP 2.0.x.
+ Java 6 users should use DBCP 1.4.x which supports JDBC 4.
+ Java 1.4 and Java 5 users should use DBCP 1.3.x which supports JDBC 3.
+      ">
+      <action issue="DBCP-411" dev="sebb" type="fix">
+        BasicManagedDataSource - unregister from JMX on close().
+      </action>
+        <action issue="DBCP-154" dev="markt" type="fix">
+        Log validation failures of poolable connections.
+      </action>
+      <action issue="DBCP-403" dev="sebb" type="fix">
+        DelegatingStatement.close() fails with NPE if statement is null
+      </action>
+      <action issue="DBCP-322" dev="sebb" type="fix">
+        CPDSConnectionFactory.validateObject(Object) ignores Throwable.
+      </action>
+      <action dev="markt" type="add">
+        Provide a new option (cacheState) to cache current values of autoCommit
+        and readOnly so database queries are not required for every call to the
+        associated getters. This option is enabled by default.
+      </action>
+      <action dev="markt" issue="DBCP-300" type="fix">
+        Removed unnecessary synchronisation in BasicDataSource#createDataSource.
+      </action>
+      <action dev="markt" type="update">
+        The Java package name has been changed from org.apache.commons.dbcp to
+        org.apache.commons.dbcp2.
+      </action>
+      <action dev="markt" type="update">
+        Update to Commons Pool 2 (based on java.util.concurrent) to provide
+        pooling functionality.
+      </action>
+      <action dev="markt" type="update">
+        Updated source code for Java 1.6 (added @Override &amp; @Deprecated
+        annotations).
+      </action>
+      <action dev="markt" type="update">
+        Removed JOCL support.
+      </action>
+      <action dev="markt" issue="DBCP-143" type="update">
+        Remove deprecated SQLNestedException.
+      </action>
+      <action dev="markt" issue="DBCP-384" type="fix">
+        Fix threading issues with accessToUnderlyingConnectionAllowed attribute
+        of PoolingDriver which is used to support unit testing.
+      </action>
+      <action dev="markt" issue="DBCP-292" type="add">
+        BasicDataSource instances are now exposed via JMX. All the configuration
+        properties are available as is the connection pool and the statement
+        pools (if statement pooling is enabled).
+      </action>
+      <action dev="markt" issue="DBCP-376" type="fix" due-to="Dave Oxley">
+        Fix thread safety issues in the SharedPoolDataSource and the
+        PerUserPoolDataSource.
+      </action>
+      <action dev="markt" issue="DBCP-382" type="fix" due-to="Stefan Rempfer">
+        Allow accessToUnderlyingConnectionAllowed to be configured when
+        configuration takes place via JNDI in a JavaEE container.
+      </action>
+      <action dev="markt" issue="DBCP-369" type="fix" due-to="Michael Pradel">
+        Fix threading issue when using multiple instances of the
+        SharedPoolDataSource concurrently.
+      </action>
+      <action dev="markt" issue="DBCP-391" type="fix">
+        Ensure that the close state of a pooled connection and the underlying
+        connection is consistent when the underlying connection is closed as a
+        result of an error condition.
+      </action>
+      <action dev="markt" issue="DBCP-404" type="fix">
+        Make all mutable fields private.
+      </action>
+      <action dev="markt" issue="DBCP-364" type="fix">
+        Return BasicDataSource rather than DataSource from
+        BasicDataSourceFactory so a cast is not required to use BasicDataSource
+        specific methods.
+      </action>
+      <action dev="markt" issue="DBCP-358" type="fix">
+        The equals() implementations of the DelegatingXxx classes are now
+        symmetric. There are some important API changes underlying this fix.
+        Firstly, two DelegatingXxx instances are no longer considered equal if
+        they have the same innermost delegate. Secondly, a DelegatingXxx
+        instance is not considered equal to its innermost delegate. The
+        getInnermostDelegateInternal() method has been made public (but remains
+        part of the internal API) to allow classes extending this implementation
+        to access the innermost delegate when required.
+      </action>
+      <action dev="markt" issue="DBCP-368" type="add">
+        Expose the new Pool 2 property evictionPolicyClassName to enable more
+        sophisticated eviction strategies to be used.
+      </action>
+      <action dev="markt" issue="DBCP-406" type="add" due-to="Steeve Beroard">
+        Add support for pooling PreparedStatements that use auto-generated keys.
+      </action>
+      <action dev="markt" issue="DBCP-180" type="fix">
+        Enable JDBC resources that are no longer referenced by client code to be
+        eligible for garbage collection.
+      </action>
+      <action dev="markt" issue="DBCP-177" type="add">
+        Enable DBCP to work with a SecurityManager such that only DBCP needs to
+        be granted the necessary permissions to communicate with the database.
+      </action>
+      <action dev="markt" issue="DBCP-410" type="fix" due-to="Andreas Sturmlechner">
+        Correct path to Javadoc overview in build.xml.
+      </action>
+      <action dev="markt" issue="DBCP-234" type="fix">
+        The default values for readOnly, autoCommit and transactionIsolation are
+        now taken from the JDBC driver. No calls to setReadOnly(),
+        setAutoCommit() or setTransactionIsolation() will be made for a newly
+        borrowed connection unless a default is explicitly configured and the
+        connection is currently using a different setting.
+      </action>
+      <action dev="markt" issue="DBCP-219" type="add">
+        Register pooled connections with JMX so that they may be forcibly closed
+        via JMX if required.
+      </action>
+      <action dev="markt" issue="DBCP-373" type="add">
+        Modify SharedPoolDataSource and PerUserPoolDataSource to expose all of
+        the configuration properties of the underlying connection pool(s). This
+        represents a significant refactoring of these classes and a number of
+        property names have changed as a result.
+      </action>
+      <action dev="markt" issue="DBCP-351" type="add">
+        Provide an option to control if autoCommit is always set to true when a
+        connection is returned to the connection pool.
+      </action>
+      <action dev="markt" issue="DBCP-399" type="add">
+        Provide an option to control if rollback is called when a connection is
+        returned to the poll with autoCommit disabled.
+      </action>
+      <action dev="markt" issue="DBCP-340" type="add">
+        Provide an option to set the default query timeout.
+      </action>
+      <action dev="markt" type="fix">
+        Connection.isValid() should not throw an SQLException if the connection
+        is closed.
+      </action>
+      <action dev="markt" issue="DBCP-357" type="fix">
+        Use Connection.isValid() to validate connections unless a validation
+        query is explicitly configured. Note that this means it is no longer
+        necessary for a validation query to be specified in order for validation
+        to take place. When testing with Oracle, this resulted in database
+        validation being approximately 7 times faster.
+      </action>
+      <action dev="markt" issue="DBCP-249" type="add">
+        Add support for validation testing database connections on creation.
+      </action>
+    </release>
+    <release version="1.5.1" date="not yet released" description="TBD">
+      <action dev="markt" issue="DBCP-400" type="fix">
+        Correct the documentation for the maxOpenPreparedStatements parameter
+        and review the use of the phrase non-positive throughout the
+        documentation and javadoc, replacing it with negative where that is the
+        correct definition to use.
+      </action>
+      <action dev="markt" issue="DBCP-405" type="fix">
+        Avoid multiple calls to Connection.getAutoCommit() in
+        PoolableConnectionFactory.passivateObject() as it could be an expensive
+        call.
+      </action>
+      <action dev="markt" issue="DBCP-392" type="fix">
+        Use one line per statement for methods with multiple statements rather
+        than using a single line.
+      </action>
+      <action dev="markt" issue="DBCP-396" type="fix">
+        Expose all of the AbandonedConfig properties through a BasicDataSource.
+      </action>
+      <action dev="markt" issue="DBCP-380" type="fix" due-to="Balazs Zsoldos">
+        Correct implementation of DelegatingConnection.isWrapperFor() so it
+        works correctly with older JDBC drivers.
+      </action>
+      <action dev="markt" issue="DBCP-347" type="fix" due-to="Robert Poskrobek">
+        Correct implementation of DelegatingStatement.isWrapperFor(). Also fix
+        DelegatingDatabaseMetaData.isWrapperFor() and
+        DelegatingResultSet.isWrapperFor() that had the same problem.
+      </action>
+      <action dev="markt" issue="DBCP-341" type="fix" due-to="Ioannis Canellos">
+        LocalXAConnectionFactory does not properly check if Xid is equal to
+        currentXid when resuming which may result in an XAException.
+      </action>
+      <action dev="markt" issue="DBCP-355" type="fix" due-to="Florent Guillaume">
+        Ensure that the XAConnection is closed when the associated Connection is
+        closed.
+      </action>
+      <action dev="markt" issue="DBCP-398" type="fix">
+        Clarify Jaavdoc for isClosed() method of PoolableConnection.
+      </action>
+      <action dev="markt" issue="DBCP-383" type="fix">
+        Avoid NullPointerException and throw an XAException if an attempt is
+        made to commit the current transaction for a connection when no
+        transaction has been started.
+      </action>
+      <action dev="markt" issue="DBCP-372" type="fix">
+        Using batchUpdate() should not invalidate the PreparedStatement when it
+        is returned to the pool.
+      </action>
+      <action dev="markt" issue="DBCP-309" type="fix">
+        Improve documentation for JNDI example using BasicDataSource.
+      </action>
+    </release>
+    <release version="1.4.1" date="not yet released" description="TBD">
+      <action dev="psteitz" issue="DBCP-334" type="update" due-to="Alberto Mozzone">
+        Exposed GenericObjectPool's softMinEvictableIdleTimeMillis property for
+        configuration and use by BasicDataSource.
+      </action>
+      <action dev="psteitz" issue="DBCP-337" type="fix" due-to="Rob Gansevles">
+        Made equals reflexive in DelegatingStatement (and subclasses), DelegatingMetaData,
+        DelegatingResultSet and PoolingDriver#PoolGuardConnectionWrapper.
+      </action>
+      <action dev="psteitz" issue="DBCP-342" type="fix" due-to="Byungchol Kim">
+        Modified createDataSource method in BasicDataSource to ensure that GenericObjectPool
+        Evictor tasks are not started and orphaned when BasicDataSource encounters errors on
+        initialization.  Prior to this fix, when minIdle and timeBetweenEvictionRunsMillis
+        are both positive, Evictors orphaned by failed initialization can continue to
+        generate database connection requests.  This issue is duplicated by DBCP-339
+        and DBCP-93.
+      </action>
+      <action dev="psteitz" issue="DBCP-330" type="fix">
+        Changed DelegatingDatabaseMetaData to no longer add itself to the AbandonedTrace
+        of its parent connection.  This was causing excessive memory consumption and was
+        not necessary, as resultsets created by DelegatingDatabaseMetaData instances are
+        attached to the parent connection's trace on creation.  Also fixes DBCP-352.
+      </action>
+      <action dev="psteitz" issue="DBCP-343" type="fix">
+        Modified execute methods of Statement objects to ensure that whenever
+        a statement is used, the lastUsed property of its parent connection is
+        updated.
+      </action>
+      <action dev="markt" issue="DBCP-333" type="fix">
+        Correctly implemented the option to configure the class loader used to load
+        the JDBC driver.
+      </action>
+      <action dev="psteitz" issue="DBCP-346" type="update" due-to="Ken Tatsushita">
+        LIFO configuration option has been added to BasicDataSource.  When set
+        to true (the default), the pool acts as a LIFO queue; setting to false
+        causes connections to enter and exit to pool in FIFO order.
+      </action>
+      <action dev="psteitz" issue="DBCP-344" type="fix" due-to="Jeremy Whiting">
+        Test transitive dependencies brought in by geronimo-transaction created
+        version conflicts (commons logging and junit).  These have been explicitly
+        excluded in the POM.
+      </action>
+      <action dev="psteitz" issue="DBCP-348" type="fix" due-to="Eiji Takahashi">
+        BasicDataSourceFactory incorrectly used "initConnectSqls" in versions
+        1.3 and 1.4 of DBCP as the property name for connectionInitSqls.
+        Online docs for 1.3/1/4 have been updated to reflect this inconsistency.
+        The BasicDataSourceFactory property name has been changed to "connectInitSqls"
+        to match the online docs and the BasicDataSource property name.
+      </action>
+    </release>
+    <release version="1.4" date="2010-02-14" description="This release includes
+     new features as well as bug fixes and enhancements.  Some bug fixes
+     change semantics (e.g. connection close is now idempotent).  The 1.3
+     and 1.4 releases of DBCP are built from the same sources.  Version 1.4
+     supports JDBC 4, so requires JDK 1.6. Applications running under
+     JDK 1.4-1.5 must use DBCP 1.3. Applications running under JDK 1.6
+     should use DBCP 1.4. Other than support for the added methods in JDBC 4,
+     there is nothing new or different in DBCP 1.4 vs. DBCP 1.3.   The list of
+     changes below since 1.2.2 applies to both the 1.3 and 1.4 release.  Other than
+     the one issue related to adding JDBC 4 support (DBCP-191), all bug fixes
+     or new features are included in both DBCP 1.3 and 1.4 ">
+      <action dev="psteitz" type="fix" issue="DBCP-320">
+        Eliminated poolKeys cache from PerUserPoolDataSource.
+      </action>
+      <action dev="sebb" type="fix" issue="DBCP-321">
+        Eliminated userKeys LRUMap cache from SharedPoolDataSource.
+      </action>
+      <action dev="psteitz" type="fix" issue="DBCP-319" due-to="Sebastian Bazley">
+        Made private fields final where possible.
+      </action>
+      <action dev="sebb" type="fix" issue="DBCP-318" due-to="Sebastian Bazley">
+        PerUserPoolDataSource.getPooledConnectionAndInfo multi-threading bug.
+      </action>
+      <action dev="sebb" type="fix" issue="DBCP-315" due-to="Sebastian Bazley">
+        Remove throws clause from method that does not throw an exception.
+      </action>
+      <action dev="sebb" type="fix" issue="DBCP-313" due-to="Sebastian Bazley">
+        Remove code that catches and ignores Exceptions when calling
+        PooledConnection.removeConnectionEventListener(ConnectionEventListener)
+        as the method does not throw any Exceptions.
+      </action>
+      <action dev="sebb" type="fix" issue="DBCP-316" due-to="Sebastian Bazley">
+        Remove impossible null check.
+      </action>
+      <action dev="sebb" type="update" issue="DBCP-314" due-to="Sebastian Bazley">
+        Renamed variables with duplicate names in different scopes.
+      </action>
+      <action dev="psteitz" type="update" issue="DBCP-312" due-to="Glen Mazza">
+        Clarified javadoc for BasicDataSource close() method.
+      </action>
+      <action dev="psteitz" type="add" issue="DBCP-204" due-to="Wei Chen">
+        Made PoolingConnection pool CallableStatements. When BasicDataSource's
+        poolPreparedStatements property is true, CallableStatements are now
+        pooled along with PreparedStatements. The maxOpenPreparedStatements
+        property limits the combined number of Callable and Prepared statements
+        that can be in use at a given time.
+      </action>
+      <action dev="markt" type="update" issue="DBCP-305" due-to="Christopher Schultz">
+        Use an API specific exception for logging abandoned objects to make
+        scanning the logs for these exceptions simpler and to provide a better
+        message that includes the creation time of the abandoned object.
+      </action>
+      <action dev="markt" type="fix" issue="DBCP-303" due-to="Dave Oxley">
+        Ensure Statement.getGeneratedKeys() works correctly with the CPDS
+        adapter.
+      </action>
+      <action dev="psteitz" type="fix" issue="DBCP-302" due-to="Sebastian Bazley">
+        Removed incorrectly advertised ClassNotFoundException from
+        JOCLContentHandler.ConstructorDetails.createObject().
+      </action>
+      <action dev="markt" type="update" issue="DBCP-203" due-to="Mark Grand">
+        Make the class loader used to load the JDBC driver configurable for the
+        BasicDatasource.
+      </action>
+      <action dev="markt" type="fix" issue="DBCP-8">
+        Handle user password changes for InstanceKeyDataSources.
+      </action>
+      <action dev="psteitz" type="update" issue="DBCP-289" due-to="Marc Kannegießer">
+        Made XADataSource configurable in BasicManagedDataSource.
+      </action>
+      <action dev="psteitz" type="fix" issue="DBCP-294" due-to="Philippe Mouawad">
+        Added PoolableManagedConnection and PoolableManagedConnectionFactory so that
+        pooled managed connections can unregister themselves from transaction registries,
+        avoiding resource leaks.
+      </action>
+      <action dev="psteitz" type="update" issue="DBCP-276">
+        Added connectionProperties property to DriverAdapterCPDS.
+      </action>
+      <action dev="psteitz" type="add" issue="DBCP-226">
+        Added a validationQueryTimeout configuration parameter to BasicDataSource
+        allowing the user to specify a timeout value (in seconds) for connection
+        validation queries.
+      </action>
+      <action dev="psteitz" type="add" issue="DBCP-175" due-to="Jiri Melichna and Jerome Lacoste">
+        Added a connectionInitSqls configuration parameter to BasicDataSource
+        allowing the user to specify a collection of SQL statements to execute
+        one time when a physical database connection is first opened.
+      </action>
+      <action dev="markt" type="fix" issue="DBCP-212">
+        PoolableConnectionFactory.makeObject() is no longer synchronized. This
+        provides improved response times when load spikes at the cost of a
+        faster rise in database server load. This change was made as a partial
+        fix for DBCP-212.  The synchronization changes in Commons Pool 1.5 complete
+        the fix for this issue.
+      </action>
+      <action dev="psteitz" type="fix" issue="DBCP-242">
+        Reverted DelegatingConnection close to 1.2.2 version to ensure
+        open statements are closed before the underlying connection is closed.
+      </action>
+      <action dev="markt" type="fix" issue="DBCP-235">
+        Refactor DelegatingConnection and ManagedConnection enable overridden
+        equals() and hashcode() to work correctly.
+      </action>
+      <action dev="markt" type="update" issue="DBCP-265">
+        Add a DelegatingDatabaseMetaData to track ResultSets returned from
+        DatabaseMetaData objects.
+      </action>
+      <action dev="markt" type="fix" issue="DBCP-215">
+        Modified BasicDataSourceFactory to complete initialization of the pool
+        by creating initialSize connections rather than leaving this to lazy
+        initialization when the pool is used.
+      </action>
+      <action dev="markt" type="fix" issue="DBCP-253">
+        Eliminated masked _stmt field in descendents of DelegatingStatement.
+       </action>
+      <action dev="markt" type="fix" issue="DBCP-191" due-to="Michael Heuer and J. David Beutel" >
+        Modified DBCP sources to support compilation under JDK 1.4-1.6
+        using Ant flags to do conditional compilation.
+      </action>
+      <action dev="markt" type="fix" issue="DBCP-272">
+        Added a static initializer to BasicDatasource that calls
+        DriverManager.getDrivers() to force initialization before we ever do
+        anything that might use Class.forName() to load (and register) a JDBC
+        driver.
+      </action>
+      <action dev="markt" type="fix" issue="DBCP-4">
+        Eliminated direct System.out calls in AbandonedTrace.
+      </action>
+      <action dev="niallp" type="fix" issue="DBCP-264">
+        Modified DelegatingStatement close to clear open batches.
+      </action>
+      <action dev="psteitz" type="fix" issue="DBCP-255">
+        Eliminated unused private "parent" field in AbandonedTrace.
+      </action>
+      <action dev="psteitz" type="fix" issue="DBCP-273" due-to="Mark Lin">
+        Fixed errors handling boolean-valued Reference properties in
+        InstanceKeyObjectFactory, DriverAdapterCPDS that were causing
+        testOnBorrow and poolPreparedStatements properties to be incorrectly
+        set when creating objects from javax.naming.Reference instances.
+      </action>
+      <action dev="psteitz" type="fix" issue="DBCP-271" due-to="Sebastian Bazley">
+        Made private instance fields of AbandonedTrace volatile (parent,
+        createdBy, lastUsed, createdTime) or final (trace).
+      </action>
+      <action dev="psteitz" type="fix" issue="DBCP-270" due-to="Filip Hanik">
+        Narrowed synchronization in AbandonedTrace to resolve an Evictor deadlock.
+      </action>
+      <action dev="bayard" type="fix" issue="DBCP-218">
+        Corrected Javadoc to state that getLoginTimeout and setLoginTimeout are
+        NOT supported by BasicDataSource.
+      </action>
+      <action dev="bayard" type="update" issue="DBCP-211">
+        Added Maven 2 pom.xml. Removed a block of code from TestJOCLed that set
+        the Xerces parser manually. This was to support early JDKs. The 1.3
+        version of DBCP requires JDK 1.4+.
+      </action>
+      <action dev="psteitz" type="add" issue="DBCP-228" due-to="Dain Sundstrom">
+        Added support for pooling managed connections.
+      </action>
+      <action dev="psteitz" type="add" issue="DBCP-230" due-to="Dain Sundstrom">
+        Added BasicManagedDataSource, extending BasicDataSource.
+        Also improved extensibility of BasicDataSource by encapsulating
+        methods to create object pool, connection factory and datasource
+        instance previously embedded in createDataSource.
+      </action>
+      <action dev="psteitz" type="update" issue="DBCP-233" due-to="Dain Sundstrom">
+        Changed behavior to allow Connection, Statement, PreparedStatement,
+        CallableStatement and ResultSet to be closed multiple times. The first
+        time close is called the resource is closed and any subsequent calls
+        have no effect. This behavior is required as per the Javadocs for these
+        classes. Also added tests for closing all types multiple times and
+        updated any tests that incorrectly assert that a resource can not be
+        closed more then once.  Fixes DBCP-3, DBCP-5, DBCP-23 and DBCP-134.
+      </action>
+      <action dev="psteitz" type="update" issue="DBCP-11" due-to="Dain Sundstrom">
+        Modified PoolingDataSource, PoolingDriver and DelegatingStatement to
+        assure that all returned Statements, PreparedStatements,
+        CallableStatements and ResultSets are wrapped with a delegating object,
+        which already properly handle the back pointers for Connection and
+        Statement.  Also added tests to to assure that the *same* object used
+        to create the statement or result set is returned  from either
+        getConnection() or getStatement().
+      </action>
+      <action dev="dain" type="update" issue="DBCP-143">
+        SQLNestedException has been deprecated and will be replaced in DBCP 2.0 with
+        SQLException and standard Java exception chaining.
+      </action>
+      <action dev="dain" type="fix" issue="DBCP-221">
+        BasicDataSource.close() now permanently marks the data source as closed,
+        and no new connections can be obtained from the data source. At close all
+        idle connections are destroyed and the method returns.  As the remaining
+        active connections are closed, they are destroyed.
+      </action>
+      <action dev="psteitz" type="fix" issue="DBCP-241">
+        Eliminated potential sources of NullPointerExceptions in
+        PoolingConnection.
+      </action>
+      <action dev="psteitz" type="fix" issue="DBCP-216" due-to="Marcos Sanz">
+        Improved error recovery and listener cleanup in
+        KeyedCPDSConnectionFactory. Substituted calls to destroyObject with
+         _pool.invalidateObject on error to ensure pool active count is
+        decremented on error events. Ensured that events from closed or invalid
+        connections are ignored and listeners are cleaned up.
+      </action>
+      <action dev="psteitz" type="fix" issue="DBCP-245" due-to="Michael Drechsel">
+        Fixed error in SharedPoolDataSource causing incorrect passwords to be
+        stored under certain conditions.
+      </action>
+      <action dev="psteitz" type="fix" issue="DBCP-237" due-to="Oliver Matz">
+        Added exception handler to ensure that PooledConnections are not
+        orphaned when an exception occurs in setUpDefaults or clearWarnings in
+        InstanceKeyDataSource.getConnection.
+      </action>
+      <action dev="psteitz" type="fix" issue="DBCP-252" due-to="FindBugs">
+        Made getPool synchronized in PoolableConnectionFactory.
+        Fixes inconsistent synchronization accessing _pool.
+      </action>
+      <action dev="psteitz" type="fix" issue="DBCP-252" due-to="FindBugs">
+        Fixed inconsistent synchronization on _rollbackAfterValidation,
+        _validationQuery and _pool in CPDSConnectionFactory and
+        KeyedCPDSConnectionFactory by making the first two volatile and making
+        both getter and setter for _pool synchronized.
+      </action>
+    </release>
+    <release version="1.3" date="2010-02-14" description="Compatability release for JDBC 3.
+      See version 1.4 description and change log.">
+     <action type="update">
+        See &lt;a href="changes-report.html#a1.4"&gt;DBCP 1.4 Changes &lt;/a&gt; for details. Version
+        1.3 is identical to 1.4, other than JDBC 4 methods being filtered out of the DBCP 1.3 sources. Changes
+        Since 1.2.2 are the same for 1.3 and 1.4.
+      </action>
+    </release>
+    <release version="1.2.2" date="2007-04-04"
+      description="This is a maintenance release containing bug fixes
+      and enhancements. All API changes are binary compatible with version 1.2.1.">
+      <action dev="dirkv " type="add">
+        Add a &lt;i&gt;JNDI How To&lt;/i&gt; to the User Guide.
+      </action>
+      <action dev="dirkv " type="fix" issue="DBCP-108" due-to="Maxwell Grender-Jones">
+        DriverManagerConnectionFactory: blank user name and password handling.
+      </action>
+      <action dev="dirkv " type="fix" issue="DBCP-113" due-to="Rohan Lenard">
+        Broken behaviour for BasicDataSource.setMaxActive(0).
+      </action>
+      <action dev="dirkv " type="fix" issue="DBCP-36" due-to="Jonathan Whitall">
+        BasicDataSource does not work with getConnection(String, String).
+      </action>
+      <action dev="dirkv " type="update" issue="DBCP-164" due-to="Todd Carmichael">
+        Enhancements to prepared statement in DriverAdapterCPDS.
+      </action>
+      <action dev="yoavs" type="update" issue="DBCP-186" due-to="Ralf Hauser">
+        Better messages and docs for LoginTimeout UnsupportedOperationException.
+      </action>
+      <action dev="yoavs" type="fix" issue="DBCP-50" due-to="Nicky Nicolson">
+        Error in JOCL snippet in org.apache.commons.dbcp package javadoc.
+      </action>
+      <action dev="yoavs" type="update" issue="DBCP-165" due-to="QM">
+        Added toString() methods to DelegatingPreparedStatement and DelegatingStatement
+      </action>
+      <action dev="yoavs" type="fix">
+        Changes to make DBCP compile on JDK 1.5 by adding source="1.4" to compiler
+        arguments (there are compiler errors in JDK 5.0 without this source switch
+        that cannot be fixed without JDK 5.0-specific syntax).
+      </action>
+      <action dev="dirkv " type="fix" issue="DBCP-20" due-to="Chris Nappin">
+        Per-user pooling with Oracle driver and default isolation settings.
+      </action>
+      <action dev="dirkv " type="fix" issue="DBCP-9" due-to="Adrian Baker">
+        Error in JOCL document in javadoc.
+      </action>
+      <action dev="sullis" type="update">
+        Added toString() method to DelegatingConnection.
+      </action>
+      <action dev="dirkv " type="update" issue="DBCP-181" due-to="Meikel Bisping">
+        Add DriverManager.invalidateConnection().
+      </action>
+      <action dev="dirkv " type="fix" issue="DBCP-184" due-to="Meikel Bisping">
+        Improved Exception nesting in ConnectionPool.
+      </action>
+      <action dev="dennisl" type="fix" issue="DBCP-144" due-to="Sebb">
+        Fix broken website links for examples.
+      </action>
+      <action dev="psteitz" type="fix" issue="DBCP-28"
+        due-to="Huw Lewis, James Ring">
+        Modified PoolableConnection close method to invalidate instance
+        when invoked on an already closed connection.
+      </action>
+      <action dev="joehni" type="fix" issue="DBCP-81">
+        Inserted null checks to avoid NPE in close operations.
+      </action>
+      <action dev="psteitz" type="fix" issue="DBCP-105"
+        due-to="Sandy McArthur, Thomas Fischer">
+        Changed getReference method in InstanceKeyDataSource to return a
+        concrete factory and added implementations of getReference in concrete
+        subclasses.
+      </action>
+      <action dev="psteitz" type="fix" issue="DBCP-39" due-to="Jindrich Vimr">
+        Inserted null check in close method of SharedPoolDataSource to avoid
+        NPE when invoked on non-initialized pool.
+      </action>
+      <action dev="psteitz" type="fix" issue="DBCP-71" due-to="Douglas Squirrel">
+        Document fact that true values for testOnBorrow, testOnReturn, testWhileIdle
+        only have effect when validationQuery is set to a non-null string.
+      </action>
+      <action dev="psteitz" type="fix" issue="DBCP-102">
+        Modified activateObject in PoolableConnection to test connection
+        properties before resetting to defaults.
+      </action>
+      <action dev="sandymac" type="fix" issue="DBCP-188">
+        Corrected maxActive documentation in configuration.html.
+      </action>
+      <action dev="psteitz"  type="update">
+        Upgraded dependency to Pool 1.3.
+      </action>
+      <action dev="psteitz" type="update" issue="DBCP-187" due-to="Ralf Hauser">
+        Added connection info to SQLException messages when closed connections
+        (resp stmts) are accessed in DelegatingConnection, DelegatingStatement.
+      </action>
+      <action dev="psteitz" type="fix" issue="DBCP-41" due-to="Anton Tagunov">
+        Fixed errors in pool parameter documentation and made
+        0 value for _maxPreparedStatements in DriverAdapterCPDS behave
+        like a negative value, to be consistent with documentation
+        and pool behavior.
+      </action>
+      <action dev="psteitz" type="fix" issue="DBCP-100">
+        Made userKeys an instance variable (i.e., not static)
+        in SharedPoolDataSource.
+      </action>
+      <action dev="psteitz" type="fix" issue="DBCP-198">
+        Changed implementation of equals in
+        PoolingDataSource.PoolGuardConnectionWrapper
+        to ensure it is reflexive, even when wrapped connections are not
+        DelegatingConnections.
+      </action>
+      <action dev="psteitz" type="update" issue="DBCP-116" due-to="Thomas Fischer">
+        Added rollbackAfterValidation property and code to issue a rollback on a
+        connection after validation when this property is set to true to eliminate
+        Oracle driver exceptions. Default property value is false.
+      </action>
+      <action dev="psteitz" type="update" issue="DBCP-68">
+        Removed dependency on Commons Collections by adding collections
+        2.1 sources for LRUMap and SequencedHashMap with package scope to
+        datasources package.
+      </action>
+      <action dev="psteitz" type="fix" issue="DBCP-65">
+        Removed synchronization from prepareStatement methods in
+        PoolingConnection. Synchronization in these methods was causing
+        deadlocks. No resources other than the prepared statement pool are
+        accessed by these methods, and the pool methods are synchronized.
+        Also fixes DBCP-202.
+      </action>
+    </release>
+
+    <release version="1.2.1" date="2004-06-12" description="Maintenance Release to restore JDK 1.3 compatibility">
+      <action type="fix">
+        See &lt;a href="release-notes-1.2.1.html"&gt;DBCP 1.2.1 Release Notes&lt;/a&gt; for details.
+      </action>
+    </release>
+
+    <release version="1.2" date="2004-06-07">
+      <action type="update">
+        See &lt;a href="release-notes-1.2.html"&gt;DBCP 1.2 Release Notes&lt;/a&gt; for details.
+      </action>
+    </release>
+
+    <release version="1.1" date="2003-10-20">
+      <action type="update">
+        See &lt;a href="release-notes-1.1.html"&gt;DBCP 1.1 Release Notes&lt;/a&gt; for details.
+      </action>
+    </release>
+
+   <release version="1.0" date="2002-08-12" description="Initial Release">
+      <action type="add">
+        Initial Release
+      </action>
+    </release>
+
+  </body>
+</document>
diff --git a/src/main/java/org/apache/commons/dbcp2/BasicDataSource.java b/src/main/java/org/apache/commons/dbcp2/BasicDataSource.java
index 3a3d065..72d4555 100644
--- a/src/main/java/org/apache/commons/dbcp2/BasicDataSource.java
+++ b/src/main/java/org/apache/commons/dbcp2/BasicDataSource.java
@@ -1,2590 +1,2853 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.commons.dbcp2;
-
-import java.io.OutputStreamWriter;
-import java.io.PrintWriter;
-import java.nio.charset.StandardCharsets;
-import java.security.AccessController;
-import java.security.PrivilegedActionException;
-import java.security.PrivilegedExceptionAction;
-import java.sql.Connection;
-import java.sql.Driver;
-import java.sql.DriverManager;
-import java.sql.SQLException;
-import java.sql.SQLFeatureNotSupportedException;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Objects;
-import java.util.Properties;
-import java.util.Set;
-import java.util.logging.Logger;
-
-import javax.management.MBeanRegistration;
-import javax.management.MBeanServer;
-import javax.management.MalformedObjectNameException;
-import javax.management.ObjectName;
-import javax.sql.DataSource;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.apache.commons.pool2.PooledObject;
-import org.apache.commons.pool2.impl.AbandonedConfig;
-import org.apache.commons.pool2.impl.BaseObjectPoolConfig;
-import org.apache.commons.pool2.impl.GenericKeyedObjectPoolConfig;
-import org.apache.commons.pool2.impl.GenericObjectPool;
-import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
-
-/**
- * <p>
- * Basic implementation of <code>javax.sql.DataSource</code> that is configured via JavaBeans properties. This is not
- * the only way to combine the <em>commons-dbcp2</em> and <em>commons-pool2</em> packages, but provides a "one stop
- * shopping" solution for basic requirements.
- * </p>
- *
- * @since 2.0
- */
-public class BasicDataSource implements DataSource, BasicDataSourceMXBean, MBeanRegistration, AutoCloseable {
-
-    /**
-     * @since 2.0
-     */
-    private class PaGetConnection implements PrivilegedExceptionAction<Connection> {
-
-        @Override
-        public Connection run() throws SQLException {
-            return createDataSource().getConnection();
-        }
-    }
-
-    private static final Log log = LogFactory.getLog(BasicDataSource.class);
-
-    // ------------------------------------------------------------- Properties
-
-    static {
-        // Attempt to prevent deadlocks - see DBCP - 272
-        DriverManager.getDrivers();
-        try {
-            // Load classes now to prevent AccessControlExceptions later
-            // A number of classes are loaded when getConnection() is called
-            // but the following classes are not loaded and therefore require
-            // explicit loading.
-            if (Utils.IS_SECURITY_ENABLED) {
-                final ClassLoader loader = BasicDataSource.class.getClassLoader();
-                final String dbcpPackageName = BasicDataSource.class.getPackage().getName();
-                loader.loadClass(dbcpPackageName + ".BasicDataSource$PaGetConnection");
-                loader.loadClass(dbcpPackageName + ".DelegatingCallableStatement");
-                loader.loadClass(dbcpPackageName + ".DelegatingDatabaseMetaData");
-                loader.loadClass(dbcpPackageName + ".DelegatingPreparedStatement");
-                loader.loadClass(dbcpPackageName + ".DelegatingResultSet");
-                loader.loadClass(dbcpPackageName + ".PoolableCallableStatement");
-                loader.loadClass(dbcpPackageName + ".PoolablePreparedStatement");
-                loader.loadClass(dbcpPackageName + ".PoolingConnection$StatementType");
-                loader.loadClass(dbcpPackageName + ".PStmtKey");
-
-                final String poolPackageName = PooledObject.class.getPackage().getName();
-                loader.loadClass(poolPackageName + ".impl.LinkedBlockingDeque$Node");
-                loader.loadClass(poolPackageName + ".impl.GenericKeyedObjectPool$ObjectDeque");
-            }
-        } catch (final ClassNotFoundException cnfe) {
-            throw new IllegalStateException("Unable to pre-load classes", cnfe);
-        }
-    }
-
-    protected static void validateConnectionFactory(final PoolableConnectionFactory connectionFactory)
-        throws Exception {
-        PoolableConnection conn = null;
-        PooledObject<PoolableConnection> p = null;
-        try {
-            p = connectionFactory.makeObject();
-            conn = p.getObject();
-            connectionFactory.activateObject(p);
-            connectionFactory.validateConnection(conn);
-            connectionFactory.passivateObject(p);
-        } finally {
-            if (p != null) {
-                connectionFactory.destroyObject(p);
-            }
-        }
-    }
-
-    /**
-     * The default auto-commit state of connections created by this pool.
-     */
-    private volatile Boolean defaultAutoCommit;
-
-    /**
-     * The default read-only state of connections created by this pool.
-     */
-    private transient Boolean defaultReadOnly;
-
-    /**
-     * The default TransactionIsolation state of connections created by this pool.
-     */
-    private volatile int defaultTransactionIsolation = PoolableConnectionFactory.UNKNOWN_TRANSACTION_ISOLATION;
-
-    private Integer defaultQueryTimeoutSeconds;
-
-    /**
-     * The default "catalog" of connections created by this pool.
-     */
-    private volatile String defaultCatalog;
-
-    /**
-     * The default "schema" of connections created by this pool.
-     */
-    private volatile String defaultSchema;
-
-    /**
-     * The property that controls if the pooled connections cache some state rather than query the database for current
-     * state to improve performance.
-     */
-    private boolean cacheState = true;
-
-    /**
-     * The instance of the JDBC Driver to use.
-     */
-    private Driver driver;
-
-    /**
-     * The fully qualified Java class name of the JDBC driver to be used.
-     */
-    private String driverClassName;
-
-    /**
-     * The class loader instance to use to load the JDBC driver. If not specified, {@link Class#forName(String)} is used
-     * to load the JDBC driver. If specified, {@link Class#forName(String, boolean, ClassLoader)} is used.
-     */
-    private ClassLoader driverClassLoader;
-
-    /**
-     * True means that borrowObject returns the most recently used ("last in") connection in the pool (if there are idle
-     * connections available). False means that the pool behaves as a FIFO queue - connections are taken from the idle
-     * instance pool in the order that they are returned to the pool.
-     */
-    private boolean lifo = BaseObjectPoolConfig.DEFAULT_LIFO;
-
-    /**
-     * The maximum number of active connections that can be allocated from this pool at the same time, or negative for
-     * no limit.
-     */
-    private int maxTotal = GenericObjectPoolConfig.DEFAULT_MAX_TOTAL;
-
-    /**
-     * The maximum number of connections that can remain idle in the pool, without extra ones being destroyed, or
-     * negative for no limit. If maxIdle is set too low on heavily loaded systems it is possible you will see
-     * connections being closed and almost immediately new connections being opened. This is a result of the active
-     * threads momentarily closing connections faster than they are opening them, causing the number of idle connections
-     * to rise above maxIdle. The best value for maxIdle for heavily loaded system will vary but the default is a good
-     * starting point.
-     */
-    private int maxIdle = GenericObjectPoolConfig.DEFAULT_MAX_IDLE;
-
-    /**
-     * The minimum number of active connections that can remain idle in the pool, without extra ones being created when
-     * the evictor runs, or 0 to create none. The pool attempts to ensure that minIdle connections are available when
-     * the idle object evictor runs. The value of this property has no effect unless
-     * {@link #timeBetweenEvictionRunsMillis} has a positive value.
-     */
-    private int minIdle = GenericObjectPoolConfig.DEFAULT_MIN_IDLE;
-
-    /**
-     * The initial number of connections that are created when the pool is started.
-     */
-    private int initialSize = 0;
-
-    /**
-     * The maximum number of milliseconds that the pool will wait (when there are no available connections) for a
-     * connection to be returned before throwing an exception, or <= 0 to wait indefinitely.
-     */
-    private long maxWaitMillis = BaseObjectPoolConfig.DEFAULT_MAX_WAIT_MILLIS;
-
-    /**
-     * Prepared statement pooling for this pool. When this property is set to <code>true</code> both PreparedStatements
-     * and CallableStatements are pooled.
-     */
-    private boolean poolPreparedStatements = false;
-
-    /**
-     * <p>
-     * The maximum number of open statements that can be allocated from the statement pool at the same time, or negative
-     * for no limit. Since a connection usually only uses one or two statements at a time, this is mostly used to help
-     * detect resource leaks.
-     * </p>
-     * <p>
-     * Note: As of version 1.3, CallableStatements (those produced by {@link Connection#prepareCall}) are pooled along
-     * with PreparedStatements (produced by {@link Connection#prepareStatement}) and
-     * <code>maxOpenPreparedStatements</code> limits the total number of prepared or callable statements that may be in
-     * use at a given time.
-     * </p>
-     */
-    private int maxOpenPreparedStatements = GenericKeyedObjectPoolConfig.DEFAULT_MAX_TOTAL;
-
-    /**
-     * The indication of whether objects will be validated as soon as they have been created by the pool. If the object
-     * fails to validate, the borrow operation that triggered the creation will fail.
-     */
-    private boolean testOnCreate = false;
-
-    /**
-     * The indication of whether objects will be validated before being borrowed from the pool. If the object fails to
-     * validate, it will be dropped from the pool, and we will attempt to borrow another.
-     */
-    private boolean testOnBorrow = true;
-
-    /**
-     * The indication of whether objects will be validated before being returned to the pool.
-     */
-    private boolean testOnReturn = false;
-
-    /**
-     * The number of milliseconds to sleep between runs of the idle object evictor thread. When non-positive, no idle
-     * object evictor thread will be run.
-     */
-    private long timeBetweenEvictionRunsMillis = BaseObjectPoolConfig.DEFAULT_TIME_BETWEEN_EVICTION_RUNS_MILLIS;
-
-    /**
-     * The number of objects to examine during each run of the idle object evictor thread (if any).
-     */
-    private int numTestsPerEvictionRun = BaseObjectPoolConfig.DEFAULT_NUM_TESTS_PER_EVICTION_RUN;
-
-    /**
-     * The minimum amount of time an object may sit idle in the pool before it is eligible for eviction by the idle
-     * object evictor (if any).
-     */
-    private long minEvictableIdleTimeMillis = BaseObjectPoolConfig.DEFAULT_MIN_EVICTABLE_IDLE_TIME_MILLIS;
-
-    /**
-     * The minimum amount of time a connection may sit idle in the pool before it is eligible for eviction by the idle
-     * object evictor, with the extra condition that at least "minIdle" connections remain in the pool. Note that
-     * {@code minEvictableIdleTimeMillis} takes precedence over this parameter. See
-     * {@link #getSoftMinEvictableIdleTimeMillis()}.
-     */
-    private long softMinEvictableIdleTimeMillis = BaseObjectPoolConfig.DEFAULT_SOFT_MIN_EVICTABLE_IDLE_TIME_MILLIS;
-
-    private String evictionPolicyClassName = BaseObjectPoolConfig.DEFAULT_EVICTION_POLICY_CLASS_NAME;
-
-    /**
-     * The indication of whether objects will be validated by the idle object evictor (if any). If an object fails to
-     * validate, it will be dropped from the pool.
-     */
-    private boolean testWhileIdle = false;
-
-    /**
-     * The connection password to be passed to our JDBC driver to establish a connection.
-     */
-    private volatile String password;
-
-    /**
-     * The connection URL to be passed to our JDBC driver to establish a connection.
-     */
-    private String url;
-
-    /**
-     * The connection user name to be passed to our JDBC driver to establish a connection.
-     */
-    private String userName;
-
-    /**
-     * The SQL query that will be used to validate connections from this pool before returning them to the caller. If
-     * specified, this query <strong>MUST</strong> be an SQL SELECT statement that returns at least one row. If not
-     * specified, {@link Connection#isValid(int)} will be used to validate connections.
-     */
-    private volatile String validationQuery;
-
-    /**
-     * Timeout in seconds before connection validation queries fail.
-     */
-    private volatile int validationQueryTimeoutSeconds = -1;
-
-    /**
-     * The fully qualified Java class name of a {@link ConnectionFactory} implementation.
-     */
-    private String connectionFactoryClassName;
-
-    /**
-     * These SQL statements run once after a Connection is created.
-     * <p>
-     * This property can be used for example to run ALTER SESSION SET NLS_SORT=XCYECH in an Oracle Database only once
-     * after connection creation.
-     * </p>
-     */
-    private volatile List<String> connectionInitSqls;
-
-    /**
-     * Controls access to the underlying connection.
-     */
-    private boolean accessToUnderlyingConnectionAllowed = false;
-
-    private long maxConnLifetimeMillis = -1;
-
-    private boolean logExpiredConnections = true;
-
-    private String jmxName;
-
-    private boolean autoCommitOnReturn = true;
-
-    private boolean rollbackOnReturn = true;
-
-    private volatile Set<String> disconnectionSqlCodes;
-
-    private boolean fastFailValidation;
-
-    /**
-     * The object pool that internally manages our connections.
-     */
-    private volatile GenericObjectPool<PoolableConnection> connectionPool;
-
-    /**
-     * The connection properties that will be sent to our JDBC driver when establishing new connections.
-     * <strong>NOTE</strong> - The "user" and "password" properties will be passed explicitly, so they do not need to be
-     * included here.
-     */
-    private Properties connectionProperties = new Properties();
-
-    /**
-     * The data source we will use to manage connections. This object should be acquired <strong>ONLY</strong> by calls
-     * to the <code>createDataSource()</code> method.
-     */
-    private volatile DataSource dataSource;
-
-    /**
-     * The PrintWriter to which log messages should be directed.
-     */
-    private volatile PrintWriter logWriter = new PrintWriter(
-        new OutputStreamWriter(System.out, StandardCharsets.UTF_8));
-
-    private AbandonedConfig abandonedConfig;
-
-    private boolean closed;
-
-    /**
-     * Actual name under which this component has been registered.
-     */
-    private ObjectNameWrapper registeredJmxObjectName;
-
-    /**
-     * Adds a custom connection property to the set that will be passed to our JDBC driver. This <strong>MUST</strong>
-     * be called before the first connection is retrieved (along with all the other configuration property setters).
-     * Calls to this method after the connection pool has been initialized have no effect.
-     *
-     * @param name
-     *            Name of the custom connection property
-     * @param value
-     *            Value of the custom connection property
-     */
-    public void addConnectionProperty(final String name, final String value) {
-        connectionProperties.put(name, value);
-    }
-
-    /**
-     * <p>
-     * Closes and releases all idle connections that are currently stored in the connection pool associated with this
-     * data source.
-     * </p>
-     * <p>
-     * Connections that are checked out to clients when this method is invoked are not affected. When client
-     * applications subsequently invoke {@link Connection#close()} to return these connections to the pool, the
-     * underlying JDBC connections are closed.
-     * </p>
-     * <p>
-     * Attempts to acquire connections using {@link #getConnection()} after this method has been invoked result in
-     * SQLExceptions.
-     * </p>
-     * <p>
-     * This method is idempotent - i.e., closing an already closed BasicDataSource has no effect and does not generate
-     * exceptions.
-     * </p>
-     *
-     * @throws SQLException
-     *             if an error occurs closing idle connections
-     */
-    @Override
-    public synchronized void close() throws SQLException {
-        if (registeredJmxObjectName != null) {
-            registeredJmxObjectName.unregisterMBean();
-            registeredJmxObjectName = null;
-        }
-        closed = true;
-        final GenericObjectPool<?> oldPool = connectionPool;
-        connectionPool = null;
-        dataSource = null;
-        try {
-            if (oldPool != null) {
-                oldPool.close();
-            }
-        } catch (final RuntimeException e) {
-            throw e;
-        } catch (final Exception e) {
-            throw new SQLException(Utils.getMessage("pool.close.fail"), e);
-        }
-    }
-
-    /**
-     * Closes the connection pool, silently swallowing any exception that occurs.
-     */
-    private void closeConnectionPool() {
-        final GenericObjectPool<?> oldPool = connectionPool;
-        connectionPool = null;
-        try {
-            if (oldPool != null) {
-                oldPool.close();
-            }
-        } catch (final Exception e) {
-            /* Ignore */
-        }
-    }
-
-    /**
-     * Creates a JDBC connection factory for this datasource. The JDBC driver is loaded using the following algorithm:
-     * <ol>
-     * <li>If a Driver instance has been specified via {@link #setDriver(Driver)} use it</li>
-     * <li>If no Driver instance was specified and {@link #driverClassName} is specified that class is loaded using the
-     * {@link ClassLoader} of this class or, if {@link #driverClassLoader} is set, {@link #driverClassName} is loaded
-     * with the specified {@link ClassLoader}.</li>
-     * <li>If {@link #driverClassName} is specified and the previous attempt fails, the class is loaded using the
-     * context class loader of the current thread.</li>
-     * <li>If a driver still isn't loaded one is loaded via the {@link DriverManager} using the specified {@link #url}.
-     * </ol>
-     * This method exists so subclasses can replace the implementation class.
-     *
-     * @return A new connection factory.
-     *
-     * @throws SQLException
-     *            If the connection factort cannot be created
-     */
-    protected ConnectionFactory createConnectionFactory() throws SQLException {
-        // Load the JDBC driver class
-        Driver driverToUse = this.driver;
-
-        if (driverToUse == null) {
-            Class<?> driverFromCCL = null;
-            if (driverClassName != null) {
-                try {
-                    try {
-                        if (driverClassLoader == null) {
-                            driverFromCCL = Class.forName(driverClassName);
-                        } else {
-                            driverFromCCL = Class.forName(driverClassName, true, driverClassLoader);
-                        }
-                    } catch (final ClassNotFoundException cnfe) {
-                        driverFromCCL = Thread.currentThread().getContextClassLoader().loadClass(driverClassName);
-                    }
-                } catch (final Exception t) {
-                    final String message = "Cannot load JDBC driver class '" + driverClassName + "'";
-                    logWriter.println(message);
-                    t.printStackTrace(logWriter);
-                    throw new SQLException(message, t);
-                }
-            }
-
-            try {
-                if (driverFromCCL == null) {
-                    driverToUse = DriverManager.getDriver(url);
-                } else {
-                    // Usage of DriverManager is not possible, as it does not
-                    // respect the ContextClassLoader
-                    // N.B. This cast may cause ClassCastException which is handled below
-                    driverToUse = (Driver) driverFromCCL.getConstructor().newInstance();
-                    if (!driverToUse.acceptsURL(url)) {
-                        throw new SQLException("No suitable driver", "08001");
-                    }
-                }
-            } catch (final Exception t) {
-                final String message = "Cannot create JDBC driver of class '"
-                    + (driverClassName != null ? driverClassName : "") + "' for connect URL '" + url + "'";
-                logWriter.println(message);
-                t.printStackTrace(logWriter);
-                throw new SQLException(message, t);
-            }
-        }
-
-        // Set up the driver connection factory we will use
-        final String user = userName;
-        if (user != null) {
-            connectionProperties.put("user", user);
-        } else {
-            log("DBCP DataSource configured without a 'username'");
-        }
-
-        final String pwd = password;
-        if (pwd != null) {
-            connectionProperties.put("password", pwd);
-        } else {
-            log("DBCP DataSource configured without a 'password'");
-        }
-
-        return createConnectionFactory(driverToUse);
-    }
-
-    /**
-     * Creates a connection pool for this datasource. This method only exists so subclasses can replace the
-     * implementation class.
-     * <p>
-     * This implementation configures all pool properties other than timeBetweenEvictionRunsMillis. Setting that
-     * property is deferred to {@link #startPoolMaintenance()}, since setting timeBetweenEvictionRunsMillis to a
-     * positive value causes {@link GenericObjectPool}'s eviction timer to be started.
-     * </p>
-     *
-     * @param factory
-     *            The factory to use to create new connections for this pool.
-     */
-    protected void createConnectionPool(final PoolableConnectionFactory factory) {
-        // Create an object pool to contain our active connections
-        final GenericObjectPoolConfig<PoolableConnection> config = new GenericObjectPoolConfig<>();
-        updateJmxName(config);
-        // Disable JMX on the underlying pool if the DS is not registered:
-        config.setJmxEnabled(registeredJmxObjectName != null);
-        final GenericObjectPool<PoolableConnection> gop = createObjectPool(factory, config, abandonedConfig);
-        gop.setMaxTotal(maxTotal);
-        gop.setMaxIdle(maxIdle);
-        gop.setMinIdle(minIdle);
-        gop.setMaxWaitMillis(maxWaitMillis);
-        gop.setTestOnCreate(testOnCreate);
-        gop.setTestOnBorrow(testOnBorrow);
-        gop.setTestOnReturn(testOnReturn);
-        gop.setNumTestsPerEvictionRun(numTestsPerEvictionRun);
-        gop.setMinEvictableIdleTimeMillis(minEvictableIdleTimeMillis);
-        gop.setSoftMinEvictableIdleTimeMillis(softMinEvictableIdleTimeMillis);
-        gop.setTestWhileIdle(testWhileIdle);
-        gop.setLifo(lifo);
-        gop.setSwallowedExceptionListener(new SwallowedExceptionLogger(log, logExpiredConnections));
-        gop.setEvictionPolicyClassName(evictionPolicyClassName);
-        factory.setPool(gop);
-        connectionPool = gop;
-    }
-
-    /**
-     * <p>
-     * Creates (if necessary) and return the internal data source we are using to manage our connections.
-     * </p>
-     *
-     * @return The current internal DataSource or a newly created instance if it has not yet been created.
-     * @throws SQLException
-     *             if the object pool cannot be created.
-     */
-    protected DataSource createDataSource() throws SQLException {
-        if (closed) {
-            throw new SQLException("Data source is closed");
-        }
-
-        // Return the pool if we have already created it
-        // This is double-checked locking. This is safe since dataSource is
-        // volatile and the code is targeted at Java 5 onwards.
-        if (dataSource != null) {
-            return dataSource;
-        }
-        synchronized (this) {
-            if (dataSource != null) {
-                return dataSource;
-            }
-
-            jmxRegister();
-
-            // create factory which returns raw physical connections
-            final ConnectionFactory driverConnectionFactory = createConnectionFactory();
-
-            // Set up the poolable connection factory
-            boolean success = false;
-            PoolableConnectionFactory poolableConnectionFactory;
-            try {
-                poolableConnectionFactory = createPoolableConnectionFactory(driverConnectionFactory);
-                poolableConnectionFactory.setPoolStatements(poolPreparedStatements);
-                poolableConnectionFactory.setMaxOpenPreparedStatements(maxOpenPreparedStatements);
-                success = true;
-            } catch (final SQLException se) {
-                throw se;
-            } catch (final RuntimeException rte) {
-                throw rte;
-            } catch (final Exception ex) {
-                throw new SQLException("Error creating connection factory", ex);
-            }
-
-            if (success) {
-                // create a pool for our connections
-                createConnectionPool(poolableConnectionFactory);
-            }
-
-            // Create the pooling data source to manage connections
-            DataSource newDataSource;
-            success = false;
-            try {
-                newDataSource = createDataSourceInstance();
-                newDataSource.setLogWriter(logWriter);
-                success = true;
-            } catch (final SQLException se) {
-                throw se;
-            } catch (final RuntimeException rte) {
-                throw rte;
-            } catch (final Exception ex) {
-                throw new SQLException("Error creating datasource", ex);
-            } finally {
-                if (!success) {
-                    closeConnectionPool();
-                }
-            }
-
-            // If initialSize > 0, preload the pool
-            try {
-                for (int i = 0; i < initialSize; i++) {
-                    connectionPool.addObject();
-                }
-            } catch (final Exception e) {
-                closeConnectionPool();
-                throw new SQLException("Error preloading the connection pool", e);
-            }
-
-            // If timeBetweenEvictionRunsMillis > 0, start the pool's evictor task
-            startPoolMaintenance();
-
-            dataSource = newDataSource;
-            return dataSource;
-        }
-    }
-
-    /**
-     * Creates the actual data source instance. This method only exists so that subclasses can replace the
-     * implementation class.
-     *
-     * @throws SQLException
-     *             if unable to create a datasource instance
-     *
-     * @return A new DataSource instance
-     */
-    protected DataSource createDataSourceInstance() throws SQLException {
-        final PoolingDataSource<PoolableConnection> pds = new PoolingDataSource<>(connectionPool);
-        pds.setAccessToUnderlyingConnectionAllowed(isAccessToUnderlyingConnectionAllowed());
-        return pds;
-    }
-
-    /**
-     * Creates an object pool used to provide pooling support for {@link Connection JDBC connections}.
-     *
-     * @param factory
-     *            the object factory
-     * @param poolConfig
-     *            the object pool configuration
-     * @param abandonedConfig
-     *            the abandoned objects configuration
-     * @return a non-null instance
-     */
-    protected GenericObjectPool<PoolableConnection> createObjectPool(final PoolableConnectionFactory factory,
-        final GenericObjectPoolConfig<PoolableConnection> poolConfig, final AbandonedConfig abandonedConfig) {
-        GenericObjectPool<PoolableConnection> gop;
-        if (abandonedConfig != null
-            && (abandonedConfig.getRemoveAbandonedOnBorrow() || abandonedConfig.getRemoveAbandonedOnMaintenance())) {
-            gop = new GenericObjectPool<>(factory, poolConfig, abandonedConfig);
-        } else {
-            gop = new GenericObjectPool<>(factory, poolConfig);
-        }
-        return gop;
-    }
-
-    /**
-     * Creates the PoolableConnectionFactory and attaches it to the connection pool. This method only exists so
-     * subclasses can replace the default implementation.
-     *
-     * @param driverConnectionFactory
-     *            JDBC connection factory
-     * @throws SQLException
-     *             if an error occurs creating the PoolableConnectionFactory
-     *
-     * @return A new PoolableConnectionFactory configured with the current configuration of this BasicDataSource
-     */
-    protected PoolableConnectionFactory createPoolableConnectionFactory(final ConnectionFactory driverConnectionFactory)
-        throws SQLException {
-        PoolableConnectionFactory connectionFactory = null;
-        try {
-            connectionFactory = new PoolableConnectionFactory(driverConnectionFactory,
-                ObjectNameWrapper.unwrap(registeredJmxObjectName));
-            connectionFactory.setValidationQuery(validationQuery);
-            connectionFactory.setValidationQueryTimeout(validationQueryTimeoutSeconds);
-            connectionFactory.setConnectionInitSql(connectionInitSqls);
-            connectionFactory.setDefaultReadOnly(defaultReadOnly);
-            connectionFactory.setDefaultAutoCommit(defaultAutoCommit);
-            connectionFactory.setDefaultTransactionIsolation(defaultTransactionIsolation);
-            connectionFactory.setDefaultCatalog(defaultCatalog);
-            connectionFactory.setDefaultSchema(defaultSchema);
-            connectionFactory.setCacheState(cacheState);
-            connectionFactory.setPoolStatements(poolPreparedStatements);
-            connectionFactory.setMaxOpenPreparedStatements(maxOpenPreparedStatements);
-            connectionFactory.setMaxConnLifetimeMillis(maxConnLifetimeMillis);
-            connectionFactory.setRollbackOnReturn(getRollbackOnReturn());
-            connectionFactory.setAutoCommitOnReturn(getAutoCommitOnReturn());
-            connectionFactory.setDefaultQueryTimeout(getDefaultQueryTimeout());
-            connectionFactory.setFastFailValidation(fastFailValidation);
-            connectionFactory.setDisconnectionSqlCodes(disconnectionSqlCodes);
-            validateConnectionFactory(connectionFactory);
-        } catch (final RuntimeException e) {
-            throw e;
-        } catch (final Exception e) {
-            throw new SQLException("Cannot create PoolableConnectionFactory (" + e.getMessage() + ")", e);
-        }
-        return connectionFactory;
-    }
-
-    /**
-     * Gets the print writer used by this configuration to log information on abandoned objects.
-     *
-     * @return The print writer used by this configuration to log information on abandoned objects.
-     */
-    public PrintWriter getAbandonedLogWriter() {
-        if (abandonedConfig != null) {
-            return abandonedConfig.getLogWriter();
-        }
-        return null;
-    }
-
-    /**
-     * If the connection pool implements {@link org.apache.commons.pool2.UsageTracking UsageTracking}, should the
-     * connection pool record a stack trace every time a method is called on a pooled connection and retain the most
-     * recent stack trace to aid debugging of abandoned connections?
-     *
-     * @return <code>true</code> if usage tracking is enabled
-     */
-    @Override
-    public boolean getAbandonedUsageTracking() {
-        if (abandonedConfig != null) {
-            return abandonedConfig.getUseUsageTracking();
-        }
-        return false;
-    }
-
-    /**
-     * Returns the value of the flag that controls whether or not connections being returned to the pool will be checked
-     * and configured with {@link Connection#setAutoCommit(boolean) Connection.setAutoCommit(true)} if the auto commit
-     * setting is {@code false} when the connection is returned. It is <code>true</code> by default.
-     *
-     * @return Whether or not connections being returned to the pool will be checked and configured with auto-commit.
-     */
-    public boolean getAutoCommitOnReturn() {
-        return autoCommitOnReturn;
-    }
-
-    /**
-     * Returns the state caching flag.
-     *
-     * @return the state caching flag
-     */
-    @Override
-    public boolean getCacheState() {
-        return cacheState;
-    }
-
-    /**
-     * Creates (if necessary) and return a connection to the database.
-     *
-     * @throws SQLException
-     *             if a database access error occurs
-     * @return a database connection
-     */
-    @Override
-    public Connection getConnection() throws SQLException {
-        if (Utils.IS_SECURITY_ENABLED) {
-            final PrivilegedExceptionAction<Connection> action = new PaGetConnection();
-            try {
-                return AccessController.doPrivileged(action);
-            } catch (final PrivilegedActionException e) {
-                final Throwable cause = e.getCause();
-                if (cause instanceof SQLException) {
-                    throw (SQLException) cause;
-                }
-                throw new SQLException(e);
-            }
-        }
-        return createDataSource().getConnection();
-    }
-
-    /**
-     * <strong>BasicDataSource does NOT support this method.</strong>
-     *
-     * @param user
-     *            Database user on whose behalf the Connection is being made
-     * @param pass
-     *            The database user's password
-     *
-     * @throws UnsupportedOperationException
-     *             always thrown.
-     * @throws SQLException
-     *             if a database access error occurs
-     * @return nothing - always throws UnsupportedOperationException
-     */
-    @Override
-    public Connection getConnection(final String user, final String pass) throws SQLException {
-        // This method isn't supported by the PoolingDataSource returned by the createDataSource
-        throw new UnsupportedOperationException("Not supported by BasicDataSource");
-    }
-
-    /**
-     * Returns the list of SQL statements executed when a physical connection is first created. Returns an empty list if
-     * there are no initialization statements configured.
-     *
-     * @return initialization SQL statements
-     */
-    public List<String> getConnectionInitSqls() {
-        final List<String> result = connectionInitSqls;
-        if (result == null) {
-            return Collections.emptyList();
-        }
-        return result;
-    }
-
-    /**
-     * Provides the same data as {@link #getConnectionInitSqls()} but in an array so it is accessible via JMX.
-     */
-    @Override
-    public String[] getConnectionInitSqlsAsArray() {
-        final Collection<String> result = getConnectionInitSqls();
-        return result.toArray(new String[result.size()]);
-    }
-
-    protected GenericObjectPool<PoolableConnection> getConnectionPool() {
-        return connectionPool;
-    }
-
-    // For unit testing
-    Properties getConnectionProperties() {
-        return connectionProperties;
-    }
-
-    /**
-     * Returns the default auto-commit property.
-     *
-     * @return true if default auto-commit is enabled
-     */
-    @Override
-    public Boolean getDefaultAutoCommit() {
-        return defaultAutoCommit;
-    }
-
-    /**
-     * Returns the default catalog.
-     *
-     * @return the default catalog
-     */
-    @Override
-    public String getDefaultCatalog() {
-        return this.defaultCatalog;
-    }
-
-    /**
-     * Gets the default query timeout that will be used for {@link java.sql.Statement Statement}s created from this
-     * connection. <code>null</code> means that the driver default will be used.
-     *
-     * @return The default query timeout in seconds.
-     */
-    public Integer getDefaultQueryTimeout() {
-        return defaultQueryTimeoutSeconds;
-    }
-
-    /**
-     * Returns the default readOnly property.
-     *
-     * @return true if connections are readOnly by default
-     */
-    @Override
-    public Boolean getDefaultReadOnly() {
-        return defaultReadOnly;
-    }
-
-    /**
-     * Returns the default schema.
-     *
-     * @return the default schema.
-     * @since 2.5.0
-     */
-    @Override
-    public String getDefaultSchema() {
-        return this.defaultSchema;
-    }
-
-    /**
-     * Returns the default transaction isolation state of returned connections.
-     *
-     * @return the default value for transaction isolation state
-     * @see Connection#getTransactionIsolation
-     */
-    @Override
-    public int getDefaultTransactionIsolation() {
-        return this.defaultTransactionIsolation;
-    }
-
-    /**
-     * Returns the set of SQL_STATE codes considered to signal fatal conditions.
-     *
-     * @return fatal disconnection state codes
-     * @see #setDisconnectionSqlCodes(Collection)
-     * @since 2.1
-     */
-    public Set<String> getDisconnectionSqlCodes() {
-        final Set<String> result = disconnectionSqlCodes;
-        if (result == null) {
-            return Collections.emptySet();
-        }
-        return result;
-    }
-
-    /**
-     * Provides the same data as {@link #getDisconnectionSqlCodes} but in an array so it is accessible via JMX.
-     *
-     * @since 2.1
-     */
-    @Override
-    public String[] getDisconnectionSqlCodesAsArray() {
-        final Collection<String> result = getDisconnectionSqlCodes();
-        return result.toArray(new String[result.size()]);
-    }
-
-    /**
-     * Returns the JDBC Driver that has been configured for use by this pool.
-     * <p>
-     * Note: This getter only returns the last value set by a call to {@link #setDriver(Driver)}. It does not return any
-     * driver instance that may have been created from the value set via {@link #setDriverClassName(String)}.
-     * </p>
-     *
-     * @return the JDBC Driver that has been configured for use by this pool
-     */
-    public synchronized Driver getDriver() {
-        return driver;
-    }
-
-    /**
-     * Returns the class loader specified for loading the JDBC driver. Returns <code>null</code> if no class loader has
-     * been explicitly specified.
-     * <p>
-     * Note: This getter only returns the last value set by a call to {@link #setDriverClassLoader(ClassLoader)}. It
-     * does not return the class loader of any driver that may have been set via {@link #setDriver(Driver)}.
-     * </p>
-     *
-     * @return The class loader specified for loading the JDBC driver.
-     */
-    public synchronized ClassLoader getDriverClassLoader() {
-        return this.driverClassLoader;
-    }
-
-    /**
-     * Returns the JDBC driver class name.
-     * <p>
-     * Note: This getter only returns the last value set by a call to {@link #setDriverClassName(String)}. It does not
-     * return the class name of any driver that may have been set via {@link #setDriver(Driver)}.
-     * </p>
-     *
-     * @return the JDBC driver class name
-     */
-    @Override
-    public synchronized String getDriverClassName() {
-        return this.driverClassName;
-    }
-
-    /**
-     * Returns the ConnectionFactoryClassName that has been configured for use by this pool.
-     * <p>
-     * Note: This getter only returns the last value set by a call to
-     * {@link #setConnectionFactoryClassName(String)}.
-     * </p>
-     *
-     * @return the ConnectionFactoryClassName that has been configured for use by this pool.
-     * @since 2.7.0
-     */
-    public String getConnectionFactoryClassName() {
-        return this.connectionFactoryClassName;
-    }
-
-    /**
-     * Returns the value of the flag that controls whether or not connections being returned to the pool will be checked
-     * and configured with {@link Connection#setAutoCommit(boolean) Connection.setAutoCommit(true)} if the auto commit
-     * setting is {@code false} when the connection is returned. It is <code>true</code> by default.
-     *
-     * @return Whether or not connections being returned to the pool will be checked and configured with auto-commit.
-     * @deprecated Use {@link #getAutoCommitOnReturn()}.
-     */
-    @Deprecated
-    public boolean getEnableAutoCommitOnReturn() {
-        return autoCommitOnReturn;
-    }
-
-    /**
-     * Gets the EvictionPolicy implementation in use with this connection pool.
-     *
-     * @return The EvictionPolicy implementation in use with this connection pool.
-     */
-    public synchronized String getEvictionPolicyClassName() {
-        return evictionPolicyClassName;
-    }
-
-    /**
-     * True means that validation will fail immediately for connections that have previously thrown SQLExceptions with
-     * SQL_STATE indicating fatal disconnection errors.
-     *
-     * @return true if connections created by this datasource will fast fail validation.
-     * @see #setDisconnectionSqlCodes(Collection)
-     * @since 2.1
-     */
-    @Override
-    public boolean getFastFailValidation() {
-        return fastFailValidation;
-    }
-
-    /**
-     * Returns the initial size of the connection pool.
-     *
-     * @return the number of connections created when the pool is initialized
-     */
-    @Override
-    public synchronized int getInitialSize() {
-        return this.initialSize;
-    }
-
-    /**
-     * Returns the JMX name that has been requested for this DataSource. If the requested name is not valid, an
-     * alternative may be chosen.
-     *
-     * @return The JMX name that has been requested for this DataSource.
-     */
-    public String getJmxName() {
-        return jmxName;
-    }
-
-    /**
-     * Returns the LIFO property.
-     *
-     * @return true if connection pool behaves as a LIFO queue.
-     */
-    @Override
-    public synchronized boolean getLifo() {
-        return this.lifo;
-    }
-
-    /**
-     * <p>
-     * Flag to log stack traces for application code which abandoned a Statement or Connection.
-     * </p>
-     * <p>
-     * Defaults to false.
-     * </p>
-     * <p>
-     * Logging of abandoned Statements and Connections adds overhead for every Connection open or new Statement because
-     * a stack trace has to be generated.
-     * </p>
-     */
-    @Override
-    public boolean getLogAbandoned() {
-        if (abandonedConfig != null) {
-            return abandonedConfig.getLogAbandoned();
-        }
-        return false;
-    }
-
-    /**
-     * When {@link #getMaxConnLifetimeMillis()} is set to limit connection lifetime, this property determines whether or
-     * not log messages are generated when the pool closes connections due to maximum lifetime exceeded.
-     *
-     * @since 2.1
-     */
-    @Override
-    public boolean getLogExpiredConnections() {
-        return logExpiredConnections;
-    }
-
-    /**
-     * <strong>BasicDataSource does NOT support this method.</strong>
-     *
-     * <p>
-     * Returns the login timeout (in seconds) for connecting to the database.
-     * </p>
-     * <p>
-     * Calls {@link #createDataSource()}, so has the side effect of initializing the connection pool.
-     * </p>
-     *
-     * @throws SQLException
-     *             if a database access error occurs
-     * @throws UnsupportedOperationException
-     *             If the DataSource implementation does not support the login timeout feature.
-     * @return login timeout in seconds
-     */
-    @Override
-    public int getLoginTimeout() throws SQLException {
-        // This method isn't supported by the PoolingDataSource returned by the createDataSource
-        throw new UnsupportedOperationException("Not supported by BasicDataSource");
-    }
-
-    /**
-     * <p>
-     * Returns the log writer being used by this data source.
-     * </p>
-     * <p>
-     * Calls {@link #createDataSource()}, so has the side effect of initializing the connection pool.
-     * </p>
-     *
-     * @throws SQLException
-     *             if a database access error occurs
-     * @return log writer in use
-     */
-    @Override
-    public PrintWriter getLogWriter() throws SQLException {
-        return createDataSource().getLogWriter();
-    }
-
-    /**
-     * Returns the maximum permitted lifetime of a connection in milliseconds. A value of zero or less indicates an
-     * infinite lifetime.
-     */
-    @Override
-    public long getMaxConnLifetimeMillis() {
-        return maxConnLifetimeMillis;
-    }
-
-    /**
-     * <p>
-     * Returns the maximum number of connections that can remain idle in the pool. Excess idle connections are destroyed
-     * on return to the pool.
-     * </p>
-     * <p>
-     * A negative value indicates that there is no limit
-     * </p>
-     *
-     * @return the maximum number of idle connections
-     */
-    @Override
-    public synchronized int getMaxIdle() {
-        return this.maxIdle;
-    }
-
-    /**
-     * Gets the value of the <code>maxOpenPreparedStatements</code> property.
-     *
-     * @return the maximum number of open statements
-     */
-    @Override
-    public synchronized int getMaxOpenPreparedStatements() {
-        return this.maxOpenPreparedStatements;
-    }
-
-    /**
-     * <p>
-     * Returns the maximum number of active connections that can be allocated at the same time.
-     * </p>
-     * <p>
-     * A negative number means that there is no limit.
-     * </p>
-     *
-     * @return the maximum number of active connections
-     */
-    @Override
-    public synchronized int getMaxTotal() {
-        return this.maxTotal;
-    }
-
-    /**
-     * Returns the maximum number of milliseconds that the pool will wait for a connection to be returned before
-     * throwing an exception. A value less than or equal to zero means the pool is set to wait indefinitely.
-     *
-     * @return the maxWaitMillis property value
-     */
-    @Override
-    public synchronized long getMaxWaitMillis() {
-        return this.maxWaitMillis;
-    }
-
-    /**
-     * Returns the {@link #minEvictableIdleTimeMillis} property.
-     *
-     * @return the value of the {@link #minEvictableIdleTimeMillis} property
-     * @see #minEvictableIdleTimeMillis
-     */
-    @Override
-    public synchronized long getMinEvictableIdleTimeMillis() {
-        return this.minEvictableIdleTimeMillis;
-    }
-
-    /**
-     * Returns the minimum number of idle connections in the pool. The pool attempts to ensure that minIdle connections
-     * are available when the idle object evictor runs. The value of this property has no effect unless
-     * {@link #timeBetweenEvictionRunsMillis} has a positive value.
-     *
-     * @return the minimum number of idle connections
-     * @see GenericObjectPool#getMinIdle()
-     */
-    @Override
-    public synchronized int getMinIdle() {
-        return this.minIdle;
-    }
-
-    /**
-     * [Read Only] The current number of active connections that have been allocated from this data source.
-     *
-     * @return the current number of active connections
-     */
-    @Override
-    public int getNumActive() {
-        // Copy reference to avoid NPE if close happens after null check
-        final GenericObjectPool<PoolableConnection> pool = connectionPool;
-        if (pool != null) {
-            return pool.getNumActive();
-        }
-        return 0;
-    }
-
-    /**
-     * [Read Only] The current number of idle connections that are waiting to be allocated from this data source.
-     *
-     * @return the current number of idle connections
-     */
-    @Override
-    public int getNumIdle() {
-        // Copy reference to avoid NPE if close happens after null check
-        final GenericObjectPool<PoolableConnection> pool = connectionPool;
-        if (pool != null) {
-            return pool.getNumIdle();
-        }
-        return 0;
-    }
-
-    /**
-     * Returns the value of the {@link #numTestsPerEvictionRun} property.
-     *
-     * @return the number of objects to examine during idle object evictor runs
-     * @see #numTestsPerEvictionRun
-     */
-    @Override
-    public synchronized int getNumTestsPerEvictionRun() {
-        return this.numTestsPerEvictionRun;
-    }
-
-    @Override
-    public Logger getParentLogger() throws SQLFeatureNotSupportedException {
-        throw new SQLFeatureNotSupportedException();
-    }
-
-    /**
-     * Returns the password passed to the JDBC driver to establish connections.
-     *
-     * @return the connection password
-     */
-    @Override
-    public String getPassword() {
-        return this.password;
-    }
-
-    protected ObjectName getRegisteredJmxName() {
-        return ObjectNameWrapper.unwrap(registeredJmxObjectName);
-    }
-
-    /**
-     * <p>
-     * Flag to remove abandoned connections if they exceed the removeAbandonedTimeout when borrowObject is invoked.
-     * </p>
-     * <p>
-     * The default value is false.
-     * </p>
-     * <p>
-     * If set to true a connection is considered abandoned and eligible for removal if it has not been used for more
-     * than {@link #getRemoveAbandonedTimeout() removeAbandonedTimeout} seconds.
-     * </p>
-     * <p>
-     * Abandoned connections are identified and removed when {@link #getConnection()} is invoked and all of the
-     * following conditions hold:
-     * </p>
-     * <ul>
-     * <li>{@link #getRemoveAbandonedOnBorrow()}</li>
-     * <li>{@link #getNumActive()} &gt; {@link #getMaxTotal()} - 3</li>
-     * <li>{@link #getNumIdle()} &lt; 2</li>
-     * </ul>
-     *
-     * @see #getRemoveAbandonedTimeout()
-     */
-    @Override
-    public boolean getRemoveAbandonedOnBorrow() {
-        if (abandonedConfig != null) {
-            return abandonedConfig.getRemoveAbandonedOnBorrow();
-        }
-        return false;
-    }
-
-    /**
-     * <p>
-     * Flag to remove abandoned connections if they exceed the removeAbandonedTimeout during pool maintenance.
-     * </p>
-     *
-     * <p>
-     * The default value is false.
-     * </p>
-     *
-     * <p>
-     * If set to true a connection is considered abandoned and eligible for removal if it has not been used for more
-     * than {@link #getRemoveAbandonedTimeout() removeAbandonedTimeout} seconds.
-     * </p>
-     *
-     * @see #getRemoveAbandonedTimeout()
-     */
-    @Override
-    public boolean getRemoveAbandonedOnMaintenance() {
-        if (abandonedConfig != null) {
-            return abandonedConfig.getRemoveAbandonedOnMaintenance();
-        }
-        return false;
-    }
-
-    /**
-     * <p>
-     * Timeout in seconds before an abandoned connection can be removed.
-     * </p>
-     * <p>
-     * Creating a Statement, PreparedStatement or CallableStatement or using one of these to execute a query (using one
-     * of the execute methods) resets the lastUsed property of the parent connection.
-     * </p>
-     * <p>
-     * Abandoned connection cleanup happens when:
-     * </p>
-     * <ul>
-     * <li>{@link #getRemoveAbandonedOnBorrow()} or {@link #getRemoveAbandonedOnMaintenance()} = true</li>
-     * <li>{@link #getNumIdle() numIdle} &lt; 2</li>
-     * <li>{@link #getNumActive() numActive} &gt; {@link #getMaxTotal() maxTotal} - 3</li>
-     * </ul>
-     * <p>
-     * The default value is 300 seconds.
-     * </p>
-     */
-    @Override
-    public int getRemoveAbandonedTimeout() {
-        if (abandonedConfig != null) {
-            return abandonedConfig.getRemoveAbandonedTimeout();
-        }
-        return 300;
-    }
-
-    /**
-     * Gets the current value of the flag that controls whether a connection will be rolled back when it is returned to
-     * the pool if auto commit is not enabled and the connection is not read only.
-     *
-     * @return whether a connection will be rolled back when it is returned to the pool.
-     */
-    public boolean getRollbackOnReturn() {
-        return rollbackOnReturn;
-    }
-
-    /**
-     * <p>
-     * Returns the minimum amount of time a connection may sit idle in the pool before it is eligible for eviction by
-     * the idle object evictor, with the extra condition that at least "minIdle" connections remain in the pool.
-     * </p>
-     *
-     * <p>
-     * When {@link #getMinEvictableIdleTimeMillis() minEvictableIdleTimeMillis} is set to a positive value,
-     * minEvictableIdleTimeMillis is examined first by the idle connection evictor - i.e. when idle connections are
-     * visited by the evictor, idle time is first compared against {@code minEvictableIdleTimeMillis} (without
-     * considering the number of idle connections in the pool) and then against {@code softMinEvictableIdleTimeMillis},
-     * including the {@code minIdle}, constraint.
-     * </p>
-     *
-     * @return minimum amount of time a connection may sit idle in the pool before it is eligible for eviction, assuming
-     *         there are minIdle idle connections in the pool
-     */
-    @Override
-    public synchronized long getSoftMinEvictableIdleTimeMillis() {
-        return softMinEvictableIdleTimeMillis;
-    }
-
-    /**
-     * Returns the {@link #testOnBorrow} property.
-     *
-     * @return true if objects are validated before being borrowed from the pool
-     *
-     * @see #testOnBorrow
-     */
-    @Override
-    public synchronized boolean getTestOnBorrow() {
-        return this.testOnBorrow;
-    }
-
-    /**
-     * Returns the {@link #testOnCreate} property.
-     *
-     * @return true if objects are validated immediately after they are created by the pool
-     * @see #testOnCreate
-     */
-    @Override
-    public synchronized boolean getTestOnCreate() {
-        return this.testOnCreate;
-    }
-
-    /**
-     * Returns the value of the {@link #testOnReturn} property.
-     *
-     * @return true if objects are validated before being returned to the pool
-     * @see #testOnReturn
-     */
-    public synchronized boolean getTestOnReturn() {
-        return this.testOnReturn;
-    }
-
-    /**
-     * Returns the value of the {@link #testWhileIdle} property.
-     *
-     * @return true if objects examined by the idle object evictor are validated
-     * @see #testWhileIdle
-     */
-    @Override
-    public synchronized boolean getTestWhileIdle() {
-        return this.testWhileIdle;
-    }
-
-    /**
-     * Returns the value of the {@link #timeBetweenEvictionRunsMillis} property.
-     *
-     * @return the time (in milliseconds) between evictor runs
-     * @see #timeBetweenEvictionRunsMillis
-     */
-    @Override
-    public synchronized long getTimeBetweenEvictionRunsMillis() {
-        return this.timeBetweenEvictionRunsMillis;
-    }
-
-    /**
-     * Returns the JDBC connection {@link #url} property.
-     *
-     * @return the {@link #url} passed to the JDBC driver to establish connections
-     */
-    @Override
-    public synchronized String getUrl() {
-        return this.url;
-    }
-
-    /**
-     * Returns the JDBC connection {@link #userName} property.
-     *
-     * @return the {@link #userName} passed to the JDBC driver to establish connections
-     */
-    @Override
-    public String getUsername() {
-        return this.userName;
-    }
-
-    /**
-     * Returns the validation query used to validate connections before returning them.
-     *
-     * @return the SQL validation query
-     * @see #validationQuery
-     */
-    @Override
-    public String getValidationQuery() {
-        return this.validationQuery;
-    }
-
-    /**
-     * Returns the validation query timeout.
-     *
-     * @return the timeout in seconds before connection validation queries fail.
-     */
-    @Override
-    public int getValidationQueryTimeout() {
-        return validationQueryTimeoutSeconds;
-    }
-
-    /**
-     * Manually invalidates a connection, effectively requesting the pool to try to close it, remove it from the pool
-     * and reclaim pool capacity.
-     *
-     * @param connection
-     *            The Connection to invalidate.
-     *
-     * @throws IllegalStateException
-     *             if invalidating the connection failed.
-     * @since 2.1
-     */
-    public void invalidateConnection(final Connection connection) throws IllegalStateException {
-        if (connection == null) {
-            return;
-        }
-        if (connectionPool == null) {
-            throw new IllegalStateException("Cannot invalidate connection: ConnectionPool is null.");
-        }
-
-        final PoolableConnection poolableConnection;
-        try {
-            poolableConnection = connection.unwrap(PoolableConnection.class);
-            if (poolableConnection == null) {
-                throw new IllegalStateException(
-                    "Cannot invalidate connection: Connection is not a poolable connection.");
-            }
-        } catch (final SQLException e) {
-            throw new IllegalStateException("Cannot invalidate connection: Unwrapping poolable connection failed.", e);
-        }
-
-        try {
-            connectionPool.invalidateObject(poolableConnection);
-        } catch (final Exception e) {
-            throw new IllegalStateException("Invalidating connection threw unexpected exception", e);
-        }
-    }
-
-    /**
-     * Manually evicts idle connections.
-     *
-     * @throws Exception Thrown by {@link GenericObjectPool#evict()}.
-     * @see GenericObjectPool#evict()
-     */
-    public void evict() throws Exception {
-        if (connectionPool != null) {
-            connectionPool.evict();
-        }
-    }
-
-    /**
-     * Returns the value of the accessToUnderlyingConnectionAllowed property.
-     *
-     * @return true if access to the underlying connection is allowed, false otherwise.
-     */
-    @Override
-    public synchronized boolean isAccessToUnderlyingConnectionAllowed() {
-        return this.accessToUnderlyingConnectionAllowed;
-    }
-
-    /**
-     * If true, this data source is closed and no more connections can be retrieved from this datasource.
-     *
-     * @return true, if the data source is closed; false otherwise
-     */
-    @Override
-    public synchronized boolean isClosed() {
-        return closed;
-    }
-
-    /**
-     * Delegates in a null-safe manner to {@link String#isEmpty()}.
-     *
-     * @param value the string to test, may be null.
-     * @return boolean false if value is null, otherwise {@link String#isEmpty()}.
-     */
-    private boolean isEmpty(String value) {
-        return value == null ? true : value.trim().isEmpty();
-    }
-
-    /**
-     * Returns true if we are pooling statements.
-     *
-     * @return true if prepared and callable statements are pooled
-     */
-    @Override
-    public synchronized boolean isPoolPreparedStatements() {
-        return this.poolPreparedStatements;
-    }
-
-    @Override
-    public boolean isWrapperFor(final Class<?> iface) throws SQLException {
-        return false;
-    }
-
-    private void jmxRegister() {
-        // Return immediately if this DataSource has already been registered
-        if (registeredJmxObjectName != null) {
-            return;
-        }
-        // Return immediately if no JMX name has been specified
-        final String requestedName = getJmxName();
-        if (requestedName == null) {
-            return;
-        }
-        try {
-            ObjectNameWrapper.wrap(requestedName).registerMBean(this);
-        } catch (final MalformedObjectNameException e) {
-            log.warn("The requested JMX name [" + requestedName + "] was not valid and will be ignored.");
-        }
-    }
-
-    protected void log(final String message) {
-        if (logWriter != null) {
-            logWriter.println(message);
-        }
-    }
-
-    @Override
-    public void postDeregister() {
-        // NO-OP
-    }
-
-    @Override
-    public void postRegister(final Boolean registrationDone) {
-        // NO-OP
-    }
-
-    @Override
-    public void preDeregister() throws Exception {
-        // NO-OP
-    }
-
-    @Override
-    public ObjectName preRegister(final MBeanServer server, final ObjectName objectName) {
-        final String requestedName = getJmxName();
-        if (requestedName != null) {
-            try {
-                registeredJmxObjectName = ObjectNameWrapper.wrap(requestedName);
-            } catch (final MalformedObjectNameException e) {
-                log.warn("The requested JMX name [" + requestedName + "] was not valid and will be ignored.");
-            }
-        }
-        if (registeredJmxObjectName == null) {
-            registeredJmxObjectName = ObjectNameWrapper.wrap(objectName);
-        }
-        return ObjectNameWrapper.unwrap(registeredJmxObjectName);
-    }
-
-    /**
-     * Removes a custom connection property.
-     *
-     * @param name
-     *            Name of the custom connection property to remove
-     * @see #addConnectionProperty(String, String)
-     */
-    public void removeConnectionProperty(final String name) {
-        connectionProperties.remove(name);
-    }
-
-    /**
-     * Sets the print writer to be used by this configuration to log information on abandoned objects.
-     *
-     * @param logWriter
-     *            The new log writer
-     */
-    public void setAbandonedLogWriter(final PrintWriter logWriter) {
-        if (abandonedConfig == null) {
-            abandonedConfig = new AbandonedConfig();
-        }
-        abandonedConfig.setLogWriter(logWriter);
-        final GenericObjectPool<?> gop = this.connectionPool;
-        if (gop != null) {
-            gop.setAbandonedConfig(abandonedConfig);
-        }
-    }
-
-    /**
-     * If the connection pool implements {@link org.apache.commons.pool2.UsageTracking UsageTracking}, configure whether
-     * the connection pool should record a stack trace every time a method is called on a pooled connection and retain
-     * the most recent stack trace to aid debugging of abandoned connections.
-     *
-     * @param usageTracking
-     *            A value of <code>true</code> will enable the recording of a stack trace on every use of a pooled
-     *            connection
-     */
-    public void setAbandonedUsageTracking(final boolean usageTracking) {
-        if (abandonedConfig == null) {
-            abandonedConfig = new AbandonedConfig();
-        }
-        abandonedConfig.setUseUsageTracking(usageTracking);
-        final GenericObjectPool<?> gop = this.connectionPool;
-        if (gop != null) {
-            gop.setAbandonedConfig(abandonedConfig);
-        }
-    }
-
-    /**
-     * <p>
-     * Sets the value of the accessToUnderlyingConnectionAllowed property. It controls if the PoolGuard allows access to
-     * the underlying connection. (Default: false)
-     * </p>
-     * <p>
-     * Note: this method currently has no effect once the pool has been initialized. The pool is initialized the first
-     * time one of the following methods is invoked: <code>getConnection, setLogwriter,
-     * setLoginTimeout, getLoginTimeout, getLogWriter.</code>
-     * </p>
-     *
-     * @param allow
-     *            Access to the underlying connection is granted when true.
-     */
-    public synchronized void setAccessToUnderlyingConnectionAllowed(final boolean allow) {
-        this.accessToUnderlyingConnectionAllowed = allow;
-    }
-
-    /**
-     * Sets the value of the flag that controls whether or not connections being returned to the pool will be checked
-     * and configured with {@link Connection#setAutoCommit(boolean) Connection.setAutoCommit(true)} if the auto commit
-     * setting is {@code false} when the connection is returned. It is <code>true</code> by default.
-     *
-     * @param autoCommitOnReturn
-     *            Whether or not connections being returned to the pool will be checked and configured with auto-commit.
-     * @since 2.6.0
-     */
-    public void setAutoCommitOnReturn(final boolean autoCommitOnReturn) {
-        this.autoCommitOnReturn = autoCommitOnReturn;
-    }
-
-    /**
-     * Sets the state caching flag.
-     *
-     * @param cacheState
-     *            The new value for the state caching flag
-     */
-    public void setCacheState(final boolean cacheState) {
-        this.cacheState = cacheState;
-    }
-
-    /**
-     * Sets the list of SQL statements to be executed when a physical connection is first created.
-     * <p>
-     * Note: this method currently has no effect once the pool has been initialized. The pool is initialized the first
-     * time one of the following methods is invoked: <code>getConnection, setLogwriter,
-     * setLoginTimeout, getLoginTimeout, getLogWriter.</code>
-     * </p>
-     *
-     * @param connectionInitSqls
-     *            Collection of SQL statements to execute on connection creation
-     */
-    public void setConnectionInitSqls(final Collection<String> connectionInitSqls) {
-        if (connectionInitSqls != null && connectionInitSqls.size() > 0) {
-            ArrayList<String> newVal = null;
-            for (final String s : connectionInitSqls) {
-                if (!isEmpty(s)) {
-                    if (newVal == null) {
-                        newVal = new ArrayList<>();
-                    }
-                    newVal.add(s);
-                }
-            }
-            this.connectionInitSqls = newVal;
-        } else {
-            this.connectionInitSqls = null;
-        }
-    }
-
-    // ----------------------------------------------------- DataSource Methods
-
-    /**
-     * Sets the connection properties passed to driver.connect(...).
-     * <p>
-     * Format of the string must be [propertyName=property;]*
-     * </p>
-     * <p>
-     * NOTE - The "user" and "password" properties will be added explicitly, so they do not need to be included here.
-     * </p>
-     *
-     * @param connectionProperties
-     *            the connection properties used to create new connections
-     */
-    public void setConnectionProperties(final String connectionProperties) {
-        Objects.requireNonNull(connectionProperties, "connectionProperties is null");
-        final String[] entries = connectionProperties.split(";");
-        final Properties properties = new Properties();
-        for (final String entry : entries) {
-            if (entry.length() > 0) {
-                final int index = entry.indexOf('=');
-                if (index > 0) {
-                    final String name = entry.substring(0, index);
-                    final String value = entry.substring(index + 1);
-                    properties.setProperty(name, value);
-                } else {
-                    // no value is empty string which is how java.util.Properties works
-                    properties.setProperty(entry, "");
-                }
-            }
-        }
-        this.connectionProperties = properties;
-    }
-
-    /**
-     * <p>
-     * Sets default auto-commit state of connections returned by this datasource.
-     * </p>
-     * <p>
-     * Note: this method currently has no effect once the pool has been initialized. The pool is initialized the first
-     * time one of the following methods is invoked: <code>getConnection, setLogwriter,
-     * setLoginTimeout, getLoginTimeout, getLogWriter.</code>
-     * </p>
-     *
-     * @param defaultAutoCommit
-     *            default auto-commit value
-     */
-    public void setDefaultAutoCommit(final Boolean defaultAutoCommit) {
-        this.defaultAutoCommit = defaultAutoCommit;
-    }
-
-    /**
-     * <p>
-     * Sets the default catalog.
-     * </p>
-     * <p>
-     * Note: this method currently has no effect once the pool has been initialized. The pool is initialized the first
-     * time one of the following methods is invoked: <code>getConnection, setLogwriter,
-     * setLoginTimeout, getLoginTimeout, getLogWriter.</code>
-     * </p>
-     *
-     * @param defaultCatalog
-     *            the default catalog
-     */
-    public void setDefaultCatalog(final String defaultCatalog) {
-        if (isEmpty(defaultCatalog)) {
-            this.defaultCatalog = null;
-        } else {
-            this.defaultCatalog = defaultCatalog;
-        }
-    }
-
-    /**
-     * Sets the default query timeout that will be used for {@link java.sql.Statement Statement}s created from this
-     * connection. <code>null</code> means that the driver default will be used.
-     *
-     * @param defaultQueryTimeoutSeconds
-     *            The default query timeout in seconds.
-     */
-    public void setDefaultQueryTimeout(final Integer defaultQueryTimeoutSeconds) {
-        this.defaultQueryTimeoutSeconds = defaultQueryTimeoutSeconds;
-    }
-
-    /**
-     * <p>
-     * Sets defaultReadonly property.
-     * </p>
-     * <p>
-     * Note: this method currently has no effect once the pool has been initialized. The pool is initialized the first
-     * time one of the following methods is invoked: <code>getConnection, setLogwriter,
-     * setLoginTimeout, getLoginTimeout, getLogWriter.</code>
-     * </p>
-     *
-     * @param defaultReadOnly
-     *            default read-only value
-     */
-    public void setDefaultReadOnly(final Boolean defaultReadOnly) {
-        this.defaultReadOnly = defaultReadOnly;
-    }
-
-    /**
-     * <p>
-     * Sets the default schema.
-     * </p>
-     * <p>
-     * Note: this method currently has no effect once the pool has been initialized. The pool is initialized the first
-     * time one of the following methods is invoked: <code>getConnection, setLogwriter,
-     * setLoginTimeout, getLoginTimeout, getLogWriter.</code>
-     * </p>
-     *
-     * @param defaultSchema
-     *            the default catalog
-     * @since 2.5.0
-     */
-    public void setDefaultSchema(final String defaultSchema) {
-        if (isEmpty(defaultSchema)) {
-            this.defaultSchema = null;
-        } else {
-            this.defaultSchema = defaultSchema;
-        }
-    }
-
-    /**
-     * <p>
-     * Sets the default transaction isolation state for returned connections.
-     * </p>
-     * <p>
-     * Note: this method currently has no effect once the pool has been initialized. The pool is initialized the first
-     * time one of the following methods is invoked: <code>getConnection, setLogwriter,
-     * setLoginTimeout, getLoginTimeout, getLogWriter.</code>
-     * </p>
-     *
-     * @param defaultTransactionIsolation
-     *            the default transaction isolation state
-     * @see Connection#getTransactionIsolation
-     */
-    public void setDefaultTransactionIsolation(final int defaultTransactionIsolation) {
-        this.defaultTransactionIsolation = defaultTransactionIsolation;
-    }
-
-    /**
-     * Sets the SQL_STATE codes considered to signal fatal conditions.
-     * <p>
-     * Overrides the defaults in {@link Utils#DISCONNECTION_SQL_CODES} (plus anything starting with
-     * {@link Utils#DISCONNECTION_SQL_CODE_PREFIX}). If this property is non-null and {@link #getFastFailValidation()}
-     * is {@code true}, whenever connections created by this datasource generate exceptions with SQL_STATE codes in this
-     * list, they will be marked as "fatally disconnected" and subsequent validations will fail fast (no attempt at
-     * isValid or validation query).
-     * </p>
-     * <p>
-     * If {@link #getFastFailValidation()} is {@code false} setting this property has no effect.
-     * </p>
-     * <p>
-     * Note: this method currently has no effect once the pool has been initialized. The pool is initialized the first
-     * time one of the following methods is invoked: {@code getConnection, setLogwriter,
-     * setLoginTimeout, getLoginTimeout, getLogWriter}.
-     * </p>
-     *
-     * @param disconnectionSqlCodes
-     *            SQL_STATE codes considered to signal fatal conditions
-     * @since 2.1
-     */
-    public void setDisconnectionSqlCodes(final Collection<String> disconnectionSqlCodes) {
-        if (disconnectionSqlCodes != null && disconnectionSqlCodes.size() > 0) {
-            HashSet<String> newVal = null;
-            for (final String s : disconnectionSqlCodes) {
-                if (!isEmpty(s)) {
-                    if (newVal == null) {
-                        newVal = new HashSet<>();
-                    }
-                    newVal.add(s);
-                }
-            }
-            this.disconnectionSqlCodes = newVal;
-        } else {
-            this.disconnectionSqlCodes = null;
-        }
-    }
-
-    /**
-     * Sets the JDBC Driver instance to use for this pool.
-     * <p>
-     * Note: this method currently has no effect once the pool has been initialized. The pool is initialized the first
-     * time one of the following methods is invoked: <code>getConnection, setLogwriter,
-     * setLoginTimeout, getLoginTimeout, getLogWriter.</code>
-     * </p>
-     *
-     * @param driver
-     *            The JDBC Driver instance to use for this pool.
-     */
-    public synchronized void setDriver(final Driver driver) {
-        this.driver = driver;
-    }
-
-    /**
-     * <p>
-     * Sets the class loader to be used to load the JDBC driver.
-     * </p>
-     * <p>
-     * Note: this method currently has no effect once the pool has been initialized. The pool is initialized the first
-     * time one of the following methods is invoked: <code>getConnection, setLogwriter,
-     * setLoginTimeout, getLoginTimeout, getLogWriter.</code>
-     * </p>
-     *
-     * @param driverClassLoader
-     *            the class loader with which to load the JDBC driver
-     */
-    public synchronized void setDriverClassLoader(final ClassLoader driverClassLoader) {
-        this.driverClassLoader = driverClassLoader;
-    }
-
-    /**
-     * <p>
-     * Sets the JDBC driver class name.
-     * </p>
-     * <p>
-     * Note: this method currently has no effect once the pool has been initialized. The pool is initialized the first
-     * time one of the following methods is invoked: <code>getConnection, setLogwriter,
-     * setLoginTimeout, getLoginTimeout, getLogWriter.</code>
-     * </p>
-     *
-     * @param driverClassName
-     *            the class name of the JDBC driver
-     */
-    public synchronized void setDriverClassName(final String driverClassName) {
-        if (isEmpty(driverClassName)) {
-            this.driverClassName = null;
-        } else {
-            this.driverClassName = driverClassName;
-        }
-    }
-
-    /**
-     * Sets the ConnectionFactory class name.
-     *
-     * @param connectionFactoryClassName
-     * @since 2.7.0
-     */
-
-    public void setConnectionFactoryClassName(final String connectionFactoryClassName) {
-        if (isEmpty(connectionFactoryClassName)) {
-            this.connectionFactoryClassName = null;
-        } else {
-            this.connectionFactoryClassName = connectionFactoryClassName;
-        }
-    }
-
-    /**
-     * Sets the value of the flag that controls whether or not connections being returned to the pool will be checked
-     * and configured with {@link Connection#setAutoCommit(boolean) Connection.setAutoCommit(true)} if the auto commit
-     * setting is {@code false} when the connection is returned. It is <code>true</code> by default.
-     *
-     * @param autoCommitOnReturn
-     *            Whether or not connections being returned to the pool will be checked and configured with auto-commit.
-     * @deprecated Use {@link #setAutoCommitOnReturn(boolean)}.
-     */
-    @Deprecated
-    public void setEnableAutoCommitOnReturn(final boolean autoCommitOnReturn) {
-        this.autoCommitOnReturn = autoCommitOnReturn;
-    }
-
-    /**
-     * Sets the EvictionPolicy implementation to use with this connection pool.
-     *
-     * @param evictionPolicyClassName
-     *            The fully qualified class name of the EvictionPolicy implementation
-     */
-    public synchronized void setEvictionPolicyClassName(final String evictionPolicyClassName) {
-        if (connectionPool != null) {
-            connectionPool.setEvictionPolicyClassName(evictionPolicyClassName);
-        }
-        this.evictionPolicyClassName = evictionPolicyClassName;
-    }
-
-    /**
-     * @see #getFastFailValidation()
-     * @param fastFailValidation
-     *            true means connections created by this factory will fast fail validation
-     * @since 2.1
-     */
-    public void setFastFailValidation(final boolean fastFailValidation) {
-        this.fastFailValidation = fastFailValidation;
-    }
-
-    /**
-     * <p>
-     * Sets the initial size of the connection pool.
-     * </p>
-     * <p>
-     * Note: this method currently has no effect once the pool has been initialized. The pool is initialized the first
-     * time one of the following methods is invoked: <code>getConnection, setLogwriter,
-     * setLoginTimeout, getLoginTimeout, getLogWriter.</code>
-     * </p>
-     *
-     * @param initialSize
-     *            the number of connections created when the pool is initialized
-     */
-    public synchronized void setInitialSize(final int initialSize) {
-        this.initialSize = initialSize;
-    }
-
-    /**
-     * Sets the JMX name that has been requested for this DataSource. If the requested name is not valid, an alternative
-     * may be chosen. This DataSource will attempt to register itself using this name. If another component registers
-     * this DataSource with JMX and this name is valid this name will be used in preference to any specified by the
-     * other component.
-     *
-     * @param jmxName
-     *            The JMX name that has been requested for this DataSource
-     */
-    public void setJmxName(final String jmxName) {
-        this.jmxName = jmxName;
-    }
-
-    /**
-     * Sets the LIFO property. True means the pool behaves as a LIFO queue; false means FIFO.
-     *
-     * @param lifo
-     *            the new value for the LIFO property
-     */
-    public synchronized void setLifo(final boolean lifo) {
-        this.lifo = lifo;
-        if (connectionPool != null) {
-            connectionPool.setLifo(lifo);
-        }
-    }
-
-    /**
-     * @param logAbandoned
-     *            new logAbandoned property value
-     */
-    public void setLogAbandoned(final boolean logAbandoned) {
-        if (abandonedConfig == null) {
-            abandonedConfig = new AbandonedConfig();
-        }
-        abandonedConfig.setLogAbandoned(logAbandoned);
-        final GenericObjectPool<?> gop = this.connectionPool;
-        if (gop != null) {
-            gop.setAbandonedConfig(abandonedConfig);
-        }
-    }
-
-    /**
-     * When {@link #getMaxConnLifetimeMillis()} is set to limit connection lifetime, this property determines whether or
-     * not log messages are generated when the pool closes connections due to maximum lifetime exceeded. Set this
-     * property to false to suppress log messages when connections expire.
-     *
-     * @param logExpiredConnections
-     *            Whether or not log messages are generated when the pool closes connections due to maximum lifetime
-     *            exceeded.
-     */
-    public void setLogExpiredConnections(final boolean logExpiredConnections) {
-        this.logExpiredConnections = logExpiredConnections;
-    }
-
-    /**
-     * <strong>BasicDataSource does NOT support this method. </strong>
-     *
-     * <p>
-     * Set the login timeout (in seconds) for connecting to the database.
-     * </p>
-     * <p>
-     * Calls {@link #createDataSource()}, so has the side effect of initializing the connection pool.
-     * </p>
-     *
-     * @param loginTimeout
-     *            The new login timeout, or zero for no timeout
-     * @throws UnsupportedOperationException
-     *             If the DataSource implementation does not support the login timeout feature.
-     * @throws SQLException
-     *             if a database access error occurs
-     */
-    @Override
-    public void setLoginTimeout(final int loginTimeout) throws SQLException {
-        // This method isn't supported by the PoolingDataSource returned by the createDataSource
-        throw new UnsupportedOperationException("Not supported by BasicDataSource");
-    }
-
-    /**
-     * <p>
-     * Sets the log writer being used by this data source.
-     * </p>
-     * <p>
-     * Calls {@link #createDataSource()}, so has the side effect of initializing the connection pool.
-     * </p>
-     *
-     * @param logWriter
-     *            The new log writer
-     * @throws SQLException
-     *             if a database access error occurs
-     */
-    @Override
-    public void setLogWriter(final PrintWriter logWriter) throws SQLException {
-        createDataSource().setLogWriter(logWriter);
-        this.logWriter = logWriter;
-    }
-
-    /**
-     * <p>
-     * Sets the maximum permitted lifetime of a connection in milliseconds. A value of zero or less indicates an
-     * infinite lifetime.
-     * </p>
-     * <p>
-     * Note: this method currently has no effect once the pool has been initialized. The pool is initialized the first
-     * time one of the following methods is invoked: <code>getConnection, setLogwriter,
-     * setLoginTimeout, getLoginTimeout, getLogWriter.</code>
-     * </p>
-     *
-     * @param maxConnLifetimeMillis
-     *            The maximum permitted lifetime of a connection in milliseconds.
-     */
-    public void setMaxConnLifetimeMillis(final long maxConnLifetimeMillis) {
-        this.maxConnLifetimeMillis = maxConnLifetimeMillis;
-    }
-
-    /**
-     * Sets the maximum number of connections that can remain idle in the pool. Excess idle connections are destroyed on
-     * return to the pool.
-     *
-     * @see #getMaxIdle()
-     * @param maxIdle
-     *            the new value for maxIdle
-     */
-    public synchronized void setMaxIdle(final int maxIdle) {
-        this.maxIdle = maxIdle;
-        if (connectionPool != null) {
-            connectionPool.setMaxIdle(maxIdle);
-        }
-    }
-
-    /**
-     * <p>
-     * Sets the value of the <code>maxOpenPreparedStatements</code> property.
-     * </p>
-     * <p>
-     * Note: this method currently has no effect once the pool has been initialized. The pool is initialized the first
-     * time one of the following methods is invoked: <code>getConnection, setLogwriter,
-     * setLoginTimeout, getLoginTimeout, getLogWriter.</code>
-     * </p>
-     *
-     * @param maxOpenStatements
-     *            the new maximum number of prepared statements
-     */
-    public synchronized void setMaxOpenPreparedStatements(final int maxOpenStatements) {
-        this.maxOpenPreparedStatements = maxOpenStatements;
-    }
-
-    /**
-     * Sets the maximum total number of idle and borrows connections that can be active at the same time. Use a negative
-     * value for no limit.
-     *
-     * @param maxTotal
-     *            the new value for maxTotal
-     * @see #getMaxTotal()
-     */
-    public synchronized void setMaxTotal(final int maxTotal) {
-        this.maxTotal = maxTotal;
-        if (connectionPool != null) {
-            connectionPool.setMaxTotal(maxTotal);
-        }
-    }
-
-    /**
-     * Sets the MaxWaitMillis property. Use -1 to make the pool wait indefinitely.
-     *
-     * @param maxWaitMillis
-     *            the new value for MaxWaitMillis
-     * @see #getMaxWaitMillis()
-     */
-    public synchronized void setMaxWaitMillis(final long maxWaitMillis) {
-        this.maxWaitMillis = maxWaitMillis;
-        if (connectionPool != null) {
-            connectionPool.setMaxWaitMillis(maxWaitMillis);
-        }
-    }
-
-    /**
-     * Sets the {@link #minEvictableIdleTimeMillis} property.
-     *
-     * @param minEvictableIdleTimeMillis
-     *            the minimum amount of time an object may sit idle in the pool
-     * @see #minEvictableIdleTimeMillis
-     */
-    public synchronized void setMinEvictableIdleTimeMillis(final long minEvictableIdleTimeMillis) {
-        this.minEvictableIdleTimeMillis = minEvictableIdleTimeMillis;
-        if (connectionPool != null) {
-            connectionPool.setMinEvictableIdleTimeMillis(minEvictableIdleTimeMillis);
-        }
-    }
-
-    /**
-     * Sets the minimum number of idle connections in the pool. The pool attempts to ensure that minIdle connections are
-     * available when the idle object evictor runs. The value of this property has no effect unless
-     * {@link #timeBetweenEvictionRunsMillis} has a positive value.
-     *
-     * @param minIdle
-     *            the new value for minIdle
-     * @see GenericObjectPool#setMinIdle(int)
-     */
-    public synchronized void setMinIdle(final int minIdle) {
-        this.minIdle = minIdle;
-        if (connectionPool != null) {
-            connectionPool.setMinIdle(minIdle);
-        }
-    }
-
-    /**
-     * Sets the value of the {@link #numTestsPerEvictionRun} property.
-     *
-     * @param numTestsPerEvictionRun
-     *            the new {@link #numTestsPerEvictionRun} value
-     * @see #numTestsPerEvictionRun
-     */
-    public synchronized void setNumTestsPerEvictionRun(final int numTestsPerEvictionRun) {
-        this.numTestsPerEvictionRun = numTestsPerEvictionRun;
-        if (connectionPool != null) {
-            connectionPool.setNumTestsPerEvictionRun(numTestsPerEvictionRun);
-        }
-    }
-
-    // ------------------------------------------------------ Protected Methods
-
-    /**
-     * <p>
-     * Sets the {@link #password}.
-     * </p>
-     * <p>
-     * Note: this method currently has no effect once the pool has been initialized. The pool is initialized the first
-     * time one of the following methods is invoked: <code>getConnection, setLogwriter,
-     * setLoginTimeout, getLoginTimeout, getLogWriter.</code>
-     * </p>
-     *
-     * @param password
-     *            new value for the password
-     */
-    public void setPassword(final String password) {
-        this.password = password;
-    }
-
-    /**
-     * <p>
-     * Sets whether to pool statements or not.
-     * </p>
-     * <p>
-     * Note: this method currently has no effect once the pool has been initialized. The pool is initialized the first
-     * time one of the following methods is invoked: <code>getConnection, setLogwriter,
-     * setLoginTimeout, getLoginTimeout, getLogWriter.</code>
-     * </p>
-     *
-     * @param poolingStatements
-     *            pooling on or off
-     */
-    public synchronized void setPoolPreparedStatements(final boolean poolingStatements) {
-        this.poolPreparedStatements = poolingStatements;
-    }
-
-    /**
-     * @param removeAbandonedOnBorrow
-     *            true means abandoned connections may be removed when connections are borrowed from the pool.
-     * @see #getRemoveAbandonedOnBorrow()
-     */
-    public void setRemoveAbandonedOnBorrow(final boolean removeAbandonedOnBorrow) {
-        if (abandonedConfig == null) {
-            abandonedConfig = new AbandonedConfig();
-        }
-        abandonedConfig.setRemoveAbandonedOnBorrow(removeAbandonedOnBorrow);
-        final GenericObjectPool<?> gop = this.connectionPool;
-        if (gop != null) {
-            gop.setAbandonedConfig(abandonedConfig);
-        }
-    }
-
-    /**
-     * @param removeAbandonedOnMaintenance
-     *            true means abandoned connections may be removed on pool maintenance.
-     * @see #getRemoveAbandonedOnMaintenance()
-     */
-    public void setRemoveAbandonedOnMaintenance(final boolean removeAbandonedOnMaintenance) {
-        if (abandonedConfig == null) {
-            abandonedConfig = new AbandonedConfig();
-        }
-        abandonedConfig.setRemoveAbandonedOnMaintenance(removeAbandonedOnMaintenance);
-        final GenericObjectPool<?> gop = this.connectionPool;
-        if (gop != null) {
-            gop.setAbandonedConfig(abandonedConfig);
-        }
-    }
-
-    /**
-     * <p>
-     * Sets the timeout in seconds before an abandoned connection can be removed.
-     * </p>
-     *
-     * <p>
-     * Setting this property has no effect if {@link #getRemoveAbandonedOnBorrow()} and
-     * {@link #getRemoveAbandonedOnMaintenance()} are false.
-     * </p>
-     *
-     * @param removeAbandonedTimeout
-     *            new abandoned timeout in seconds
-     * @see #getRemoveAbandonedTimeout()
-     * @see #getRemoveAbandonedOnBorrow()
-     * @see #getRemoveAbandonedOnMaintenance()
-     */
-    public void setRemoveAbandonedTimeout(final int removeAbandonedTimeout) {
-        if (abandonedConfig == null) {
-            abandonedConfig = new AbandonedConfig();
-        }
-        abandonedConfig.setRemoveAbandonedTimeout(removeAbandonedTimeout);
-        final GenericObjectPool<?> gop = this.connectionPool;
-        if (gop != null) {
-            gop.setAbandonedConfig(abandonedConfig);
-        }
-    }
-
-    /**
-     * Sets the flag that controls if a connection will be rolled back when it is returned to the pool if auto commit is
-     * not enabled and the connection is not read only.
-     *
-     * @param rollbackOnReturn
-     *            whether a connection will be rolled back when it is returned to the pool.
-     */
-    public void setRollbackOnReturn(final boolean rollbackOnReturn) {
-        this.rollbackOnReturn = rollbackOnReturn;
-    }
-
-    /**
-     * Sets the minimum amount of time a connection may sit idle in the pool before it is eligible for eviction by the
-     * idle object evictor, with the extra condition that at least "minIdle" connections remain in the pool.
-     *
-     * @param softMinEvictableIdleTimeMillis
-     *            minimum amount of time a connection may sit idle in the pool before it is eligible for eviction,
-     *            assuming there are minIdle idle connections in the pool.
-     * @see #getSoftMinEvictableIdleTimeMillis
-     */
-    public synchronized void setSoftMinEvictableIdleTimeMillis(final long softMinEvictableIdleTimeMillis) {
-        this.softMinEvictableIdleTimeMillis = softMinEvictableIdleTimeMillis;
-        if (connectionPool != null) {
-            connectionPool.setSoftMinEvictableIdleTimeMillis(softMinEvictableIdleTimeMillis);
-        }
-    }
-
-    /**
-     * Sets the {@link #testOnBorrow} property. This property determines whether or not the pool will validate objects
-     * before they are borrowed from the pool.
-     *
-     * @param testOnBorrow
-     *            new value for testOnBorrow property
-     */
-    public synchronized void setTestOnBorrow(final boolean testOnBorrow) {
-        this.testOnBorrow = testOnBorrow;
-        if (connectionPool != null) {
-            connectionPool.setTestOnBorrow(testOnBorrow);
-        }
-    }
-
-    /**
-     * Sets the {@link #testOnCreate} property. This property determines whether or not the pool will validate objects
-     * immediately after they are created by the pool
-     *
-     * @param testOnCreate
-     *            new value for testOnCreate property
-     */
-    public synchronized void setTestOnCreate(final boolean testOnCreate) {
-        this.testOnCreate = testOnCreate;
-        if (connectionPool != null) {
-            connectionPool.setTestOnCreate(testOnCreate);
-        }
-    }
-
-    /**
-     * Sets the <code>testOnReturn</code> property. This property determines whether or not the pool will validate
-     * objects before they are returned to the pool.
-     *
-     * @param testOnReturn
-     *            new value for testOnReturn property
-     */
-    public synchronized void setTestOnReturn(final boolean testOnReturn) {
-        this.testOnReturn = testOnReturn;
-        if (connectionPool != null) {
-            connectionPool.setTestOnReturn(testOnReturn);
-        }
-    }
-
-    /**
-     * Sets the <code>testWhileIdle</code> property. This property determines whether or not the idle object evictor
-     * will validate connections.
-     *
-     * @param testWhileIdle
-     *            new value for testWhileIdle property
-     */
-    public synchronized void setTestWhileIdle(final boolean testWhileIdle) {
-        this.testWhileIdle = testWhileIdle;
-        if (connectionPool != null) {
-            connectionPool.setTestWhileIdle(testWhileIdle);
-        }
-    }
-
-    /**
-     * Sets the {@link #timeBetweenEvictionRunsMillis} property.
-     *
-     * @param timeBetweenEvictionRunsMillis
-     *            the new time between evictor runs
-     * @see #timeBetweenEvictionRunsMillis
-     */
-    public synchronized void setTimeBetweenEvictionRunsMillis(final long timeBetweenEvictionRunsMillis) {
-        this.timeBetweenEvictionRunsMillis = timeBetweenEvictionRunsMillis;
-        if (connectionPool != null) {
-            connectionPool.setTimeBetweenEvictionRunsMillis(timeBetweenEvictionRunsMillis);
-        }
-    }
-
-    /**
-     * <p>
-     * Sets the {@link #url}.
-     * </p>
-     * <p>
-     * Note: this method currently has no effect once the pool has been initialized. The pool is initialized the first
-     * time one of the following methods is invoked: <code>getConnection, setLogwriter,
-     * setLoginTimeout, getLoginTimeout, getLogWriter.</code>
-     * </p>
-     *
-     * @param url
-     *            the new value for the JDBC connection url
-     */
-    public synchronized void setUrl(final String url) {
-        this.url = url;
-    }
-
-    /**
-     * <p>
-     * Sets the {@link #userName}.
-     * </p>
-     * <p>
-     * Note: this method currently has no effect once the pool has been initialized. The pool is initialized the first
-     * time one of the following methods is invoked: <code>getConnection, setLogwriter,
-     * setLoginTimeout, getLoginTimeout, getLogWriter.</code>
-     * </p>
-     *
-     * @param userName
-     *            the new value for the JDBC connection user name
-     */
-    public void setUsername(final String userName) {
-        this.userName = userName;
-    }
-
-    /**
-     * <p>
-     * Sets the {@link #validationQuery}.
-     * </p>
-     * <p>
-     * Note: this method currently has no effect once the pool has been initialized. The pool is initialized the first
-     * time one of the following methods is invoked: <code>getConnection, setLogwriter,
-     * setLoginTimeout, getLoginTimeout, getLogWriter.</code>
-     * </p>
-     *
-     * @param validationQuery
-     *            the new value for the validation query
-     */
-    public void setValidationQuery(final String validationQuery) {
-        if (isEmpty(validationQuery)) {
-            this.validationQuery = null;
-        } else {
-            this.validationQuery = validationQuery;
-        }
-    }
-
-    /**
-     * Sets the validation query timeout, the amount of time, in seconds, that connection validation will wait for a
-     * response from the database when executing a validation query. Use a value less than or equal to 0 for no timeout.
-     * <p>
-     * Note: this method currently has no effect once the pool has been initialized. The pool is initialized the first
-     * time one of the following methods is invoked: <code>getConnection, setLogwriter,
-     * setLoginTimeout, getLoginTimeout, getLogWriter.</code>
-     * </p>
-     *
-     * @param validationQueryTimeoutSeconds
-     *            new validation query timeout value in seconds
-     */
-    public void setValidationQueryTimeout(final int validationQueryTimeoutSeconds) {
-        this.validationQueryTimeoutSeconds = validationQueryTimeoutSeconds;
-    }
-
-    /**
-     * Starts the connection pool maintenance task, if configured.
-     */
-    protected void startPoolMaintenance() {
-        if (connectionPool != null && timeBetweenEvictionRunsMillis > 0) {
-            connectionPool.setTimeBetweenEvictionRunsMillis(timeBetweenEvictionRunsMillis);
-        }
-    }
-
-    @Override
-    public <T> T unwrap(final Class<T> iface) throws SQLException {
-        throw new SQLException("BasicDataSource is not a wrapper.");
-    }
-
-    private void updateJmxName(final GenericObjectPoolConfig<?> config) {
-        if (registeredJmxObjectName == null) {
-            return;
-        }
-        final StringBuilder base = new StringBuilder(registeredJmxObjectName.toString());
-        base.append(Constants.JMX_CONNECTION_POOL_BASE_EXT);
-        config.setJmxNameBase(base.toString());
-        config.setJmxNamePrefix(Constants.JMX_CONNECTION_POOL_PREFIX);
-    }
-
-    private ConnectionFactory createConnectionFactory(final Driver driver) throws SQLException {
-        if (connectionFactoryClassName != null) {
-            try {
-                Class<?> connectionFactoryFromCCL = Class.forName(connectionFactoryClassName);
-                return (ConnectionFactory) connectionFactoryFromCCL
-                    .getConstructor(Driver.class, String.class, Properties.class)
-                    .newInstance(driver, url, connectionProperties);
-            } catch (final Exception t) {
-                final String message = "Cannot load ConnectionFactory implementation '" + connectionFactoryClassName + "'";
-                logWriter.println(message);
-                t.printStackTrace(logWriter);
-                throw new SQLException(message, t);
-            }
-        }
-        return new DriverConnectionFactory(driver, url, connectionProperties);
-    }
-
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.dbcp2;
+
+import java.io.OutputStreamWriter;
+import java.io.PrintWriter;
+import java.nio.charset.StandardCharsets;
+import java.security.AccessController;
+import java.security.PrivilegedActionException;
+import java.security.PrivilegedExceptionAction;
+import java.sql.Connection;
+import java.sql.Driver;
+import java.sql.DriverManager;
+import java.sql.SQLException;
+import java.sql.SQLFeatureNotSupportedException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Objects;
+import java.util.Properties;
+import java.util.Set;
+import java.util.logging.Logger;
+
+import javax.management.MBeanRegistration;
+import javax.management.MBeanServer;
+import javax.management.MalformedObjectNameException;
+import javax.management.ObjectName;
+import javax.sql.DataSource;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.commons.pool2.PooledObject;
+import org.apache.commons.pool2.impl.AbandonedConfig;
+import org.apache.commons.pool2.impl.BaseObjectPoolConfig;
+import org.apache.commons.pool2.impl.GenericKeyedObjectPoolConfig;
+import org.apache.commons.pool2.impl.GenericObjectPool;
+import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
+
+/**
+ * <p>
+ * Basic implementation of <code>javax.sql.DataSource</code> that is configured
+ * via JavaBeans properties. This is not the only way to combine the
+ * <em>commons-dbcp2</em> and <em>commons-pool2</em> packages, but provides a
+ * "one stop shopping" solution for basic requirements.
+ * </p>
+ *
+ * @since 2.0
+ */
+public class BasicDataSource
+        implements DataSource, BasicDataSourceMXBean, MBeanRegistration, AutoCloseable {
+
+    /**
+     * @since 2.0
+     */
+    private class PaGetConnection implements PrivilegedExceptionAction<Connection> {
+
+        @Override
+        public Connection run() throws SQLException {
+            return createDataSource().getConnection();
+        }
+    }
+
+    private static final Log log = LogFactory.getLog(BasicDataSource.class);
+
+    // ------------------------------------------------------------- Properties
+
+    static {
+        // Attempt to prevent deadlocks - see DBCP - 272
+        DriverManager.getDrivers();
+        try {
+            // Load classes now to prevent AccessControlExceptions later
+            // A number of classes are loaded when getConnection() is called
+            // but the following classes are not loaded and therefore require
+            // explicit loading.
+            if (Utils.IS_SECURITY_ENABLED) {
+                final ClassLoader loader = BasicDataSource.class.getClassLoader();
+                final String dbcpPackageName = BasicDataSource.class.getPackage().getName();
+                loader.loadClass(dbcpPackageName + ".BasicDataSource$PaGetConnection");
+                loader.loadClass(dbcpPackageName + ".DelegatingCallableStatement");
+                loader.loadClass(dbcpPackageName + ".DelegatingDatabaseMetaData");
+                loader.loadClass(dbcpPackageName + ".DelegatingPreparedStatement");
+                loader.loadClass(dbcpPackageName + ".DelegatingResultSet");
+                loader.loadClass(dbcpPackageName + ".PoolableCallableStatement");
+                loader.loadClass(dbcpPackageName + ".PoolablePreparedStatement");
+                loader.loadClass(dbcpPackageName + ".PoolingConnection$StatementType");
+                loader.loadClass(dbcpPackageName + ".PStmtKey");
+
+                final String poolPackageName = PooledObject.class.getPackage().getName();
+                loader.loadClass(poolPackageName + ".impl.LinkedBlockingDeque$Node");
+                loader.loadClass(poolPackageName + ".impl.GenericKeyedObjectPool$ObjectDeque");
+            }
+        } catch (final ClassNotFoundException cnfe) {
+            throw new IllegalStateException("Unable to pre-load classes", cnfe);
+        }
+    }
+
+
+    protected static void validateConnectionFactory(
+            final PoolableConnectionFactory connectionFactory) throws Exception {
+        PoolableConnection conn = null;
+        PooledObject<PoolableConnection> p = null;
+        try {
+            p = connectionFactory.makeObject();
+            conn = p.getObject();
+            connectionFactory.activateObject(p);
+            connectionFactory.validateConnection(conn);
+            connectionFactory.passivateObject(p);
+        } finally {
+            if (p != null) {
+                connectionFactory.destroyObject(p);
+            }
+        }
+    }
+
+    /**
+     * The default auto-commit state of connections created by this pool.
+     */
+    private volatile Boolean defaultAutoCommit;
+
+    /**
+     * The default read-only state of connections created by this pool.
+     */
+    private transient Boolean defaultReadOnly;
+
+    /**
+     * The default TransactionIsolation state of connections created by this
+     * pool.
+     */
+    private volatile int defaultTransactionIsolation = PoolableConnectionFactory.UNKNOWN_TRANSACTION_ISOLATION;
+
+    private Integer defaultQueryTimeoutSeconds;
+
+    /**
+     * The default "catalog" of connections created by this pool.
+     */
+    private volatile String defaultCatalog;
+
+    /**
+     * The default "schema" of connections created by this pool.
+     */
+    private volatile String defaultSchema;
+
+    /**
+     * The property that controls if the pooled connections cache some state
+     * rather than query the database for current state to improve performance.
+     */
+    private boolean cacheState = true;
+
+    /**
+     * The instance of the JDBC Driver to use.
+     */
+    private Driver driver;
+
+    /**
+     * The fully qualified Java class name of the JDBC driver to be used.
+     */
+    private String driverClassName;
+
+    /**
+     * The class loader instance to use to load the JDBC driver. If not
+     * specified, {@link Class#forName(String)} is used to load the JDBC driver.
+     * If specified, {@link Class#forName(String, boolean, ClassLoader)} is
+     * used.
+     */
+    private ClassLoader driverClassLoader;
+
+    /**
+     * True means that borrowObject returns the most recently used ("last in")
+     * connection in the pool (if there are idle connections available). False
+     * means that the pool behaves as a FIFO queue - connections are taken from
+     * the idle instance pool in the order that they are returned to the pool.
+     */
+    private boolean lifo = BaseObjectPoolConfig.DEFAULT_LIFO;
+
+    /**
+     * The maximum number of active connections that can be allocated from this
+     * pool at the same time, or negative for no limit.
+     */
+    private int maxTotal = GenericObjectPoolConfig.DEFAULT_MAX_TOTAL;
+
+    /**
+     * The maximum number of connections that can remain idle in the pool,
+     * without extra ones being destroyed, or negative for no limit. If maxIdle
+     * is set too low on heavily loaded systems it is possible you will see
+     * connections being closed and almost immediately new connections being
+     * opened. This is a result of the active threads momentarily closing
+     * connections faster than they are opening them, causing the number of idle
+     * connections to rise above maxIdle. The best value for maxIdle for heavily
+     * loaded system will vary but the default is a good starting point.
+     */
+    private int maxIdle = GenericObjectPoolConfig.DEFAULT_MAX_IDLE;
+
+    /**
+     * The minimum number of active connections that can remain idle in the
+     * pool, without extra ones being created when the evictor runs, or 0 to
+     * create none. The pool attempts to ensure that minIdle connections are
+     * available when the idle object evictor runs. The value of this property
+     * has no effect unless {@link #timeBetweenEvictionRunsMillis} has a
+     * positive value.
+     */
+    private int minIdle = GenericObjectPoolConfig.DEFAULT_MIN_IDLE;
+
+    /**
+     * The initial number of connections that are created when the pool is
+     * started.
+     */
+    private int initialSize = 0;
+
+    /**
+     * The maximum number of milliseconds that the pool will wait (when there
+     * are no available connections) for a connection to be returned before
+     * throwing an exception, or <= 0 to wait indefinitely.
+     */
+    private long maxWaitMillis = BaseObjectPoolConfig.DEFAULT_MAX_WAIT_MILLIS;
+
+    /**
+     * Prepared statement pooling for this pool. When this property is set to
+     * <code>true</code> both PreparedStatements and CallableStatements are
+     * pooled.
+     */
+    private boolean poolPreparedStatements = false;
+
+    /**
+     * <p>
+     * The maximum number of open statements that can be allocated from the
+     * statement pool at the same time, or negative for no limit. Since a
+     * connection usually only uses one or two statements at a time, this is
+     * mostly used to help detect resource leaks.
+     * </p>
+     * <p>
+     * Note: As of version 1.3, CallableStatements (those produced by
+     * {@link Connection#prepareCall}) are pooled along with PreparedStatements
+     * (produced by {@link Connection#prepareStatement}) and
+     * <code>maxOpenPreparedStatements</code> limits the total number of
+     * prepared or callable statements that may be in use at a given time.
+     * </p>
+     */
+    private int maxOpenPreparedStatements = GenericKeyedObjectPoolConfig.DEFAULT_MAX_TOTAL;
+
+    /**
+     * The indication of whether objects will be validated as soon as they have
+     * been created by the pool. If the object fails to validate, the borrow
+     * operation that triggered the creation will fail.
+     */
+    private boolean testOnCreate = false;
+
+    /**
+     * The indication of whether objects will be validated before being borrowed
+     * from the pool. If the object fails to validate, it will be dropped from
+     * the pool, and we will attempt to borrow another.
+     */
+    private boolean testOnBorrow = true;
+
+    /**
+     * The indication of whether objects will be validated before being returned
+     * to the pool.
+     */
+    private boolean testOnReturn = false;
+
+    /**
+     * The number of milliseconds to sleep between runs of the idle object
+     * evictor thread. When non-positive, no idle object evictor thread will be
+     * run.
+     */
+    private long timeBetweenEvictionRunsMillis = BaseObjectPoolConfig.DEFAULT_TIME_BETWEEN_EVICTION_RUNS_MILLIS;
+
+    /**
+     * The number of objects to examine during each run of the idle object
+     * evictor thread (if any).
+     */
+    private int numTestsPerEvictionRun = BaseObjectPoolConfig.DEFAULT_NUM_TESTS_PER_EVICTION_RUN;
+
+    /**
+     * The minimum amount of time an object may sit idle in the pool before it
+     * is eligible for eviction by the idle object evictor (if any).
+     */
+    private long minEvictableIdleTimeMillis = BaseObjectPoolConfig.DEFAULT_MIN_EVICTABLE_IDLE_TIME_MILLIS;
+
+    /**
+     * The minimum amount of time a connection may sit idle in the pool before
+     * it is eligible for eviction by the idle object evictor, with the extra
+     * condition that at least "minIdle" connections remain in the pool. Note
+     * that {@code minEvictableIdleTimeMillis} takes precedence over this
+     * parameter. See {@link #getSoftMinEvictableIdleTimeMillis()}.
+     */
+    private long softMinEvictableIdleTimeMillis = BaseObjectPoolConfig.DEFAULT_SOFT_MIN_EVICTABLE_IDLE_TIME_MILLIS;
+
+    private String evictionPolicyClassName = BaseObjectPoolConfig.DEFAULT_EVICTION_POLICY_CLASS_NAME;
+
+    /**
+     * The indication of whether objects will be validated by the idle object
+     * evictor (if any). If an object fails to validate, it will be dropped from
+     * the pool.
+     */
+    private boolean testWhileIdle = false;
+
+    /**
+     * The connection password to be passed to our JDBC driver to establish a
+     * connection.
+     */
+    private volatile String password;
+
+    /**
+     * The connection URL to be passed to our JDBC driver to establish a
+     * connection.
+     */
+    private String url;
+
+    /**
+     * The connection user name to be passed to our JDBC driver to establish a
+     * connection.
+     */
+    private String userName;
+
+    /**
+     * The SQL query that will be used to validate connections from this pool
+     * before returning them to the caller. If specified, this query
+     * <strong>MUST</strong> be an SQL SELECT statement that returns at least
+     * one row. If not specified, {@link Connection#isValid(int)} will be used
+     * to validate connections.
+     */
+    private volatile String validationQuery;
+
+    /**
+     * Timeout in seconds before connection validation queries fail.
+     */
+    private volatile int validationQueryTimeoutSeconds = -1;
+
+    /**
+     * The fully qualified Java class name of a {@link ConnectionFactory}
+     * implementation.
+     */
+    private String connectionFactoryClassName;
+
+    /**
+     * These SQL statements run once after a Connection is created.
+     * <p>
+     * This property can be used for example to run ALTER SESSION SET
+     * NLS_SORT=XCYECH in an Oracle Database only once after connection
+     * creation.
+     * </p>
+     */
+    private volatile List<String> connectionInitSqls;
+
+    /**
+     * Controls access to the underlying connection.
+     */
+    private boolean accessToUnderlyingConnectionAllowed = false;
+
+    private long maxConnLifetimeMillis = -1;
+
+    private boolean logExpiredConnections = true;
+
+    private String jmxName;
+
+    private boolean autoCommitOnReturn = true;
+
+    private boolean rollbackOnReturn = true;
+
+    private volatile Set<String> disconnectionSqlCodes;
+
+    private boolean fastFailValidation;
+
+    /**
+     * The object pool that internally manages our connections.
+     */
+    private volatile GenericObjectPool<PoolableConnection> connectionPool;
+
+    /**
+     * The connection properties that will be sent to our JDBC driver when
+     * establishing new connections. <strong>NOTE</strong> - The "user" and
+     * "password" properties will be passed explicitly, so they do not need to
+     * be included here.
+     */
+    private Properties connectionProperties = new Properties();
+
+    /**
+     * The data source we will use to manage connections. This object should be
+     * acquired <strong>ONLY</strong> by calls to the
+     * <code>createDataSource()</code> method.
+     */
+    private volatile DataSource dataSource;
+
+    /**
+     * The PrintWriter to which log messages should be directed.
+     */
+    private volatile PrintWriter logWriter = new PrintWriter(
+            new OutputStreamWriter(System.out, StandardCharsets.UTF_8));
+
+    private AbandonedConfig abandonedConfig;
+
+    private boolean closed;
+
+    /**
+     * Actual name under which this component has been registered.
+     */
+    private ObjectNameWrapper registeredJmxObjectName;
+
+
+    /**
+     * Adds a custom connection property to the set that will be passed to our
+     * JDBC driver. This <strong>MUST</strong> be called before the first
+     * connection is retrieved (along with all the other configuration property
+     * setters). Calls to this method after the connection pool has been
+     * initialized have no effect.
+     *
+     * @param name Name of the custom connection property
+     * @param value Value of the custom connection property
+     */
+    public void addConnectionProperty(final String name, final String value) {
+        connectionProperties.put(name, value);
+    }
+
+
+    /**
+     * <p>
+     * Closes and releases all idle connections that are currently stored in the
+     * connection pool associated with this data source.
+     * </p>
+     * <p>
+     * Connections that are checked out to clients when this method is invoked
+     * are not affected. When client applications subsequently invoke
+     * {@link Connection#close()} to return these connections to the pool, the
+     * underlying JDBC connections are closed.
+     * </p>
+     * <p>
+     * Attempts to acquire connections using {@link #getConnection()} after this
+     * method has been invoked result in SQLExceptions.
+     * </p>
+     * <p>
+     * This method is idempotent - i.e., closing an already closed
+     * BasicDataSource has no effect and does not generate exceptions.
+     * </p>
+     *
+     * @throws SQLException if an error occurs closing idle connections
+     */
+    @Override
+    public synchronized void close() throws SQLException {
+        if (registeredJmxObjectName != null) {
+            registeredJmxObjectName.unregisterMBean();
+            registeredJmxObjectName = null;
+        }
+        closed = true;
+        final GenericObjectPool<?> oldPool = connectionPool;
+        connectionPool = null;
+        dataSource = null;
+        try {
+            if (oldPool != null) {
+                oldPool.close();
+            }
+        } catch (final RuntimeException e) {
+            throw e;
+        } catch (final Exception e) {
+            throw new SQLException(Utils.getMessage("pool.close.fail"), e);
+        }
+    }
+
+
+    /**
+     * Closes the connection pool, silently swallowing any exception that
+     * occurs.
+     */
+    private void closeConnectionPool() {
+        final GenericObjectPool<?> oldPool = connectionPool;
+        connectionPool = null;
+        try {
+            if (oldPool != null) {
+                oldPool.close();
+            }
+        } catch (final Exception e) {
+            /* Ignore */
+        }
+    }
+
+
+    /**
+     * Creates a JDBC connection factory for this datasource. The JDBC driver is
+     * loaded using the following algorithm:
+     * <ol>
+     * <li>If a Driver instance has been specified via
+     * {@link #setDriver(Driver)} use it</li>
+     * <li>If no Driver instance was specified and {@link #driverClassName} is
+     * specified that class is loaded using the {@link ClassLoader} of this
+     * class or, if {@link #driverClassLoader} is set, {@link #driverClassName}
+     * is loaded with the specified {@link ClassLoader}.</li>
+     * <li>If {@link #driverClassName} is specified and the previous attempt
+     * fails, the class is loaded using the context class loader of the current
+     * thread.</li>
+     * <li>If a driver still isn't loaded one is loaded via the
+     * {@link DriverManager} using the specified {@link #url}.
+     * </ol>
+     * This method exists so subclasses can replace the implementation class.
+     *
+     * @return A new connection factory.
+     *
+     * @throws SQLException If the connection factort cannot be created
+     */
+    protected ConnectionFactory createConnectionFactory() throws SQLException {
+        // Load the JDBC driver class
+        Driver driverToUse = this.driver;
+
+        if (driverToUse == null) {
+            Class<?> driverFromCCL = null;
+            if (driverClassName != null) {
+                try {
+                    try {
+                        if (driverClassLoader == null) {
+                            driverFromCCL = Class.forName(driverClassName);
+                        } else {
+                            driverFromCCL = Class.forName(driverClassName, true, driverClassLoader);
+                        }
+                    } catch (final ClassNotFoundException cnfe) {
+                        driverFromCCL = Thread.currentThread().getContextClassLoader()
+                                .loadClass(driverClassName);
+                    }
+                } catch (final Exception t) {
+                    final String message = "Cannot load JDBC driver class '" + driverClassName +
+                            "'";
+                    logWriter.println(message);
+                    t.printStackTrace(logWriter);
+                    throw new SQLException(message, t);
+                }
+            }
+
+            try {
+                if (driverFromCCL == null) {
+                    driverToUse = DriverManager.getDriver(url);
+                } else {
+                    // Usage of DriverManager is not possible, as it does not
+                    // respect the ContextClassLoader
+                    // N.B. This cast may cause ClassCastException which is
+                    // handled below
+                    driverToUse = (Driver) driverFromCCL.getConstructor().newInstance();
+                    if (!driverToUse.acceptsURL(url)) {
+                        throw new SQLException("No suitable driver", "08001");
+                    }
+                }
+            } catch (final Exception t) {
+                final String message = "Cannot create JDBC driver of class '" +
+                        (driverClassName != null ? driverClassName : "") + "' for connect URL '" +
+                        url + "'";
+                logWriter.println(message);
+                t.printStackTrace(logWriter);
+                throw new SQLException(message, t);
+            }
+        }
+
+        // Set up the driver connection factory we will use
+        final String user = userName;
+        if (user != null) {
+            connectionProperties.put("user", user);
+        } else {
+            log("DBCP DataSource configured without a 'username'");
+        }
+
+        final String pwd = password;
+        if (pwd != null) {
+            connectionProperties.put("password", pwd);
+        } else {
+            log("DBCP DataSource configured without a 'password'");
+        }
+
+        return createConnectionFactory(driverToUse);
+    }
+
+
+    /**
+     * Creates a connection pool for this datasource. This method only exists so
+     * subclasses can replace the implementation class.
+     * <p>
+     * This implementation configures all pool properties other than
+     * timeBetweenEvictionRunsMillis. Setting that property is deferred to
+     * {@link #startPoolMaintenance()}, since setting
+     * timeBetweenEvictionRunsMillis to a positive value causes
+     * {@link GenericObjectPool}'s eviction timer to be started.
+     * </p>
+     *
+     * @param factory The factory to use to create new connections for this
+     *            pool.
+     */
+    protected void createConnectionPool(final PoolableConnectionFactory factory) {
+        // Create an object pool to contain our active connections
+        final GenericObjectPoolConfig<PoolableConnection> config = new GenericObjectPoolConfig<>();
+        updateJmxName(config);
+        // Disable JMX on the underlying pool if the DS is not registered:
+        config.setJmxEnabled(registeredJmxObjectName != null);
+        final GenericObjectPool<PoolableConnection> gop = createObjectPool(factory, config,
+                abandonedConfig);
+        gop.setMaxTotal(maxTotal);
+        gop.setMaxIdle(maxIdle);
+        gop.setMinIdle(minIdle);
+        gop.setMaxWaitMillis(maxWaitMillis);
+        gop.setTestOnCreate(testOnCreate);
+        gop.setTestOnBorrow(testOnBorrow);
+        gop.setTestOnReturn(testOnReturn);
+        gop.setNumTestsPerEvictionRun(numTestsPerEvictionRun);
+        gop.setMinEvictableIdleTimeMillis(minEvictableIdleTimeMillis);
+        gop.setSoftMinEvictableIdleTimeMillis(softMinEvictableIdleTimeMillis);
+        gop.setTestWhileIdle(testWhileIdle);
+        gop.setLifo(lifo);
+        gop.setSwallowedExceptionListener(new SwallowedExceptionLogger(log, logExpiredConnections));
+        gop.setEvictionPolicyClassName(evictionPolicyClassName);
+        factory.setPool(gop);
+        connectionPool = gop;
+    }
+
+
+    /**
+     * <p>
+     * Creates (if necessary) and return the internal data source we are using
+     * to manage our connections.
+     * </p>
+     *
+     * @return The current internal DataSource or a newly created instance if it
+     *         has not yet been created.
+     * @throws SQLException if the object pool cannot be created.
+     */
+    protected DataSource createDataSource() throws SQLException {
+        if (closed) {
+            throw new SQLException("Data source is closed");
+        }
+
+        // Return the pool if we have already created it
+        // This is double-checked locking. This is safe since dataSource is
+        // volatile and the code is targeted at Java 5 onwards.
+        if (dataSource != null) {
+            return dataSource;
+        }
+        synchronized (this) {
+            if (dataSource != null) {
+                return dataSource;
+            }
+
+            jmxRegister();
+
+            // create factory which returns raw physical connections
+            final ConnectionFactory driverConnectionFactory = createConnectionFactory();
+
+            // Set up the poolable connection factory
+            boolean success = false;
+            PoolableConnectionFactory poolableConnectionFactory;
+            try {
+                poolableConnectionFactory = createPoolableConnectionFactory(
+                        driverConnectionFactory);
+                poolableConnectionFactory.setPoolStatements(poolPreparedStatements);
+                poolableConnectionFactory.setMaxOpenPreparedStatements(maxOpenPreparedStatements);
+                success = true;
+            } catch (final SQLException se) {
+                throw se;
+            } catch (final RuntimeException rte) {
+                throw rte;
+            } catch (final Exception ex) {
+                throw new SQLException("Error creating connection factory", ex);
+            }
+
+            if (success) {
+                // create a pool for our connections
+                createConnectionPool(poolableConnectionFactory);
+            }
+
+            // Create the pooling data source to manage connections
+            DataSource newDataSource;
+            success = false;
+            try {
+                newDataSource = createDataSourceInstance();
+                newDataSource.setLogWriter(logWriter);
+                success = true;
+            } catch (final SQLException se) {
+                throw se;
+            } catch (final RuntimeException rte) {
+                throw rte;
+            } catch (final Exception ex) {
+                throw new SQLException("Error creating datasource", ex);
+            } finally {
+                if (!success) {
+                    closeConnectionPool();
+                }
+            }
+
+            // If initialSize > 0, preload the pool
+            try {
+                for (int i = 0; i < initialSize; i++) {
+                    connectionPool.addObject();
+                }
+            } catch (final Exception e) {
+                closeConnectionPool();
+                throw new SQLException("Error preloading the connection pool", e);
+            }
+
+            // If timeBetweenEvictionRunsMillis > 0, start the pool's evictor
+            // task
+            startPoolMaintenance();
+
+            dataSource = newDataSource;
+            return dataSource;
+        }
+    }
+
+
+    /**
+     * Creates the actual data source instance. This method only exists so that
+     * subclasses can replace the implementation class.
+     *
+     * @throws SQLException if unable to create a datasource instance
+     *
+     * @return A new DataSource instance
+     */
+    protected DataSource createDataSourceInstance() throws SQLException {
+        final PoolingDataSource<PoolableConnection> pds = new PoolingDataSource<>(connectionPool);
+        pds.setAccessToUnderlyingConnectionAllowed(isAccessToUnderlyingConnectionAllowed());
+        return pds;
+    }
+
+
+    /**
+     * Creates an object pool used to provide pooling support for
+     * {@link Connection JDBC connections}.
+     *
+     * @param factory the object factory
+     * @param poolConfig the object pool configuration
+     * @param abandonedConfig the abandoned objects configuration
+     * @return a non-null instance
+     */
+    protected GenericObjectPool<PoolableConnection> createObjectPool(
+            final PoolableConnectionFactory factory,
+            final GenericObjectPoolConfig<PoolableConnection> poolConfig,
+            final AbandonedConfig abandonedConfig) {
+        GenericObjectPool<PoolableConnection> gop;
+        if (abandonedConfig != null && (abandonedConfig.getRemoveAbandonedOnBorrow() ||
+                abandonedConfig.getRemoveAbandonedOnMaintenance())) {
+            gop = new GenericObjectPool<>(factory, poolConfig, abandonedConfig);
+        } else {
+            gop = new GenericObjectPool<>(factory, poolConfig);
+        }
+        return gop;
+    }
+
+
+    /**
+     * Creates the PoolableConnectionFactory and attaches it to the connection
+     * pool. This method only exists so subclasses can replace the default
+     * implementation.
+     *
+     * @param driverConnectionFactory JDBC connection factory
+     * @throws SQLException if an error occurs creating the
+     *             PoolableConnectionFactory
+     *
+     * @return A new PoolableConnectionFactory configured with the current
+     *         configuration of this BasicDataSource
+     */
+    protected PoolableConnectionFactory createPoolableConnectionFactory(
+            final ConnectionFactory driverConnectionFactory) throws SQLException {
+        PoolableConnectionFactory connectionFactory = null;
+        try {
+            connectionFactory = new PoolableConnectionFactory(driverConnectionFactory,
+                    ObjectNameWrapper.unwrap(registeredJmxObjectName));
+            connectionFactory.setValidationQuery(validationQuery);
+            connectionFactory.setValidationQueryTimeout(validationQueryTimeoutSeconds);
+            connectionFactory.setConnectionInitSql(connectionInitSqls);
+            connectionFactory.setDefaultReadOnly(defaultReadOnly);
+            connectionFactory.setDefaultAutoCommit(defaultAutoCommit);
+            connectionFactory.setDefaultTransactionIsolation(defaultTransactionIsolation);
+            connectionFactory.setDefaultCatalog(defaultCatalog);
+            connectionFactory.setDefaultSchema(defaultSchema);
+            connectionFactory.setCacheState(cacheState);
+            connectionFactory.setPoolStatements(poolPreparedStatements);
+            connectionFactory.setMaxOpenPreparedStatements(maxOpenPreparedStatements);
+            connectionFactory.setMaxConnLifetimeMillis(maxConnLifetimeMillis);
+            connectionFactory.setRollbackOnReturn(getRollbackOnReturn());
+            connectionFactory.setAutoCommitOnReturn(getAutoCommitOnReturn());
+            connectionFactory.setDefaultQueryTimeout(getDefaultQueryTimeout());
+            connectionFactory.setFastFailValidation(fastFailValidation);
+            connectionFactory.setDisconnectionSqlCodes(disconnectionSqlCodes);
+            validateConnectionFactory(connectionFactory);
+        } catch (final RuntimeException e) {
+            throw e;
+        } catch (final Exception e) {
+            throw new SQLException(
+                    "Cannot create PoolableConnectionFactory (" + e.getMessage() + ")", e);
+        }
+        return connectionFactory;
+    }
+
+
+    /**
+     * Gets the print writer used by this configuration to log information on
+     * abandoned objects.
+     *
+     * @return The print writer used by this configuration to log information on
+     *         abandoned objects.
+     */
+    public PrintWriter getAbandonedLogWriter() {
+        if (abandonedConfig != null) {
+            return abandonedConfig.getLogWriter();
+        }
+        return null;
+    }
+
+
+    /**
+     * If the connection pool implements
+     * {@link org.apache.commons.pool2.UsageTracking UsageTracking}, should the
+     * connection pool record a stack trace every time a method is called on a
+     * pooled connection and retain the most recent stack trace to aid debugging
+     * of abandoned connections?
+     *
+     * @return <code>true</code> if usage tracking is enabled
+     */
+    @Override
+    public boolean getAbandonedUsageTracking() {
+        if (abandonedConfig != null) {
+            return abandonedConfig.getUseUsageTracking();
+        }
+        return false;
+    }
+
+
+    /**
+     * Returns the value of the flag that controls whether or not connections
+     * being returned to the pool will be checked and configured with
+     * {@link Connection#setAutoCommit(boolean) Connection.setAutoCommit(true)}
+     * if the auto commit setting is {@code false} when the connection is
+     * returned. It is <code>true</code> by default.
+     *
+     * @return Whether or not connections being returned to the pool will be
+     *         checked and configured with auto-commit.
+     */
+    public boolean getAutoCommitOnReturn() {
+        return autoCommitOnReturn;
+    }
+
+
+    /**
+     * Returns the state caching flag.
+     *
+     * @return the state caching flag
+     */
+    @Override
+    public boolean getCacheState() {
+        return cacheState;
+    }
+
+
+    /**
+     * Creates (if necessary) and return a connection to the database.
+     *
+     * @throws SQLException if a database access error occurs
+     * @return a database connection
+     */
+    @Override
+    public Connection getConnection() throws SQLException {
+        if (Utils.IS_SECURITY_ENABLED) {
+            final PrivilegedExceptionAction<Connection> action = new PaGetConnection();
+            try {
+                return AccessController.doPrivileged(action);
+            } catch (final PrivilegedActionException e) {
+                final Throwable cause = e.getCause();
+                if (cause instanceof SQLException) {
+                    throw (SQLException) cause;
+                }
+                throw new SQLException(e);
+            }
+        }
+        return createDataSource().getConnection();
+    }
+
+
+    /**
+     * <strong>BasicDataSource does NOT support this method.</strong>
+     *
+     * @param user Database user on whose behalf the Connection is being made
+     * @param pass The database user's password
+     *
+     * @throws UnsupportedOperationException always thrown.
+     * @throws SQLException if a database access error occurs
+     * @return nothing - always throws UnsupportedOperationException
+     */
+    @Override
+    public Connection getConnection(final String user, final String pass) throws SQLException {
+        // This method isn't supported by the PoolingDataSource returned by the
+        // createDataSource
+        throw new UnsupportedOperationException("Not supported by BasicDataSource");
+    }
+
+
+    /**
+     * Returns the list of SQL statements executed when a physical connection is
+     * first created. Returns an empty list if there are no initialization
+     * statements configured.
+     *
+     * @return initialization SQL statements
+     */
+    public List<String> getConnectionInitSqls() {
+        final List<String> result = connectionInitSqls;
+        if (result == null) {
+            return Collections.emptyList();
+        }
+        return result;
+    }
+
+
+    /**
+     * Provides the same data as {@link #getConnectionInitSqls()} but in an
+     * array so it is accessible via JMX.
+     */
+    @Override
+    public String[] getConnectionInitSqlsAsArray() {
+        final Collection<String> result = getConnectionInitSqls();
+        return result.toArray(new String[result.size()]);
+    }
+
+
+    protected GenericObjectPool<PoolableConnection> getConnectionPool() {
+        return connectionPool;
+    }
+
+
+    // For unit testing
+    Properties getConnectionProperties() {
+        return connectionProperties;
+    }
+
+
+    /**
+     * Returns the default auto-commit property.
+     *
+     * @return true if default auto-commit is enabled
+     */
+    @Override
+    public Boolean getDefaultAutoCommit() {
+        return defaultAutoCommit;
+    }
+
+
+    /**
+     * Returns the default catalog.
+     *
+     * @return the default catalog
+     */
+    @Override
+    public String getDefaultCatalog() {
+        return this.defaultCatalog;
+    }
+
+
+    /**
+     * Gets the default query timeout that will be used for
+     * {@link java.sql.Statement Statement}s created from this connection.
+     * <code>null</code> means that the driver default will be used.
+     *
+     * @return The default query timeout in seconds.
+     */
+    public Integer getDefaultQueryTimeout() {
+        return defaultQueryTimeoutSeconds;
+    }
+
+
+    /**
+     * Returns the default readOnly property.
+     *
+     * @return true if connections are readOnly by default
+     */
+    @Override
+    public Boolean getDefaultReadOnly() {
+        return defaultReadOnly;
+    }
+
+
+    /**
+     * Returns the default schema.
+     *
+     * @return the default schema.
+     * @since 2.5.0
+     */
+    @Override
+    public String getDefaultSchema() {
+        return this.defaultSchema;
+    }
+
+
+    /**
+     * Returns the default transaction isolation state of returned connections.
+     *
+     * @return the default value for transaction isolation state
+     * @see Connection#getTransactionIsolation
+     */
+    @Override
+    public int getDefaultTransactionIsolation() {
+        return this.defaultTransactionIsolation;
+    }
+
+
+    /**
+     * Returns the set of SQL_STATE codes considered to signal fatal conditions.
+     *
+     * @return fatal disconnection state codes
+     * @see #setDisconnectionSqlCodes(Collection)
+     * @since 2.1
+     */
+    public Set<String> getDisconnectionSqlCodes() {
+        final Set<String> result = disconnectionSqlCodes;
+        if (result == null) {
+            return Collections.emptySet();
+        }
+        return result;
+    }
+
+
+    /**
+     * Provides the same data as {@link #getDisconnectionSqlCodes} but in an
+     * array so it is accessible via JMX.
+     *
+     * @since 2.1
+     */
+    @Override
+    public String[] getDisconnectionSqlCodesAsArray() {
+        final Collection<String> result = getDisconnectionSqlCodes();
+        return result.toArray(new String[result.size()]);
+    }
+
+
+    /**
+     * Returns the JDBC Driver that has been configured for use by this pool.
+     * <p>
+     * Note: This getter only returns the last value set by a call to
+     * {@link #setDriver(Driver)}. It does not return any driver instance that
+     * may have been created from the value set via
+     * {@link #setDriverClassName(String)}.
+     * </p>
+     *
+     * @return the JDBC Driver that has been configured for use by this pool
+     */
+    public synchronized Driver getDriver() {
+        return driver;
+    }
+
+
+    /**
+     * Returns the class loader specified for loading the JDBC driver. Returns
+     * <code>null</code> if no class loader has been explicitly specified.
+     * <p>
+     * Note: This getter only returns the last value set by a call to
+     * {@link #setDriverClassLoader(ClassLoader)}. It does not return the class
+     * loader of any driver that may have been set via
+     * {@link #setDriver(Driver)}.
+     * </p>
+     *
+     * @return The class loader specified for loading the JDBC driver.
+     */
+    public synchronized ClassLoader getDriverClassLoader() {
+        return this.driverClassLoader;
+    }
+
+
+    /**
+     * Returns the JDBC driver class name.
+     * <p>
+     * Note: This getter only returns the last value set by a call to
+     * {@link #setDriverClassName(String)}. It does not return the class name of
+     * any driver that may have been set via {@link #setDriver(Driver)}.
+     * </p>
+     *
+     * @return the JDBC driver class name
+     */
+    @Override
+    public synchronized String getDriverClassName() {
+        return this.driverClassName;
+    }
+
+
+    /**
+     * Returns the ConnectionFactoryClassName that has been configured for use
+     * by this pool.
+     * <p>
+     * Note: This getter only returns the last value set by a call to
+     * {@link #setConnectionFactoryClassName(String)}.
+     * </p>
+     *
+     * @return the ConnectionFactoryClassName that has been configured for use
+     *         by this pool.
+     * @since 2.7.0
+     */
+    public String getConnectionFactoryClassName() {
+        return this.connectionFactoryClassName;
+    }
+
+
+    /**
+     * Returns the value of the flag that controls whether or not connections
+     * being returned to the pool will be checked and configured with
+     * {@link Connection#setAutoCommit(boolean) Connection.setAutoCommit(true)}
+     * if the auto commit setting is {@code false} when the connection is
+     * returned. It is <code>true</code> by default.
+     *
+     * @return Whether or not connections being returned to the pool will be
+     *         checked and configured with auto-commit.
+     * @deprecated Use {@link #getAutoCommitOnReturn()}.
+     */
+    @Deprecated
+    public boolean getEnableAutoCommitOnReturn() {
+        return autoCommitOnReturn;
+    }
+
+
+    /**
+     * Gets the EvictionPolicy implementation in use with this connection pool.
+     *
+     * @return The EvictionPolicy implementation in use with this connection
+     *         pool.
+     */
+    public synchronized String getEvictionPolicyClassName() {
+        return evictionPolicyClassName;
+    }
+
+
+    /**
+     * True means that validation will fail immediately for connections that
+     * have previously thrown SQLExceptions with SQL_STATE indicating fatal
+     * disconnection errors.
+     *
+     * @return true if connections created by this datasource will fast fail
+     *         validation.
+     * @see #setDisconnectionSqlCodes(Collection)
+     * @since 2.1
+     */
+    @Override
+    public boolean getFastFailValidation() {
+        return fastFailValidation;
+    }
+
+
+    /**
+     * Returns the initial size of the connection pool.
+     *
+     * @return the number of connections created when the pool is initialized
+     */
+    @Override
+    public synchronized int getInitialSize() {
+        return this.initialSize;
+    }
+
+
+    /**
+     * Returns the JMX name that has been requested for this DataSource. If the
+     * requested name is not valid, an alternative may be chosen.
+     *
+     * @return The JMX name that has been requested for this DataSource.
+     */
+    public String getJmxName() {
+        return jmxName;
+    }
+
+
+    /**
+     * Returns the LIFO property.
+     *
+     * @return true if connection pool behaves as a LIFO queue.
+     */
+    @Override
+    public synchronized boolean getLifo() {
+        return this.lifo;
+    }
+
+
+    /**
+     * <p>
+     * Flag to log stack traces for application code which abandoned a Statement
+     * or Connection.
+     * </p>
+     * <p>
+     * Defaults to false.
+     * </p>
+     * <p>
+     * Logging of abandoned Statements and Connections adds overhead for every
+     * Connection open or new Statement because a stack trace has to be
+     * generated.
+     * </p>
+     */
+    @Override
+    public boolean getLogAbandoned() {
+        if (abandonedConfig != null) {
+            return abandonedConfig.getLogAbandoned();
+        }
+        return false;
+    }
+
+
+    /**
+     * When {@link #getMaxConnLifetimeMillis()} is set to limit connection
+     * lifetime, this property determines whether or not log messages are
+     * generated when the pool closes connections due to maximum lifetime
+     * exceeded.
+     *
+     * @since 2.1
+     */
+    @Override
+    public boolean getLogExpiredConnections() {
+        return logExpiredConnections;
+    }
+
+
+    /**
+     * <strong>BasicDataSource does NOT support this method.</strong>
+     *
+     * <p>
+     * Returns the login timeout (in seconds) for connecting to the database.
+     * </p>
+     * <p>
+     * Calls {@link #createDataSource()}, so has the side effect of initializing
+     * the connection pool.
+     * </p>
+     *
+     * @throws SQLException if a database access error occurs
+     * @throws UnsupportedOperationException If the DataSource implementation
+     *             does not support the login timeout feature.
+     * @return login timeout in seconds
+     */
+    @Override
+    public int getLoginTimeout() throws SQLException {
+        // This method isn't supported by the PoolingDataSource returned by the
+        // createDataSource
+        throw new UnsupportedOperationException("Not supported by BasicDataSource");
+    }
+
+
+    /**
+     * <p>
+     * Returns the log writer being used by this data source.
+     * </p>
+     * <p>
+     * Calls {@link #createDataSource()}, so has the side effect of initializing
+     * the connection pool.
+     * </p>
+     *
+     * @throws SQLException if a database access error occurs
+     * @return log writer in use
+     */
+    @Override
+    public PrintWriter getLogWriter() throws SQLException {
+        return createDataSource().getLogWriter();
+    }
+
+
+    /**
+     * Returns the maximum permitted lifetime of a connection in milliseconds. A
+     * value of zero or less indicates an infinite lifetime.
+     */
+    @Override
+    public long getMaxConnLifetimeMillis() {
+        return maxConnLifetimeMillis;
+    }
+
+
+    /**
+     * <p>
+     * Returns the maximum number of connections that can remain idle in the
+     * pool. Excess idle connections are destroyed on return to the pool.
+     * </p>
+     * <p>
+     * A negative value indicates that there is no limit
+     * </p>
+     *
+     * @return the maximum number of idle connections
+     */
+    @Override
+    public synchronized int getMaxIdle() {
+        return this.maxIdle;
+    }
+
+
+    /**
+     * Gets the value of the <code>maxOpenPreparedStatements</code> property.
+     *
+     * @return the maximum number of open statements
+     */
+    @Override
+    public synchronized int getMaxOpenPreparedStatements() {
+        return this.maxOpenPreparedStatements;
+    }
+
+
+    /**
+     * <p>
+     * Returns the maximum number of active connections that can be allocated at
+     * the same time.
+     * </p>
+     * <p>
+     * A negative number means that there is no limit.
+     * </p>
+     *
+     * @return the maximum number of active connections
+     */
+    @Override
+    public synchronized int getMaxTotal() {
+        return this.maxTotal;
+    }
+
+
+    /**
+     * Returns the maximum number of milliseconds that the pool will wait for a
+     * connection to be returned before throwing an exception. A value less than
+     * or equal to zero means the pool is set to wait indefinitely.
+     *
+     * @return the maxWaitMillis property value
+     */
+    @Override
+    public synchronized long getMaxWaitMillis() {
+        return this.maxWaitMillis;
+    }
+
+
+    /**
+     * Returns the {@link #minEvictableIdleTimeMillis} property.
+     *
+     * @return the value of the {@link #minEvictableIdleTimeMillis} property
+     * @see #minEvictableIdleTimeMillis
+     */
+    @Override
+    public synchronized long getMinEvictableIdleTimeMillis() {
+        return this.minEvictableIdleTimeMillis;
+    }
+
+
+    /**
+     * Returns the minimum number of idle connections in the pool. The pool
+     * attempts to ensure that minIdle connections are available when the idle
+     * object evictor runs. The value of this property has no effect unless
+     * {@link #timeBetweenEvictionRunsMillis} has a positive value.
+     *
+     * @return the minimum number of idle connections
+     * @see GenericObjectPool#getMinIdle()
+     */
+    @Override
+    public synchronized int getMinIdle() {
+        return this.minIdle;
+    }
+
+
+    /**
+     * [Read Only] The current number of active connections that have been
+     * allocated from this data source.
+     *
+     * @return the current number of active connections
+     */
+    @Override
+    public int getNumActive() {
+        // Copy reference to avoid NPE if close happens after null check
+        final GenericObjectPool<PoolableConnection> pool = connectionPool;
+        if (pool != null) {
+            return pool.getNumActive();
+        }
+        return 0;
+    }
+
+
+    /**
+     * [Read Only] The current number of idle connections that are waiting to be
+     * allocated from this data source.
+     *
+     * @return the current number of idle connections
+     */
+    @Override
+    public int getNumIdle() {
+        // Copy reference to avoid NPE if close happens after null check
+        final GenericObjectPool<PoolableConnection> pool = connectionPool;
+        if (pool != null) {
+            return pool.getNumIdle();
+        }
+        return 0;
+    }
+
+
+    /**
+     * Returns the value of the {@link #numTestsPerEvictionRun} property.
+     *
+     * @return the number of objects to examine during idle object evictor runs
+     * @see #numTestsPerEvictionRun
+     */
+    @Override
+    public synchronized int getNumTestsPerEvictionRun() {
+        return this.numTestsPerEvictionRun;
+    }
+
+
+    @Override
+    public Logger getParentLogger() throws SQLFeatureNotSupportedException {
+        throw new SQLFeatureNotSupportedException();
+    }
+
+
+    /**
+     * Returns the password passed to the JDBC driver to establish connections.
+     *
+     * @return the connection password
+     */
+    @Override
+    public String getPassword() {
+        return this.password;
+    }
+
+
+    protected ObjectName getRegisteredJmxName() {
+        return ObjectNameWrapper.unwrap(registeredJmxObjectName);
+    }
+
+
+    /**
+     * <p>
+     * Flag to remove abandoned connections if they exceed the
+     * removeAbandonedTimeout when borrowObject is invoked.
+     * </p>
+     * <p>
+     * The default value is false.
+     * </p>
+     * <p>
+     * If set to true a connection is considered abandoned and eligible for
+     * removal if it has not been used for more than
+     * {@link #getRemoveAbandonedTimeout() removeAbandonedTimeout} seconds.
+     * </p>
+     * <p>
+     * Abandoned connections are identified and removed when
+     * {@link #getConnection()} is invoked and all of the following conditions
+     * hold:
+     * </p>
+     * <ul>
+     * <li>{@link #getRemoveAbandonedOnBorrow()}</li>
+     * <li>{@link #getNumActive()} &gt; {@link #getMaxTotal()} - 3</li>
+     * <li>{@link #getNumIdle()} &lt; 2</li>
+     * </ul>
+     *
+     * @see #getRemoveAbandonedTimeout()
+     */
+    @Override
+    public boolean getRemoveAbandonedOnBorrow() {
+        if (abandonedConfig != null) {
+            return abandonedConfig.getRemoveAbandonedOnBorrow();
+        }
+        return false;
+    }
+
+
+    /**
+     * <p>
+     * Flag to remove abandoned connections if they exceed the
+     * removeAbandonedTimeout during pool maintenance.
+     * </p>
+     *
+     * <p>
+     * The default value is false.
+     * </p>
+     *
+     * <p>
+     * If set to true a connection is considered abandoned and eligible for
+     * removal if it has not been used for more than
+     * {@link #getRemoveAbandonedTimeout() removeAbandonedTimeout} seconds.
+     * </p>
+     *
+     * @see #getRemoveAbandonedTimeout()
+     */
+    @Override
+    public boolean getRemoveAbandonedOnMaintenance() {
+        if (abandonedConfig != null) {
+            return abandonedConfig.getRemoveAbandonedOnMaintenance();
+        }
+        return false;
+    }
+
+
+    /**
+     * <p>
+     * Timeout in seconds before an abandoned connection can be removed.
+     * </p>
+     * <p>
+     * Creating a Statement, PreparedStatement or CallableStatement or using one
+     * of these to execute a query (using one of the execute methods) resets the
+     * lastUsed property of the parent connection.
+     * </p>
+     * <p>
+     * Abandoned connection cleanup happens when:
+     * </p>
+     * <ul>
+     * <li>{@link #getRemoveAbandonedOnBorrow()} or
+     * {@link #getRemoveAbandonedOnMaintenance()} = true</li>
+     * <li>{@link #getNumIdle() numIdle} &lt; 2</li>
+     * <li>{@link #getNumActive() numActive} &gt; {@link #getMaxTotal()
+     * maxTotal} - 3</li>
+     * </ul>
+     * <p>
+     * The default value is 300 seconds.
+     * </p>
+     */
+    @Override
+    public int getRemoveAbandonedTimeout() {
+        if (abandonedConfig != null) {
+            return abandonedConfig.getRemoveAbandonedTimeout();
+        }
+        return 300;
+    }
+
+
+    /**
+     * Gets the current value of the flag that controls whether a connection
+     * will be rolled back when it is returned to the pool if auto commit is not
+     * enabled and the connection is not read only.
+     *
+     * @return whether a connection will be rolled back when it is returned to
+     *         the pool.
+     */
+    public boolean getRollbackOnReturn() {
+        return rollbackOnReturn;
+    }
+
+
+    /**
+     * <p>
+     * Returns the minimum amount of time a connection may sit idle in the pool
+     * before it is eligible for eviction by the idle object evictor, with the
+     * extra condition that at least "minIdle" connections remain in the pool.
+     * </p>
+     *
+     * <p>
+     * When {@link #getMinEvictableIdleTimeMillis() minEvictableIdleTimeMillis}
+     * is set to a positive value, minEvictableIdleTimeMillis is examined first
+     * by the idle connection evictor - i.e. when idle connections are visited
+     * by the evictor, idle time is first compared against
+     * {@code minEvictableIdleTimeMillis} (without considering the number of
+     * idle connections in the pool) and then against
+     * {@code softMinEvictableIdleTimeMillis}, including the {@code minIdle},
+     * constraint.
+     * </p>
+     *
+     * @return minimum amount of time a connection may sit idle in the pool
+     *         before it is eligible for eviction, assuming there are minIdle
+     *         idle connections in the pool
+     */
+    @Override
+    public synchronized long getSoftMinEvictableIdleTimeMillis() {
+        return softMinEvictableIdleTimeMillis;
+    }
+
+
+    /**
+     * Returns the {@link #testOnBorrow} property.
+     *
+     * @return true if objects are validated before being borrowed from the pool
+     *
+     * @see #testOnBorrow
+     */
+    @Override
+    public synchronized boolean getTestOnBorrow() {
+        return this.testOnBorrow;
+    }
+
+
+    /**
+     * Returns the {@link #testOnCreate} property.
+     *
+     * @return true if objects are validated immediately after they are created
+     *         by the pool
+     * @see #testOnCreate
+     */
+    @Override
+    public synchronized boolean getTestOnCreate() {
+        return this.testOnCreate;
+    }
+
+
+    /**
+     * Returns the value of the {@link #testOnReturn} property.
+     *
+     * @return true if objects are validated before being returned to the pool
+     * @see #testOnReturn
+     */
+    public synchronized boolean getTestOnReturn() {
+        return this.testOnReturn;
+    }
+
+
+    /**
+     * Returns the value of the {@link #testWhileIdle} property.
+     *
+     * @return true if objects examined by the idle object evictor are validated
+     * @see #testWhileIdle
+     */
+    @Override
+    public synchronized boolean getTestWhileIdle() {
+        return this.testWhileIdle;
+    }
+
+
+    /**
+     * Returns the value of the {@link #timeBetweenEvictionRunsMillis} property.
+     *
+     * @return the time (in milliseconds) between evictor runs
+     * @see #timeBetweenEvictionRunsMillis
+     */
+    @Override
+    public synchronized long getTimeBetweenEvictionRunsMillis() {
+        return this.timeBetweenEvictionRunsMillis;
+    }
+
+
+    /**
+     * Returns the JDBC connection {@link #url} property.
+     *
+     * @return the {@link #url} passed to the JDBC driver to establish
+     *         connections
+     */
+    @Override
+    public synchronized String getUrl() {
+        return this.url;
+    }
+
+
+    /**
+     * Returns the JDBC connection {@link #userName} property.
+     *
+     * @return the {@link #userName} passed to the JDBC driver to establish
+     *         connections
+     */
+    @Override
+    public String getUsername() {
+        return this.userName;
+    }
+
+
+    /**
+     * Returns the validation query used to validate connections before
+     * returning them.
+     *
+     * @return the SQL validation query
+     * @see #validationQuery
+     */
+    @Override
+    public String getValidationQuery() {
+        return this.validationQuery;
+    }
+
+
+    /**
+     * Returns the validation query timeout.
+     *
+     * @return the timeout in seconds before connection validation queries fail.
+     */
+    @Override
+    public int getValidationQueryTimeout() {
+        return validationQueryTimeoutSeconds;
+    }
+
+
+    /**
+     * Manually invalidates a connection, effectively requesting the pool to try
+     * to close it, remove it from the pool and reclaim pool capacity.
+     *
+     * @param connection The Connection to invalidate.
+     *
+     * @throws IllegalStateException if invalidating the connection failed.
+     * @since 2.1
+     */
+    public void invalidateConnection(final Connection connection) throws IllegalStateException {
+        if (connection == null) {
+            return;
+        }
+        if (connectionPool == null) {
+            throw new IllegalStateException(
+                    "Cannot invalidate connection: ConnectionPool is null.");
+        }
+
+        final PoolableConnection poolableConnection;
+        try {
+            poolableConnection = connection.unwrap(PoolableConnection.class);
+            if (poolableConnection == null) {
+                throw new IllegalStateException(
+                        "Cannot invalidate connection: Connection is not a poolable connection.");
+            }
+        } catch (final SQLException e) {
+            throw new IllegalStateException(
+                    "Cannot invalidate connection: Unwrapping poolable connection failed.", e);
+        }
+
+        try {
+            connectionPool.invalidateObject(poolableConnection);
+        } catch (final Exception e) {
+            throw new IllegalStateException("Invalidating connection threw unexpected exception",
+                    e);
+        }
+    }
+
+
+    /**
+     * Manually evicts idle connections.
+     *
+     * @throws Exception Thrown by {@link GenericObjectPool#evict()}.
+     * @see GenericObjectPool#evict()
+     */
+    public void evict() throws Exception {
+        if (connectionPool != null) {
+            connectionPool.evict();
+        }
+    }
+
+
+    /**
+     * Returns the value of the accessToUnderlyingConnectionAllowed property.
+     *
+     * @return true if access to the underlying connection is allowed, false
+     *         otherwise.
+     */
+    @Override
+    public synchronized boolean isAccessToUnderlyingConnectionAllowed() {
+        return this.accessToUnderlyingConnectionAllowed;
+    }
+
+
+    /**
+     * If true, this data source is closed and no more connections can be
+     * retrieved from this datasource.
+     *
+     * @return true, if the data source is closed; false otherwise
+     */
+    @Override
+    public synchronized boolean isClosed() {
+        return closed;
+    }
+
+
+    /**
+     * Delegates in a null-safe manner to {@link String#isEmpty()}.
+     *
+     * @param value the string to test, may be null.
+     * @return boolean false if value is null, otherwise
+     *         {@link String#isEmpty()}.
+     */
+    private boolean isEmpty(String value) {
+        return value == null ? true : value.trim().isEmpty();
+    }
+
+
+    /**
+     * Returns true if we are pooling statements.
+     *
+     * @return true if prepared and callable statements are pooled
+     */
+    @Override
+    public synchronized boolean isPoolPreparedStatements() {
+        return this.poolPreparedStatements;
+    }
+
+
+    @Override
+    public boolean isWrapperFor(final Class<?> iface) throws SQLException {
+        return false;
+    }
+
+
+    private void jmxRegister() {
+        // Return immediately if this DataSource has already been registered
+        if (registeredJmxObjectName != null) {
+            return;
+        }
+        // Return immediately if no JMX name has been specified
+        final String requestedName = getJmxName();
+        if (requestedName == null) {
+            return;
+        }
+        try {
+            ObjectNameWrapper.wrap(requestedName).registerMBean(this);
+        } catch (final MalformedObjectNameException e) {
+            log.warn("The requested JMX name [" + requestedName +
+                    "] was not valid and will be ignored.");
+        }
+    }
+
+
+    protected void log(final String message) {
+        if (logWriter != null) {
+            logWriter.println(message);
+        }
+    }
+
+
+    @Override
+    public void postDeregister() {
+        // NO-OP
+    }
+
+
+    @Override
+    public void postRegister(final Boolean registrationDone) {
+        // NO-OP
+    }
+
+
+    @Override
+    public void preDeregister() throws Exception {
+        // NO-OP
+    }
+
+
+    @Override
+    public ObjectName preRegister(final MBeanServer server, final ObjectName objectName) {
+        final String requestedName = getJmxName();
+        if (requestedName != null) {
+            try {
+                registeredJmxObjectName = ObjectNameWrapper.wrap(requestedName);
+            } catch (final MalformedObjectNameException e) {
+                log.warn("The requested JMX name [" + requestedName +
+                        "] was not valid and will be ignored.");
+            }
+        }
+        if (registeredJmxObjectName == null) {
+            registeredJmxObjectName = ObjectNameWrapper.wrap(objectName);
+        }
+        return ObjectNameWrapper.unwrap(registeredJmxObjectName);
+    }
+
+
+    /**
+     * Removes a custom connection property.
+     *
+     * @param name Name of the custom connection property to remove
+     * @see #addConnectionProperty(String, String)
+     */
+    public void removeConnectionProperty(final String name) {
+        connectionProperties.remove(name);
+    }
+
+
+    /**
+     * Sets the print writer to be used by this configuration to log information
+     * on abandoned objects.
+     *
+     * @param logWriter The new log writer
+     */
+    public void setAbandonedLogWriter(final PrintWriter logWriter) {
+        if (abandonedConfig == null) {
+            abandonedConfig = new AbandonedConfig();
+        }
+        abandonedConfig.setLogWriter(logWriter);
+        final GenericObjectPool<?> gop = this.connectionPool;
+        if (gop != null) {
+            gop.setAbandonedConfig(abandonedConfig);
+        }
+    }
+
+
+    /**
+     * If the connection pool implements
+     * {@link org.apache.commons.pool2.UsageTracking UsageTracking}, configure
+     * whether the connection pool should record a stack trace every time a
+     * method is called on a pooled connection and retain the most recent stack
+     * trace to aid debugging of abandoned connections.
+     *
+     * @param usageTracking A value of <code>true</code> will enable the
+     *            recording of a stack trace on every use of a pooled connection
+     */
+    public void setAbandonedUsageTracking(final boolean usageTracking) {
+        if (abandonedConfig == null) {
+            abandonedConfig = new AbandonedConfig();
+        }
+        abandonedConfig.setUseUsageTracking(usageTracking);
+        final GenericObjectPool<?> gop = this.connectionPool;
+        if (gop != null) {
+            gop.setAbandonedConfig(abandonedConfig);
+        }
+    }
+
+
+    /**
+     * <p>
+     * Sets the value of the accessToUnderlyingConnectionAllowed property. It
+     * controls if the PoolGuard allows access to the underlying connection.
+     * (Default: false)
+     * </p>
+     * <p>
+     * Note: this method currently has no effect once the pool has been
+     * initialized. The pool is initialized the first time one of the following
+     * methods is invoked: <code>getConnection, setLogwriter,
+     * setLoginTimeout, getLoginTimeout, getLogWriter.</code>
+     * </p>
+     *
+     * @param allow Access to the underlying connection is granted when true.
+     */
+    public synchronized void setAccessToUnderlyingConnectionAllowed(final boolean allow) {
+        this.accessToUnderlyingConnectionAllowed = allow;
+    }
+
+
+    /**
+     * Sets the value of the flag that controls whether or not connections being
+     * returned to the pool will be checked and configured with
+     * {@link Connection#setAutoCommit(boolean) Connection.setAutoCommit(true)}
+     * if the auto commit setting is {@code false} when the connection is
+     * returned. It is <code>true</code> by default.
+     *
+     * @param autoCommitOnReturn Whether or not connections being returned to
+     *            the pool will be checked and configured with auto-commit.
+     * @since 2.6.0
+     */
+    public void setAutoCommitOnReturn(final boolean autoCommitOnReturn) {
+        this.autoCommitOnReturn = autoCommitOnReturn;
+    }
+
+
+    /**
+     * Sets the state caching flag.
+     *
+     * @param cacheState The new value for the state caching flag
+     */
+    public void setCacheState(final boolean cacheState) {
+        this.cacheState = cacheState;
+    }
+
+
+    /**
+     * Sets the list of SQL statements to be executed when a physical connection
+     * is first created.
+     * <p>
+     * Note: this method currently has no effect once the pool has been
+     * initialized. The pool is initialized the first time one of the following
+     * methods is invoked: <code>getConnection, setLogwriter,
+     * setLoginTimeout, getLoginTimeout, getLogWriter.</code>
+     * </p>
+     *
+     * @param connectionInitSqls Collection of SQL statements to execute on
+     *            connection creation
+     */
+    public void setConnectionInitSqls(final Collection<String> connectionInitSqls) {
+        if (connectionInitSqls != null && connectionInitSqls.size() > 0) {
+            ArrayList<String> newVal = null;
+            for (final String s : connectionInitSqls) {
+                if (!isEmpty(s)) {
+                    if (newVal == null) {
+                        newVal = new ArrayList<>();
+                    }
+                    newVal.add(s);
+                }
+            }
+            this.connectionInitSqls = newVal;
+        } else {
+            this.connectionInitSqls = null;
+        }
+    }
+
+
+    // ----------------------------------------------------- DataSource Methods
+
+    /**
+     * Sets the connection properties passed to driver.connect(...).
+     * <p>
+     * Format of the string must be [propertyName=property;]*
+     * </p>
+     * <p>
+     * NOTE - The "user" and "password" properties will be added explicitly, so
+     * they do not need to be included here.
+     * </p>
+     *
+     * @param connectionProperties the connection properties used to create new
+     *            connections
+     */
+    public void setConnectionProperties(final String connectionProperties) {
+        Objects.requireNonNull(connectionProperties, "connectionProperties is null");
+        final String[] entries = connectionProperties.split(";");
+        final Properties properties = new Properties();
+        for (final String entry : entries) {
+            if (entry.length() > 0) {
+                final int index = entry.indexOf('=');
+                if (index > 0) {
+                    final String name = entry.substring(0, index);
+                    final String value = entry.substring(index + 1);
+                    properties.setProperty(name, value);
+                } else {
+                    // no value is empty string which is how
+                    // java.util.Properties works
+                    properties.setProperty(entry, "");
+                }
+            }
+        }
+        this.connectionProperties = properties;
+    }
+
+
+    /**
+     * <p>
+     * Sets default auto-commit state of connections returned by this
+     * datasource.
+     * </p>
+     * <p>
+     * Note: this method currently has no effect once the pool has been
+     * initialized. The pool is initialized the first time one of the following
+     * methods is invoked: <code>getConnection, setLogwriter,
+     * setLoginTimeout, getLoginTimeout, getLogWriter.</code>
+     * </p>
+     *
+     * @param defaultAutoCommit default auto-commit value
+     */
+    public void setDefaultAutoCommit(final Boolean defaultAutoCommit) {
+        this.defaultAutoCommit = defaultAutoCommit;
+    }
+
+
+    /**
+     * <p>
+     * Sets the default catalog.
+     * </p>
+     * <p>
+     * Note: this method currently has no effect once the pool has been
+     * initialized. The pool is initialized the first time one of the following
+     * methods is invoked: <code>getConnection, setLogwriter,
+     * setLoginTimeout, getLoginTimeout, getLogWriter.</code>
+     * </p>
+     *
+     * @param defaultCatalog the default catalog
+     */
+    public void setDefaultCatalog(final String defaultCatalog) {
+        if (isEmpty(defaultCatalog)) {
+            this.defaultCatalog = null;
+        } else {
+            this.defaultCatalog = defaultCatalog;
+        }
+    }
+
+
+    /**
+     * Sets the default query timeout that will be used for
+     * {@link java.sql.Statement Statement}s created from this connection.
+     * <code>null</code> means that the driver default will be used.
+     *
+     * @param defaultQueryTimeoutSeconds The default query timeout in seconds.
+     */
+    public void setDefaultQueryTimeout(final Integer defaultQueryTimeoutSeconds) {
+        this.defaultQueryTimeoutSeconds = defaultQueryTimeoutSeconds;
+    }
+
+
+    /**
+     * <p>
+     * Sets defaultReadonly property.
+     * </p>
+     * <p>
+     * Note: this method currently has no effect once the pool has been
+     * initialized. The pool is initialized the first time one of the following
+     * methods is invoked: <code>getConnection, setLogwriter,
+     * setLoginTimeout, getLoginTimeout, getLogWriter.</code>
+     * </p>
+     *
+     * @param defaultReadOnly default read-only value
+     */
+    public void setDefaultReadOnly(final Boolean defaultReadOnly) {
+        this.defaultReadOnly = defaultReadOnly;
+    }
+
+
+    /**
+     * <p>
+     * Sets the default schema.
+     * </p>
+     * <p>
+     * Note: this method currently has no effect once the pool has been
+     * initialized. The pool is initialized the first time one of the following
+     * methods is invoked: <code>getConnection, setLogwriter,
+     * setLoginTimeout, getLoginTimeout, getLogWriter.</code>
+     * </p>
+     *
+     * @param defaultSchema the default catalog
+     * @since 2.5.0
+     */
+    public void setDefaultSchema(final String defaultSchema) {
+        if (isEmpty(defaultSchema)) {
+            this.defaultSchema = null;
+        } else {
+            this.defaultSchema = defaultSchema;
+        }
+    }
+
+
+    /**
+     * <p>
+     * Sets the default transaction isolation state for returned connections.
+     * </p>
+     * <p>
+     * Note: this method currently has no effect once the pool has been
+     * initialized. The pool is initialized the first time one of the following
+     * methods is invoked: <code>getConnection, setLogwriter,
+     * setLoginTimeout, getLoginTimeout, getLogWriter.</code>
+     * </p>
+     *
+     * @param defaultTransactionIsolation the default transaction isolation
+     *            state
+     * @see Connection#getTransactionIsolation
+     */
+    public void setDefaultTransactionIsolation(final int defaultTransactionIsolation) {
+        this.defaultTransactionIsolation = defaultTransactionIsolation;
+    }
+
+
+    /**
+     * Sets the SQL_STATE codes considered to signal fatal conditions.
+     * <p>
+     * Overrides the defaults in {@link Utils#DISCONNECTION_SQL_CODES} (plus
+     * anything starting with {@link Utils#DISCONNECTION_SQL_CODE_PREFIX}). If
+     * this property is non-null and {@link #getFastFailValidation()} is
+     * {@code true}, whenever connections created by this datasource generate
+     * exceptions with SQL_STATE codes in this list, they will be marked as
+     * "fatally disconnected" and subsequent validations will fail fast (no
+     * attempt at isValid or validation query).
+     * </p>
+     * <p>
+     * If {@link #getFastFailValidation()} is {@code false} setting this
+     * property has no effect.
+     * </p>
+     * <p>
+     * Note: this method currently has no effect once the pool has been
+     * initialized. The pool is initialized the first time one of the following
+     * methods is invoked: {@code getConnection, setLogwriter,
+     * setLoginTimeout, getLoginTimeout, getLogWriter}.
+     * </p>
+     *
+     * @param disconnectionSqlCodes SQL_STATE codes considered to signal fatal
+     *            conditions
+     * @since 2.1
+     */
+    public void setDisconnectionSqlCodes(final Collection<String> disconnectionSqlCodes) {
+        if (disconnectionSqlCodes != null && disconnectionSqlCodes.size() > 0) {
+            HashSet<String> newVal = null;
+            for (final String s : disconnectionSqlCodes) {
+                if (!isEmpty(s)) {
+                    if (newVal == null) {
+                        newVal = new HashSet<>();
+                    }
+                    newVal.add(s);
+                }
+            }
+            this.disconnectionSqlCodes = newVal;
+        } else {
+            this.disconnectionSqlCodes = null;
+        }
+    }
+
+
+    /**
+     * Sets the JDBC Driver instance to use for this pool.
+     * <p>
+     * Note: this method currently has no effect once the pool has been
+     * initialized. The pool is initialized the first time one of the following
+     * methods is invoked: <code>getConnection, setLogwriter,
+     * setLoginTimeout, getLoginTimeout, getLogWriter.</code>
+     * </p>
+     *
+     * @param driver The JDBC Driver instance to use for this pool.
+     */
+    public synchronized void setDriver(final Driver driver) {
+        this.driver = driver;
+    }
+
+
+    /**
+     * <p>
+     * Sets the class loader to be used to load the JDBC driver.
+     * </p>
+     * <p>
+     * Note: this method currently has no effect once the pool has been
+     * initialized. The pool is initialized the first time one of the following
+     * methods is invoked: <code>getConnection, setLogwriter,
+     * setLoginTimeout, getLoginTimeout, getLogWriter.</code>
+     * </p>
+     *
+     * @param driverClassLoader the class loader with which to load the JDBC
+     *            driver
+     */
+    public synchronized void setDriverClassLoader(final ClassLoader driverClassLoader) {
+        this.driverClassLoader = driverClassLoader;
+    }
+
+
+    /**
+     * <p>
+     * Sets the JDBC driver class name.
+     * </p>
+     * <p>
+     * Note: this method currently has no effect once the pool has been
+     * initialized. The pool is initialized the first time one of the following
+     * methods is invoked: <code>getConnection, setLogwriter,
+     * setLoginTimeout, getLoginTimeout, getLogWriter.</code>
+     * </p>
+     *
+     * @param driverClassName the class name of the JDBC driver
+     */
+    public synchronized void setDriverClassName(final String driverClassName) {
+        if (isEmpty(driverClassName)) {
+            this.driverClassName = null;
+        } else {
+            this.driverClassName = driverClassName;
+        }
+    }
+
+
+    /**
+     * Sets the ConnectionFactory class name.
+     *
+     * @param connectionFactoryClassName
+     * @since 2.7.0
+     */
+
+    public void setConnectionFactoryClassName(final String connectionFactoryClassName) {
+        if (isEmpty(connectionFactoryClassName)) {
+            this.connectionFactoryClassName = null;
+        } else {
+            this.connectionFactoryClassName = connectionFactoryClassName;
+        }
+    }
+
+
+    /**
+     * Sets the value of the flag that controls whether or not connections being
+     * returned to the pool will be checked and configured with
+     * {@link Connection#setAutoCommit(boolean) Connection.setAutoCommit(true)}
+     * if the auto commit setting is {@code false} when the connection is
+     * returned. It is <code>true</code> by default.
+     *
+     * @param autoCommitOnReturn Whether or not connections being returned to
+     *            the pool will be checked and configured with auto-commit.
+     * @deprecated Use {@link #setAutoCommitOnReturn(boolean)}.
+     */
+    @Deprecated
+    public void setEnableAutoCommitOnReturn(final boolean autoCommitOnReturn) {
+        this.autoCommitOnReturn = autoCommitOnReturn;
+    }
+
+
+    /**
+     * Sets the EvictionPolicy implementation to use with this connection pool.
+     *
+     * @param evictionPolicyClassName The fully qualified class name of the
+     *            EvictionPolicy implementation
+     */
+    public synchronized void setEvictionPolicyClassName(final String evictionPolicyClassName) {
+        if (connectionPool != null) {
+            connectionPool.setEvictionPolicyClassName(evictionPolicyClassName);
+        }
+        this.evictionPolicyClassName = evictionPolicyClassName;
+    }
+
+
+    /**
+     * @see #getFastFailValidation()
+     * @param fastFailValidation true means connections created by this factory
+     *            will fast fail validation
+     * @since 2.1
+     */
+    public void setFastFailValidation(final boolean fastFailValidation) {
+        this.fastFailValidation = fastFailValidation;
+    }
+
+
+    /**
+     * <p>
+     * Sets the initial size of the connection pool.
+     * </p>
+     * <p>
+     * Note: this method currently has no effect once the pool has been
+     * initialized. The pool is initialized the first time one of the following
+     * methods is invoked: <code>getConnection, setLogwriter,
+     * setLoginTimeout, getLoginTimeout, getLogWriter.</code>
+     * </p>
+     *
+     * @param initialSize the number of connections created when the pool is
+     *            initialized
+     */
+    public synchronized void setInitialSize(final int initialSize) {
+        this.initialSize = initialSize;
+    }
+
+
+    /**
+     * Sets the JMX name that has been requested for this DataSource. If the
+     * requested name is not valid, an alternative may be chosen. This
+     * DataSource will attempt to register itself using this name. If another
+     * component registers this DataSource with JMX and this name is valid this
+     * name will be used in preference to any specified by the other component.
+     *
+     * @param jmxName The JMX name that has been requested for this DataSource
+     */
+    public void setJmxName(final String jmxName) {
+        this.jmxName = jmxName;
+    }
+
+
+    /**
+     * Sets the LIFO property. True means the pool behaves as a LIFO queue;
+     * false means FIFO.
+     *
+     * @param lifo the new value for the LIFO property
+     */
+    public synchronized void setLifo(final boolean lifo) {
+        this.lifo = lifo;
+        if (connectionPool != null) {
+            connectionPool.setLifo(lifo);
+        }
+    }
+
+
+    /**
+     * @param logAbandoned new logAbandoned property value
+     */
+    public void setLogAbandoned(final boolean logAbandoned) {
+        if (abandonedConfig == null) {
+            abandonedConfig = new AbandonedConfig();
+        }
+        abandonedConfig.setLogAbandoned(logAbandoned);
+        final GenericObjectPool<?> gop = this.connectionPool;
+        if (gop != null) {
+            gop.setAbandonedConfig(abandonedConfig);
+        }
+    }
+
+
+    /**
+     * When {@link #getMaxConnLifetimeMillis()} is set to limit connection
+     * lifetime, this property determines whether or not log messages are
+     * generated when the pool closes connections due to maximum lifetime
+     * exceeded. Set this property to false to suppress log messages when
+     * connections expire.
+     *
+     * @param logExpiredConnections Whether or not log messages are generated
+     *            when the pool closes connections due to maximum lifetime
+     *            exceeded.
+     */
+    public void setLogExpiredConnections(final boolean logExpiredConnections) {
+        this.logExpiredConnections = logExpiredConnections;
+    }
+
+
+    /**
+     * <strong>BasicDataSource does NOT support this method. </strong>
+     *
+     * <p>
+     * Set the login timeout (in seconds) for connecting to the database.
+     * </p>
+     * <p>
+     * Calls {@link #createDataSource()}, so has the side effect of initializing
+     * the connection pool.
+     * </p>
+     *
+     * @param loginTimeout The new login timeout, or zero for no timeout
+     * @throws UnsupportedOperationException If the DataSource implementation
+     *             does not support the login timeout feature.
+     * @throws SQLException if a database access error occurs
+     */
+    @Override
+    public void setLoginTimeout(final int loginTimeout) throws SQLException {
+        // This method isn't supported by the PoolingDataSource returned by the
+        // createDataSource
+        throw new UnsupportedOperationException("Not supported by BasicDataSource");
+    }
+
+
+    /**
+     * <p>
+     * Sets the log writer being used by this data source.
+     * </p>
+     * <p>
+     * Calls {@link #createDataSource()}, so has the side effect of initializing
+     * the connection pool.
+     * </p>
+     *
+     * @param logWriter The new log writer
+     * @throws SQLException if a database access error occurs
+     */
+    @Override
+    public void setLogWriter(final PrintWriter logWriter) throws SQLException {
+        createDataSource().setLogWriter(logWriter);
+        this.logWriter = logWriter;
+    }
+
+
+    /**
+     * <p>
+     * Sets the maximum permitted lifetime of a connection in milliseconds. A
+     * value of zero or less indicates an infinite lifetime.
+     * </p>
+     * <p>
+     * Note: this method currently has no effect once the pool has been
+     * initialized. The pool is initialized the first time one of the following
+     * methods is invoked: <code>getConnection, setLogwriter,
+     * setLoginTimeout, getLoginTimeout, getLogWriter.</code>
+     * </p>
+     *
+     * @param maxConnLifetimeMillis The maximum permitted lifetime of a
+     *            connection in milliseconds.
+     */
+    public void setMaxConnLifetimeMillis(final long maxConnLifetimeMillis) {
+        this.maxConnLifetimeMillis = maxConnLifetimeMillis;
+    }
+
+
+    /**
+     * Sets the maximum number of connections that can remain idle in the pool.
+     * Excess idle connections are destroyed on return to the pool.
+     *
+     * @see #getMaxIdle()
+     * @param maxIdle the new value for maxIdle
+     */
+    public synchronized void setMaxIdle(final int maxIdle) {
+        this.maxIdle = maxIdle;
+        if (connectionPool != null) {
+            connectionPool.setMaxIdle(maxIdle);
+        }
+    }
+
+
+    /**
+     * <p>
+     * Sets the value of the <code>maxOpenPreparedStatements</code> property.
+     * </p>
+     * <p>
+     * Note: this method currently has no effect once the pool has been
+     * initialized. The pool is initialized the first time one of the following
+     * methods is invoked: <code>getConnection, setLogwriter,
+     * setLoginTimeout, getLoginTimeout, getLogWriter.</code>
+     * </p>
+     *
+     * @param maxOpenStatements the new maximum number of prepared statements
+     */
+    public synchronized void setMaxOpenPreparedStatements(final int maxOpenStatements) {
+        this.maxOpenPreparedStatements = maxOpenStatements;
+    }
+
+
+    /**
+     * Sets the maximum total number of idle and borrows connections that can be
+     * active at the same time. Use a negative value for no limit.
+     *
+     * @param maxTotal the new value for maxTotal
+     * @see #getMaxTotal()
+     */
+    public synchronized void setMaxTotal(final int maxTotal) {
+        this.maxTotal = maxTotal;
+        if (connectionPool != null) {
+            connectionPool.setMaxTotal(maxTotal);
+        }
+    }
+
+
+    /**
+     * Sets the MaxWaitMillis property. Use -1 to make the pool wait
+     * indefinitely.
+     *
+     * @param maxWaitMillis the new value for MaxWaitMillis
+     * @see #getMaxWaitMillis()
+     */
+    public synchronized void setMaxWaitMillis(final long maxWaitMillis) {
+        this.maxWaitMillis = maxWaitMillis;
+        if (connectionPool != null) {
+            connectionPool.setMaxWaitMillis(maxWaitMillis);
+        }
+    }
+
+
+    /**
+     * Sets the {@link #minEvictableIdleTimeMillis} property.
+     *
+     * @param minEvictableIdleTimeMillis the minimum amount of time an object
+     *            may sit idle in the pool
+     * @see #minEvictableIdleTimeMillis
+     */
+    public synchronized void setMinEvictableIdleTimeMillis(final long minEvictableIdleTimeMillis) {
+        this.minEvictableIdleTimeMillis = minEvictableIdleTimeMillis;
+        if (connectionPool != null) {
+            connectionPool.setMinEvictableIdleTimeMillis(minEvictableIdleTimeMillis);
+        }
+    }
+
+
+    /**
+     * Sets the minimum number of idle connections in the pool. The pool
+     * attempts to ensure that minIdle connections are available when the idle
+     * object evictor runs. The value of this property has no effect unless
+     * {@link #timeBetweenEvictionRunsMillis} has a positive value.
+     *
+     * @param minIdle the new value for minIdle
+     * @see GenericObjectPool#setMinIdle(int)
+     */
+    public synchronized void setMinIdle(final int minIdle) {
+        this.minIdle = minIdle;
+        if (connectionPool != null) {
+            connectionPool.setMinIdle(minIdle);
+        }
+    }
+
+
+    /**
+     * Sets the value of the {@link #numTestsPerEvictionRun} property.
+     *
+     * @param numTestsPerEvictionRun the new {@link #numTestsPerEvictionRun}
+     *            value
+     * @see #numTestsPerEvictionRun
+     */
+    public synchronized void setNumTestsPerEvictionRun(final int numTestsPerEvictionRun) {
+        this.numTestsPerEvictionRun = numTestsPerEvictionRun;
+        if (connectionPool != null) {
+            connectionPool.setNumTestsPerEvictionRun(numTestsPerEvictionRun);
+        }
+    }
+
+
+    // ------------------------------------------------------ Protected Methods
+
+    /**
+     * <p>
+     * Sets the {@link #password}.
+     * </p>
+     * <p>
+     * Note: this method currently has no effect once the pool has been
+     * initialized. The pool is initialized the first time one of the following
+     * methods is invoked: <code>getConnection, setLogwriter,
+     * setLoginTimeout, getLoginTimeout, getLogWriter.</code>
+     * </p>
+     *
+     * @param password new value for the password
+     */
+    public void setPassword(final String password) {
+        this.password = password;
+    }
+
+
+    /**
+     * <p>
+     * Sets whether to pool statements or not.
+     * </p>
+     * <p>
+     * Note: this method currently has no effect once the pool has been
+     * initialized. The pool is initialized the first time one of the following
+     * methods is invoked: <code>getConnection, setLogwriter,
+     * setLoginTimeout, getLoginTimeout, getLogWriter.</code>
+     * </p>
+     *
+     * @param poolingStatements pooling on or off
+     */
+    public synchronized void setPoolPreparedStatements(final boolean poolingStatements) {
+        this.poolPreparedStatements = poolingStatements;
+    }
+
+
+    /**
+     * @param removeAbandonedOnBorrow true means abandoned connections may be
+     *            removed when connections are borrowed from the pool.
+     * @see #getRemoveAbandonedOnBorrow()
+     */
+    public void setRemoveAbandonedOnBorrow(final boolean removeAbandonedOnBorrow) {
+        if (abandonedConfig == null) {
+            abandonedConfig = new AbandonedConfig();
+        }
+        abandonedConfig.setRemoveAbandonedOnBorrow(removeAbandonedOnBorrow);
+        final GenericObjectPool<?> gop = this.connectionPool;
+        if (gop != null) {
+            gop.setAbandonedConfig(abandonedConfig);
+        }
+    }
+
+
+    /**
+     * @param removeAbandonedOnMaintenance true means abandoned connections may
+     *            be removed on pool maintenance.
+     * @see #getRemoveAbandonedOnMaintenance()
+     */
+    public void setRemoveAbandonedOnMaintenance(final boolean removeAbandonedOnMaintenance) {
+        if (abandonedConfig == null) {
+            abandonedConfig = new AbandonedConfig();
+        }
+        abandonedConfig.setRemoveAbandonedOnMaintenance(removeAbandonedOnMaintenance);
+        final GenericObjectPool<?> gop = this.connectionPool;
+        if (gop != null) {
+            gop.setAbandonedConfig(abandonedConfig);
+        }
+    }
+
+
+    /**
+     * <p>
+     * Sets the timeout in seconds before an abandoned connection can be
+     * removed.
+     * </p>
+     *
+     * <p>
+     * Setting this property has no effect if
+     * {@link #getRemoveAbandonedOnBorrow()} and
+     * {@link #getRemoveAbandonedOnMaintenance()} are false.
+     * </p>
+     *
+     * @param removeAbandonedTimeout new abandoned timeout in seconds
+     * @see #getRemoveAbandonedTimeout()
+     * @see #getRemoveAbandonedOnBorrow()
+     * @see #getRemoveAbandonedOnMaintenance()
+     */
+    public void setRemoveAbandonedTimeout(final int removeAbandonedTimeout) {
+        if (abandonedConfig == null) {
+            abandonedConfig = new AbandonedConfig();
+        }
+        abandonedConfig.setRemoveAbandonedTimeout(removeAbandonedTimeout);
+        final GenericObjectPool<?> gop = this.connectionPool;
+        if (gop != null) {
+            gop.setAbandonedConfig(abandonedConfig);
+        }
+    }
+
+
+    /**
+     * Sets the flag that controls if a connection will be rolled back when it
+     * is returned to the pool if auto commit is not enabled and the connection
+     * is not read only.
+     *
+     * @param rollbackOnReturn whether a connection will be rolled back when it
+     *            is returned to the pool.
+     */
+    public void setRollbackOnReturn(final boolean rollbackOnReturn) {
+        this.rollbackOnReturn = rollbackOnReturn;
+    }
+
+
+    /**
+     * Sets the minimum amount of time a connection may sit idle in the pool
+     * before it is eligible for eviction by the idle object evictor, with the
+     * extra condition that at least "minIdle" connections remain in the pool.
+     *
+     * @param softMinEvictableIdleTimeMillis minimum amount of time a connection
+     *            may sit idle in the pool before it is eligible for eviction,
+     *            assuming there are minIdle idle connections in the pool.
+     * @see #getSoftMinEvictableIdleTimeMillis
+     */
+    public synchronized void setSoftMinEvictableIdleTimeMillis(
+            final long softMinEvictableIdleTimeMillis) {
+        this.softMinEvictableIdleTimeMillis = softMinEvictableIdleTimeMillis;
+        if (connectionPool != null) {
+            connectionPool.setSoftMinEvictableIdleTimeMillis(softMinEvictableIdleTimeMillis);
+        }
+    }
+
+
+    /**
+     * Sets the {@link #testOnBorrow} property. This property determines whether
+     * or not the pool will validate objects before they are borrowed from the
+     * pool.
+     *
+     * @param testOnBorrow new value for testOnBorrow property
+     */
+    public synchronized void setTestOnBorrow(final boolean testOnBorrow) {
+        this.testOnBorrow = testOnBorrow;
+        if (connectionPool != null) {
+            connectionPool.setTestOnBorrow(testOnBorrow);
+        }
+    }
+
+
+    /**
+     * Sets the {@link #testOnCreate} property. This property determines whether
+     * or not the pool will validate objects immediately after they are created
+     * by the pool
+     *
+     * @param testOnCreate new value for testOnCreate property
+     */
+    public synchronized void setTestOnCreate(final boolean testOnCreate) {
+        this.testOnCreate = testOnCreate;
+        if (connectionPool != null) {
+            connectionPool.setTestOnCreate(testOnCreate);
+        }
+    }
+
+
+    /**
+     * Sets the <code>testOnReturn</code> property. This property determines
+     * whether or not the pool will validate objects before they are returned to
+     * the pool.
+     *
+     * @param testOnReturn new value for testOnReturn property
+     */
+    public synchronized void setTestOnReturn(final boolean testOnReturn) {
+        this.testOnReturn = testOnReturn;
+        if (connectionPool != null) {
+            connectionPool.setTestOnReturn(testOnReturn);
+        }
+    }
+
+
+    /**
+     * Sets the <code>testWhileIdle</code> property. This property determines
+     * whether or not the idle object evictor will validate connections.
+     *
+     * @param testWhileIdle new value for testWhileIdle property
+     */
+    public synchronized void setTestWhileIdle(final boolean testWhileIdle) {
+        this.testWhileIdle = testWhileIdle;
+        if (connectionPool != null) {
+            connectionPool.setTestWhileIdle(testWhileIdle);
+        }
+    }
+
+
+    /**
+     * Sets the {@link #timeBetweenEvictionRunsMillis} property.
+     *
+     * @param timeBetweenEvictionRunsMillis the new time between evictor runs
+     * @see #timeBetweenEvictionRunsMillis
+     */
+    public synchronized void setTimeBetweenEvictionRunsMillis(
+            final long timeBetweenEvictionRunsMillis) {
+        this.timeBetweenEvictionRunsMillis = timeBetweenEvictionRunsMillis;
+        if (connectionPool != null) {
+            connectionPool.setTimeBetweenEvictionRunsMillis(timeBetweenEvictionRunsMillis);
+        }
+    }
+
+
+    /**
+     * <p>
+     * Sets the {@link #url}.
+     * </p>
+     * <p>
+     * Note: this method currently has no effect once the pool has been
+     * initialized. The pool is initialized the first time one of the following
+     * methods is invoked: <code>getConnection, setLogwriter,
+     * setLoginTimeout, getLoginTimeout, getLogWriter.</code>
+     * </p>
+     *
+     * @param url the new value for the JDBC connection url
+     */
+    public synchronized void setUrl(final String url) {
+        this.url = url;
+    }
+
+
+    /**
+     * <p>
+     * Sets the {@link #userName}.
+     * </p>
+     * <p>
+     * Note: this method currently has no effect once the pool has been
+     * initialized. The pool is initialized the first time one of the following
+     * methods is invoked: <code>getConnection, setLogwriter,
+     * setLoginTimeout, getLoginTimeout, getLogWriter.</code>
+     * </p>
+     *
+     * @param userName the new value for the JDBC connection user name
+     */
+    public void setUsername(final String userName) {
+        this.userName = userName;
+    }
+
+
+    /**
+     * <p>
+     * Sets the {@link #validationQuery}.
+     * </p>
+     * <p>
+     * Note: this method currently has no effect once the pool has been
+     * initialized. The pool is initialized the first time one of the following
+     * methods is invoked: <code>getConnection, setLogwriter,
+     * setLoginTimeout, getLoginTimeout, getLogWriter.</code>
+     * </p>
+     *
+     * @param validationQuery the new value for the validation query
+     */
+    public void setValidationQuery(final String validationQuery) {
+        if (isEmpty(validationQuery)) {
+            this.validationQuery = null;
+        } else {
+            this.validationQuery = validationQuery;
+        }
+    }
+
+
+    /**
+     * Sets the validation query timeout, the amount of time, in seconds, that
+     * connection validation will wait for a response from the database when
+     * executing a validation query. Use a value less than or equal to 0 for no
+     * timeout.
+     * <p>
+     * Note: this method currently has no effect once the pool has been
+     * initialized. The pool is initialized the first time one of the following
+     * methods is invoked: <code>getConnection, setLogwriter,
+     * setLoginTimeout, getLoginTimeout, getLogWriter.</code>
+     * </p>
+     *
+     * @param validationQueryTimeoutSeconds new validation query timeout value
+     *            in seconds
+     */
+    public void setValidationQueryTimeout(final int validationQueryTimeoutSeconds) {
+        this.validationQueryTimeoutSeconds = validationQueryTimeoutSeconds;
+    }
+
+
+    /**
+     * Starts the connection pool maintenance task, if configured.
+     */
+    protected void startPoolMaintenance() {
+        if (connectionPool != null && timeBetweenEvictionRunsMillis > 0) {
+            connectionPool.setTimeBetweenEvictionRunsMillis(timeBetweenEvictionRunsMillis);
+        }
+    }
+
+
+    @Override
+    public <T> T unwrap(final Class<T> iface) throws SQLException {
+        throw new SQLException("BasicDataSource is not a wrapper.");
+    }
+
+
+    private void updateJmxName(final GenericObjectPoolConfig<?> config) {
+        if (registeredJmxObjectName == null) {
+            return;
+        }
+        final StringBuilder base = new StringBuilder(registeredJmxObjectName.toString());
+        base.append(Constants.JMX_CONNECTION_POOL_BASE_EXT);
+        config.setJmxNameBase(base.toString());
+        config.setJmxNamePrefix(Constants.JMX_CONNECTION_POOL_PREFIX);
+    }
+
+
+    private ConnectionFactory createConnectionFactory(final Driver driver) throws SQLException {
+        if (connectionFactoryClassName != null) {
+            try {
+                Class<?> connectionFactoryFromCCL = Class.forName(connectionFactoryClassName);
+                return (ConnectionFactory) connectionFactoryFromCCL
+                        .getConstructor(Driver.class, String.class, Properties.class)
+                        .newInstance(driver, url, connectionProperties);
+            } catch (final Exception t) {
+                final String message = "Cannot load ConnectionFactory implementation '" +
+                        connectionFactoryClassName + "'";
+                logWriter.println(message);
+                t.printStackTrace(logWriter);
+                throw new SQLException(message, t);
+            }
+        }
+        return new DriverConnectionFactory(driver, url, connectionProperties);
+    }
+
+}
diff --git a/src/main/java/org/apache/commons/dbcp2/managed/ManagedDataSource.java b/src/main/java/org/apache/commons/dbcp2/managed/ManagedDataSource.java
index 0220e52..791e384 100644
--- a/src/main/java/org/apache/commons/dbcp2/managed/ManagedDataSource.java
+++ b/src/main/java/org/apache/commons/dbcp2/managed/ManagedDataSource.java
@@ -1,93 +1,93 @@
-/**
- *
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-package org.apache.commons.dbcp2.managed;
-
-import org.apache.commons.pool2.ObjectPool;
-import org.apache.commons.dbcp2.PoolingDataSource;
-
-import java.sql.Connection;
-import java.sql.SQLException;
-import java.util.Objects;
-
-/**
- * The ManagedDataSource is a PoolingDataSource that creates ManagedConnections.
- *
- * @param <C>
- *            The kind of {@link Connection} to manage.
- * @since 2.0
- */
-public class ManagedDataSource<C extends Connection> extends PoolingDataSource<C> {
-    private TransactionRegistry transactionRegistry;
-
-    /**
-     * Creates a ManagedDataSource which obtains connections from the specified pool and manages them using the
-     * specified transaction registry. The TransactionRegistry must be the transaction registry obtained from the
-     * XAConnectionFactory used to create the connection pool. If not, an error will occur when attempting to use the
-     * connection in a global transaction because the XAResource object associated with the connection will be
-     * unavailable.
-     *
-     * @param pool
-     *            the connection pool
-     * @param transactionRegistry
-     *            the transaction registry obtained from the XAConnectionFactory used to create the connection pool
-     *            object factory
-     */
-    public ManagedDataSource(final ObjectPool<C> pool, final TransactionRegistry transactionRegistry) {
-        super(pool);
-        this.transactionRegistry = transactionRegistry;
-    }
-
-    @Override
-    public Connection getConnection() throws SQLException {
-        if (getPool() == null) {
-            throw new IllegalStateException("Pool has not been set");
-        }
-        if (transactionRegistry == null) {
-            throw new IllegalStateException("TransactionRegistry has not been set");
-        }
-
-        return new ManagedConnection<>(getPool(), transactionRegistry, isAccessToUnderlyingConnectionAllowed());
-    }
-
-    /**
-     * Gets the transaction registry.
-     * 
-     * @return The transaction registry.
-     * @see #setTransactionRegistry(TransactionRegistry)
-     * @since 2.6.0
-     */
-    public TransactionRegistry getTransactionRegistry() {
-        return transactionRegistry;
-    }
-
-    /**
-     * Sets the transaction registry from the XAConnectionFactory used to create the pool. The transaction registry can
-     * only be set once using either a connector or this setter method.
-     *
-     * @param transactionRegistry
-     *            the transaction registry acquired from the XAConnectionFactory used to create the pool
-     */
-    public void setTransactionRegistry(final TransactionRegistry transactionRegistry) {
-        if (this.transactionRegistry != null) {
-            throw new IllegalStateException("TransactionRegistry already set");
-        }
-        Objects.requireNonNull(transactionRegistry, "transactionRegistry is null");
-
-        this.transactionRegistry = transactionRegistry;
-    }
-}
+/**
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+package org.apache.commons.dbcp2.managed;
+
+import org.apache.commons.pool2.ObjectPool;
+import org.apache.commons.dbcp2.PoolingDataSource;
+
+import java.sql.Connection;
+import java.sql.SQLException;
+import java.util.Objects;
+
+/**
+ * The ManagedDataSource is a PoolingDataSource that creates ManagedConnections.
+ *
+ * @param <C>
+ *            The kind of {@link Connection} to manage.
+ * @since 2.0
+ */
+public class ManagedDataSource<C extends Connection> extends PoolingDataSource<C> {
+    private TransactionRegistry transactionRegistry;
+
+    /**
+     * Creates a ManagedDataSource which obtains connections from the specified pool and manages them using the
+     * specified transaction registry. The TransactionRegistry must be the transaction registry obtained from the
+     * XAConnectionFactory used to create the connection pool. If not, an error will occur when attempting to use the
+     * connection in a global transaction because the XAResource object associated with the connection will be
+     * unavailable.
+     *
+     * @param pool
+     *            the connection pool
+     * @param transactionRegistry
+     *            the transaction registry obtained from the XAConnectionFactory used to create the connection pool
+     *            object factory
+     */
+    public ManagedDataSource(final ObjectPool<C> pool, final TransactionRegistry transactionRegistry) {
+        super(pool);
+        this.transactionRegistry = transactionRegistry;
+    }
+
+    @Override
+    public Connection getConnection() throws SQLException {
+        if (getPool() == null) {
+            throw new IllegalStateException("Pool has not been set");
+        }
+        if (transactionRegistry == null) {
+            throw new IllegalStateException("TransactionRegistry has not been set");
+        }
+
+        return new ManagedConnection<>(getPool(), transactionRegistry, isAccessToUnderlyingConnectionAllowed());
+    }
+
+    /**
+     * Gets the transaction registry.
+     * 
+     * @return The transaction registry.
+     * @see #setTransactionRegistry(TransactionRegistry)
+     * @since 2.6.0
+     */
+    public TransactionRegistry getTransactionRegistry() {
+        return transactionRegistry;
+    }
+
+    /**
+     * Sets the transaction registry from the XAConnectionFactory used to create the pool. The transaction registry can
+     * only be set once using either a connector or this setter method.
+     *
+     * @param transactionRegistry
+     *            the transaction registry acquired from the XAConnectionFactory used to create the pool
+     */
+    public void setTransactionRegistry(final TransactionRegistry transactionRegistry) {
+        if (this.transactionRegistry != null) {
+            throw new IllegalStateException("TransactionRegistry already set");
+        }
+        Objects.requireNonNull(transactionRegistry, "transactionRegistry is null");
+
+        this.transactionRegistry = transactionRegistry;
+    }
+}
diff --git a/src/site/site.xml b/src/site/site.xml
index d5dc330..23236e6 100644
--- a/src/site/site.xml
+++ b/src/site/site.xml
@@ -1,60 +1,60 @@
-<?xml version="1.0" encoding="ISO-8859-1"?>
- <!--
-   Licensed to the Apache Software Foundation (ASF) under one or more
-  contributor license agreements.  See the NOTICE file distributed with
-  this work for additional information regarding copyright ownership.
-  The ASF licenses this file to You under the Apache License, Version 2.0
-  (the "License"); you may not use this file except in compliance with
-  the License.  You may obtain a copy of the License at
-
-       http://www.apache.org/licenses/LICENSE-2.0
-
-   Unless required by applicable law or agreed to in writing, software
-   distributed under the License is distributed on an "AS IS" BASIS,
-   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-   See the License for the specific language governing permissions and
-   limitations under the License.
-  -->
-<!DOCTYPE org.apache.commons.menus SYSTEM 'https://commons.apache.org/build/maven-build.dtd'>
-<project name="DBCP">
-  <bannerRight>
-    <name>Commons DBCP</name>
-    <src>/images/dbcp-logo-white.png</src>
-    <href>/index.html</href>
-  </bannerRight>
-    <body>
-      <menu name="Commons&#xA0;DBCP">
-        <item name="Overview"               href="/index.html" />
-        <item name="Configuration"          href="/configuration.html" />
-        <item name="Javadoc&#xA0;1.2.2"     href="/api-1.2.2/index.html"/>
-        <item name="Javadoc&#xA0;1.3"       href="/api-1.3/index.html"/>
-        <item name="Javadoc&#xA0;1.4"       href="/api-1.4/index.html"/>
-        <item name="Javadoc&#xA0;2.0.1"     href="/api-2.0.1/index.html"/>
-        <item name="Javadoc&#xA0;2.1"       href="/api-2.1/index.html"/>
-        <item name="Javadoc&#xA0;2.1.1"     href="/api-2.1.1/index.html"/>
-        <item name="Javadoc&#xA0;2.2.0"     href="/api-2.2.0/index.html"/>
-        <item name="Javadoc&#xA0;2.3.0"     href="/api-2.3.0/index.html"/>
-        <item name="Javadoc&#xA0;2.4.0"     href="/api-2.4.0/index.html"/>
-        <item name="Javadoc&#xA0;2.5.0"     href="/api-2.5.0/index.html"/>
-        <item name="Javadoc&#xA0;2.6.0"     href="/api-2.6.0/index.html"/>
-        <item name="Developers&#xA0;Guide"  href="/guide/index.html" collapse="true">
-        <item name="JNDI&#xA0;Howto"        href="/guide/jndi-howto.html"/>
-        <item name="Class&#xA0;Diagrams"    href="/guide/classdiagrams.html"/>
-        <item name="Sequence&#xA0;Diagrams" href="/guide/sequencediagrams.html"/>
-        </item>
-        <item name="Examples"               href="https://git-wip-us.apache.org/repos/asf?p=commons-dbcp.git;a=tree;f=doc;hb=HEAD"/>
-        <item name="Downloads"              href="/download_dbcp.cgi"/>
-        <item name="Wiki"                   href="http://wiki.apache.org/commons/DBCP"/>
-      </menu>
-  
-      <menu name="Development">
-        <item name="History"                href="/changes-report.html"/>
-        <item name="Building"               href="/building.html"/>
-        <item name="Mailing&#xA0;Lists"     href="/mail-lists.html"/>
-        <item name="Issue&#xA0;Tracking"    href="/issue-tracking.html"/>
-        <item name="Team"                   href="/team-list.html"/>
-        <item name="Source&#xA0;Repository" href="/source-repository.html"/>
-      </menu>
-
-    </body>
-</project>
+<?xml version="1.0" encoding="ISO-8859-1"?>
+ <!--
+   Licensed to the Apache Software Foundation (ASF) under one or more
+  contributor license agreements.  See the NOTICE file distributed with
+  this work for additional information regarding copyright ownership.
+  The ASF licenses this file to You under the Apache License, Version 2.0
+  (the "License"); you may not use this file except in compliance with
+  the License.  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+  -->
+<!DOCTYPE org.apache.commons.menus SYSTEM 'https://commons.apache.org/build/maven-build.dtd'>
+<project name="DBCP">
+  <bannerRight>
+    <name>Commons DBCP</name>
+    <src>/images/dbcp-logo-white.png</src>
+    <href>/index.html</href>
+  </bannerRight>
+    <body>
+      <menu name="Commons&#xA0;DBCP">
+        <item name="Overview"               href="/index.html" />
+        <item name="Configuration"          href="/configuration.html" />
+        <item name="Javadoc&#xA0;1.2.2"     href="/api-1.2.2/index.html"/>
+        <item name="Javadoc&#xA0;1.3"       href="/api-1.3/index.html"/>
+        <item name="Javadoc&#xA0;1.4"       href="/api-1.4/index.html"/>
+        <item name="Javadoc&#xA0;2.0.1"     href="/api-2.0.1/index.html"/>
+        <item name="Javadoc&#xA0;2.1"       href="/api-2.1/index.html"/>
+        <item name="Javadoc&#xA0;2.1.1"     href="/api-2.1.1/index.html"/>
+        <item name="Javadoc&#xA0;2.2.0"     href="/api-2.2.0/index.html"/>
+        <item name="Javadoc&#xA0;2.3.0"     href="/api-2.3.0/index.html"/>
+        <item name="Javadoc&#xA0;2.4.0"     href="/api-2.4.0/index.html"/>
+        <item name="Javadoc&#xA0;2.5.0"     href="/api-2.5.0/index.html"/>
+        <item name="Javadoc&#xA0;2.6.0"     href="/api-2.6.0/index.html"/>
+        <item name="Developers&#xA0;Guide"  href="/guide/index.html" collapse="true">
+        <item name="JNDI&#xA0;Howto"        href="/guide/jndi-howto.html"/>
+        <item name="Class&#xA0;Diagrams"    href="/guide/classdiagrams.html"/>
+        <item name="Sequence&#xA0;Diagrams" href="/guide/sequencediagrams.html"/>
+        </item>
+        <item name="Examples"               href="https://git-wip-us.apache.org/repos/asf?p=commons-dbcp.git;a=tree;f=doc;hb=HEAD"/>
+        <item name="Downloads"              href="/download_dbcp.cgi"/>
+        <item name="Wiki"                   href="http://wiki.apache.org/commons/DBCP"/>
+      </menu>
+  
+      <menu name="Development">
+        <item name="History"                href="/changes-report.html"/>
+        <item name="Building"               href="/building.html"/>
+        <item name="Mailing&#xA0;Lists"     href="/mail-lists.html"/>
+        <item name="Issue&#xA0;Tracking"    href="/issue-tracking.html"/>
+        <item name="Team"                   href="/team-list.html"/>
+        <item name="Source&#xA0;Repository" href="/source-repository.html"/>
+      </menu>
+
+    </body>
+</project>
diff --git a/src/site/xdoc/download_dbcp.xml b/src/site/xdoc/download_dbcp.xml
index 6855b74..d356a46 100644
--- a/src/site/xdoc/download_dbcp.xml
+++ b/src/site/xdoc/download_dbcp.xml
@@ -1,246 +1,246 @@
-<?xml version="1.0"?>
-<!--
-Licensed to the Apache Software Foundation (ASF) under one or more
-contributor license agreements.  See the NOTICE file distributed with
-this work for additional information regarding copyright ownership.
-The ASF licenses this file to You under the Apache License, Version 2.0
-(the "License"); you may not use this file except in compliance with
-the License.  You may obtain a copy of the License at
-
-     http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
--->
-<!--
- +======================================================================+
- |****                                                              ****|
- |****      THIS FILE IS GENERATED BY THE COMMONS BUILD PLUGIN      ****|
- |****                    DO NOT EDIT DIRECTLY                      ****|
- |****                                                              ****|
- +======================================================================+
- | TEMPLATE FILE: download-page-template.xml                            |
- | commons-build-plugin/trunk/src/main/resources/commons-xdoc-templates |
- +======================================================================+
- |                                                                      |
- | 1) Re-generate using: mvn commons-build:download-page                |
- |                                                                      |
- | 2) Set the following properties in the component's pom:              |
- |    - commons.componentid     (required, alphabetic, lower case)      |
- |    - commons.release.version (required)                              |
- |    - commons.release.name    (required)                              |
- |    - commons.binary.suffix   (optional)                              |
- |      (defaults to "-bin", set to "" for pre-maven2 releases)         |
- |    - commons.release.desc    (optional)                              |
- |    - commons.release.subdir  (optional)                              |
- |    - commons.release.hash    (optional, lowercase, default sha256)   |
- |                                                                      |
- |    - commons.release.[234].version       (conditional)               |
- |    - commons.release.[234].name          (conditional)               |
- |    - commons.release.[234].binary.suffix (optional)                  |
- |    - commons.release.[234].desc          (optional)                  |
- |    - commons.release.[234].subdir        (optional)                  |
- |    - commons.release.[234].hash       (optional, lowercase, [sha256])|
- |                                                                      |
- | 3) Example Properties                                                |
- |    (commons.release.name inherited by parent:                        |
- |     ${project.artifactId}-${commons.release.version}                 |
- |                                                                      |
- |  <properties>                                                        |
- |    <commons.componentid>math</commons.componentid>                   |
- |    <commons.release.version>1.2</commons.release.version>            |
- |  </properties>                                                       |
- |                                                                      |
- +======================================================================+
--->
-<document>
-  <properties>
-    <title>Download Apache Commons DBCP</title>
-    <author email="dev@commons.apache.org">Apache Commons Documentation Team</author>
-  </properties>
-  <body>
-    <section name="Download Apache Commons DBCP">
-    <subsection name="Using a Mirror">
-      <p>
-        We recommend you use a mirror to download our release
-        builds, but you <strong>must</strong> <a href="http://www.apache.org/info/verification.html">verify the integrity</a> of
-        the downloaded files using signatures downloaded from our main
-        distribution directories. Recent releases (48 hours) may not yet
-        be available from all the mirrors.
-      </p>
-
-      <p>
-        You are currently using <b>[preferred]</b>.  If you
-        encounter a problem with this mirror, please select another
-        mirror.  If all mirrors are failing, there are <i>backup</i>
-        mirrors (at the end of the mirrors list) that should be
-        available.
-        <br></br>
-        [if-any logo]<a href="[link]"><img align="right" src="[logo]" border="0"></img></a>[end]
-      </p>
-
-      <form action="[location]" method="get" id="SelectMirror">
-        <p>
-          Other mirrors:
-          <select name="Preferred">
-          [if-any http]
-            [for http]<option value="[http]">[http]</option>[end]
-          [end]
-          [if-any ftp]
-            [for ftp]<option value="[ftp]">[ftp]</option>[end]
-          [end]
-          [if-any backup]
-            [for backup]<option value="[backup]">[backup] (backup)</option>[end]
-          [end]
-          </select>
-          <input type="submit" value="Change"></input>
-        </p>
-      </form>
-
-      <p>
-        It is essential that you
-        <a href="https://www.apache.org/info/verification.html">verify the integrity</a>
-        of downloaded files, preferably using the <code>PGP</code> signature (<code>*.asc</code> files);
-        failing that using the <code>SHA256</code> hash (<code>*.sha256</code> checksum files).
-      </p>
-      <p>
-        The <a href="https://www.apache.org/dist/commons/KEYS">KEYS</a>
-        file contains the public PGP keys used by Apache Commons developers
-        to sign releases.
-      </p>
-    </subsection>
-    </section>
-    <section name="Apache Commons DBCP 2.6.0 for JDBC 4.2 on Java 8">
-      <subsection name="Binaries">
-        <table>
-          <tr>
-              <td><a href="[preferred]/commons/dbcp/binaries/commons-dbcp2-2.6.0-bin.tar.gz">commons-dbcp2-2.6.0-bin.tar.gz</a></td>
-              <td><a href="https://www.apache.org/dist/commons/dbcp/binaries/commons-dbcp2-2.6.0-bin.tar.gz.sha256">sha256</a></td>
-              <td><a href="https://www.apache.org/dist/commons/dbcp/binaries/commons-dbcp2-2.6.0-bin.tar.gz.asc">pgp</a></td>
-          </tr>
-          <tr>
-              <td><a href="[preferred]/commons/dbcp/binaries/commons-dbcp2-2.6.0-bin.zip">commons-dbcp2-2.6.0-bin.zip</a></td>
-              <td><a href="https://www.apache.org/dist/commons/dbcp/binaries/commons-dbcp2-2.6.0-bin.zip.sha256">sha256</a></td>
-              <td><a href="https://www.apache.org/dist/commons/dbcp/binaries/commons-dbcp2-2.6.0-bin.zip.asc">pgp</a></td>
-          </tr>
-        </table>
-      </subsection>
-      <subsection name="Source">
-        <table>
-          <tr>
-              <td><a href="[preferred]/commons/dbcp/source/commons-dbcp2-2.6.0-src.tar.gz">commons-dbcp2-2.6.0-src.tar.gz</a></td>
-              <td><a href="https://www.apache.org/dist/commons/dbcp/source/commons-dbcp2-2.6.0-src.tar.gz.sha256">sha256</a></td>
-              <td><a href="https://www.apache.org/dist/commons/dbcp/source/commons-dbcp2-2.6.0-src.tar.gz.asc">pgp</a></td>
-          </tr>
-          <tr>
-              <td><a href="[preferred]/commons/dbcp/source/commons-dbcp2-2.6.0-src.zip">commons-dbcp2-2.6.0-src.zip</a></td>
-              <td><a href="https://www.apache.org/dist/commons/dbcp/source/commons-dbcp2-2.6.0-src.zip.sha256">sha256</a></td>
-              <td><a href="https://www.apache.org/dist/commons/dbcp/source/commons-dbcp2-2.6.0-src.zip.asc">pgp</a></td>
-          </tr>
-        </table>
-      </subsection>
-    </section>
-    <section name="Apache Commons DBCP 2.4.0 for JDBC 4.1 on Java 7">
-      <subsection name="Binaries">
-        <table>
-          <tr>
-              <td><a href="[preferred]/commons/dbcp/binaries/commons-dbcp2-2.4.0-bin.tar.gz">commons-dbcp2-2.4.0-bin.tar.gz</a></td>
-              <td><a href="https://www.apache.org/dist/commons/dbcp/binaries/commons-dbcp2-2.4.0-bin.tar.gz.sha256">sha256</a></td>
-              <td><a href="https://www.apache.org/dist/commons/dbcp/binaries/commons-dbcp2-2.4.0-bin.tar.gz.asc">pgp</a></td>
-          </tr>
-          <tr>
-              <td><a href="[preferred]/commons/dbcp/binaries/commons-dbcp2-2.4.0-bin.zip">commons-dbcp2-2.4.0-bin.zip</a></td>
-              <td><a href="https://www.apache.org/dist/commons/dbcp/binaries/commons-dbcp2-2.4.0-bin.zip.sha256">sha256</a></td>
-              <td><a href="https://www.apache.org/dist/commons/dbcp/binaries/commons-dbcp2-2.4.0-bin.zip.asc">pgp</a></td>
-          </tr>
-        </table>
-      </subsection>
-      <subsection name="Source">
-        <table>
-          <tr>
-              <td><a href="[preferred]/commons/dbcp/source/commons-dbcp2-2.4.0-src.tar.gz">commons-dbcp2-2.4.0-src.tar.gz</a></td>
-              <td><a href="https://www.apache.org/dist/commons/dbcp/source/commons-dbcp2-2.4.0-src.tar.gz.sha256">sha256</a></td>
-              <td><a href="https://www.apache.org/dist/commons/dbcp/source/commons-dbcp2-2.4.0-src.tar.gz.asc">pgp</a></td>
-          </tr>
-          <tr>
-              <td><a href="[preferred]/commons/dbcp/source/commons-dbcp2-2.4.0-src.zip">commons-dbcp2-2.4.0-src.zip</a></td>
-              <td><a href="https://www.apache.org/dist/commons/dbcp/source/commons-dbcp2-2.4.0-src.zip.sha256">sha256</a></td>
-              <td><a href="https://www.apache.org/dist/commons/dbcp/source/commons-dbcp2-2.4.0-src.zip.asc">pgp</a></td>
-          </tr>
-        </table>
-      </subsection>
-    </section>
-    <section name="Apache Commons DBCP 1.4 for JDBC 4 on Java 6">
-      <subsection name="Binaries">
-        <table>
-          <tr>
-              <td><a href="[preferred]/commons/dbcp/binaries/commons-dbcp-1.4-bin.tar.gz">commons-dbcp-1.4-bin.tar.gz</a></td>
-              <td><a href="https://www.apache.org/dist/commons/dbcp/binaries/commons-dbcp-1.4-bin.tar.gz.sha256">sha256</a></td>
-              <td><a href="https://www.apache.org/dist/commons/dbcp/binaries/commons-dbcp-1.4-bin.tar.gz.asc">pgp</a></td>
-          </tr>
-          <tr>
-              <td><a href="[preferred]/commons/dbcp/binaries/commons-dbcp-1.4-bin.zip">commons-dbcp-1.4-bin.zip</a></td>
-              <td><a href="https://www.apache.org/dist/commons/dbcp/binaries/commons-dbcp-1.4-bin.zip.sha256">sha256</a></td>
-              <td><a href="https://www.apache.org/dist/commons/dbcp/binaries/commons-dbcp-1.4-bin.zip.asc">pgp</a></td>
-          </tr>
-        </table>
-      </subsection>
-      <subsection name="Source">
-        <table>
-          <tr>
-              <td><a href="[preferred]/commons/dbcp/source/commons-dbcp-1.4-src.tar.gz">commons-dbcp-1.4-src.tar.gz</a></td>
-              <td><a href="https://www.apache.org/dist/commons/dbcp/source/commons-dbcp-1.4-src.tar.gz.sha256">sha256</a></td>
-              <td><a href="https://www.apache.org/dist/commons/dbcp/source/commons-dbcp-1.4-src.tar.gz.asc">pgp</a></td>
-          </tr>
-          <tr>
-              <td><a href="[preferred]/commons/dbcp/source/commons-dbcp-1.4-src.zip">commons-dbcp-1.4-src.zip</a></td>
-              <td><a href="https://www.apache.org/dist/commons/dbcp/source/commons-dbcp-1.4-src.zip.sha256">sha256</a></td>
-              <td><a href="https://www.apache.org/dist/commons/dbcp/source/commons-dbcp-1.4-src.zip.asc">pgp</a></td>
-          </tr>
-        </table>
-      </subsection>
-    </section>
-    <section name="Apache Commons DBCP 1.3 for JDBC 3 on Java 1.4 or 5">
-      <subsection name="Binaries">
-        <table>
-          <tr>
-              <td><a href="[preferred]/commons/dbcp/binaries/commons-dbcp-1.3${commons.release.4.binary.suffix}.tar.gz">commons-dbcp-1.3${commons.release.4.binary.suffix}.tar.gz</a></td>
-              <td><a href="https://www.apache.org/dist/commons/dbcp/binaries/commons-dbcp-1.3${commons.release.4.binary.suffix}.tar.gz.sha256">sha256</a></td>
-              <td><a href="https://www.apache.org/dist/commons/dbcp/binaries/commons-dbcp-1.3${commons.release.4.binary.suffix}.tar.gz.asc">pgp</a></td>
-          </tr>
-          <tr>
-              <td><a href="[preferred]/commons/dbcp/binaries/commons-dbcp-1.3${commons.release.4.binary.suffix}.zip">commons-dbcp-1.3${commons.release.4.binary.suffix}.zip</a></td>
-              <td><a href="https://www.apache.org/dist/commons/dbcp/binaries/commons-dbcp-1.3${commons.release.4.binary.suffix}.zip.sha256">sha256</a></td>
-              <td><a href="https://www.apache.org/dist/commons/dbcp/binaries/commons-dbcp-1.3${commons.release.4.binary.suffix}.zip.asc">pgp</a></td>
-          </tr>
-        </table>
-      </subsection>
-      <subsection name="Source">
-        <table>
-          <tr>
-              <td><a href="[preferred]/commons/dbcp/source/commons-dbcp-1.3-src.tar.gz">commons-dbcp-1.3-src.tar.gz</a></td>
-              <td><a href="https://www.apache.org/dist/commons/dbcp/source/commons-dbcp-1.3-src.tar.gz.sha256">sha256</a></td>
-              <td><a href="https://www.apache.org/dist/commons/dbcp/source/commons-dbcp-1.3-src.tar.gz.asc">pgp</a></td>
-          </tr>
-          <tr>
-              <td><a href="[preferred]/commons/dbcp/source/commons-dbcp-1.3-src.zip">commons-dbcp-1.3-src.zip</a></td>
-              <td><a href="https://www.apache.org/dist/commons/dbcp/source/commons-dbcp-1.3-src.zip.sha256">sha256</a></td>
-              <td><a href="https://www.apache.org/dist/commons/dbcp/source/commons-dbcp-1.3-src.zip.asc">pgp</a></td>
-          </tr>
-        </table>
-      </subsection>
-    </section>
-    <section name="Archives">
-        <p>
-          Older releases can be obtained from the archives.
-        </p>
-        <ul>
-          <li class="download"><a href="[preferred]/commons/dbcp/">browse download area</a></li>
-          <li><a href="https://archive.apache.org/dist/commons/dbcp/">archives...</a></li>
-        </ul>
-    </section>
-  </body>
-</document>
+<?xml version="1.0"?>
+<!--
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements.  See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License.  You may obtain a copy of the License at
+
+     http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+-->
+<!--
+ +======================================================================+
+ |****                                                              ****|
+ |****      THIS FILE IS GENERATED BY THE COMMONS BUILD PLUGIN      ****|
+ |****                    DO NOT EDIT DIRECTLY                      ****|
+ |****                                                              ****|
+ +======================================================================+
+ | TEMPLATE FILE: download-page-template.xml                            |
+ | commons-build-plugin/trunk/src/main/resources/commons-xdoc-templates |
+ +======================================================================+
+ |                                                                      |
+ | 1) Re-generate using: mvn commons-build:download-page                |
+ |                                                                      |
+ | 2) Set the following properties in the component's pom:              |
+ |    - commons.componentid     (required, alphabetic, lower case)      |
+ |    - commons.release.version (required)                              |
+ |    - commons.release.name    (required)                              |
+ |    - commons.binary.suffix   (optional)                              |
+ |      (defaults to "-bin", set to "" for pre-maven2 releases)         |
+ |    - commons.release.desc    (optional)                              |
+ |    - commons.release.subdir  (optional)                              |
+ |    - commons.release.hash    (optional, lowercase, default sha256)   |
+ |                                                                      |
+ |    - commons.release.[234].version       (conditional)               |
+ |    - commons.release.[234].name          (conditional)               |
+ |    - commons.release.[234].binary.suffix (optional)                  |
+ |    - commons.release.[234].desc          (optional)                  |
+ |    - commons.release.[234].subdir        (optional)                  |
+ |    - commons.release.[234].hash       (optional, lowercase, [sha256])|
+ |                                                                      |
+ | 3) Example Properties                                                |
+ |    (commons.release.name inherited by parent:                        |
+ |     ${project.artifactId}-${commons.release.version}                 |
+ |                                                                      |
+ |  <properties>                                                        |
+ |    <commons.componentid>math</commons.componentid>                   |
+ |    <commons.release.version>1.2</commons.release.version>            |
+ |  </properties>                                                       |
+ |                                                                      |
+ +======================================================================+
+-->
+<document>
+  <properties>
+    <title>Download Apache Commons DBCP</title>
+    <author email="dev@commons.apache.org">Apache Commons Documentation Team</author>
+  </properties>
+  <body>
+    <section name="Download Apache Commons DBCP">
+    <subsection name="Using a Mirror">
+      <p>
+        We recommend you use a mirror to download our release
+        builds, but you <strong>must</strong> <a href="http://www.apache.org/info/verification.html">verify the integrity</a> of
+        the downloaded files using signatures downloaded from our main
+        distribution directories. Recent releases (48 hours) may not yet
+        be available from all the mirrors.
+      </p>
+
+      <p>
+        You are currently using <b>[preferred]</b>.  If you
+        encounter a problem with this mirror, please select another
+        mirror.  If all mirrors are failing, there are <i>backup</i>
+        mirrors (at the end of the mirrors list) that should be
+        available.
+        <br></br>
+        [if-any logo]<a href="[link]"><img align="right" src="[logo]" border="0"></img></a>[end]
+      </p>
+
+      <form action="[location]" method="get" id="SelectMirror">
+        <p>
+          Other mirrors:
+          <select name="Preferred">
+          [if-any http]
+            [for http]<option value="[http]">[http]</option>[end]
+          [end]
+          [if-any ftp]
+            [for ftp]<option value="[ftp]">[ftp]</option>[end]
+          [end]
+          [if-any backup]
+            [for backup]<option value="[backup]">[backup] (backup)</option>[end]
+          [end]
+          </select>
+          <input type="submit" value="Change"></input>
+        </p>
+      </form>
+
+      <p>
+        It is essential that you
+        <a href="https://www.apache.org/info/verification.html">verify the integrity</a>
+        of downloaded files, preferably using the <code>PGP</code> signature (<code>*.asc</code> files);
+        failing that using the <code>SHA256</code> hash (<code>*.sha256</code> checksum files).
+      </p>
+      <p>
+        The <a href="https://www.apache.org/dist/commons/KEYS">KEYS</a>
+        file contains the public PGP keys used by Apache Commons developers
+        to sign releases.
+      </p>
+    </subsection>
+    </section>
+    <section name="Apache Commons DBCP 2.6.0 for JDBC 4.2 on Java 8">
+      <subsection name="Binaries">
+        <table>
+          <tr>
+              <td><a href="[preferred]/commons/dbcp/binaries/commons-dbcp2-2.6.0-bin.tar.gz">commons-dbcp2-2.6.0-bin.tar.gz</a></td>
+              <td><a href="https://www.apache.org/dist/commons/dbcp/binaries/commons-dbcp2-2.6.0-bin.tar.gz.sha256">sha256</a></td>
+              <td><a href="https://www.apache.org/dist/commons/dbcp/binaries/commons-dbcp2-2.6.0-bin.tar.gz.asc">pgp</a></td>
+          </tr>
+          <tr>
+              <td><a href="[preferred]/commons/dbcp/binaries/commons-dbcp2-2.6.0-bin.zip">commons-dbcp2-2.6.0-bin.zip</a></td>
+              <td><a href="https://www.apache.org/dist/commons/dbcp/binaries/commons-dbcp2-2.6.0-bin.zip.sha256">sha256</a></td>
+              <td><a href="https://www.apache.org/dist/commons/dbcp/binaries/commons-dbcp2-2.6.0-bin.zip.asc">pgp</a></td>
+          </tr>
+        </table>
+      </subsection>
+      <subsection name="Source">
+        <table>
+          <tr>
+              <td><a href="[preferred]/commons/dbcp/source/commons-dbcp2-2.6.0-src.tar.gz">commons-dbcp2-2.6.0-src.tar.gz</a></td>
+              <td><a href="https://www.apache.org/dist/commons/dbcp/source/commons-dbcp2-2.6.0-src.tar.gz.sha256">sha256</a></td>
+              <td><a href="https://www.apache.org/dist/commons/dbcp/source/commons-dbcp2-2.6.0-src.tar.gz.asc">pgp</a></td>
+          </tr>
+          <tr>
+              <td><a href="[preferred]/commons/dbcp/source/commons-dbcp2-2.6.0-src.zip">commons-dbcp2-2.6.0-src.zip</a></td>
+              <td><a href="https://www.apache.org/dist/commons/dbcp/source/commons-dbcp2-2.6.0-src.zip.sha256">sha256</a></td>
+              <td><a href="https://www.apache.org/dist/commons/dbcp/source/commons-dbcp2-2.6.0-src.zip.asc">pgp</a></td>
+          </tr>
+        </table>
+      </subsection>
+    </section>
+    <section name="Apache Commons DBCP 2.4.0 for JDBC 4.1 on Java 7">
+      <subsection name="Binaries">
+        <table>
+          <tr>
+              <td><a href="[preferred]/commons/dbcp/binaries/commons-dbcp2-2.4.0-bin.tar.gz">commons-dbcp2-2.4.0-bin.tar.gz</a></td>
+              <td><a href="https://www.apache.org/dist/commons/dbcp/binaries/commons-dbcp2-2.4.0-bin.tar.gz.sha256">sha256</a></td>
+              <td><a href="https://www.apache.org/dist/commons/dbcp/binaries/commons-dbcp2-2.4.0-bin.tar.gz.asc">pgp</a></td>
+          </tr>
+          <tr>
+              <td><a href="[preferred]/commons/dbcp/binaries/commons-dbcp2-2.4.0-bin.zip">commons-dbcp2-2.4.0-bin.zip</a></td>
+              <td><a href="https://www.apache.org/dist/commons/dbcp/binaries/commons-dbcp2-2.4.0-bin.zip.sha256">sha256</a></td>
+              <td><a href="https://www.apache.org/dist/commons/dbcp/binaries/commons-dbcp2-2.4.0-bin.zip.asc">pgp</a></td>
+          </tr>
+        </table>
+      </subsection>
+      <subsection name="Source">
+        <table>
+          <tr>
+              <td><a href="[preferred]/commons/dbcp/source/commons-dbcp2-2.4.0-src.tar.gz">commons-dbcp2-2.4.0-src.tar.gz</a></td>
+              <td><a href="https://www.apache.org/dist/commons/dbcp/source/commons-dbcp2-2.4.0-src.tar.gz.sha256">sha256</a></td>
+              <td><a href="https://www.apache.org/dist/commons/dbcp/source/commons-dbcp2-2.4.0-src.tar.gz.asc">pgp</a></td>
+          </tr>
+          <tr>
+              <td><a href="[preferred]/commons/dbcp/source/commons-dbcp2-2.4.0-src.zip">commons-dbcp2-2.4.0-src.zip</a></td>
+              <td><a href="https://www.apache.org/dist/commons/dbcp/source/commons-dbcp2-2.4.0-src.zip.sha256">sha256</a></td>
+              <td><a href="https://www.apache.org/dist/commons/dbcp/source/commons-dbcp2-2.4.0-src.zip.asc">pgp</a></td>
+          </tr>
+        </table>
+      </subsection>
+    </section>
+    <section name="Apache Commons DBCP 1.4 for JDBC 4 on Java 6">
+      <subsection name="Binaries">
+        <table>
+          <tr>
+              <td><a href="[preferred]/commons/dbcp/binaries/commons-dbcp-1.4-bin.tar.gz">commons-dbcp-1.4-bin.tar.gz</a></td>
+              <td><a href="https://www.apache.org/dist/commons/dbcp/binaries/commons-dbcp-1.4-bin.tar.gz.sha256">sha256</a></td>
+              <td><a href="https://www.apache.org/dist/commons/dbcp/binaries/commons-dbcp-1.4-bin.tar.gz.asc">pgp</a></td>
+          </tr>
+          <tr>
+              <td><a href="[preferred]/commons/dbcp/binaries/commons-dbcp-1.4-bin.zip">commons-dbcp-1.4-bin.zip</a></td>
+              <td><a href="https://www.apache.org/dist/commons/dbcp/binaries/commons-dbcp-1.4-bin.zip.sha256">sha256</a></td>
+              <td><a href="https://www.apache.org/dist/commons/dbcp/binaries/commons-dbcp-1.4-bin.zip.asc">pgp</a></td>
+          </tr>
+        </table>
+      </subsection>
+      <subsection name="Source">
+        <table>
+          <tr>
+              <td><a href="[preferred]/commons/dbcp/source/commons-dbcp-1.4-src.tar.gz">commons-dbcp-1.4-src.tar.gz</a></td>
+              <td><a href="https://www.apache.org/dist/commons/dbcp/source/commons-dbcp-1.4-src.tar.gz.sha256">sha256</a></td>
+              <td><a href="https://www.apache.org/dist/commons/dbcp/source/commons-dbcp-1.4-src.tar.gz.asc">pgp</a></td>
+          </tr>
+          <tr>
+              <td><a href="[preferred]/commons/dbcp/source/commons-dbcp-1.4-src.zip">commons-dbcp-1.4-src.zip</a></td>
+              <td><a href="https://www.apache.org/dist/commons/dbcp/source/commons-dbcp-1.4-src.zip.sha256">sha256</a></td>
+              <td><a href="https://www.apache.org/dist/commons/dbcp/source/commons-dbcp-1.4-src.zip.asc">pgp</a></td>
+          </tr>
+        </table>
+      </subsection>
+    </section>
+    <section name="Apache Commons DBCP 1.3 for JDBC 3 on Java 1.4 or 5">
+      <subsection name="Binaries">
+        <table>
+          <tr>
+              <td><a href="[preferred]/commons/dbcp/binaries/commons-dbcp-1.3${commons.release.4.binary.suffix}.tar.gz">commons-dbcp-1.3${commons.release.4.binary.suffix}.tar.gz</a></td>
+              <td><a href="https://www.apache.org/dist/commons/dbcp/binaries/commons-dbcp-1.3${commons.release.4.binary.suffix}.tar.gz.sha256">sha256</a></td>
+              <td><a href="https://www.apache.org/dist/commons/dbcp/binaries/commons-dbcp-1.3${commons.release.4.binary.suffix}.tar.gz.asc">pgp</a></td>
+          </tr>
+          <tr>
+              <td><a href="[preferred]/commons/dbcp/binaries/commons-dbcp-1.3${commons.release.4.binary.suffix}.zip">commons-dbcp-1.3${commons.release.4.binary.suffix}.zip</a></td>
+              <td><a href="https://www.apache.org/dist/commons/dbcp/binaries/commons-dbcp-1.3${commons.release.4.binary.suffix}.zip.sha256">sha256</a></td>
+              <td><a href="https://www.apache.org/dist/commons/dbcp/binaries/commons-dbcp-1.3${commons.release.4.binary.suffix}.zip.asc">pgp</a></td>
+          </tr>
+        </table>
+      </subsection>
+      <subsection name="Source">
+        <table>
+          <tr>
+              <td><a href="[preferred]/commons/dbcp/source/commons-dbcp-1.3-src.tar.gz">commons-dbcp-1.3-src.tar.gz</a></td>
+              <td><a href="https://www.apache.org/dist/commons/dbcp/source/commons-dbcp-1.3-src.tar.gz.sha256">sha256</a></td>
+              <td><a href="https://www.apache.org/dist/commons/dbcp/source/commons-dbcp-1.3-src.tar.gz.asc">pgp</a></td>
+          </tr>
+          <tr>
+              <td><a href="[preferred]/commons/dbcp/source/commons-dbcp-1.3-src.zip">commons-dbcp-1.3-src.zip</a></td>
+              <td><a href="https://www.apache.org/dist/commons/dbcp/source/commons-dbcp-1.3-src.zip.sha256">sha256</a></td>
+              <td><a href="https://www.apache.org/dist/commons/dbcp/source/commons-dbcp-1.3-src.zip.asc">pgp</a></td>
+          </tr>
+        </table>
+      </subsection>
+    </section>
+    <section name="Archives">
+        <p>
+          Older releases can be obtained from the archives.
+        </p>
+        <ul>
+          <li class="download"><a href="[preferred]/commons/dbcp/">browse download area</a></li>
+          <li><a href="https://archive.apache.org/dist/commons/dbcp/">archives...</a></li>
+        </ul>
+    </section>
+  </body>
+</document>
diff --git a/src/site/xdoc/index.xml b/src/site/xdoc/index.xml
index ce46bf4..8149b53 100644
--- a/src/site/xdoc/index.xml
+++ b/src/site/xdoc/index.xml
@@ -1,104 +1,104 @@
-<?xml version="1.0" encoding="ISO-8859-1"?>
- <!--
-   Licensed to the Apache Software Foundation (ASF) under one or more
-  contributor license agreements.  See the NOTICE file distributed with
-  this work for additional information regarding copyright ownership.
-  The ASF licenses this file to You under the Apache License, Version 2.0
-  (the "License"); you may not use this file except in compliance with
-  the License.  You may obtain a copy of the License at
-
-       http://www.apache.org/licenses/LICENSE-2.0
-
-   Unless required by applicable law or agreed to in writing, software
-   distributed under the License is distributed on an "AS IS" BASIS,
-   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-   See the License for the specific language governing permissions and
-   limitations under the License.
-  -->
-<document>
-
- <properties>
-  <title>Overview</title>
-  <author email="dev@commons.apache.org">Commons Documentation Team</author>
- </properties>
-
- <body>
-
-<section name="The DBCP Component">
-
-<p>Many Apache projects support interaction with a relational database.
-Creating a new connection for each user can be time consuming (often
-requiring multiple seconds of clock time), in order to perform a database
-transaction that might take milliseconds.  Opening a connection per user
-can be unfeasible in a publicly-hosted Internet application where the
-number of simultaneous users can be very large.  Accordingly, developers
-often wish to share a "pool" of open connections between all of the
-application's current users.  The number of users actually performing
-a request at any given time is usually a very small percentage of the
-total number of active users, and during request processing is the only
-time that a database connection is required.  The application itself logs
-into the DBMS, and handles any user account issues internally.</p>
-
-<p>There are several Database Connection Pools already available, both
-within Apache products and elsewhere.  This Commons package provides an
-opportunity to coordinate the efforts required to create and maintain an
-efficient, feature-rich package under the ASF license.</p>
-
-<p>The <code>commons-dbcp2</code> package relies on code in the
-<code>commons-pool2</code> package to provide the underlying object pool
-mechanisms that it utilizes.</p>
-
-<p>DBCP now comes in four different versions to support different versions of
-JDBC. Here is how it works:
-<ul>
-<li>DBCP 2.6.0 compiles and runs under Java 8 only (JDBC 4.2)</li>
-<li>DBCP 2.5.0 compiles and runs under Java 8 only (JDBC 4.2)</li>
-<li>DBCP 2.4.0 compiles and runs under Java 7 only (JDBC 4.1)</li>
-<li>DBCP 1.4 compiles and runs under Java 6 only (JDBC 4)</li>
-<li>DBCP 1.3 compiles and runs under Java 1.4-5.0 only (JDBC 3)</li>
-</ul>
... 1098 lines suppressed ...