diff --git a/.gitignore b/.gitignore
index 8f8f95a..f9801b8 100755
--- a/.gitignore
+++ b/.gitignore
@@ -40,3 +40,5 @@
 
 # BlackDuck generated file
 sdnc-core_bdio.jsonld
+blackDuckHubProjectName.txt
+blackDuckHubProjectVersionName.txt
diff --git a/.scanignore b/.scanignore
new file mode 100644
index 0000000..06ff17a
--- /dev/null
+++ b/.scanignore
@@ -0,0 +1,5 @@
+.git
+./dblib/provider/src/main/resources/dblib.properties:org.openecomp.sdnc.sli.jdbc.password=gamma
+./sli/common/src/test/resources/svclogic.properties:org.openecomp.sdnc.sli.jdbc.password = gamma
+./sli/provider/src/test/resources/svclogic.properties:org.openecomp.sdnc.sli.jdbc.password = gamma
+./sli/recording/src/main/resources/svclogic.properties:org.openecomp.sdnc.sli.jdbc.password = gamma
diff --git a/dblib/common/LICENSE b/dblib/common/LICENSE
new file mode 100755
index 0000000..f49a4e1
--- /dev/null
+++ b/dblib/common/LICENSE
@@ -0,0 +1,201 @@
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   Licensed 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.
\ No newline at end of file
diff --git a/dblib/common/NOTICE b/dblib/common/NOTICE
new file mode 100755
index 0000000..0b6fc4b
--- /dev/null
+++ b/dblib/common/NOTICE
@@ -0,0 +1,6 @@
+Apache Tomcat JDBC Pool
+Copyright 2008-2016 The Apache Software Foundation
+
+This product includes software developed at
+The Apache Software Foundation (http://www.apache.org/).
+
diff --git a/dblib/common/doc/changelog.xml b/dblib/common/doc/changelog.xml
new file mode 100755
index 0000000..2d7ddf8
--- /dev/null
+++ b/dblib/common/doc/changelog.xml
@@ -0,0 +1,133 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  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 document [
+  <!ENTITY project SYSTEM "@TOMCAT_PROJECT_DEST@">
+]>
+<?xml-stylesheet type="text/xsl" href="package.xsl"?>
+<document url="changelog.html">
+
+  &project;
+
+  <properties>
+    <author email="fhanik@apache.org">Filip Hanik</author>
+    <title>Changelog</title>
+  </properties>
+
+<body>
+
+<section name="Tomcat JDBC Connection Pool - Apache Tomcat 7.0.19 and later">
+  <p>
+    Starting with Apache Tomcat 7.0.19 in July 2011, Tomcat JDBC Connection Pool
+    is built and released as a component in official releases of Tomcat.
+    The changes are now listed in "jdbc-pool" sections of Apache Tomcat
+    changelog file. This changelog file is obsolete.
+  </p>
+</section>
+
+<section name="Tomcat JDBC Connection Pool 1.1.0.0">
+  <subsection name="pool">
+    <changelog>
+      <add><rev>1207712</rev> Pool cleaner should be a global thread, not spawn one thread per connection pool. (fhanik)</add>
+      <fix><rev>1073531</rev> <bug>50805</bug> Only initialize connections once when async (fhanik)</fix>
+      <fix><rev>1076380</rev> <bug>50857</bug> Correctly handle timeouts when the pool is busy when async (fhanik)</fix>
+      <add>Added QueryTimeoutInterceptor to be able to configure timeouts on running queries automatically.</add>
+    </changelog>
+  </subsection>
+</section>
+
+<section name="Tomcat JDBC Connection Pool 1.0.9.4">
+  <subsection name="pool">
+    <changelog>
+      <fix><rev>1069864</rev> <bug>50759</bug> Correctly set validation timestamp when using external validator.(fhanik)</fix>
+    </changelog>
+  </subsection>
+</section>
+
+<section name="Tomcat JDBC Connection Pool 1.0.9.3">
+  <subsection name="pool">
+    <changelog>
+      <fix><rev>1060998</rev> <bug>50613</bug> Fix concurrency issue around pool size calculation.(fhanik)</fix>
+    </changelog>
+  </subsection>
+</section>
+<section name="Tomcat JDBC Connection Pool 1.0.9.2">
+  <subsection name="pool">
+    <changelog>
+      <fix><rev>1057743</rev> Make sure passwords are masked.(fhanik)</fix>
+    </changelog>
+  </subsection>
+</section>
+<section name="Tomcat JDBC Connection Pool 1.0.9.0">
+  <subsection name="pool">
+    <changelog>
+      <fix><rev>997321</rev> Ensure threads borrowing connections do not
+      get stuck waiting for a new connection if a connection is released in
+      another thread. (markt)</fix>
+      <fix><rev>995432</rev> Make interceptor class names, property names
+      and property values tolerant of whitespace by trimming the values before
+      use. (markt)</fix>
+      <fix><rev>995091</rev> <bug>49831</bug> Make sure pooled XAConnections are
+      closed when the connection pool shuts down. Patch provided by Daniel
+      Mikusa. (markt)</fix>
+      <update><rev>995087</rev> Code clean-up. Remove some unused code. (markt)
+      </update>
+      <update><rev>995083</rev> Update to Tomcat 6.0.29 (for JULI). (markt)
+      </update>
+      <update><rev>992409</rev> Code clean-up. Reduce sequences of three or more
+      blank lines to two blank lines. (markt)</update>
+      <add><rev>952811</rev>, <rev>995095</rev> <bug>48814</bug> Add Validator
+      interface and allow users to configure a Validator class name. Patch
+      provided by Matt Passell. (markt)</add>
+      <update><rev>948073</rev> Code clean-up. Remove unused imports. (markt)
+      </update>
+      <fix><rev>943434</rev> <bug>49224</bug> Only try setting the username and
+      password if they are non-null. Patch provided by Matt Passell. (markt)
+      </fix>
+      <fix><rev>943032</rev> <bug>49269</bug> Set maxIdle to maxActive by
+      default to prevent warning on start when maxIdle > maxActive. Patch
+      provided by Matt Passell. (markt)</fix>
+      <fix><rev>940574</rev> <bug>49241</bug> Don&apos;t ignore the
+      suspectTimeout property. (fhanik)</fix>
+      <fix><rev>939320</rev> Fix svn:keywords for property replacement.
+      (kkolinko)</fix>
+      <add><rev>931550</rev>, <rev>934651</rev>, <rev>934677</rev> Add a
+      statement cache. (fhanik)</add>
+      <update><rev>919076</rev> Improve XA support. (fhanik)</update>
+      <fix><rev>915940</rev> <bug>48392</bug> Add an interceptor to wrap
+      Statements and ResultSets to prevent access to the physical connection.
+      (fhanik)</fix>
+      <fix><rev>912026</rev> Call <code>setTransactionIsolation()</code> before
+      anything else as some drivers require this to be the first call. (fhanik)
+      </fix>
+      <update><rev>900017</rev> Update Javadoc for XADataSource. (kkolinko)
+      </update>
+    </changelog>
+  </subsection>
+</section>
+<section name="Tomcat JDBC Connection Pool prior to 1.0.9.0 (incomplete)">
+  <subsection name="pool">
+    <changelog>
+      <update><rev>720253</rev> Document how to use interceptors</update>
+      <update><rev>717972</rev> Added an interceptor that will clean up non closed statements when a connection is returned to the pool. (<code>org.apache.tomcat.jdbc.pool.interceptor.StatementFinalizer</code>)</update>
+      <update><rev>713763</rev> Improve connection state handling</update>
+      <fix><rev>713763</rev> Improve connection state handling</fix>
+    </changelog>
+  </subsection>
+</section>
+</body>
+</document>
diff --git a/dblib/common/doc/jdbc-pool.xml b/dblib/common/doc/jdbc-pool.xml
new file mode 100755
index 0000000..8d69624
--- /dev/null
+++ b/dblib/common/doc/jdbc-pool.xml
@@ -0,0 +1,988 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  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 document [
+  <!ENTITY project SYSTEM "@TOMCAT_PROJECT_DEST@">
+]>
+<document url="jdbc-pool.html">
+
+  &project;
+
+ <properties>
+    <author email="fhanik@apache.org">Filip Hanik</author>
+    <title>The Tomcat JDBC Connection Pool</title>
+  </properties>
+
+<body>
+
+<section name="Table of Contents">
+<toc/>
+</section>
+
+<section name="Introduction">
+
+  <p>The <strong>JDBC Connection Pool <code>org.apache.tomcat.jdbc.pool</code></strong>
+  is a replacement or an alternative to the <a href="http://commons.apache.org/dbcp/">Apache Commons DBCP</a>
+  connection pool.</p>
+
+  <p>So why do we need a new connection pool?</p>
+
+  <p>Here are a few of the reasons:</p>
+    <ol>
+      <li>Commons DBCP 1.x is single threaded. In order to be thread safe
+          Commons locks the entire pool for short periods during both object
+          allocation and object return. Note that this does not apply to
+          Commons DBCP 2.x.</li>
+      <li>Commons DBCP 1.x can be slow. As the number of logical CPUs grows and
+          the number of concurrent threads attempting to borrow or return
+          objects increases, the performance suffers. For highly concurrent
+          systems the impact can be significant. Note that this does not apply
+          to Commons DBCP 2.x.</li>
+      <li>Commons DBCP is over 60 classes. tomcat-jdbc-pool core is 8 classes,
+          hence modifications for future requirement will require much less
+          changes. This is all you need to run the connection pool itself, the
+          rest is gravy.</li>
+      <li>Commons DBCP uses static interfaces. This means you have to use the
+          right version for a given JRE version or you may see
+          <code>NoSuchMethodException</code> exceptions.</li>
+      <li>It's not worth rewriting over 60 classes, when a connection pool can
+          be accomplished with a much simpler implementation.</li>
+      <li>Tomcat jdbc pool implements the ability retrieve a connection
+          asynchronously, without adding additional threads to the library
+          itself.</li>
+      <li>Tomcat jdbc pool is a Tomcat module, it depends on Tomcat JULI, a
+          simplified logging framework used in Tomcat.</li>
+      <li>Retrieve the underlying connection using the
+          <code>javax.sql.PooledConnection</code> interface.</li>
+      <li>Starvation proof. If a pool is empty, and threads are waiting for a
+          connection, when a connection is returned, the pool will awake the
+          correct thread waiting. Most pools will simply starve.</li>
+    </ol>
+
+  <p>Features added over other connection pool implementations</p>
+    <ol>
+      <li>Support for highly concurrent environments and multi core/cpu systems.</li>
+      <li>Dynamic implementation of interface, will support <code>java.sql</code> and <code>javax.sql</code> interfaces for
+          your runtime environment (as long as your JDBC driver does the same), even when compiled with a lower version of the JDK.</li>
+      <li>Validation intervals - we don't have to validate every single time we use the connection, we can do this
+          when we borrow or return the connection, just not more frequent than an interval we can configure.</li>
+      <li>Run-Once query, a configurable query that will be run only once, when the connection to the database is established.
+          Very useful to setup session settings, that you want to exist during the entire time the connection is established.</li>
+      <li>Ability to configure custom interceptors.
+          This allows you to write custom interceptors to enhance the functionality. You can use interceptors to gather query stats,
+          cache session states, reconnect the connection upon failures, retry queries, cache query results, and so on.
+          Your options are endless and the interceptors are dynamic, not tied to a JDK version of a
+          <code>java.sql</code>/<code>javax.sql</code> interface.</li>
+      <li>High performance - we will show some differences in performance later on</li>
+      <li>Extremely simple, due to the very simplified implementation, the line count and source file count are very low, compare with c3p0
+          that has over 200 source files(last time we checked), Tomcat jdbc has a core of 8 files, the connection pool itself is about half
+          that. As bugs may occur, they will be faster to track down, and easier to fix. Complexity reduction has been a focus from inception.</li>
+      <li>Asynchronous connection retrieval - you can queue your request for a connection and receive a <code>Future&lt;Connection&gt;</code> back.</li>
+      <li>Better idle connection handling. Instead of closing connections directly, it can still pool connections and sizes the idle pool with a smarter algorithm.</li>
+      <li>You can decide at what moment connections are considered abandoned, is it when the pool is full, or directly at a timeout
+          by specifying a pool usage threshold.
+      </li>
+      <li>The abandon connection timer will reset upon a statement/query activity. Allowing a connections that is in use for a long time to not timeout.
+          This is achieved using the <code>ResetAbandonedTimer</code>
+      </li>
+      <li>Close connections after they have been connected for a certain time. Age based close upon return to the pool.
+      </li>
+      <li>Get JMX notifications and log entries when connections are suspected for being abandoned. This is similar to
+          the <code>removeAbandonedTimeout</code> but it doesn't take any action, only reports the information.
+          This is achieved using the <code>suspectTimeout</code> attribute.</li>
+      <li>Connections can be retrieved from a <code>java.sql.Driver</code>, <code>javax.sql.DataSource</code> or <code>javax.sql.XADataSource</code>
+          This is achieved using the <code>dataSource</code> and <code>dataSourceJNDI</code> attributes.</li>
+      <li>XA connection support</li>
+    </ol>
+
+
+</section>
+<section name="How to use">
+  <p>
+    Usage of the Tomcat connection pool has been made to be as simple as possible, for those of you that are familiar with commons-dbcp, the
+    transition will be very simple. Moving from other connection pools is also fairly straight forward.
+  </p>
+  <subsection name="Additional features">
+    <p>The Tomcat connection pool offers a few additional features over what most other pools let you do:</p>
+    <ul>
+      <li><code>initSQL</code> - the ability to run a SQL statement exactly once, when the connection is created</li>
+      <li><code>validationInterval</code> - in addition to running validations on connections, avoid running them too frequently.</li>
+      <li><code>jdbcInterceptors</code> - flexible and pluggable interceptors to create any customizations around the pool,
+          the query execution and the result set handling. More on this in the advanced section.</li>
+      <li><code>fairQueue</code> - Set the fair flag to true to achieve thread fairness or to use asynchronous connection retrieval</li>
+    </ul>
+  </subsection>
+  <subsection name="Inside the Apache Tomcat Container">
+    <p>
+      The Tomcat Connection pool is configured as a resource described in <a href="http://tomcat.apache.org/tomcat-8.0-doc/jndi-datasource-examples-howto.html" target="_blank">The Tomcat JDBC documentation</a>
+      With the only difference being that you have to specify the <code>factory</code> attribute and set the value to
+      <code>org.apache.tomcat.jdbc.pool.DataSourceFactory</code>
+    </p>
+  </subsection>
+  <subsection name="Standalone">
+    <p>
+      The connection pool only has another dependency, and that is on tomcat-juli.jar.
+      To configure the pool in a stand alone project using bean instantiation, the bean to instantiate is
+      <code>org.apache.tomcat.jdbc.pool.DataSource</code>. The same attributes (documented below) as you use to configure a connection
+      pool as a JNDI resource, are used to configure a data source as a bean.
+    </p>
+  </subsection>
+  <subsection name="JMX">
+    <p>
+      The connection pool object exposes an MBean that can be registered.
+      In order for the connection pool object to create the MBean, the flag <code>jmxEnabled</code> has to be set to true.
+      This doesn't imply that the pool will be registered with an MBean server, merely that the MBean is created.
+      In a container like Tomcat, Tomcat itself registers the DataSource with the MBean server, the
+      <code>org.apache.tomcat.jdbc.pool.DataSource</code> object will then register the actual
+      connection pool MBean.
+      If you're running outside of a container, you can register the DataSource yourself under any object name you specify,
+      and it propagates the registration to the underlying pool. To do this you would call <code>mBeanServer.registerMBean(dataSource.getPool().getJmxPool(),objectname)</code>.
+      Prior to this call, ensure that the pool has been created by calling <code>dataSource.createPool()</code>.
+    </p>
+  </subsection>
+
+</section>
+<section name="Attributes">
+  <p>To provide a very simple switch to and from commons-dbcp and tomcat-jdbc-pool,
+     Most attributes are the same and have the same meaning.</p>
+  <subsection name="JNDI Factory and Type">
+    <attributes>
+      <attribute name="factory" required="true">
+        <p>factory is required, and the value should be <code>org.apache.tomcat.jdbc.pool.DataSourceFactory</code></p>
+      </attribute>
+      <attribute name="type" required="true">
+        <p>Type should always be <code>javax.sql.DataSource</code> or <code>javax.sql.XADataSource</code></p>
+        <p>Depending on the type a <code>org.apache.tomcat.jdbc.pool.DataSource</code> or a <code>org.apache.tomcat.jdbc.pool.XADataSource</code> will be created.</p>
+      </attribute>
+    </attributes>
+  </subsection>
+
+  <subsection name="System Properties">
+    <p>System properties are JVM wide, affect all pools created in the JVM</p>
+    <attributes>
+      <attribute name="org.apache.tomcat.jdbc.pool.onlyAttemptCurrentClassLoader" required="false">
+        <p>(boolean) Controls classloading of dynamic classes, such as
+           JDBC drivers, interceptors and validators. If set to
+           <code>false</code>, default value, the pool will first attempt
+           to load using the current loader (i.e. the class loader that
+           loaded the pool classes) and if class loading fails attempt to
+           load using the thread context loader. Set this value to
+           <code>true</code>, if you wish to remain backwards compatible
+           with Apache Tomcat 8.0.8 and earlier, and only attempt the
+           current loader.
+           If not set then the default value is <code>false</code>.
+        </p>
+      </attribute>
+    </attributes>
+  </subsection>
+
+  <subsection name="Common Attributes">
+  <p>These attributes are shared between commons-dbcp and tomcat-jdbc-pool, in some cases default values are different.</p>
+  <attributes>
+
+    <attribute name="defaultAutoCommit" required="false">
+      <p>(boolean) The default auto-commit state of connections created by this pool. If not set, default is JDBC driver default (If not set then the <code>setAutoCommit</code> method will not be called.)</p>
+    </attribute>
+
+    <attribute name="defaultReadOnly" required="false">
+      <p>(boolean) The default read-only state of connections created by this pool. If not set then the <code>setReadOnly</code> method will not be called. (Some drivers don't support read only mode, ex: Informix)</p>
+    </attribute>
+
+    <attribute name="defaultTransactionIsolation" required="false">
+      <p>(String) The default TransactionIsolation state of connections created by this pool. One of the following: (see javadoc )</p>
+         <ul>
+           <li><code>NONE</code></li>
+           <li><code>READ_COMMITTED</code></li>
+           <li><code>READ_UNCOMMITTED</code></li>
+           <li><code>REPEATABLE_READ</code></li>
+           <li><code>SERIALIZABLE</code></li>
+         </ul>
+         <p>If not set, the method will not be called and it defaults to the JDBC driver.</p>
+    </attribute>
+
+    <attribute name="defaultCatalog" required="false">
+      <p>(String) The default catalog of connections created by this pool.</p>
+    </attribute>
+
+    <attribute name="driverClassName" required="true">
+      <p>(String) The fully qualified Java class name of the JDBC driver to be used. The driver has to be accessible
+         from the same classloader as tomcat-jdbc.jar
+      </p>
+    </attribute>
+
+    <attribute name="username" required="true">
+      <p>(String) The connection username to be passed to our JDBC driver to establish a connection.
+         Note that method <code>DataSource.getConnection(username,password)</code>
+         by default will not use credentials passed into the method,
+         but will use the ones configured here. See <code>alternateUsernameAllowed</code>
+         property for more details.
+      </p>
+    </attribute>
+
+    <attribute name="password" required="true">
+      <p>(String) The connection password to be passed to our JDBC driver to establish a connection.
+         Note that method <code>DataSource.getConnection(username,password)</code>
+         by default will not use credentials passed into the method,
+         but will use the ones configured here. See <code>alternateUsernameAllowed</code>
+         property for more details.
+      </p>
+    </attribute>
+
+    <attribute name="maxActive" required="false">
+      <p>(int) The maximum number of active connections that can be allocated from this pool at the same time.
+         The default value is <code>100</code></p>
+    </attribute>
+
+    <attribute name="maxIdle" required="false">
+      <p>(int) The maximum number of connections that should be kept in the pool at all times.
+         Default value is  <code>maxActive</code>:<code>100</code>
+         Idle connections are checked periodically (if enabled) and
+         connections that been idle for longer than <code>minEvictableIdleTimeMillis</code>
+         will be released. (also see <code>testWhileIdle</code>)</p>
+    </attribute>
+
+    <attribute name="minIdle" required="false">
+      <p>
+        (int) The minimum number of established connections that should be kept in the pool at all times.
+        The connection pool can shrink below this number if validation queries fail.
+        Default value is derived from <code>initialSize</code>:<code>10</code> (also see <code>testWhileIdle</code>)
+      </p>
+    </attribute>
+
+    <attribute name="initialSize" required="false">
+      <p>(int)The initial number of connections that are created when the pool is started.
+         Default value is <code>10</code></p>
+    </attribute>
+
+    <attribute name="maxWait" required="false">
+      <p>(int) 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.
+         Default value is <code>30000</code> (30 seconds)</p>
+    </attribute>
+
+    <attribute name="testOnBorrow" required="false">
+      <p>(boolean) 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.
+         NOTE - for a true value to have any effect, the <code>validationQuery</code>
+         or <code>validatorClassName</code> parameter must be set to a non-null string.
+         In order to have a more efficient validation, see <code>validationInterval</code>.
+         Default value is <code>false</code>
+      </p>
+    </attribute>
+
+    <attribute name="testOnConnect" required="false">
+      <p>(boolean) The indication of whether objects will be validated when a connection is first created.
+         If an object fails to validate, it will be throw <code>SQLException</code>.
+         NOTE - for a true value to have any effect, the <code>validationQuery</code>, <code>initSQL</code>
+         or <code>validatorClassName</code> parameter must be set to a non-null string.
+         Default value is <code>false</code>
+      </p>
+    </attribute>
+
+    <attribute name="testOnReturn" required="false">
+      <p>(boolean) The indication of whether objects will be validated before being returned to the pool.
+         NOTE - for a true value to have any effect, the <code>validationQuery</code>
+         or <code>validatorClassName</code> parameter must be set to a non-null string.
+         The default value is <code>false</code>.
+      </p>
+    </attribute>
+
+    <attribute name="testWhileIdle" required="false">
+      <p>(boolean) 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.
+         NOTE - for a true value to have any effect, the <code>validationQuery</code>
+         or <code>validatorClassName</code> parameter must be set to a non-null string.
+         The default value is <code>false</code> and this property has to be set in order for the
+         pool cleaner/test thread is to run (also see <code>timeBetweenEvictionRunsMillis</code>)
+      </p>
+    </attribute>
+
+    <attribute name="validationQuery" required="false">
+      <p>(String) The SQL query that will be used to validate connections from this pool before returning them to the caller.
+         If specified, this query does not have to return any data, it just can't throw a <code>SQLException</code>.
+         The default value is <code>null</code>.
+         Example values are <code>SELECT 1</code>(mysql), <code>select 1 from dual</code>(oracle), <code>SELECT 1</code>(MS Sql Server)
+      </p>
+    </attribute>
+
+    <attribute name="validationQueryTimeout" required="false">
+      <p>(int) The timeout in seconds before a connection validation queries fail.  This works by calling
+         <code>java.sql.Statement.setQueryTimeout(seconds)</code> on the statement that executes the <code>validationQuery</code>.
+         The pool itself doesn't timeout the query, it is still up to the JDBC driver to enforce query timeouts.
+         A value less than or equal to zero will disable this feature.
+         The default value is <code>-1</code>.
+      </p>
+    </attribute>
+
+    <attribute name="validatorClassName" required="false">
+      <p>(String) The name of a class which implements the
+         <code>org.apache.tomcat.jdbc.pool.Validator</code> interface and
+         provides a no-arg constructor (may be implicit). If specified, the
+         class will be used to create a Validator instance which is then used
+         instead of any validation query to validate connections. The default
+         value is <code>null</code>. An example value is
+         <code>com.mycompany.project.SimpleValidator</code>.
+      </p>
+    </attribute>
+
+    <attribute name="timeBetweenEvictionRunsMillis" required="false">
+      <p>(int) The number of milliseconds to sleep between runs of the idle connection validation/cleaner thread.
+         This value should not be set under 1 second. It dictates how often we check for idle, abandoned connections, and how often
+         we validate idle connections.
+         The default value is <code>5000</code> (5 seconds). <br/>
+      </p>
+    </attribute>
+
+    <attribute name="numTestsPerEvictionRun" required="false">
+      <p>(int) Property not used in tomcat-jdbc-pool.</p>
+    </attribute>
+
+    <attribute name="minEvictableIdleTimeMillis" required="false">
+      <p>(int) The minimum amount of time an object may sit idle in the pool before it is eligible for eviction.
+         The default value is <code>60000</code> (60 seconds).</p>
+    </attribute>
+
+    <attribute name="accessToUnderlyingConnectionAllowed" required="false">
+      <p>(boolean) Property not used. Access can be achieved by calling <code>unwrap</code> on the pooled connection.
+         see <code>javax.sql.DataSource</code> interface, or call <code>getConnection</code> through reflection or
+         cast the object as <code>javax.sql.PooledConnection</code></p>
+    </attribute>
+
+    <attribute name="removeAbandoned" required="false">
+      <p>(boolean) Flag to remove abandoned connections if they exceed the <code>removeAbandonedTimeout</code>.
+         If set to true a connection is considered abandoned and eligible for removal if it has been in use
+         longer than the <code>removeAbandonedTimeout</code> Setting this to <code>true</code> can recover db connections from
+         applications that fail to close a connection. See also <code>logAbandoned</code>
+         The default value is <code>false</code>.</p>
+    </attribute>
+
+    <attribute name="removeAbandonedTimeout" required="false">
+      <p>(int) Timeout in seconds before an abandoned(in use) connection can be removed.
+         The default value is <code>60</code> (60 seconds). The value should be set to the longest running query your applications
+         might have.</p>
+    </attribute>
+
+    <attribute name="logAbandoned" required="false">
+      <p>(boolean) Flag to log stack traces for application code which abandoned a Connection.
+         Logging of abandoned Connections adds overhead for every Connection borrow because a stack trace has to be generated.
+         The default value is <code>false</code>.</p>
+    </attribute>
+
+    <attribute name="connectionProperties" required="false">
+      <p>(String) The connection properties that will be sent to our JDBC driver when establishing new connections.
+         Format of the string must be [propertyName=property;]*
+         NOTE - The "user" and "password" properties will be passed explicitly, so they do not need to be included here.
+         The default value is <code>null</code>.</p>
+    </attribute>
+
+    <attribute name="poolPreparedStatements" required="false">
+      <p>(boolean) Property not used.</p>
+    </attribute>
+
+    <attribute name="maxOpenPreparedStatements" required="false">
+      <p>(int) Property not used.</p>
+    </attribute>
+
+  </attributes>
+
+  </subsection>
+
+  <subsection name="Tomcat JDBC Enhanced Attributes">
+
+  <attributes>
+
+    <attribute name="initSQL" required="false">
+      <p>(String) A custom query to be run when a connection is first created.
+         The default value is <code>null</code>.</p>
+    </attribute>
+
+    <attribute name="jdbcInterceptors" required="false">
+      <p>(String) A semicolon separated list of classnames extending
+         <code>org.apache.tomcat.jdbc.pool.JdbcInterceptor</code> class.
+         See <a href="#Configuring_JDBC_interceptors">Configuring JDBC interceptors</a>
+         below for more detailed description of syntaz and examples.
+      </p>
+      <p>
+         These interceptors will be inserted as an interceptor into the chain
+         of operations on a <code>java.sql.Connection</code> object.
+         The default value is <code>null</code>.
+      </p>
+      <p>
+         Predefined interceptors:<br/>
+         <code>org.apache.tomcat.jdbc.pool.interceptor.<br />ConnectionState</code>
+          - keeps track of auto commit, read only, catalog and transaction isolation level.<br/>
+         <code>org.apache.tomcat.jdbc.pool.interceptor.<br />StatementFinalizer</code>
+          - keeps track of opened statements, and closes them when the connection is returned to the pool.
+      </p>
+      <p>
+         More predefined interceptors are described in detail in the
+         <a href="#JDBC_interceptors">JDBC Interceptors section</a>.
+      </p>
+    </attribute>
+
+    <attribute name="validationInterval" required="false">
+      <p>(long) avoid excess validation, only run validation at most at this frequency - time in milliseconds.
+         If a connection is due for validation, but has been validated previously within this interval, it will not be validated again.
+         The default value is <code>3000</code> (3 seconds).</p>
+    </attribute>
+
+    <attribute name="jmxEnabled" required="false">
+      <p>(boolean) Register the pool with JMX or not.
+         The default value is <code>true</code>.</p>
+    </attribute>
+
+    <attribute name="fairQueue" required="false">
+      <p>(boolean) Set to true if you wish that calls to getConnection should be treated
+         fairly in a true FIFO fashion. This uses the <code>org.apache.tomcat.jdbc.pool.FairBlockingQueue</code>
+         implementation for the list of the idle connections. The default value is <code>true</code>.
+         This flag is required when you want to use asynchronous connection retrieval.<br/>
+         Setting this flag ensures that threads receive connections in the order they arrive.<br/>
+         During performance tests, there is a very large difference in how locks
+         and lock waiting is implemented. When <code>fairQueue=true</code>
+         there is a decision making process based on what operating system the system is running.
+         If the system is running on Linux (property <code>os.name=Linux</code>.
+         To disable this Linux specific behavior and still use the fair queue, simply add the property
+         <code>org.apache.tomcat.jdbc.pool.FairBlockingQueue.ignoreOS=true</code> to your system properties
+         before the connection pool classes are loaded.
+      </p>
+    </attribute>
+
+    <attribute name="abandonWhenPercentageFull" required="false">
+      <p>(int) Connections that have been abandoned (timed out) wont get closed and reported up unless
+         the number of connections in use are above the percentage defined by <code>abandonWhenPercentageFull</code>.
+         The value should be between 0-100.
+         The default value is <code>0</code>, which implies that connections are eligible for closure as soon
+         as <code>removeAbandonedTimeout</code> has been reached.</p>
+    </attribute>
+
+    <attribute name="maxAge" required="false">
+      <p>(long) Time in milliseconds to keep this connection. This attribute
+         works both when returning connection and when borrowing connection.
+         When a connection is borrowed from the pool, the pool will check to see
+         if the <code>now - time-when-connected > maxAge</code> has been reached
+         , and if so, it reconnects before borrow it. When a connection is
+         returned to the pool, the pool will check to see if the
+         <code>now - time-when-connected > maxAge</code> has been reached, and
+         if so, it closes the connection rather than returning it to the pool.
+         The default value is <code>0</code>, which implies that connections
+         will be left open and no age check will be done upon borrowing from the
+         pool and returning the connection to the pool.</p>
+    </attribute>
+
+    <attribute name="useEquals" required="false">
+      <p>(boolean) Set to true if you wish the <code>ProxyConnection</code> class to use <code>String.equals</code> and set to <code>false</code>
+         when you wish to use <code>==</code> when comparing method names. This property does not apply to added interceptors as those are configured individually.
+         The default value is <code>true</code>.
+      </p>
+    </attribute>
+    <attribute name="suspectTimeout" required="false">
+      <p>(int) Timeout value in seconds. Default value is <code>0</code>.<br/>
+           Similar to to the <code>removeAbandonedTimeout</code> value but instead of treating the connection
+           as abandoned, and potentially closing the connection, this simply logs the warning if
+           <code>logAbandoned</code> is set to true. If this value is equal or less than 0, no suspect
+           checking will be performed. Suspect checking only takes place if the timeout value is larger than 0 and
+           the connection was not abandoned or if abandon check is disabled. If a connection is suspect a WARN message gets
+           logged and a JMX notification gets sent once.
+      </p>
+    </attribute>
+    <attribute name="rollbackOnReturn" required="false">
+      <p>(boolean) If <code>autoCommit==false</code> then the pool can terminate the transaction by calling rollback on the connection as it is returned to the pool
+          Default value is <code>false</code>.<br/>
+      </p>
+    </attribute>
+    <attribute name="commitOnReturn" required="false">
+      <p>(boolean) If <code>autoCommit==false</code> then the pool can complete the transaction by calling commit on the connection as it is returned to the pool
+          If <code>rollbackOnReturn==true</code> then this attribute is ignored.
+          Default value is <code>false</code>.<br/>
+      </p>
+    </attribute>
+    <attribute name="alternateUsernameAllowed" required="false">
+      <p>(boolean) By default, the jdbc-pool will ignore the
+         <a href="http://docs.oracle.com/javase/6/docs/api/javax/sql/DataSource.html#getConnection(java.lang.String,%20java.lang.String)"><code>DataSource.getConnection(username,password)</code></a>
+         call, and simply return a previously pooled connection under the globally configured properties <code>username</code> and <code>password</code>, for performance reasons.
+      </p>
+      <p>
+         The pool can however be configured to allow use of different credentials
+         each time a connection is requested.  To enable the functionality described in the
+         <a href="http://docs.oracle.com/javase/6/docs/api/javax/sql/DataSource.html#getConnection(java.lang.String,%20java.lang.String)"><code>DataSource.getConnection(username,password)</code></a>
+         call, simply set the property <code>alternateUsernameAllowed</code>
+         to <code>true</code>.<br />
+         Should you request a connection with the credentials user1/password1 and the connection
+         was previously connected using different user2/password2, the connection will be closed,
+         and reopened with the requested credentials. This way, the pool size is still managed
+         on a global level, and not on a per schema level. <br/>
+         The default value is <code>false</code>.<br/>
+         This property was added as an enhancement to <a href="https://bz.apache.org/bugzilla/show_bug.cgi?id=50025">bug 50025</a>.
+      </p>
+    </attribute>
+    <attribute name="dataSource" required="false">
+      <p>(javax.sql.DataSource) Inject a data source to the connection pool, and the pool will use the data source to retrieve connections instead of establishing them using the <code>java.sql.Driver</code> interface.
+         This is useful when you wish to pool XA connections or connections established using a data source instead of a connection string. Default value is <code>null</code>
+      </p>
+    </attribute>
+    <attribute name="dataSourceJNDI" required="false">
+      <p>(String) The JNDI name for a data source to be looked up in JNDI and then used to establish connections to the database. See the <code>dataSource</code> attribute. Default value is <code>null</code>
+      </p>
+    </attribute>
+    <attribute name="useDisposableConnectionFacade" required="false">
+      <p>(boolean) Set this to true if you wish to put a facade on your connection so that it cannot be reused after it has been closed. This prevents a thread holding on to a
+                   reference of a connection it has already called closed on, to execute queries on it. Default value is <code>true</code>.
+      </p>
+    </attribute>
+    <attribute name="logValidationErrors" required="false">
+      <p>(boolean) Set this to true to log errors during the validation phase to the log file. If set to true, errors will be logged as SEVERE. Default value is <code>false</code> for backwards compatibility.
+      </p>
+    </attribute>
+    <attribute name="propagateInterruptState" required="false">
+      <p>(boolean) Set this to true to propagate the interrupt state for a thread that has been interrupted (not clearing the interrupt state). Default value is <code>false</code> for backwards compatibility.
+      </p>
+    </attribute>
+    <attribute name="ignoreExceptionOnPreLoad" required="false">
+      <p>(boolean) Flag whether ignore error of connection creation while initializing the pool.
+         Set to true if you want to ignore error of connection creation while initializing the pool.
+         Set to false if you want to fail the initialization of the pool by throwing exception.
+         The default value is <code>false</code>.
+      </p>
+    </attribute>
+
+  </attributes>
+  </subsection>
+</section>
+<section name="Advanced usage">
+  <subsection name="JDBC interceptors">
+    <p>To see an example of how to use an interceptor, take a look at
+    <code>org.apache.tomcat.jdbc.pool.interceptor.ConnectionState</code>.
+    This simple interceptor is a cache of three attributes, transaction isolation level, auto commit and read only state,
+    in order for the system to avoid not needed roundtrips to the database.
+    </p>
+    <p>Further interceptors will be added to the core of the pool as the need arises. Contributions are always welcome!</p>
+    <p>Interceptors are of course not limited to just <code>java.sql.Connection</code> but can be used to wrap any
+    of the results from a method invokation as well. You could build query performance analyzer that provides JMX notifications when a
+    query is running longer than the expected time.</p>
+  </subsection>
+  <subsection name="Configuring JDBC interceptors">
+    <p>Configuring JDBC interceptors is done using the <b>jdbcInterceptors</b> property.
+    The property contains a list of semicolon separated class names. If the
+    classname is not fully qualified it will be prefixed with the
+    <code>org.apache.tomcat.jdbc.pool.interceptor.</code> prefix.
+    </p>
+    <p>Example:<br/>
+      <code>
+      jdbcInterceptors=&quot;org.apache.tomcat.jdbc.pool.interceptor.ConnectionState;
+        org.apache.tomcat.jdbc.pool.interceptor.StatementFinalizer&quot;
+      </code>
+      <br/>
+      is the same as
+      <br/>
+      <code> jdbcInterceptors=&quot;ConnectionState;StatementFinalizer&quot;</code>
+    </p>
+    <p>
+    Interceptors can have properties as well. Properties for an interceptor
+    are specified within parentheses after the class name. Several properties
+    are separated by commas.
+    </p>
+    <p>Example:<br/>
+    <code>
+      jdbcInterceptors=&quot;ConnectionState;StatementFinalizer(useEquals=true)&quot;
+    </code>
+    </p>
+    <p>
+    Extra whitespace characters around class names, property names and values
+    are ignored.
+    </p>
+  </subsection>
+  <subsection name="org.apache.tomcat.jdbc.pool.JdbcInterceptor">
+    <p>Abstract base class for all interceptors, cannot be instantiated.</p>
+    <attributes>
+      <attribute name="useEquals" required="false">
+        <p>(boolean) Set to true if you wish the <code>ProxyConnection</code> class to use <code>String.equals</code> and set to <code>false</code>
+         when you wish to use <code>==</code> when comparing method names.
+         The default value is <code>true</code>.
+        </p>
+      </attribute>
+    </attributes>
+  </subsection>
+  <subsection name="org.apache.tomcat.jdbc.pool.interceptor.ConnectionState">
+    <p>Caches the connection for the following attributes <code>autoCommit</code>, <code>readOnly</code>,
+       <code>transactionIsolation</code> and <code>catalog</code>.
+       It is a performance enhancement to avoid roundtrip to the database when getters are called or setters are called with an already set value.
+    </p>
+    <attributes>
+    </attributes>
+  </subsection>
+  <subsection name="org.apache.tomcat.jdbc.pool.interceptor.StatementFinalizer">
+    <p>Keeps track of all statements created using <code>createStatement</code>, <code>prepareStatement</code> or <code>prepareCall</code>
+       and closes these statements when the connection is returned to the pool.
+    </p>
+    <attributes>
+      <attribute name="trace" required="false">
+        <p>(boolean as String) Enable tracing of unclosed statements.
+           When enabled and a connection is closed, and statements are not closed,
+           the interceptor will log all stack traces.
+           The default value is <code>false</code>.
+        </p>
+      </attribute>
+    </attributes>
+  </subsection>
+  <subsection name="org.apache.tomcat.jdbc.pool.interceptor.StatementCache">
+    <p>Caches <code>PreparedStatement</code> and/or <code>CallableStatement</code>
+       instances on a connection.
+    </p>
+    <p>The statements are cached per connection.
+       The count limit is counted globally for all connections that belong to
+       the same pool. Once the count reaches <code>max</code>, subsequent
+       statements are not returned to the cache and are closed immediately.
+    </p>
+    <attributes>
+      <attribute name="prepared" required="false">
+        <p>(boolean as String) Enable caching of <code>PreparedStatement</code>
+           instances created using <code>prepareStatement</code> calls.
+           The default value is <code>true</code>.
+        </p>
+      </attribute>
+      <attribute name="callable" required="false">
+        <p>(boolean as String) Enable caching of <code>CallableStatement</code>
+           instances created using <code>prepareCall</code> calls.
+           The default value is <code>false</code>.
+        </p>
+      </attribute>
+      <attribute name="max" required="false">
+        <p>(int as String) Limit on the count of cached statements across
+           the connection pool.
+           The default value is <code>50</code>.
+        </p>
+      </attribute>
+    </attributes>
+  </subsection>
+  <subsection name="org.apache.tomcat.jdbc.pool.interceptor.StatementDecoratorInterceptor">
+    <p>See <bug>48392</bug>. Interceptor to wrap statements and result sets in order to prevent access to the actual connection
+       using the methods <code>ResultSet.getStatement().getConnection()</code> and <code>Statement.getConnection()</code>
+    </p>
+    <attributes>
+    </attributes>
+  </subsection>
+  <subsection name="org.apache.tomcat.jdbc.pool.interceptor.QueryTimeoutInterceptor">
+    <p>Automatically calls <code>java.sql.Statement.setQueryTimeout(seconds)</code> when a new statement is created.
+       The pool itself doesn't timeout the query, it is still up to the JDBC driver to enforce query timeouts.
+    </p>
+    <attributes>
+      <attribute name="queryTimeout" required="true">
+        <p>(int as String) The number of seconds to set for the query timeout.
+           A value less than or equal to zero will disable this feature.
+           The default value is <code>1</code> seconds.
+        </p>
+      </attribute>
+    </attributes>
+  </subsection>
+  <subsection name="org.apache.tomcat.jdbc.pool.interceptor.SlowQueryReport">
+    <p>Keeps track of query performance and issues log entries when queries exceed a time threshold of fail.
+       The log level used is <code>WARN</code>
+    </p>
+    <attributes>
+      <attribute name="threshold" required="false">
+        <p>(int as String) The number of milliseconds a query has to exceed before issuing a log alert.
+           The default value is <code>1000</code> milliseconds.
+        </p>
+      </attribute>
+      <attribute name="maxQueries" required="false">
+        <p>(int as String) The maximum number of queries to keep track of in order to preserve memory space.
+           A value less than or equal to 0 will disable this feature.
+           The default value is <code>1000</code>.
+        </p>
+      </attribute>
+      <attribute name="logSlow" required="false">
+        <p>(boolean as String) Set to <code>true</code> if you wish to log slow queries.
+            The default value is <code>true</code>.
+        </p>
+      </attribute>
+      <attribute name="logFailed" required="false">
+        <p>(boolean as String) Set to <code>true</code> if you wish to log failed queries.
+            The default value is <code>false</code>.
+        </p>
+      </attribute>
+    </attributes>
+  </subsection>
+  <subsection name="org.apache.tomcat.jdbc.pool.interceptor.SlowQueryReportJmx">
+    <p>Extends the <code>SlowQueryReport</code> and in addition to log entries it issues JMX notification
+       for monitoring tools to react to. Inherits all the attributes from its parent class.
+       This class uses Tomcat's JMX engine so it wont work outside of the Tomcat container.
+       By default, JMX notifications are sent through the ConnectionPool mbean if it is enabled.
+       The <code>SlowQueryReportJmx</code> can also register an MBean if <code>notifyPool=false</code>
+    </p>
+    <attributes>
+      <attribute name="notifyPool" required="false">
+        <p>(boolean as String) Set to false if you want JMX notifications to go to the <code>SlowQueryReportJmx</code> MBean
+           The default value is <code>true</code>.
+        </p>
+      </attribute>
+      <attribute name="objectName" required="false">
+        <p>(String) Define a valid <code>javax.management.ObjectName</code> string that will be used to register this object with the platform mbean server
+           The default value is <code>null</code> and the object will be registered using
+           tomcat.jdbc:type=org.apache.tomcat.jdbc.pool.interceptor.SlowQueryReportJmx,name=the-name-of-the-pool
+        </p>
+      </attribute>
+    </attributes>
+  </subsection>
+  <subsection name="org.apache.tomcat.jdbc.pool.interceptor.ResetAbandonedTimer">
+    <p>
+        The abandoned timer starts when a connection is checked out from the pool.
+        This means if you have a 30second timeout and run 10x10second queries using the connection
+        it will be marked abandoned and potentially reclaimed depending on the <code>abandonWhenPercentageFull</code>
+        attribute.
+        Using this interceptor it will reset the checkout timer every time you perform an operation on the connection or execute a
+        query successfully.
+    </p>
+    <attributes>
+    </attributes>
+  </subsection>
+</section>
+
+<section name="Code Example">
+  <p>Other examples of Tomcat configuration for JDBC usage can be found <a href="http://tomcat.apache.org/tomcat-8.0-doc/jndi-datasource-examples-howto.html">in the Tomcat documentation</a>. </p>
+  <subsection name="Plain Ol' Java">
+    <p>Here is a simple example of how to create and use a data source.</p>
+<source><![CDATA[  import java.sql.Connection;
+  import java.sql.ResultSet;
+  import java.sql.Statement;
+
+  import org.apache.tomcat.jdbc.pool.DataSource;
+  import org.apache.tomcat.jdbc.pool.PoolProperties;
+
+  public class SimplePOJOExample {
+
+      public static void main(String[] args) throws Exception {
+          PoolProperties p = new PoolProperties();
+          p.setUrl("jdbc:mysql://localhost:3306/mysql");
+          p.setDriverClassName("com.mysql.jdbc.Driver");
+          p.setUsername("root");
+          p.setPassword("password");
+          p.setJmxEnabled(true);
+          p.setTestWhileIdle(false);
+          p.setTestOnBorrow(true);
+          p.setValidationQuery("SELECT 1");
+          p.setTestOnReturn(false);
+          p.setValidationInterval(30000);
+          p.setTimeBetweenEvictionRunsMillis(30000);
+          p.setMaxActive(100);
+          p.setInitialSize(10);
+          p.setMaxWait(10000);
+          p.setRemoveAbandonedTimeout(60);
+          p.setMinEvictableIdleTimeMillis(30000);
+          p.setMinIdle(10);
+          p.setLogAbandoned(true);
+          p.setRemoveAbandoned(true);
+          p.setJdbcInterceptors(
+            "org.apache.tomcat.jdbc.pool.interceptor.ConnectionState;"+
+            "org.apache.tomcat.jdbc.pool.interceptor.StatementFinalizer");
+          DataSource datasource = new DataSource();
+          datasource.setPoolProperties(p);
+
+          Connection con = null;
+          try {
+            con = datasource.getConnection();
+            Statement st = con.createStatement();
+            ResultSet rs = st.executeQuery("select * from user");
+            int cnt = 1;
+            while (rs.next()) {
+                System.out.println((cnt++)+". Host:" +rs.getString("Host")+
+                  " User:"+rs.getString("User")+" Password:"+rs.getString("Password"));
+            }
+            rs.close();
+            st.close();
+          } finally {
+            if (con!=null) try {con.close();}catch (Exception ignore) {}
+          }
+      }
+
+  }]]></source>
+  </subsection>
+  <subsection name="As a Resource">
+    <p>And here is an example on how to configure a resource for JNDI lookups</p>
+<source><![CDATA[<Resource name="jdbc/TestDB"
+          auth="Container"
+          type="javax.sql.DataSource"
+          factory="org.apache.tomcat.jdbc.pool.DataSourceFactory"
+          testWhileIdle="true"
+          testOnBorrow="true"
+          testOnReturn="false"
+          validationQuery="SELECT 1"
+          validationInterval="30000"
+          timeBetweenEvictionRunsMillis="30000"
+          maxActive="100"
+          minIdle="10"
+          maxWait="10000"
+          initialSize="10"
+          removeAbandonedTimeout="60"
+          removeAbandoned="true"
+          logAbandoned="true"
+          minEvictableIdleTimeMillis="30000"
+          jmxEnabled="true"
+          jdbcInterceptors="org.apache.tomcat.jdbc.pool.interceptor.ConnectionState;
+            org.apache.tomcat.jdbc.pool.interceptor.StatementFinalizer"
+          username="root"
+          password="password"
+          driverClassName="com.mysql.jdbc.Driver"
+          url="jdbc:mysql://localhost:3306/mysql"/>]]></source>
+
+  </subsection>
+  <subsection name="Asynchronous Connection Retrieval">
+    <p> The Tomcat JDBC connection pool supports asynchronous connection retrieval without adding additional threads to the
+        pool library. It does this by adding a method to the data source called <code>Future&lt;Connection&gt; getConnectionAsync()</code>.
+        In order to use the async retrieval, two conditions must be met:
+    </p>
+        <ol>
+          <li>You must configure the <code>fairQueue</code> property to be <code>true</code>.</li>
+          <li>You will have to cast the data source to <code>org.apache.tomcat.jdbc.pool.DataSource</code></li>
+        </ol>
+        An example of using the async feature is show below.
+<source><![CDATA[  Connection con = null;
+  try {
+    Future<Connection> future = datasource.getConnectionAsync();
+    while (!future.isDone()) {
+      System.out.println("Connection is not yet available. Do some background work");
+      try {
+        Thread.sleep(100); //simulate work
+      }catch (InterruptedException x) {
+        Thread.currentThread().interrupt();
+      }
+    }
+    con = future.get(); //should return instantly
+    Statement st = con.createStatement();
+    ResultSet rs = st.executeQuery("select * from user");]]></source>
+
+  </subsection>
+  <subsection name="Interceptors">
+    <p>Interceptors are a powerful way to enable, disable or modify functionality on a specific connection or its sub components.
+       There are many different use cases for when interceptors are useful. By default, and for performance reasons, the connection pool is stateless.
+       The only state the pool itself inserts are <code>defaultAutoCommit</code>, <code>defaultReadOnly</code>, <code>defaultTransactionIsolation</code>, <code>defaultCatalog</code> if
+       these are set. These 4 properties are only set upon connection creation. Should these properties be modified during the usage of the connection,
+       the pool itself will not reset them.</p>
+    <p>An interceptor has to extend the <code>org.apache.tomcat.jdbc.pool.JdbcInterceptor</code> class. This class is fairly simple,
+       You will need to have a no arg constructor</p>
+<source><![CDATA[  public JdbcInterceptor() {
+  }]]></source>
+    <p>
+       When a connection is borrowed from the pool, the interceptor can initialize or in some other way react to the event by implementing the
+    </p>
+<source><![CDATA[  public abstract void reset(ConnectionPool parent, PooledConnection con);]]></source>
+    <p>
+       method. This method gets called with two parameters, a reference to the connection pool itself <code>ConnectionPool parent</code>
+       and a reference to the underlying connection <code>PooledConnection con</code>.
+    </p>
+    <p>
+       When a method on the <code>java.sql.Connection</code> object is invoked, it will cause the
+    </p>
+<source><![CDATA[  public Object invoke(Object proxy, Method method, Object[] args) throws Throwable]]></source>
+    <p>
+       method to get invoked. The <code>Method method</code> is the actual method invoked, and <code>Object[] args</code> are the arguments.
+       To look at a very simple example, where we demonstrate how to make the invokation to <code>java.sql.Connection.close()</code> a noop
+       if the connection has been closed
+    </p>
+<source><![CDATA[  if (CLOSE_VAL==method.getName()) {
+      if (isClosed()) return null; //noop for already closed.
+  }
+  return super.invoke(proxy,method,args);]]></source>
+    <p>
+        There is an observation being made. It is the comparison of the method name. One way to do this would be to do
+        <code>&quot;close&quot;.equals(method.getName())</code>.
+        Above we see a direct reference comparison between the method name and <code>static final String</code> reference.
+        According to the JVM spec, method names and static final String end up in a shared constant pool, so the reference comparison should work.
+        One could of course do this as well:
+    </p>
+<source><![CDATA[  if (compare(CLOSE_VAL,method)) {
+      if (isClosed()) return null; //noop for already closed.
+  }
+  return super.invoke(proxy,method,args);]]></source>
+    <p>
+        The <code>compare(String,Method)</code> will use the <code>useEquals</code> flag on an interceptor and do either reference comparison or
+        a string value comparison when the <code>useEquals=true</code> flag is set.
+    </p>
+    <p>Pool start/stop<br/>
+       When the connection pool is started or closed, you can be notifed. You will only be notified once per interceptor class
+       even though it is an instance method. and you will be notified using an interceptor currently not attached to a pool.
+    </p>
+<source><![CDATA[  public void poolStarted(ConnectionPool pool) {
+  }
+
+  public void poolClosed(ConnectionPool pool) {
+  }]]></source>
+    <p>
+       When overriding these methods, don't forget to call super if you are extending a class other than <code>JdbcInterceptor</code>
+    </p>
+    <p>Configuring interceptors<br/>
+       Interceptors are configured using the <code>jdbcInterceptors</code> property or the <code>setJdbcInterceptors</code> method.
+       An interceptor can have properties, and would be configured like this
+    </p>
+<source><![CDATA[  String jdbcInterceptors=
+    "org.apache.tomcat.jdbc.pool.interceptor.ConnectionState(useEquals=true,fast=yes)"]]></source>
+
+    <p>Interceptor properties<br/>
+       Since interceptors can have properties, you need to be able to read the values of these properties within your
+       interceptor. Taking an example like the one above, you can override the <code>setProperties</code> method.
+    </p>
+<source><![CDATA[  public void setProperties(Map<String, InterceptorProperty> properties) {
+     super.setProperties(properties);
+     final String myprop = "myprop";
+     InterceptorProperty p1 = properties.get(myprop);
+     if (p1!=null) {
+         setMyprop(Long.parseLong(p1.getValue()));
+     }
+  }]]></source>
+
+  </subsection>
+  <subsection name="Getting the actual JDBC connection">
+    <p>Connection pools create wrappers around the actual connection in order to properly pool them.
+       We also create interceptors in these wrappers to be able to perform certain functions.
+       If there is a need to retrieve the actual connection, one can do so using the <code>javax.sql.PooledConnection</code>
+       interface.
+    </p>
+<source><![CDATA[  Connection con = datasource.getConnection();
+  Connection actual = ((javax.sql.PooledConnection)con).getConnection();]]></source>
+
+  </subsection>
+
+</section>
+
+<section name="Building">
+  <p>We build the JDBC pool code with 1.6, but it is backwards compatible down to 1.5 for runtime environment. For unit test, we use 1.6 and higher</p>
+  <p>Other examples of Tomcat configuration for JDBC usage can be found <a href="http://tomcat.apache.org/tomcat-8.0-doc/jndi-datasource-examples-howto.html">in the Tomcat documentation</a>. </p>
+  <subsection name="Building from source">
+    <p>Building is pretty simple. The pool has a dependency on <code>tomcat-juli.jar</code> and in case you want the <code>SlowQueryReportJmx</code></p>
+<source><![CDATA[  javac -classpath tomcat-juli.jar \
+        -d . \
+        org/apache/tomcat/jdbc/pool/*.java \
+        org/apache/tomcat/jdbc/pool/interceptor/*.java \
+        org/apache/tomcat/jdbc/pool/jmx/*.java]]></source>
+    <p>
+       A build file can be found in the Tomcat <a href="http://svn.apache.org/viewvc/tomcat/trunk/modules/jdbc-pool/">source repository</a>.
+    </p>
+    <p>
+      As a convenience, a build file is also included where a simple build command will generate all files needed.
+    </p>
+<source>  ant download  (downloads dependencies)
+  ant build     (compiles and generates .jar files)
+  ant dist      (creates a release package)
+  ant test      (runs tests, expects a test database to be setup)</source>
+
+    <p>
+      The system is structured for a Maven build, but does generate release artifacts. Just the library itself.
+    </p>
+  </subsection>
+</section>
+</body>
+
+</document>
diff --git a/dblib/common/doc/package.xsl b/dblib/common/doc/package.xsl
new file mode 100755
index 0000000..cdadd53
--- /dev/null
+++ b/dblib/common/doc/package.xsl
@@ -0,0 +1,249 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  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.
+-->
+<!--
+  Stylesheet that generates "package.html" for Javadoc tool
+  from jdbc-pool.xml documentation file.
+  It is based on "tomcat-docs" stylesheet, but it needs to avoid
+  generating complicated headers and footers, as those cannot be
+  digested by Javadoc tool and break layout of javadoc pages.
+-->
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+  version="1.0">
+
+
+  <!-- Output method -->
+  <xsl:output method="html"
+            encoding="UTF-8"
+              indent="no"/>
+
+
+  <!-- Defined parameters (overrideable) -->
+  <xsl:param    name="relative-path"    select="'.'"/>
+  <xsl:param    name="void-image"       select="'/images/void.gif'"/>
+  <xsl:param    name="standalone"       select="''"/>
+  <xsl:param    name="buglink"          select="'http://bz.apache.org/bugzilla/show_bug.cgi?id='"/>
+  <xsl:param    name="revlink"          select="'http://svn.apache.org/viewvc?view=rev&amp;rev='"/>
+
+  <!-- Defined variables (non-overrideable) -->
+  <xsl:variable name="body-bg"          select="'#ffffff'"/>
+  <xsl:variable name="body-fg"          select="'#000000'"/>
+  <xsl:variable name="body-link"        select="'#525D76'"/>
+  <xsl:variable name="banner-bg"        select="'#525D76'"/>
+  <xsl:variable name="banner-fg"        select="'#ffffff'"/>
+  <xsl:variable name="sub-banner-bg"    select="'#828DA6'"/>
+  <xsl:variable name="sub-banner-fg"    select="'#ffffff'"/>
+  <xsl:variable name="source-color"     select="'#023264'"/>
+  <xsl:variable name="attributes-color" select="'#023264'"/>
+  <xsl:variable name="table-th-bg"      select="'#039acc'"/>
+  <xsl:variable name="table-td-bg"      select="'#a0ddf0'"/>
+
+  <!-- Process an entire document into an HTML page -->
+  <xsl:template match="document">
+  <xsl:variable name="project"
+              select="document('project.xml')/project"/>
+    <html>
+    <head>
+    <title><xsl:value-of select="project/title"/> - <xsl:value-of select="properties/title"/></title>
+    </head>
+
+    <body bgcolor="{$body-bg}" text="{$body-fg}" link="{$body-link}"
+          alink="{$body-link}" vlink="{$body-link}">
+
+          <h2><xsl:value-of select="properties/title"/>.</h2>
+          <xsl:apply-templates select="body/section"/>
+    </body>
+    </html>
+
+  </xsl:template>
+
+
+  <!-- Process a documentation section -->
+  <xsl:template match="section">
+    <xsl:variable name="name">
+      <xsl:value-of select="@name"/>
+    </xsl:variable>
+    <table border="0" cellspacing="0" cellpadding="2">
+      <!-- Section heading -->
+      <tr><td bgcolor="{$banner-bg}">
+          <font color="{$banner-fg}" face="arial,helvetica.sanserif">
+          <a name="{$name}">
+          <strong><xsl:value-of select="@name"/></strong></a></font>
+      </td></tr>
+      <!-- Section body -->
+      <tr><td><blockquote>
+        <xsl:apply-templates/>
+      </blockquote></td></tr>
+    </table>
+  </xsl:template>
+
+
+  <!-- Process a documentation subsection -->
+  <xsl:template match="subsection">
+    <xsl:variable name="name">
+      <xsl:value-of select="@name"/>
+    </xsl:variable>
+    <table border="0" cellspacing="0" cellpadding="2">
+      <!-- Subsection heading -->
+      <tr><td bgcolor="{$sub-banner-bg}">
+          <font color="{$sub-banner-fg}" face="arial,helvetica.sanserif">
+          <a name="{$name}">
+          <strong><xsl:value-of select="@name"/></strong></a></font>
+      </td></tr>
+      <!-- Subsection body -->
+      <tr><td><blockquote>
+        <xsl:apply-templates/>
+      </blockquote></td></tr>
+    </table>
+  </xsl:template>
+
+
+  <!-- Process a source code example -->
+  <xsl:template match="source">
+    <xsl:variable name="void">
+      <xsl:value-of select="$relative-path"/><xsl:value-of select="$void-image"/>
+    </xsl:variable>
+    <div align="left">
+      <table cellspacing="4" cellpadding="0" border="0">
+        <tr>
+          <td bgcolor="{$source-color}" width="1" height="1">
+            <img src="{$void}" width="1" height="1" vspace="0" hspace="0" border="0"/>
+          </td>
+          <td bgcolor="{$source-color}" height="1">
+            <img src="{$void}" width="1" height="1" vspace="0" hspace="0" border="0"/>
+          </td>
+          <td bgcolor="{$source-color}" width="1" height="1">
+            <img src="{$void}" width="1" height="1" vspace="0" hspace="0" border="0"/>
+          </td>
+        </tr>
+        <tr>
+          <td bgcolor="{$source-color}" width="1">
+            <img src="{$void}" width="1" height="1" vspace="0" hspace="0" border="0"/>
+          </td>
+          <td bgcolor="#ffffff" height="1"><pre>
+            <xsl:value-of select="."/>
+          </pre></td>
+          <td bgcolor="{$source-color}" width="1">
+            <img src="{$void}" width="1" height="1" vspace="0" hspace="0" border="0"/>
+          </td>
+        </tr>
+        <tr>
+          <td bgcolor="{$source-color}" width="1" height="1">
+            <img src="{$void}" width="1" height="1" vspace="0" hspace="0" border="0"/>
+          </td>
+          <td bgcolor="{$source-color}" height="1">
+            <img src="{$void}" width="1" height="1" vspace="0" hspace="0" border="0"/>
+          </td>
+          <td bgcolor="{$source-color}" width="1" height="1">
+            <img src="{$void}" width="1" height="1" vspace="0" hspace="0" border="0"/>
+          </td>
+        </tr>
+      </table>
+    </div>
+  </xsl:template>
+
+
+  <!-- Process an attributes list with nested attribute elements -->
+  <xsl:template match="attributes">
+    <table border="1" cellpadding="5">
+      <tr>
+        <th width="15%" bgcolor="{$attributes-color}">
+          <font color="#ffffff">Attribute</font>
+        </th>
+        <th width="85%" bgcolor="{$attributes-color}">
+          <font color="#ffffff">Description</font>
+        </th>
+      </tr>
+      <xsl:for-each select="attribute">
+        <tr>
+          <td align="left" valign="center">
+            <xsl:if test="@required = 'true'">
+              <strong><code><xsl:value-of select="@name"/></code></strong>
+            </xsl:if>
+            <xsl:if test="@required != 'true'">
+              <code><xsl:value-of select="@name"/></code>
+            </xsl:if>
+          </td>
+          <td align="left" valign="center">
+            <xsl:apply-templates/>
+          </td>
+        </tr>
+      </xsl:for-each>
+    </table>
+  </xsl:template>
+
+  <!-- Process a properties list with nested property elements -->
+  <xsl:template match="properties">
+    <table border="1" cellpadding="5">
+      <tr>
+        <th width="15%" bgcolor="{$attributes-color}">
+          <font color="#ffffff">Property</font>
+        </th>
+        <th width="85%" bgcolor="{$attributes-color}">
+          <font color="#ffffff">Description</font>
+        </th>
+      </tr>
+      <xsl:for-each select="property">
+        <tr>
+          <td align="left" valign="center">
+            <code><xsl:value-of select="@name"/></code>
+          </td>
+          <td align="left" valign="center">
+            <xsl:apply-templates/>
+          </td>
+        </tr>
+      </xsl:for-each>
+    </table>
+  </xsl:template>
+
+  <!-- Fix relative links in printer friendly versions of the docs -->
+  <xsl:template match="a">
+    <xsl:variable name="href" select="@href"/>
+    <xsl:choose>
+      <xsl:when test="$standalone = 'standalone'">
+        <xsl:apply-templates/>
+      </xsl:when>
+      <xsl:when test="$href != ''">
+        <a href="{$href}"><xsl:apply-templates/></a>
+      </xsl:when>
+      <xsl:otherwise>
+        <xsl:variable name="name" select="@name"/>
+        <a name="{$name}"><xsl:apply-templates/></a>
+      </xsl:otherwise>
+    </xsl:choose>
+  </xsl:template>
+
+  <!-- Link to a bug report -->
+  <xsl:template match="bug">
+      <xsl:variable name="link"><xsl:value-of select="$buglink"/><xsl:value-of select="text()"/></xsl:variable>
+      <a href="{$link}"><xsl:apply-templates/></a>
+  </xsl:template>
+
+  <!-- Link to a SVN revision report -->
+  <xsl:template match="rev">
+      <xsl:variable name="link"><xsl:value-of select="$revlink"/><xsl:value-of select="text()"/></xsl:variable>
+      <a href="{$link}"><xsl:apply-templates/></a>
+  </xsl:template>
+
+  <!-- Process everything else by just passing it through -->
+  <xsl:template match="*|@*">
+    <xsl:copy>
+      <xsl:apply-templates select="@*|*|text()"/>
+    </xsl:copy>
+  </xsl:template>
+
+</xsl:stylesheet>
diff --git a/dblib/common/doc/project.xml b/dblib/common/doc/project.xml
new file mode 100755
index 0000000..912903d
--- /dev/null
+++ b/dblib/common/doc/project.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  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 name="Apache Tomcat JDBC Pool Documentation"
+        href="http://tomcat.apache.org/">
+
+    <title>Apache Tomcat JDBC Pool</title>
+
+    <logo href="/images/tomcat.gif">
+      The Apache Tomcat Servlet/JSP Container
+    </logo>
+
+    <body>
+    </body>
+
+</project>
+
diff --git a/dblib/common/pom.xml b/dblib/common/pom.xml
new file mode 100755
index 0000000..fa25c98
--- /dev/null
+++ b/dblib/common/pom.xml
@@ -0,0 +1,88 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<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/xsd/maven-4.0.0.xsd">
+	<modelVersion>4.0.0</modelVersion>
+	<parent>
+		<groupId>org.openecomp.sdnc.core</groupId>
+		<artifactId>dblib</artifactId>
+		<version>1.1.0-SNAPSHOT</version>
+  </parent>
+  <artifactId>dblib-common</artifactId>
+  <packaging>bundle</packaging>
+  <name>DBLIB Adaptor - Common</name>
+  <properties>
+    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+  </properties>
+
+	<dependencies>
+		<dependency>
+			<groupId>org.apache.tomcat</groupId>
+			<artifactId>juli</artifactId>
+			<version>6.0.32</version>
+		</dependency>
+		<dependency>
+			<groupId>junit</groupId>
+			<artifactId>junit</artifactId>
+			<version>4.11</version>
+			<scope>test</scope>
+		</dependency>
+		<dependency>
+			<groupId>org.apache.tomcat</groupId>
+			<artifactId>tomcat-dbcp</artifactId>
+			<version>8.0.14</version>
+			<scope>test</scope>
+		</dependency>
+		<dependency>
+			<groupId>com.h2database</groupId>
+			<artifactId>h2</artifactId>
+			<version>1.3.152</version>
+			<scope>test</scope>
+		</dependency>
+		<dependency>
+			<groupId>equinoxSDK381</groupId>
+			<artifactId>org.eclipse.osgi</artifactId>
+			<version>${equinox.osgi.version}</version>
+		</dependency>
+		<dependency>
+			<groupId>mysql</groupId>
+			<artifactId>mysql-connector-java</artifactId>
+			<version>${mysql.connector.version}</version>
+		</dependency>
+
+	</dependencies>
+
+	<build>
+		<plugins>
+			<plugin>
+				<groupId>org.apache.maven.plugins</groupId>
+				<artifactId>maven-compiler-plugin</artifactId>
+				<configuration>
+					<source>1.7</source>
+					<target>1.7</target>
+				</configuration>
+			</plugin>
+			<plugin>
+				<groupId>org.apache.felix</groupId>
+				<artifactId>maven-bundle-plugin</artifactId>
+				<extensions>true</extensions>
+				<configuration>
+					<instructions>
+						<Bundle-Activator>org.openecomp.sdnc.sli.resource.common.CommonActivator</Bundle-Activator>
+						<Export-Package>
+							org.openecomp.sdnc.sli.resource.common;version=${project.version},
+							org.apache.tomcat.jdbc;version=${project.version},
+							org.apache.tomcat.jdbc.pool;version=${project.version},
+							org.apache.tomcat.jdbc.naming;version=${project.version},
+							org.apache.tomcat.jdbc.pool.interceptor;version=${project.version},
+							org.apache.tomcat.jdbc.pool.jmx;version=${project.version}</Export-Package>
+						<Import-Package>*</Import-Package>
+						<!--
+						<Embed-Dependency>*;scope=compile;artifactId=commons-lang|commons-lang3</Embed-Dependency>
+						 -->
+						<Embed-Transitive>true</Embed-Transitive>
+					</instructions>
+					<manifestLocation>${project.basedir}/src/main/resources/META-INF</manifestLocation>
+				</configuration>
+			</plugin>
+		</plugins>
+	</build>
+</project>
diff --git a/dblib/common/src/main/java/org/apache/tomcat/jdbc/naming/GenericNamingResourcesFactory.java b/dblib/common/src/main/java/org/apache/tomcat/jdbc/naming/GenericNamingResourcesFactory.java
new file mode 100644
index 0000000..c6112a1
--- /dev/null
+++ b/dblib/common/src/main/java/org/apache/tomcat/jdbc/naming/GenericNamingResourcesFactory.java
@@ -0,0 +1,254 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * openecomp
+ * ================================================================================
+ * Copyright (C) 2016 - 2017 AT&T
+ * ================================================================================
+ * Licensed 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.
+ * ============LICENSE_END=========================================================
+ */
+
+/*
+ * 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.tomcat.jdbc.naming;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+import java.util.Enumeration;
+import java.util.Hashtable;
+
+import javax.naming.Context;
+import javax.naming.Name;
+import javax.naming.RefAddr;
+import javax.naming.Reference;
+import javax.naming.spi.ObjectFactory;
+
+import org.apache.juli.logging.Log;
+import org.apache.juli.logging.LogFactory;
+import org.apache.tomcat.jdbc.pool.ClassLoaderUtil;
+
+/**
+ * Simple way of configuring generic resources by using reflection.
+ * Example usage:
+ * <pre><code>
+ * &lt;Resource factory=&quot;org.apache.tomcat.jdbc.naming.GenericNamingResourcesFactory&quot;
+ *              name=&quot;jdbc/test&quot;
+ *              type=&quot;org.apache.derby.jdbc.ClientXADataSource&quot;
+ *              databaseName=&quot;sample&quot;
+ *              createDatabase=&quot;create&quot;
+ *              serverName=&quot;localhost&quot;
+ *              port=&quot;1527&quot;/&gt;
+ * </code></pre>
+ *
+ */
+public class GenericNamingResourcesFactory implements ObjectFactory {
+    private static final Log log = LogFactory.getLog(GenericNamingResourcesFactory.class);
+
+    @Override
+    public Object getObjectInstance(Object obj, Name name, Context nameCtx, Hashtable<?, ?> environment) throws Exception {
+        if ((obj == null) || !(obj instanceof Reference)) {
+            return null;
+        }
+        Reference ref = (Reference) obj;
+        Enumeration<RefAddr> refs = ref.getAll();
+
+        String type = ref.getClassName();
+        Object o =
+            ClassLoaderUtil.loadClass(
+                type,
+                GenericNamingResourcesFactory.class.getClassLoader(),
+                Thread.currentThread().getContextClassLoader())
+            .newInstance();
+
+        while (refs.hasMoreElements()) {
+            RefAddr addr = refs.nextElement();
+            String param = addr.getType();
+            String value = null;
+            if (addr.getContent()!=null) {
+                value = addr.getContent().toString();
+            }
+            if (setProperty(o, param, value)) {
+
+            } else {
+                log.debug("Property not configured["+param+"]. No setter found on["+o+"].");
+            }
+        }
+        return o;
+    }
+
+    @SuppressWarnings("null") // setPropertyMethodVoid can't be null when used
+    private static boolean setProperty(Object o, String name, String value) {
+        if (log.isDebugEnabled())
+            log.debug("IntrospectionUtils: setProperty(" +
+                    o.getClass() + " " + name + "=" + value + ")");
+
+        String setter = "set" + capitalize(name);
+
+        try {
+            Method methods[] = o.getClass().getMethods();
+            Method setPropertyMethodVoid = null;
+            Method setPropertyMethodBool = null;
+
+            // First, the ideal case - a setFoo( String ) method
+            for (int i = 0; i < methods.length; i++) {
+                Class<?> paramT[] = methods[i].getParameterTypes();
+                if (setter.equals(methods[i].getName()) && paramT.length == 1
+                        && "java.lang.String".equals(paramT[0].getName())) {
+
+                    methods[i].invoke(o, new Object[] { value });
+                    return true;
+                }
+            }
+
+            // Try a setFoo ( int ) or ( boolean )
+            for (int i = 0; i < methods.length; i++) {
+                boolean ok = true;
+                if (setter.equals(methods[i].getName())
+                        && methods[i].getParameterTypes().length == 1) {
+
+                    // match - find the type and invoke it
+                    Class<?> paramType = methods[i].getParameterTypes()[0];
+                    Object params[] = new Object[1];
+
+                    // Try a setFoo ( int )
+                    if ("java.lang.Integer".equals(paramType.getName())
+                            || "int".equals(paramType.getName())) {
+                        try {
+                            params[0] = new Integer(value);
+                        } catch (NumberFormatException ex) {
+                            ok = false;
+                        }
+                    // Try a setFoo ( long )
+                    }else if ("java.lang.Long".equals(paramType.getName())
+                                || "long".equals(paramType.getName())) {
+                            try {
+                                params[0] = new Long(value);
+                            } catch (NumberFormatException ex) {
+                                ok = false;
+                            }
+
+                        // Try a setFoo ( boolean )
+                    } else if ("java.lang.Boolean".equals(paramType.getName())
+                            || "boolean".equals(paramType.getName())) {
+                        params[0] = Boolean.valueOf(value);
+
+                        // Try a setFoo ( InetAddress )
+                    } else if ("java.net.InetAddress".equals(paramType
+                            .getName())) {
+                        try {
+                            params[0] = InetAddress.getByName(value);
+                        } catch (UnknownHostException exc) {
+                            if (log.isDebugEnabled())
+                                log.debug("IntrospectionUtils: Unable to resolve host name:" + value);
+                            ok = false;
+                        }
+
+                        // Unknown type
+                    } else {
+                        if (log.isDebugEnabled())
+                            log.debug("IntrospectionUtils: Unknown type " +
+                                    paramType.getName());
+                    }
+
+                    if (ok) {
+                        methods[i].invoke(o, params);
+                        return true;
+                    }
+                }
+
+                // save "setProperty" for later
+                if ("setProperty".equals(methods[i].getName())) {
+                    if (methods[i].getReturnType()==Boolean.TYPE){
+                        setPropertyMethodBool = methods[i];
+                    }else {
+                        setPropertyMethodVoid = methods[i];
+                    }
+
+                }
+            }
+
+            // Ok, no setXXX found, try a setProperty("name", "value")
+            if (setPropertyMethodBool != null || setPropertyMethodVoid != null) {
+                Object params[] = new Object[2];
+                params[0] = name;
+                params[1] = value;
+                if (setPropertyMethodBool != null) {
+                    try {
+                        return ((Boolean) setPropertyMethodBool.invoke(o, params)).booleanValue();
+                    }catch (IllegalArgumentException biae) {
+                        //the boolean method had the wrong
+                        //parameter types. lets try the other
+                        if (setPropertyMethodVoid!=null) {
+                            setPropertyMethodVoid.invoke(o, params);
+                            return true;
+                        }else {
+                            throw biae;
+                        }
+                    }
+                } else {
+                    setPropertyMethodVoid.invoke(o, params);
+                    return true;
+                }
+            }
+
+        } catch (IllegalArgumentException ex2) {
+            log.warn("IAE " + o + " " + name + " " + value, ex2);
+        } catch (SecurityException ex1) {
+            if (log.isDebugEnabled())
+                log.debug("IntrospectionUtils: SecurityException for " +
+                        o.getClass() + " " + name + "=" + value + ")", ex1);
+        } catch (IllegalAccessException iae) {
+            if (log.isDebugEnabled())
+                log.debug("IntrospectionUtils: IllegalAccessException for " +
+                        o.getClass() + " " + name + "=" + value + ")", iae);
+        } catch (InvocationTargetException ie) {
+            Throwable cause = ie.getCause();
+            if (cause instanceof ThreadDeath) {
+                throw (ThreadDeath) cause;
+            }
+            if (cause instanceof VirtualMachineError) {
+                throw (VirtualMachineError) cause;
+            }
+            if (log.isDebugEnabled())
+                log.debug("IntrospectionUtils: InvocationTargetException for " +
+                        o.getClass() + " " + name + "=" + value + ")", ie);
+        }
+        return false;
+    }
+
+    public static String capitalize(String name) {
+        if (name == null || name.length() == 0) {
+            return name;
+        }
+        char chars[] = name.toCharArray();
+        chars[0] = Character.toUpperCase(chars[0]);
+        return new String(chars);
+    }
+
+}
diff --git a/dblib/common/src/main/java/org/apache/tomcat/jdbc/pool/ClassLoaderUtil.java b/dblib/common/src/main/java/org/apache/tomcat/jdbc/pool/ClassLoaderUtil.java
new file mode 100644
index 0000000..23b5668
--- /dev/null
+++ b/dblib/common/src/main/java/org/apache/tomcat/jdbc/pool/ClassLoaderUtil.java
@@ -0,0 +1,81 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * openecomp
+ * ================================================================================
+ * Copyright (C) 2016 - 2017 AT&T
+ * ================================================================================
+ * Licensed 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.
+ * ============LICENSE_END=========================================================
+ */
+
+/*
+ * 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.tomcat.jdbc.pool;
+
+
+import org.apache.juli.logging.Log;
+import org.apache.juli.logging.LogFactory;
+
+public class ClassLoaderUtil {
+    private static final Log log = LogFactory.getLog(ClassLoaderUtil.class);
+
+    private static final boolean onlyAttemptFirstLoader =
+        Boolean.parseBoolean(System.getProperty("org.apache.tomcat.jdbc.pool.onlyAttemptCurrentClassLoader", "false"));
+
+    public static Class<?> loadClass(String className, ClassLoader... classLoaders) throws ClassNotFoundException {
+        ClassNotFoundException last = null;
+        StringBuilder errorMsg = null;
+        for (ClassLoader cl : classLoaders) {
+            try {
+                if (cl!=null) {
+                    if (log.isDebugEnabled()) {
+                        log.debug("Attempting to load class["+className+"] from "+cl);
+                    }
+                    return Class.forName(className, true, cl);
+                } else {
+                    throw new ClassNotFoundException("Classloader is null");
+                }
+            } catch (ClassNotFoundException x) {
+                last = x;
+                if (errorMsg==null) {
+                    errorMsg = new StringBuilder();
+                } else {
+                    errorMsg.append(';');
+                }
+                errorMsg.append("ClassLoader:");
+                errorMsg.append(cl);
+            }
+            if (onlyAttemptFirstLoader) {
+                break;
+            }
+        }
+        throw new ClassNotFoundException("Unable to load class: "+className+" from "+errorMsg, last);
+    }
+
+
+
+}
diff --git a/dblib/common/src/main/java/org/apache/tomcat/jdbc/pool/ConnectionPool.java b/dblib/common/src/main/java/org/apache/tomcat/jdbc/pool/ConnectionPool.java
new file mode 100644
index 0000000..7b081df
--- /dev/null
+++ b/dblib/common/src/main/java/org/apache/tomcat/jdbc/pool/ConnectionPool.java
@@ -0,0 +1,1500 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * openecomp
+ * ================================================================================
+ * Copyright (C) 2016 - 2017 AT&T
+ * ================================================================================
+ * Licensed 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.
+ * ============LICENSE_END=========================================================
+ */
+
+/*
+ * 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.tomcat.jdbc.pool;
+
+import java.lang.ref.WeakReference;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.Proxy;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.sql.Connection;
+import java.sql.SQLException;
+import java.util.Collections;
+import java.util.ConcurrentModificationException;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Set;
+import java.util.Timer;
+import java.util.TimerTask;
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Future;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.ThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.concurrent.atomic.AtomicLong;
+
+import org.apache.juli.logging.Log;
+import org.apache.juli.logging.LogFactory;
+
+/**
+ * Implementation of simple connection pool.
+ * The ConnectionPool uses a {@link PoolProperties} object for storing all the meta information about the connection pool.
+ * As the underlying implementation, the connection pool uses {@link java.util.concurrent.BlockingQueue} to store active and idle connections.
+ * A custom implementation of a fair {@link FairBlockingQueue} blocking queue is provided with the connection pool itself.
+ * @version 1.0
+ */
+public class ConnectionPool {
+
+    /**
+     * Default domain for objects registering with an mbean server
+     */
+    public static final String POOL_JMX_DOMAIN = "tomcat.jdbc";
+    /**
+     * Prefix type for JMX registration
+     */
+    public static final String POOL_JMX_TYPE_PREFIX = POOL_JMX_DOMAIN+":type=";
+
+    /**
+     * Logger
+     */
+    private static final Log log = LogFactory.getLog(ConnectionPool.class);
+
+    //===============================================================================
+    //         INSTANCE/QUICK ACCESS VARIABLE
+    //===============================================================================
+    /**
+     * Carries the size of the pool, instead of relying on a queue implementation
+     * that usually iterates over to get an exact count
+     */
+    private AtomicInteger size = new AtomicInteger(0);
+
+    /**
+     * All the information about the connection pool
+     * These are the properties the pool got instantiated with
+     */
+    private PoolConfiguration poolProperties;
+
+    /**
+     * Contains all the connections that are in use
+     * TODO - this shouldn't be a blocking queue, simply a list to hold our objects
+     */
+    private BlockingQueue<PooledConnection> busy;
+
+    /**
+     * Contains all the idle connections
+     */
+    private BlockingQueue<PooledConnection> idle;
+
+    /**
+     * The thread that is responsible for checking abandoned and idle threads
+     */
+    private volatile PoolCleaner poolCleaner;
+
+    /**
+     * Pool closed flag
+     */
+    private volatile boolean closed = false;
+
+    /**
+     * Since newProxyInstance performs the same operation, over and over
+     * again, it is much more optimized if we simply store the constructor ourselves.
+     */
+    private Constructor<?> proxyClassConstructor;
+
+    /**
+     * Executor service used to cancel Futures
+     */
+    private ThreadPoolExecutor cancellator = new ThreadPoolExecutor(0,1,1000,TimeUnit.MILLISECONDS,new LinkedBlockingQueue<Runnable>());
+
+    /**
+     * reference to the JMX mbean
+     */
+    protected org.apache.tomcat.jdbc.pool.jmx.ConnectionPool jmxPool = null;
+
+    /**
+     * counter to track how many threads are waiting for a connection
+     */
+    private AtomicInteger waitcount = new AtomicInteger(0);
+
+    private AtomicLong poolVersion = new AtomicLong(Long.MIN_VALUE);
+
+    /**
+     * The counters for statistics of the pool.
+     */
+    private final AtomicLong borrowedCount = new AtomicLong(0);
+    private final AtomicLong returnedCount = new AtomicLong(0);
+    private final AtomicLong createdCount = new AtomicLong(0);
+    private final AtomicLong releasedCount = new AtomicLong(0);
+    private final AtomicLong reconnectedCount = new AtomicLong(0);
+    private final AtomicLong removeAbandonedCount = new AtomicLong(0);
+    private final AtomicLong releasedIdleCount = new AtomicLong(0);
+
+    //===============================================================================
+    //         PUBLIC METHODS
+    //===============================================================================
+
+    /**
+     * Instantiate a connection pool. This will create connections if initialSize is larger than 0.
+     * The {@link PoolProperties} should not be reused for another connection pool.
+     * @param prop PoolProperties - all the properties for this connection pool
+     * @throws SQLException Pool initialization error
+     */
+    public ConnectionPool(PoolConfiguration prop) throws SQLException {
+        //setup quick access variables and pools
+        init(prop);
+    }
+
+
+    /**
+     * Retrieves a Connection future. If a connection is not available, one can block using future.get()
+     * until a connection has become available.
+     * If a connection is not retrieved, the Future must be cancelled in order for the connection to be returned
+     * to the pool.
+     * @return a Future containing a reference to the connection or the future connection
+     * @throws SQLException Cannot use asynchronous connect
+     */
+    public Future<Connection> getConnectionAsync() throws SQLException {
+        try {
+            PooledConnection pc = borrowConnection(0, null, null);
+            if (pc!=null) {
+                return new ConnectionFuture(pc);
+            }
+        }catch (SQLException x) {
+            if (x.getMessage().indexOf("NoWait")<0) {
+                throw x;
+            }
+        }
+        //we can only retrieve a future if the underlying queue supports it.
+        if (idle instanceof FairBlockingQueue<?>) {
+            Future<PooledConnection> pcf = ((FairBlockingQueue<PooledConnection>)idle).pollAsync();
+            return new ConnectionFuture(pcf);
+        } else if (idle instanceof MultiLockFairBlockingQueue<?>) {
+                Future<PooledConnection> pcf = ((MultiLockFairBlockingQueue<PooledConnection>)idle).pollAsync();
+                return new ConnectionFuture(pcf);
+        } else {
+            throw new SQLException("Connection pool is misconfigured, doesn't support async retrieval. Set the 'fair' property to 'true'");
+        }
+    }
+
+    /**
+     * Borrows a connection from the pool. If a connection is available (in the idle queue) or the pool has not reached
+     * {@link PoolProperties#maxActive maxActive} connections a connection is returned immediately.
+     * If no connection is available, the pool will attempt to fetch a connection for {@link PoolProperties#maxWait maxWait} milliseconds.
+     * @return Connection - a java.sql.Connection/javax.sql.PooledConnection reflection proxy, wrapping the underlying object.
+     * @throws SQLException - if the wait times out or a failure occurs creating a connection
+     */
+    public Connection getConnection() throws SQLException {
+        //check out a connection
+        PooledConnection con = borrowConnection(-1,null,null);
+        return setupConnection(con);
+    }
+
+
+    /**
+     * Borrows a connection from the pool. If a connection is available (in the
+     * idle queue) or the pool has not reached {@link PoolProperties#maxActive
+     * maxActive} connections a connection is returned immediately. If no
+     * connection is available, the pool will attempt to fetch a connection for
+     * {@link PoolProperties#maxWait maxWait} milliseconds.
+     * @param username The user name to use for the connection
+     * @param password The password for the connection
+     * @return Connection - a java.sql.Connection/javax.sql.PooledConnection
+     *         reflection proxy, wrapping the underlying object.
+     * @throws SQLException
+     *             - if the wait times out or a failure occurs creating a
+     *             connection
+     */
+    public Connection getConnection(String username, String password) throws SQLException {
+        // check out a connection
+        PooledConnection con = borrowConnection(-1, username, password);
+        return setupConnection(con);
+    }
+
+    /**
+     * Returns the name of this pool
+     * @return String - the name of the pool
+     */
+    public String getName() {
+        return getPoolProperties().getPoolName();
+    }
+
+    /**
+     * Return the number of threads waiting for a connection
+     * @return number of threads waiting for a connection
+     */
+    public int getWaitCount() {
+        return waitcount.get();
+    }
+
+    /**
+     * Returns the pool properties associated with this connection pool
+     * @return PoolProperties
+     *
+     */
+    public PoolConfiguration getPoolProperties() {
+        return this.poolProperties;
+    }
+
+    /**
+     * Returns the total size of this pool, this includes both busy and idle connections
+     * @return int - number of established connections to the database
+     */
+    public int getSize() {
+        return size.get();
+    }
+
+    /**
+     * Returns the number of connections that are in use
+     * @return int - number of established connections that are being used by the application
+     */
+    public int getActive() {
+        return busy.size();
+    }
+
+    /**
+     * Returns the number of idle connections
+     * @return int - number of established connections not being used
+     */
+    public int getIdle() {
+        return idle.size();
+    }
+
+    /**
+     * Returns true if {@link #close close} has been called, and the connection pool is unusable
+     * @return boolean
+     */
+    public  boolean isClosed() {
+        return this.closed;
+    }
+
+    //===============================================================================
+    //         PROTECTED METHODS
+    //===============================================================================
+
+
+    /**
+     * configures a pooled connection as a proxy.
+     * This Proxy implements {@link java.sql.Connection} and {@link javax.sql.PooledConnection} interfaces.
+     * All calls on {@link java.sql.Connection} methods will be propagated down to the actual JDBC connection except for the
+     * {@link java.sql.Connection#close()} method.
+     * @param con a {@link PooledConnection} to wrap in a Proxy
+     * @return a {@link java.sql.Connection} object wrapping a pooled connection.
+     * @throws SQLException if an interceptor can't be configured, if the proxy can't be instantiated
+     */
+    protected Connection setupConnection(PooledConnection con) throws SQLException {
+        //fetch previously cached interceptor proxy - one per connection
+        JdbcInterceptor handler = con.getHandler();
+        if (handler==null) {
+            //build the proxy handler
+            handler = new ProxyConnection(this,con,getPoolProperties().isUseEquals());
+            //set up the interceptor chain
+            PoolProperties.InterceptorDefinition[] proxies = getPoolProperties().getJdbcInterceptorsAsArray();
+            for (int i=proxies.length-1; i>=0; i--) {
+                try {
+                    //create a new instance
+                    JdbcInterceptor interceptor = proxies[i].getInterceptorClass().newInstance();
+                    //configure properties
+                    interceptor.setProperties(proxies[i].getProperties());
+                    //setup the chain
+                    interceptor.setNext(handler);
+                    //call reset
+                    interceptor.reset(this, con);
+                    //configure the last one to be held by the connection
+                    handler = interceptor;
+                }catch(Exception x) {
+                    SQLException sx = new SQLException("Unable to instantiate interceptor chain.");
+                    sx.initCause(x);
+                    throw sx;
+                }
+            }
+            //cache handler for the next iteration
+            con.setHandler(handler);
+        } else {
+            JdbcInterceptor next = handler;
+            //we have a cached handler, reset it
+            while (next!=null) {
+                next.reset(this, con);
+                next = next.getNext();
+            }
+        }
+
+        try {
+            getProxyConstructor(con.getXAConnection() != null);
+            //create the proxy
+            //TODO possible optimization, keep track if this connection was returned properly, and don't generate a new facade
+            Connection connection = null;
+            if (getPoolProperties().getUseDisposableConnectionFacade() ) {
+                connection = (Connection)proxyClassConstructor.newInstance(new Object[] { new DisposableConnectionFacade(handler) });
+            } else {
+                connection = (Connection)proxyClassConstructor.newInstance(new Object[] {handler});
+            }
+            //return the connection
+            return connection;
+        }catch (Exception x) {
+            SQLException s = new SQLException();
+            s.initCause(x);
+            throw s;
+        }
+
+    }
+
+    /**
+     * Creates and caches a {@link java.lang.reflect.Constructor} used to instantiate the proxy object.
+     * We cache this, since the creation of a constructor is fairly slow.
+     * @param xa Use a XA connection
+     * @return constructor used to instantiate the wrapper object
+     * @throws NoSuchMethodException Failed to get a constructor
+     */
+    public Constructor<?> getProxyConstructor(boolean xa) throws NoSuchMethodException {
+        //cache the constructor
+        if (proxyClassConstructor == null ) {
+            Class<?> proxyClass = xa ?
+                Proxy.getProxyClass(ConnectionPool.class.getClassLoader(), new Class[] {java.sql.Connection.class,javax.sql.PooledConnection.class, javax.sql.XAConnection.class}) :
+                Proxy.getProxyClass(ConnectionPool.class.getClassLoader(), new Class[] {java.sql.Connection.class,javax.sql.PooledConnection.class});
+            proxyClassConstructor = proxyClass.getConstructor(new Class[] { InvocationHandler.class });
+        }
+        return proxyClassConstructor;
+    }
+
+    /**
+     * Closes the pool and all disconnects all idle connections
+     * Active connections will be closed upon the {@link java.sql.Connection#close close} method is called
+     * on the underlying connection instead of being returned to the pool
+     * @param force - true to even close the active connections
+     */
+    protected void close(boolean force) {
+        //are we already closed
+        if (this.closed) return;
+        //prevent other threads from entering
+        this.closed = true;
+        //stop background thread
+        if (poolCleaner!=null) {
+            poolCleaner.stopRunning();
+        }
+
+        /* release all idle connections */
+        BlockingQueue<PooledConnection> pool = (idle.size()>0)?idle:(force?busy:idle);
+        while (pool.size()>0) {
+            try {
+                //retrieve the next connection
+                PooledConnection con = pool.poll(1000, TimeUnit.MILLISECONDS);
+                //close it and retrieve the next one, if one is available
+                while (con != null) {
+                    //close the connection
+                    if (pool==idle)
+                        release(con);
+                    else
+                        abandon(con);
+                    if (pool.size()>0) {
+                        con = pool.poll(1000, TimeUnit.MILLISECONDS);
+                    } else {
+                        break;
+                    }
+                } //while
+            } catch (InterruptedException ex) {
+                if (getPoolProperties().getPropagateInterruptState()) {
+                    Thread.currentThread().interrupt();
+                }
+            }
+            if (pool.size()==0 && force && pool!=busy) pool = busy;
+        }
+        if (this.getPoolProperties().isJmxEnabled()) this.jmxPool = null;
+        PoolProperties.InterceptorDefinition[] proxies = getPoolProperties().getJdbcInterceptorsAsArray();
+        for (int i=0; i<proxies.length; i++) {
+            try {
+                JdbcInterceptor interceptor = proxies[i].getInterceptorClass().newInstance();
+                interceptor.setProperties(proxies[i].getProperties());
+                interceptor.poolClosed(this);
+            }catch (Exception x) {
+                log.debug("Unable to inform interceptor of pool closure.",x);
+            }
+        }
+    } //closePool
+
+
+    /**
+     * Initialize the connection pool - called from the constructor
+     * @param properties PoolProperties - properties used to initialize the pool with
+     * @throws SQLException if initialization fails
+     */
+    protected void init(PoolConfiguration properties) throws SQLException {
+        poolProperties = properties;
+
+        //make sure the pool is properly configured
+        checkPoolConfiguration(properties);
+
+        //make space for 10 extra in case we flow over a bit
+        busy = new LinkedBlockingQueue<>();
+        //busy = new FairBlockingQueue<PooledConnection>();
+        //make space for 10 extra in case we flow over a bit
+        if (properties.isFairQueue()) {
+            idle = new FairBlockingQueue<>();
+            //idle = new MultiLockFairBlockingQueue<PooledConnection>();
+            //idle = new LinkedTransferQueue<PooledConnection>();
+            //idle = new ArrayBlockingQueue<PooledConnection>(properties.getMaxActive(),false);
+        } else {
+            idle = new LinkedBlockingQueue<>();
+        }
+
+        initializePoolCleaner(properties);
+
+        //create JMX MBean
+        if (this.getPoolProperties().isJmxEnabled()) createMBean();
+
+        //Parse and create an initial set of interceptors. Letting them know the pool has started.
+        //These interceptors will not get any connection.
+        PoolProperties.InterceptorDefinition[] proxies = getPoolProperties().getJdbcInterceptorsAsArray();
+        for (int i=0; i<proxies.length; i++) {
+            try {
+                if (log.isDebugEnabled()) {
+                    log.debug("Creating interceptor instance of class:"+proxies[i].getInterceptorClass());
+                }
+                JdbcInterceptor interceptor = proxies[i].getInterceptorClass().newInstance();
+                interceptor.setProperties(proxies[i].getProperties());
+                interceptor.poolStarted(this);
+            }catch (Exception x) {
+                log.error("Unable to inform interceptor of pool start.",x);
+                if (jmxPool!=null) jmxPool.notify(org.apache.tomcat.jdbc.pool.jmx.ConnectionPool.NOTIFY_INIT, getStackTrace(x));
+                close(true);
+                SQLException ex = new SQLException();
+                ex.initCause(x);
+                throw ex;
+            }
+        }
+
+        //initialize the pool with its initial set of members
+        PooledConnection[] initialPool = new PooledConnection[poolProperties.getInitialSize()];
+        try {
+            for (int i = 0; i < initialPool.length; i++) {
+                initialPool[i] = this.borrowConnection(0, null, null); //don't wait, should be no contention
+            } //for
+
+        } catch (SQLException x) {
+            log.error("Unable to create initial connections of pool.", x);
+            if (!poolProperties.isIgnoreExceptionOnPreLoad()) {
+                if (jmxPool!=null) jmxPool.notify(org.apache.tomcat.jdbc.pool.jmx.ConnectionPool.NOTIFY_INIT, getStackTrace(x));
+                close(true);
+                throw x;
+            }
+        } finally {
+            //return the members as idle to the pool
+            for (int i = 0; i < initialPool.length; i++) {
+                if (initialPool[i] != null) {
+                    try {this.returnConnection(initialPool[i]);}catch(Exception x){/*NOOP*/}
+                } //end if
+            } //for
+        } //catch
+
+        closed = false;
+    }
+
+    public void checkPoolConfiguration(PoolConfiguration properties) {
+        //make sure the pool is properly configured
+        if (properties.getMaxActive()<1) {
+            log.warn("maxActive is smaller than 1, setting maxActive to: "+PoolProperties.DEFAULT_MAX_ACTIVE);
+            properties.setMaxActive(PoolProperties.DEFAULT_MAX_ACTIVE);
+        }
+        if (properties.getMaxActive()<properties.getInitialSize()) {
+            log.warn("initialSize is larger than maxActive, setting initialSize to: "+properties.getMaxActive());
+            properties.setInitialSize(properties.getMaxActive());
+        }
+        if (properties.getMinIdle()>properties.getMaxActive()) {
+            log.warn("minIdle is larger than maxActive, setting minIdle to: "+properties.getMaxActive());
+            properties.setMinIdle(properties.getMaxActive());
+        }
+        if (properties.getMaxIdle()>properties.getMaxActive()) {
+            log.warn("maxIdle is larger than maxActive, setting maxIdle to: "+properties.getMaxActive());
+            properties.setMaxIdle(properties.getMaxActive());
+        }
+        if (properties.getMaxIdle()<properties.getMinIdle()) {
+            log.warn("maxIdle is smaller than minIdle, setting maxIdle to: "+properties.getMinIdle());
+            properties.setMaxIdle(properties.getMinIdle());
+        }
+    }
+
+    public void initializePoolCleaner(PoolConfiguration properties) {
+        //if the evictor thread is supposed to run, start it now
+        if (properties.isPoolSweeperEnabled()) {
+            poolCleaner = new PoolCleaner(this, properties.getTimeBetweenEvictionRunsMillis());
+            poolCleaner.start();
+        } //end if
+    }
+
+    public void terminatePoolCleaner() {
+        if (poolCleaner!= null) {
+            poolCleaner.stopRunning();
+            poolCleaner = null;
+        }
+    }
+
+
+//===============================================================================
+//         CONNECTION POOLING IMPL LOGIC
+//===============================================================================
+
+    /**
+     * thread safe way to abandon a connection
+     * signals a connection to be abandoned.
+     * this will disconnect the connection, and log the stack trace if logAbandoned=true
+     * @param con PooledConnection
+     */
+    protected void abandon(PooledConnection con) {
+        if (con == null)
+            return;
+        try {
+            con.lock();
+            String trace = con.getStackTrace();
+            if (getPoolProperties().isLogAbandoned()) {
+                log.warn("Connection has been abandoned " + con + ":" + trace);
+            }
+            if (jmxPool!=null) {
+                jmxPool.notify(org.apache.tomcat.jdbc.pool.jmx.ConnectionPool.NOTIFY_ABANDON, trace);
+            }
+            //release the connection
+            removeAbandonedCount.incrementAndGet();
+            release(con);
+        } finally {
+            con.unlock();
+        }
+    }
+
+    /**
+     * Thread safe way to suspect a connection. Similar to
+     * {@link #abandon(PooledConnection)}, but instead of actually abandoning
+     * the connection, this will log a warning and set the suspect flag on the
+     * {@link PooledConnection} if logAbandoned=true
+     *
+     * @param con PooledConnection
+     */
+    protected void suspect(PooledConnection con) {
+        if (con == null)
+            return;
+        if (con.isSuspect())
+            return;
+        try {
+            con.lock();
+            String trace = con.getStackTrace();
+            if (getPoolProperties().isLogAbandoned()) {
+                log.warn("Connection has been marked suspect, possibly abandoned " + con + "["+(System.currentTimeMillis()-con.getTimestamp())+" ms.]:" + trace);
+            }
+            if (jmxPool!=null) {
+                jmxPool.notify(org.apache.tomcat.jdbc.pool.jmx.ConnectionPool.SUSPECT_ABANDONED_NOTIFICATION, trace);
+            }
+            con.setSuspect(true);
+        } finally {
+            con.unlock();
+        }
+    }
+
+    /**
+     * thread safe way to release a connection
+     * @param con PooledConnection
+     */
+    protected void release(PooledConnection con) {
+        if (con == null)
+            return;
+        try {
+            con.lock();
+            if (con.release()) {
+                //counter only decremented once
+                size.addAndGet(-1);
+                con.setHandler(null);
+            }
+            releasedCount.incrementAndGet();
+        } finally {
+            con.unlock();
+        }
+        // we've asynchronously reduced the number of connections
+        // we could have threads stuck in idle.poll(timeout) that will never be
+        // notified
+        if (waitcount.get() > 0) {
+            idle.offer(create(true));
+        }
+    }
+
+    /**
+     * Thread safe way to retrieve a connection from the pool
+     * @param wait - time to wait, overrides the maxWait from the properties,
+     * set to -1 if you wish to use maxWait, 0 if you wish no wait time.
+     * @param username The user name to use for the connection
+     * @param password The password for the connection
+     * @return a connection
+     * @throws SQLException Failed to get a connection
+     */
+    private PooledConnection borrowConnection(int wait, String username, String password) throws SQLException {
+
+        if (isClosed()) {
+            throw new SQLException("Connection pool closed.");
+        } //end if
+
+        //get the current time stamp
+        long now = System.currentTimeMillis();
+        //see if there is one available immediately
+        PooledConnection con = idle.poll();
+
+        while (true) {
+            if (con!=null) {
+                //configure the connection and return it
+                PooledConnection result = borrowConnection(now, con, username, password);
+                borrowedCount.incrementAndGet();
+                if (result!=null) return result;
+            }
+
+            //if we get here, see if we need to create one
+            //this is not 100% accurate since it doesn't use a shared
+            //atomic variable - a connection can become idle while we are creating
+            //a new connection
+            if (size.get() < getPoolProperties().getMaxActive()) {
+                //atomic duplicate check
+                if (size.addAndGet(1) > getPoolProperties().getMaxActive()) {
+                    //if we got here, two threads passed through the first if
+                    size.decrementAndGet();
+                } else {
+                    //create a connection, we're below the limit
+                    return createConnection(now, con, username, password);
+                }
+            } //end if
+
+            //calculate wait time for this iteration
+            long maxWait = wait;
+            //if the passed in wait time is -1, means we should use the pool property value
+            if (wait==-1) {
+                maxWait = (getPoolProperties().getMaxWait()<=0)?Long.MAX_VALUE:getPoolProperties().getMaxWait();
+            }
+
+            long timetowait = Math.max(0, maxWait - (System.currentTimeMillis() - now));
+            waitcount.incrementAndGet();
+            try {
+                //retrieve an existing connection
+                con = idle.poll(timetowait, TimeUnit.MILLISECONDS);
+            } catch (InterruptedException ex) {
+                if (getPoolProperties().getPropagateInterruptState()) {
+                    Thread.currentThread().interrupt();
+                }
+                SQLException sx = new SQLException("Pool wait interrupted.");
+                sx.initCause(ex);
+                throw sx;
+            } finally {
+                waitcount.decrementAndGet();
+            }
+            if (maxWait==0 && con == null) { //no wait, return one if we have one
+                if (jmxPool!=null) {
+                    jmxPool.notify(org.apache.tomcat.jdbc.pool.jmx.ConnectionPool.POOL_EMPTY, "Pool empty - no wait.");
+                }
+                throw new PoolExhaustedException("[" + Thread.currentThread().getName()+"] " +
+                        "NoWait: Pool empty. Unable to fetch a connection, none available["+busy.size()+" in use].");
+            }
+            //we didn't get a connection, lets see if we timed out
+            if (con == null) {
+                if ((System.currentTimeMillis() - now) >= maxWait) {
+                    if (jmxPool!=null) {
+                        jmxPool.notify(org.apache.tomcat.jdbc.pool.jmx.ConnectionPool.POOL_EMPTY, "Pool empty - timeout.");
+                    }
+                    throw new PoolExhaustedException("[" + Thread.currentThread().getName()+"] " +
+                        "Timeout: Pool empty. Unable to fetch a connection in " + (maxWait / 1000) +
+                        " seconds, none available[size:"+size.get() +"; busy:"+busy.size()+"; idle:"+idle.size()+"; lastwait:"+timetowait+"].");
+                } else {
+                    //no timeout, lets try again
+                    continue;
+                }
+            }
+        } //while
+    }
+
+    /**
+     * Creates a JDBC connection and tries to connect to the database.
+     * @param now timestamp of when this was called
+     * @param notUsed Argument not used
+     * @param username The user name to use for the connection
+     * @param password The password for the connection
+     * @return a PooledConnection that has been connected
+     * @throws SQLException Failed to get a connection
+     */
+    protected PooledConnection createConnection(long now, PooledConnection notUsed, String username, String password) throws SQLException {
+        //no connections where available we'll create one
+        PooledConnection con = create(false);
+        if (username!=null) con.getAttributes().put(PooledConnection.PROP_USER, username);
+        if (password!=null) con.getAttributes().put(PooledConnection.PROP_PASSWORD, password);
+        boolean error = false;
+        try {
+            //connect and validate the connection
+            con.lock();
+            con.connect();
+            if (con.validate(PooledConnection.VALIDATE_INIT)) {
+                //no need to lock a new one, its not contented
+                con.setTimestamp(now);
+                if (getPoolProperties().isLogAbandoned()) {
+                    con.setStackTrace(getThreadDump());
+                }
+                if (!busy.offer(con)) {
+                    log.debug("Connection doesn't fit into busy array, connection will not be traceable.");
+                }
+                createdCount.incrementAndGet();
+                return con;
+            } else {
+                //validation failed, make sure we disconnect
+                //and clean up
+                throw new SQLException("Validation Query Failed, enable logValidationErrors for more details.");
+            } //end if
+        } catch (Exception e) {
+            error = true;
+            if (log.isDebugEnabled())
+                log.debug("Unable to create a new JDBC connection.", e);
+            if (e instanceof SQLException) {
+                throw (SQLException)e;
+            } else {
+                SQLException ex = new SQLException(e.getMessage());
+                ex.initCause(e);
+                throw ex;
+            }
+        } finally {
+            // con can never be null here
+            if (error ) {
+                release(con);
+            }
+            con.unlock();
+        }//catch
+    }
+
+    /**
+     * Validates and configures a previously idle connection
+     * @param now - timestamp
+     * @param con - the connection to validate and configure
+     * @param username The user name to use for the connection
+     * @param password The password for the connection
+     * @return a connection
+     * @throws SQLException if a validation error happens
+     */
+    protected PooledConnection borrowConnection(long now, PooledConnection con, String username, String password) throws SQLException {
+        //we have a connection, lets set it up
+
+        //flag to see if we need to nullify
+        boolean setToNull = false;
+        try {
+            con.lock();
+            if (con.isReleased()) {
+                return null;
+            }
+
+            //evaluate username/password change as well as max age functionality
+            boolean forceReconnect = con.shouldForceReconnect(username, password) || con.isMaxAgeExpired();
+
+            if (!con.isDiscarded() && !con.isInitialized()) {
+                //here it states that the connection not discarded, but the connection is null
+                //don't attempt a connect here. It will be done during the reconnect.
+                forceReconnect = true;
+            }
+
+            if (!forceReconnect) {
+                if ((!con.isDiscarded()) && con.validate(PooledConnection.VALIDATE_BORROW)) {
+                    //set the timestamp
+                    con.setTimestamp(now);
+                    if (getPoolProperties().isLogAbandoned()) {
+                        //set the stack trace for this pool
+                        con.setStackTrace(getThreadDump());
+                    }
+                    if (!busy.offer(con)) {
+                        log.debug("Connection doesn't fit into busy array, connection will not be traceable.");
+                    }
+                    return con;
+                }
+            }
+            //if we reached here, that means the connection
+            //is either has another principal, is discarded or validation failed.
+            //we will make one more attempt
+            //in order to guarantee that the thread that just acquired
+            //the connection shouldn't have to poll again.
+            try {
+                con.reconnect();
+                reconnectedCount.incrementAndGet();
+                int validationMode = getPoolProperties().isTestOnConnect() || getPoolProperties().getInitSQL()!=null ?
+                    PooledConnection.VALIDATE_INIT :
+                    PooledConnection.VALIDATE_BORROW;
+
+                if (con.validate(validationMode)) {
+                    //set the timestamp
+                    con.setTimestamp(now);
+                    if (getPoolProperties().isLogAbandoned()) {
+                        //set the stack trace for this pool
+                        con.setStackTrace(getThreadDump());
+                    }
+                    if (!busy.offer(con)) {
+                        log.debug("Connection doesn't fit into busy array, connection will not be traceable.");
+                    }
+                    return con;
+                } else {
+                    //validation failed.
+                    throw new SQLException("Failed to validate a newly established connection.");
+                }
+            } catch (Exception x) {
+                release(con);
+                setToNull = true;
+                if (x instanceof SQLException) {
+                    throw (SQLException)x;
+                } else {
+                    SQLException ex  = new SQLException(x.getMessage());
+                    ex.initCause(x);
+                    throw ex;
+                }
+            }
+        } finally {
+            con.unlock();
+            if (setToNull) {
+                con = null;
+            }
+        }
+    }
+    /**
+     * Terminate the current transaction for the given connection.
+     * @param con The connection
+     * @return <code>true</code> if the connection TX termination succeeded
+     *         otherwise <code>false</code>
+     */
+    protected boolean terminateTransaction(PooledConnection con) {
+        try {
+            if (Boolean.FALSE.equals(con.getPoolProperties().getDefaultAutoCommit())) {
+                if (this.getPoolProperties().getRollbackOnReturn()) {
+                    boolean autocommit = con.getConnection().getAutoCommit();
+                    if (!autocommit) con.getConnection().rollback();
+                } else if (this.getPoolProperties().getCommitOnReturn()) {
+                    boolean autocommit = con.getConnection().getAutoCommit();
+                    if (!autocommit) con.getConnection().commit();
+                }
+            }
+            return true;
+        } catch (SQLException x) {
+            log.warn("Unable to terminate transaction, connection will be closed.",x);
+            return false;
+        }
+
+    }
+
+    /**
+     * Determines if a connection should be closed upon return to the pool.
+     * @param con - the connection
+     * @param action - the validation action that should be performed
+     * @return <code>true</code> if the connection should be closed
+     */
+    protected boolean shouldClose(PooledConnection con, int action) {
+        if (con.getConnectionVersion() < getPoolVersion()) return true;
+        if (con.isDiscarded()) return true;
+        if (isClosed()) return true;
+        if (!con.validate(action)) return true;
+        if (!terminateTransaction(con)) return true;
+        if (con.isMaxAgeExpired()) return true;
+        else return false;
+    }
+
+    /**
+     * Returns a connection to the pool
+     * If the pool is closed, the connection will be released
+     * If the connection is not part of the busy queue, it will be released.
+     * If {@link PoolProperties#testOnReturn} is set to true it will be validated
+     * @param con PooledConnection to be returned to the pool
+     */
+    protected void returnConnection(PooledConnection con) {
+        if (isClosed()) {
+            //if the connection pool is closed
+            //close the connection instead of returning it
+            release(con);
+            return;
+        } //end if
+
+        if (con != null) {
+            try {
+                returnedCount.incrementAndGet();
+                con.lock();
+                if (con.isSuspect()) {
+                    if (poolProperties.isLogAbandoned() && log.isInfoEnabled()) {
+                        log.info("Connection(" + con + ") that has been marked suspect was returned."
+                                + " The processing time is " + (System.currentTimeMillis()-con.getTimestamp()) + " ms.");
+                    }
+                    if (jmxPool!=null) {
+                        jmxPool.notify(org.apache.tomcat.jdbc.pool.jmx.ConnectionPool.SUSPECT_RETURNED_NOTIFICATION,
+                                "Connection(" + con + ") that has been marked suspect was returned.");
+                    }
+                }
+                if (busy.remove(con)) {
+
+                    if (!shouldClose(con,PooledConnection.VALIDATE_RETURN)) {
+                        con.setStackTrace(null);
+                        con.setTimestamp(System.currentTimeMillis());
+                        if (((idle.size()>=poolProperties.getMaxIdle()) && !poolProperties.isPoolSweeperEnabled()) || (!idle.offer(con))) {
+                            if (log.isDebugEnabled()) {
+                                log.debug("Connection ["+con+"] will be closed and not returned to the pool, idle["+idle.size()+"]>=maxIdle["+poolProperties.getMaxIdle()+"] idle.offer failed.");
+                            }
+                            release(con);
+                        }
+                    } else {
+                        if (log.isDebugEnabled()) {
+                            log.debug("Connection ["+con+"] will be closed and not returned to the pool.");
+                        }
+                        release(con);
+                    } //end if
+                } else {
+                    if (log.isDebugEnabled()) {
+                        log.debug("Connection ["+con+"] will be closed and not returned to the pool, busy.remove failed.");
+                    }
+                    release(con);
+                }
+            } finally {
+                con.unlock();
+            }
+        } //end if
+    } //checkIn
+
+    /**
+     * Determines if a connection should be abandoned based on
+     * {@link PoolProperties#abandonWhenPercentageFull} setting.
+     * @return <code>true</code> if the connection should be abandoned
+     */
+    protected boolean shouldAbandon() {
+        if (!poolProperties.isRemoveAbandoned()) return false;
+        if (poolProperties.getAbandonWhenPercentageFull()==0) return true;
+        float used = busy.size();
+        float max  = poolProperties.getMaxActive();
+        float perc = poolProperties.getAbandonWhenPercentageFull();
+        return (used/max*100f)>=perc;
+    }
+
+    /**
+     * Iterates through all the busy connections and checks for connections that have timed out
+     */
+    public void checkAbandoned() {
+        try {
+            if (busy.size()==0) return;
+            Iterator<PooledConnection> locked = busy.iterator();
+            int sto = getPoolProperties().getSuspectTimeout();
+            while (locked.hasNext()) {
+                PooledConnection con = locked.next();
+                boolean setToNull = false;
+                try {
+                    con.lock();
+                    //the con has been returned to the pool or released
+                    //ignore it
+                    if (idle.contains(con) || con.isReleased())
+                        continue;
+                    long time = con.getTimestamp();
+                    long now = System.currentTimeMillis();
+                    if (shouldAbandon() && (now - time) > con.getAbandonTimeout()) {
+                        busy.remove(con);
+                        abandon(con);
+                        setToNull = true;
+                    } else if (sto > 0 && (now - time) > (sto * 1000L)) {
+                        suspect(con);
+                    } else {
+                        //do nothing
+                    } //end if
+                } finally {
+                    con.unlock();
+                    if (setToNull)
+                        con = null;
+                }
+            } //while
+        } catch (ConcurrentModificationException e) {
+            log.debug("checkAbandoned failed." ,e);
+        } catch (Exception e) {
+            log.warn("checkAbandoned failed, it will be retried.",e);
+        }
+    }
+
+    /**
+     * Iterates through the idle connections and resizes the idle pool based on parameters
+     * {@link PoolProperties#maxIdle}, {@link PoolProperties#minIdle}, {@link PoolProperties#minEvictableIdleTimeMillis}
+     */
+    public void checkIdle() {
+        checkIdle(false);
+    }
+
+    public void checkIdle(boolean ignoreMinSize) {
+
+        try {
+            if (idle.size()==0) return;
+            long now = System.currentTimeMillis();
+            Iterator<PooledConnection> unlocked = idle.iterator();
+            while ( (ignoreMinSize || (idle.size()>=getPoolProperties().getMinIdle())) && unlocked.hasNext()) {
+                PooledConnection con = unlocked.next();
+                boolean setToNull = false;
+                try {
+                    con.lock();
+                    //the con been taken out, we can't clean it up
+                    if (busy.contains(con))
+                        continue;
+                    long time = con.getTimestamp();
+                    if (shouldReleaseIdle(now, con, time)) {
+                        releasedIdleCount.incrementAndGet();
+                        release(con);
+                        idle.remove(con);
+                        setToNull = true;
+                    } else {
+                        //do nothing
+                    } //end if
+                } finally {
+                    con.unlock();
+                    if (setToNull)
+                        con = null;
+                }
+            } //while
+        } catch (ConcurrentModificationException e) {
+            log.debug("checkIdle failed." ,e);
+        } catch (Exception e) {
+            log.warn("checkIdle failed, it will be retried.",e);
+        }
+
+    }
+
+
+    protected boolean shouldReleaseIdle(long now, PooledConnection con, long time) {
+        if (con.getConnectionVersion() < getPoolVersion()) return true;
+        else return (con.getReleaseTime()>0) && ((now - time) > con.getReleaseTime()) && (getSize()>getPoolProperties().getMinIdle());
+    }
+
+    /**
+     * Forces a validation of all idle connections if {@link PoolProperties#testWhileIdle} is set.
+     */
+    public void testAllIdle() {
+        try {
+            if (idle.size()==0) return;
+            Iterator<PooledConnection> unlocked = idle.iterator();
+            while (unlocked.hasNext()) {
+                PooledConnection con = unlocked.next();
+                try {
+                    con.lock();
+                    //the con been taken out, we can't clean it up
+                    if (busy.contains(con))
+                        continue;
+                    if (!con.validate(PooledConnection.VALIDATE_IDLE)) {
+                        idle.remove(con);
+                        release(con);
+                    }
+                } finally {
+                    con.unlock();
+                }
+            } //while
+        } catch (ConcurrentModificationException e) {
+            log.debug("testAllIdle failed." ,e);
+        } catch (Exception e) {
+            log.warn("testAllIdle failed, it will be retried.",e);
+        }
+
+    }
+
+    /**
+     * Creates a stack trace representing the existing thread's current state.
+     * @return a string object representing the current state.
+     * TODO investigate if we simply should store {@link java.lang.Thread#getStackTrace()} elements
+     */
+    protected static String getThreadDump() {
+        Exception x = new Exception();
+        x.fillInStackTrace();
+        return getStackTrace(x);
+    }
+
+    /**
+     * Convert an exception into a String
+     * @param x - the throwable
+     * @return a string representing the stack trace
+     */
+    public static String getStackTrace(Throwable x) {
+        if (x == null) {
+            return null;
+        } else {
+            java.io.ByteArrayOutputStream bout = new java.io.ByteArrayOutputStream();
+            java.io.PrintStream writer = new java.io.PrintStream(bout);
+            x.printStackTrace(writer);
+            String result = bout.toString();
+            return (x.getMessage()!=null && x.getMessage().length()>0)? x.getMessage()+";"+result:result;
+        } //end if
+    }
+
+
+    /**
+     * Create a new pooled connection object. Not connected nor validated.
+     * @param incrementCounter <code>true</code> to increment the connection count
+     * @return a pooled connection object
+     */
+    protected PooledConnection create(boolean incrementCounter) {
+        if (incrementCounter) size.incrementAndGet();
+        PooledConnection con = new PooledConnection(getPoolProperties(), this);
+        return con;
+    }
+
+    /**
+     * Purges all connections in the pool.
+     * For connections currently in use, these connections will be
+     * purged when returned on the pool. This call also
+     * purges connections that are idle and in the pool
+     * To only purge used/active connections see {@link #purgeOnReturn()}
+     */
+    public void purge() {
+        purgeOnReturn();
+        checkIdle(true);
+    }
+
+    /**
+     * Purges connections when they are returned from the pool.
+     * This call does not purge idle connections until they are used.
+     * To purge idle connections see {@link #purge()}
+     */
+    public void purgeOnReturn() {
+        poolVersion.incrementAndGet();
+    }
+
+    /**
+     * Hook to perform final actions on a pooled connection object once it has been disconnected and will be discarded
+     * @param con The connection
+     */
+    protected void finalize(PooledConnection con) {
+        JdbcInterceptor handler = con.getHandler();
+        while (handler!=null) {
+            handler.reset(null, null);
+            handler=handler.getNext();
+        }
+    }
+
+    /**
+     * Hook to perform final actions on a pooled connection object once it has been disconnected and will be discarded
+     * @param con The connection
+     * @param finalizing <code>true</code> if finalizing the connection
+     */
+    protected void disconnectEvent(PooledConnection con, boolean finalizing) {
+        JdbcInterceptor handler = con.getHandler();
+        while (handler!=null) {
+            handler.disconnected(this, con, finalizing);
+            handler=handler.getNext();
+        }
+    }
+
+    /**
+     * Return the object that is potentially registered in JMX for notifications
+     * @return the object implementing the {@link org.apache.tomcat.jdbc.pool.jmx.ConnectionPoolMBean} interface
+     */
+    public org.apache.tomcat.jdbc.pool.jmx.ConnectionPool getJmxPool() {
+        return jmxPool;
+    }
+
+    /**
+     * Create MBean object that can be registered.
+     */
+    protected void createMBean() {
+        try {
+            jmxPool = new org.apache.tomcat.jdbc.pool.jmx.ConnectionPool(this);
+        } catch (Exception x) {
+            log.warn("Unable to start JMX integration for connection pool. Instance["+getName()+"] can't be monitored.",x);
+        }
+    }
+
+    /**
+     * The total number of connections borrowed from this pool.
+     * @return the borrowed connection count
+     */
+    public long getBorrowedCount() {
+        return borrowedCount.get();
+    }
+
+    /**
+     * The total number of connections returned to this pool.
+     * @return the returned connection count
+     */
+    public long getReturnedCount() {
+        return returnedCount.get();
+    }
+
+    /**
+     * The total number of connections created by this pool.
+     * @return the created connection count
+     */
+    public long getCreatedCount() {
+        return createdCount.get();
+    }
+
+    /**
+     * The total number of connections released from this pool.
+     * @return the released connection count
+     */
+    public long getReleasedCount() {
+        return releasedCount.get();
+    }
+
+    /**
+     * The total number of connections reconnected by this pool.
+     * @return the reconnected connection count
+     */
+    public long getReconnectedCount() {
+        return reconnectedCount.get();
+    }
+
+    /**
+     * The total number of connections released by remove abandoned.
+     * @return the PoolCleaner removed abandoned connection count
+     */
+    public long getRemoveAbandonedCount() {
+        return removeAbandonedCount.get();
+    }
+
+    /**
+     * The total number of connections released by eviction.
+     * @return the PoolCleaner evicted idle connection count
+     */
+    public long getReleasedIdleCount() {
+        return releasedIdleCount.get();
+    }
+
+    /**
+     * reset the statistics of this pool.
+     */
+    public void resetStats() {
+        borrowedCount.set(0);
+        returnedCount.set(0);
+        createdCount.set(0);
+        releasedCount.set(0);
+        reconnectedCount.set(0);
+        removeAbandonedCount.set(0);
+        releasedIdleCount.set(0);
+    }
+
+    /**
+     * Tread safe wrapper around a future for the regular queue
+     * This one retrieves the pooled connection object
+     * and performs the initialization according to
+     * interceptors and validation rules.
+     * This class is thread safe and is cancellable
+     *
+     */
+    protected class ConnectionFuture implements Future<Connection>, Runnable {
+        Future<PooledConnection> pcFuture = null;
+        AtomicBoolean configured = new AtomicBoolean(false);
+        CountDownLatch latch = new CountDownLatch(1);
+        volatile Connection result = null;
+        SQLException cause = null;
+        AtomicBoolean cancelled = new AtomicBoolean(false);
+        volatile PooledConnection pc = null;
+        public ConnectionFuture(Future<PooledConnection> pcf) {
+            this.pcFuture = pcf;
+        }
+
+        public ConnectionFuture(PooledConnection pc) throws SQLException {
+            this.pc = pc;
+            result = ConnectionPool.this.setupConnection(pc);
+            configured.set(true);
+        }
+        /**
+         * {@inheritDoc}
+         */
+        @Override
+        public boolean cancel(boolean mayInterruptIfRunning) {
+            if (pc!=null) {
+                return false;
+            } else if ((!cancelled.get()) && cancelled.compareAndSet(false, true)) {
+                //cancel by retrieving the connection and returning it to the pool
+                ConnectionPool.this.cancellator.execute(this);
+            }
+            return true;
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        @Override
+        public Connection get() throws InterruptedException, ExecutionException {
+            try {
+                return get(Long.MAX_VALUE, TimeUnit.MILLISECONDS);
+            }catch (TimeoutException x) {
+                throw new ExecutionException(x);
+            }
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        @Override
+        public Connection get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException {
+            PooledConnection pc = this.pc!=null?this.pc:pcFuture.get(timeout,unit);
+            if (pc!=null) {
+                if (result!=null) return result;
+                if (configured.compareAndSet(false, true)) {
+                    try {
+                        pc = borrowConnection(System.currentTimeMillis(),pc, null, null);
+                        result = ConnectionPool.this.setupConnection(pc);
+                    } catch (SQLException x) {
+                        cause = x;
+                    } finally {
+                        latch.countDown();
+                    }
+                } else {
+                    //if we reach here, another thread is configuring the actual connection
+                    latch.await(timeout,unit); //this shouldn't block for long
+                }
+                if (result==null) throw new ExecutionException(cause);
+                return result;
+            } else {
+                return null;
+            }
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        @Override
+        public boolean isCancelled() {
+            return pc==null && (pcFuture.isCancelled() || cancelled.get());
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        @Override
+        public boolean isDone() {
+            return pc!=null || pcFuture.isDone();
+        }
+
+        /**
+         * run method to be executed when cancelled by an executor
+         */
+        @Override
+        public void run() {
+            try {
+                Connection con = get(); //complete this future
+                con.close(); //return to the pool
+            }catch (ExecutionException ex) {
+                //we can ignore this
+            }catch (Exception x) {
+                ConnectionPool.log.error("Unable to cancel ConnectionFuture.",x);
+            }
+        }
+
+    }
+
+
+
+    private static volatile Timer poolCleanTimer = null;
+    private static HashSet<PoolCleaner> cleaners = new HashSet<>();
+
+    private static synchronized void registerCleaner(PoolCleaner cleaner) {
+        unregisterCleaner(cleaner);
+        cleaners.add(cleaner);
+        if (poolCleanTimer == null) {
+            ClassLoader loader = Thread.currentThread().getContextClassLoader();
+            try {
+                Thread.currentThread().setContextClassLoader(ConnectionPool.class.getClassLoader());
+                // Create the timer thread in a PrivilegedAction so that a
+                // reference to the web application class loader is not created
+                // via Thread.inheritedAccessControlContext
+                PrivilegedAction<Timer> pa = new PrivilegedNewTimer();
+                poolCleanTimer = AccessController.doPrivileged(pa);
+            } finally {
+                Thread.currentThread().setContextClassLoader(loader);
+            }
+        }
+        poolCleanTimer.schedule(cleaner, cleaner.sleepTime,cleaner.sleepTime);
+    }
+
+    private static synchronized void unregisterCleaner(PoolCleaner cleaner) {
+        boolean removed = cleaners.remove(cleaner);
+        if (removed) {
+            cleaner.cancel();
+            if (poolCleanTimer != null) {
+                poolCleanTimer.purge();
+                if (cleaners.size() == 0) {
+                    poolCleanTimer.cancel();
+                    poolCleanTimer = null;
+                }
+            }
+        }
+    }
+
+    private static class PrivilegedNewTimer implements PrivilegedAction<Timer> {
+        @Override
+        public Timer run() {
+            return new Timer("Tomcat JDBC Pool Cleaner["+ System.identityHashCode(ConnectionPool.class.getClassLoader()) + ":"+
+                    System.currentTimeMillis() + "]", true);
+        }
+    }
+
+    public static Set<TimerTask> getPoolCleaners() {
+        return Collections.<TimerTask>unmodifiableSet(cleaners);
+    }
+
+    public long getPoolVersion() {
+        return poolVersion.get();
+    }
+
+    public static Timer getPoolTimer() {
+        return poolCleanTimer;
+    }
+
+    protected static class PoolCleaner extends TimerTask {
+        protected WeakReference<ConnectionPool> pool;
+        protected long sleepTime;
+
+        PoolCleaner(ConnectionPool pool, long sleepTime) {
+            this.pool = new WeakReference<>(pool);
+            this.sleepTime = sleepTime;
+            if (sleepTime <= 0) {
+                log.warn("Database connection pool evicter thread interval is set to 0, defaulting to 30 seconds");
+                this.sleepTime = 1000 * 30;
+            } else if (sleepTime < 1000) {
+                log.warn("Database connection pool evicter thread interval is set to lower than 1 second.");
+            }
+        }
+
+        @Override
+        public void run() {
+            ConnectionPool pool = this.pool.get();
+            if (pool == null) {
+                stopRunning();
+            } else if (!pool.isClosed()) {
+                try {
+                    if (pool.getPoolProperties().isRemoveAbandoned()
+                            || pool.getPoolProperties().getSuspectTimeout() > 0)
+                        pool.checkAbandoned();
+                    if (pool.getPoolProperties().getMinIdle() < pool.idle
+                            .size())
+                        pool.checkIdle();
+                    if (pool.getPoolProperties().isTestWhileIdle())
+                        pool.testAllIdle();
+                } catch (Exception x) {
+                    log.error("", x);
+                }
+            }
+        }
+
+        public void start() {
+            registerCleaner(this);
+        }
+
+        public void stopRunning() {
+            unregisterCleaner(this);
+        }
+    }
+}
diff --git a/dblib/common/src/main/java/org/apache/tomcat/jdbc/pool/DataSource.java b/dblib/common/src/main/java/org/apache/tomcat/jdbc/pool/DataSource.java
new file mode 100644
index 0000000..4922bf0
--- /dev/null
+++ b/dblib/common/src/main/java/org/apache/tomcat/jdbc/pool/DataSource.java
@@ -0,0 +1,180 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * openecomp
+ * ================================================================================
+ * Copyright (C) 2016 - 2017 AT&T
+ * ================================================================================
+ * Licensed 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.
+ * ============LICENSE_END=========================================================
+ */
+
+/*
+ * 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.tomcat.jdbc.pool;
+
+import java.lang.management.ManagementFactory;
+import java.util.Hashtable;
+
+import javax.management.InstanceNotFoundException;
+import javax.management.MBeanRegistration;
+import javax.management.MBeanServer;
+import javax.management.MalformedObjectNameException;
+import javax.management.ObjectName;
+
+import org.apache.juli.logging.Log;
+import org.apache.juli.logging.LogFactory;
+
+
+/**
+ * A DataSource that can be instantiated through IoC and implements the DataSource interface
+ * since the DataSourceProxy is used as a generic proxy.
+ * The DataSource simply wraps a {@link ConnectionPool} in order to provide a standard interface to the user.
+ * @version 1.0
+ */
+public class DataSource extends DataSourceProxy implements javax.sql.DataSource,MBeanRegistration, org.apache.tomcat.jdbc.pool.jmx.ConnectionPoolMBean, javax.sql.ConnectionPoolDataSource {
+    private static final Log log = LogFactory.getLog(DataSource.class);
+
+    /**
+     * Constructor for reflection only. A default set of pool properties will be created.
+     */
+    public DataSource() {
+        super();
+    }
+
+    /**
+     * Constructs a DataSource object wrapping a connection
+     * @param poolProperties The pool properties
+     */
+    public DataSource(PoolConfiguration poolProperties) {
+        super(poolProperties);
+    }
+
+
+
+
+
+//===============================================================================
+//  JMX Operations - Register the actual pool itself under the tomcat.jdbc domain
+//===============================================================================
+    protected volatile ObjectName oname = null;
+
+    /**
+     * Unregisters the underlying connection pool mbean.<br>
+     * {@inheritDoc}
+     */
+    @Override
+    public void postDeregister() {
+        if (oname!=null) unregisterJmx();
+    }
+
+    /**
+     * no-op<br>
+     * {@inheritDoc}
+     */
+    @Override
+    public void postRegister(Boolean registrationDone) {
+        // NOOP
+    }
+
+
+    /**
+     * no-op<br>
+     * {@inheritDoc}
+     */
+    @Override
+    public void preDeregister() throws Exception {
+        // NOOP
+    }
+
+    /**
+     * If the connection pool MBean exists, it will be registered during this operation.<br>
+     * {@inheritDoc}
+     */
+    @Override
+    public ObjectName preRegister(MBeanServer server, ObjectName name) throws Exception {
+        try {
+            if ( isJmxEnabled() ) {
+                this.oname = createObjectName(name);
+                if (oname!=null) registerJmx();
+            }
+        }catch (MalformedObjectNameException x) {
+            log.error("Unable to create object name for JDBC pool.",x);
+        }
+        return name;
+    }
+
+    /**
+     * Creates the ObjectName for the ConnectionPoolMBean object to be registered
+     * @param original the ObjectName for the DataSource
+     * @return the ObjectName for the ConnectionPoolMBean
+     * @throws MalformedObjectNameException Invalid object name
+     */
+    public ObjectName createObjectName(ObjectName original) throws MalformedObjectNameException {
+        String domain = ConnectionPool.POOL_JMX_DOMAIN;
+        Hashtable<String,String> properties = original.getKeyPropertyList();
+        String origDomain = original.getDomain();
+        properties.put("type", "ConnectionPool");
+        properties.put("class", this.getClass().getName());
+        if (original.getKeyProperty("path")!=null || properties.get("context")!=null) {
+            //this ensures that if the registration came from tomcat, we're not losing
+            //the unique domain, but putting that into as an engine attribute
+            properties.put("engine", origDomain);
+        }
+        ObjectName name = new ObjectName(domain,properties);
+        return name;
+    }
+
+    /**
+     * Registers the ConnectionPoolMBean under a unique name based on the ObjectName for the DataSource
+     */
+    protected void registerJmx() {
+        try {
+            if (pool.getJmxPool()!=null) {
+                MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
+                mbs.registerMBean(pool.getJmxPool(), oname);
+            }
+        } catch (Exception e) {
+            log.error("Unable to register JDBC pool with JMX",e);
+        }
+    }
+
+    /**
+     *
+     */
+    protected void unregisterJmx() {
+        try {
+            MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
+            mbs.unregisterMBean(oname);
+        } catch (InstanceNotFoundException ignore) {
+            // NOOP
+        } catch (Exception e) {
+            log.error("Unable to unregister JDBC pool with JMX",e);
+        }
+    }
+
+
+}
diff --git a/dblib/common/src/main/java/org/apache/tomcat/jdbc/pool/DataSourceFactory.java b/dblib/common/src/main/java/org/apache/tomcat/jdbc/pool/DataSourceFactory.java
new file mode 100644
index 0000000..d0a5127
--- /dev/null
+++ b/dblib/common/src/main/java/org/apache/tomcat/jdbc/pool/DataSourceFactory.java
@@ -0,0 +1,612 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * openecomp
+ * ================================================================================
+ * Copyright (C) 2016 - 2017 AT&T
+ * ================================================================================
+ * Licensed 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.
+ * ============LICENSE_END=========================================================
+ */
+
+/*
+ * 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.tomcat.jdbc.pool;
+
+
+import java.sql.Connection;
+import java.util.Hashtable;
+import java.util.Properties;
+
+import javax.management.ObjectName;
+import javax.naming.Context;
+import javax.naming.InitialContext;
+import javax.naming.Name;
+import javax.naming.NamingException;
+import javax.naming.RefAddr;
+import javax.naming.Reference;
+import javax.naming.spi.ObjectFactory;
+import javax.sql.DataSource;
+
+import org.apache.juli.logging.Log;
+import org.apache.juli.logging.LogFactory;
+
+/**
+ * <p>JNDI object factory that creates an instance of
+ * <code>BasicDataSource</code> that has been configured based on the
+ * <code>RefAddr</code> values of the specified <code>Reference</code>,
+ * which must match the names and data types of the
+ * <code>BasicDataSource</code> bean properties.</p>
+ * <br>
+ * Properties available for configuration:<br>
+ * <a href="http://commons.apache.org/dbcp/configuration.html">Commons DBCP properties</a><br>
+ *<ol>
+ *  <li>initSQL - A query that gets executed once, right after the connection is established.</li>
+ *  <li>testOnConnect - run validationQuery after connection has been established.</li>
+ *  <li>validationInterval - avoid excess validation, only run validation at most at this frequency - time in milliseconds.</li>
+ *  <li>jdbcInterceptors - a semicolon separated list of classnames extending {@link JdbcInterceptor} class.</li>
+ *  <li>jmxEnabled - true of false, whether to register the pool with JMX.</li>
+ *  <li>fairQueue - true of false, whether the pool should sacrifice a little bit of performance for true fairness.</li>
+ *</ol>
+ * @author Craig R. McClanahan
+ * @author Dirk Verbeeck
+ */
+public class DataSourceFactory implements ObjectFactory {
+    private static final Log log = LogFactory.getLog(DataSourceFactory.class);
+
+    protected static final String PROP_DEFAULTAUTOCOMMIT = "defaultAutoCommit";
+    protected static final String PROP_DEFAULTREADONLY = "defaultReadOnly";
+    protected static final String PROP_DEFAULTTRANSACTIONISOLATION = "defaultTransactionIsolation";
+    protected static final String PROP_DEFAULTCATALOG = "defaultCatalog";
+
+    protected static final String PROP_DRIVERCLASSNAME = "driverClassName";
+    protected static final String PROP_PASSWORD = "password";
+    protected static final String PROP_URL = "url";
+    protected static final String PROP_USERNAME = "username";
+
+    protected static final String PROP_MAXACTIVE = "maxActive";
+    protected static final String PROP_MAXIDLE = "maxIdle";
+    protected static final String PROP_MINIDLE = "minIdle";
+    protected static final String PROP_INITIALSIZE = "initialSize";
+    protected static final String PROP_MAXWAIT = "maxWait";
+    protected static final String PROP_MAXAGE = "maxAge";
+
+    protected static final String PROP_TESTONBORROW = "testOnBorrow";
+    protected static final String PROP_TESTONRETURN = "testOnReturn";
+    protected static final String PROP_TESTWHILEIDLE = "testWhileIdle";
+    protected static final String PROP_TESTONCONNECT = "testOnConnect";
+    protected static final String PROP_VALIDATIONQUERY = "validationQuery";
+    protected static final String PROP_VALIDATIONQUERY_TIMEOUT = "validationQueryTimeout";
+    protected static final String PROP_VALIDATOR_CLASS_NAME = "validatorClassName";
+
+    protected static final String PROP_NUMTESTSPEREVICTIONRUN = "numTestsPerEvictionRun";
+    protected static final String PROP_TIMEBETWEENEVICTIONRUNSMILLIS = "timeBetweenEvictionRunsMillis";
+    protected static final String PROP_MINEVICTABLEIDLETIMEMILLIS = "minEvictableIdleTimeMillis";
+
+    protected static final String PROP_ACCESSTOUNDERLYINGCONNECTIONALLOWED = "accessToUnderlyingConnectionAllowed";
+
+    protected static final String PROP_REMOVEABANDONED = "removeAbandoned";
+    protected static final String PROP_REMOVEABANDONEDTIMEOUT = "removeAbandonedTimeout";
+    protected static final String PROP_LOGABANDONED = "logAbandoned";
+    protected static final String PROP_ABANDONWHENPERCENTAGEFULL = "abandonWhenPercentageFull";
+
+    protected static final String PROP_POOLPREPAREDSTATEMENTS = "poolPreparedStatements";
+    protected static final String PROP_MAXOPENPREPAREDSTATEMENTS = "maxOpenPreparedStatements";
+    protected static final String PROP_CONNECTIONPROPERTIES = "connectionProperties";
+
+    protected static final String PROP_INITSQL = "initSQL";
+    protected static final String PROP_INTERCEPTORS = "jdbcInterceptors";
+    protected static final String PROP_VALIDATIONINTERVAL = "validationInterval";
+    protected static final String PROP_JMX_ENABLED = "jmxEnabled";
+    protected static final String PROP_FAIR_QUEUE = "fairQueue";
+
+    protected static final String PROP_USE_EQUALS = "useEquals";
+    protected static final String PROP_USE_CON_LOCK = "useLock";
+
+    protected static final String PROP_DATASOURCE= "dataSource";
+    protected static final String PROP_DATASOURCE_JNDI = "dataSourceJNDI";
+
+    protected static final String PROP_SUSPECT_TIMEOUT = "suspectTimeout";
+
+    protected static final String PROP_ALTERNATE_USERNAME_ALLOWED = "alternateUsernameAllowed";
+
+    protected static final String PROP_COMMITONRETURN = "commitOnReturn";
+    protected static final String PROP_ROLLBACKONRETURN = "rollbackOnReturn";
+
+    protected static final String PROP_USEDISPOSABLECONNECTIONFACADE = "useDisposableConnectionFacade";
+
+    protected static final String PROP_LOGVALIDATIONERRORS = "logValidationErrors";
+
+    protected static final String PROP_PROPAGATEINTERRUPTSTATE = "propagateInterruptState";
+
+    protected static final String PROP_IGNOREEXCEPTIONONPRELOAD = "ignoreExceptionOnPreLoad";
+
+    public static final int UNKNOWN_TRANSACTIONISOLATION = -1;
+
+    public static final String OBJECT_NAME = "object_name";
+
+
+    protected static final String[] ALL_PROPERTIES = {
+        PROP_DEFAULTAUTOCOMMIT,
+        PROP_DEFAULTREADONLY,
+        PROP_DEFAULTTRANSACTIONISOLATION,
+        PROP_DEFAULTCATALOG,
+        PROP_DRIVERCLASSNAME,
+        PROP_MAXACTIVE,
+        PROP_MAXIDLE,
+        PROP_MINIDLE,
+        PROP_INITIALSIZE,
+        PROP_MAXWAIT,
+        PROP_TESTONBORROW,
+        PROP_TESTONRETURN,
+        PROP_TIMEBETWEENEVICTIONRUNSMILLIS,
+        PROP_NUMTESTSPEREVICTIONRUN,
+        PROP_MINEVICTABLEIDLETIMEMILLIS,
+        PROP_TESTWHILEIDLE,
+        PROP_TESTONCONNECT,
+        PROP_PASSWORD,
+        PROP_URL,
+        PROP_USERNAME,
+        PROP_VALIDATIONQUERY,
+        PROP_VALIDATIONQUERY_TIMEOUT,
+        PROP_VALIDATOR_CLASS_NAME,
+        PROP_VALIDATIONINTERVAL,
+        PROP_ACCESSTOUNDERLYINGCONNECTIONALLOWED,
+        PROP_REMOVEABANDONED,
+        PROP_REMOVEABANDONEDTIMEOUT,
+        PROP_LOGABANDONED,
+        PROP_POOLPREPAREDSTATEMENTS,
+        PROP_MAXOPENPREPAREDSTATEMENTS,
+        PROP_CONNECTIONPROPERTIES,
+        PROP_INITSQL,
+        PROP_INTERCEPTORS,
+        PROP_JMX_ENABLED,
+        PROP_FAIR_QUEUE,
+        PROP_USE_EQUALS,
+        OBJECT_NAME,
+        PROP_ABANDONWHENPERCENTAGEFULL,
+        PROP_MAXAGE,
+        PROP_USE_CON_LOCK,
+        PROP_DATASOURCE,
+        PROP_DATASOURCE_JNDI,
+        PROP_SUSPECT_TIMEOUT,
+        PROP_ALTERNATE_USERNAME_ALLOWED,
+        PROP_COMMITONRETURN,
+        PROP_ROLLBACKONRETURN,
+        PROP_USEDISPOSABLECONNECTIONFACADE,
+        PROP_LOGVALIDATIONERRORS,
+        PROP_PROPAGATEINTERRUPTSTATE,
+        PROP_IGNOREEXCEPTIONONPRELOAD
+    };
+
+    // -------------------------------------------------- ObjectFactory Methods
+
+    /**
+     * <p>Create and return a new <code>BasicDataSource</code> instance.  If no
+     * instance can be created, return <code>null</code> instead.</p>
+     *
+     * @param obj The possibly null object containing location or
+     *  reference information that can be used in creating an object
+     * @param name The name of this object relative to <code>nameCtx</code>
+     * @param nameCtx The context relative to which the <code>name</code>
+     *  parameter is specified, or <code>null</code> if <code>name</code>
+     *  is relative to the default initial context
+     * @param environment The possibly null environment that is used in
+     *  creating this object
+     *
+     * @exception Exception if an exception occurs creating the instance
+     */
+    @Override
+    public Object getObjectInstance(Object obj, Name name, Context nameCtx,
+                                    Hashtable<?,?> environment) throws Exception {
+
+        // We only know how to deal with <code>javax.naming.Reference</code>s
+        // that specify a class name of "javax.sql.DataSource"
+        if ((obj == null) || !(obj instanceof Reference)) {
+            return null;
+        }
+        Reference ref = (Reference) obj;
+        boolean XA = false;
+        boolean ok = false;
+        if ("javax.sql.DataSource".equals(ref.getClassName())) {
+            ok = true;
+        }
+        if ("javax.sql.XADataSource".equals(ref.getClassName())) {
+            ok = true;
+            XA = true;
+        }
+        if (org.apache.tomcat.jdbc.pool.DataSource.class.getName().equals(ref.getClassName())) {
+            ok = true;
+        }
+
+        if (!ok) {
+            log.warn(ref.getClassName()+" is not a valid class name/type for this JNDI factory.");
+            return null;
+        }
+
+
+        Properties properties = new Properties();
+        for (int i = 0; i < ALL_PROPERTIES.length; i++) {
+            String propertyName = ALL_PROPERTIES[i];
+            RefAddr ra = ref.get(propertyName);
+            if (ra != null) {
+                String propertyValue = ra.getContent().toString();
+                properties.setProperty(propertyName, propertyValue);
+            }
+        }
+
+        return createDataSource(properties,nameCtx,XA);
+    }
+
+    public static PoolConfiguration parsePoolProperties(Properties properties) {
+        PoolConfiguration poolProperties = new PoolProperties();
+        String value = null;
+
+        value = properties.getProperty(PROP_DEFAULTAUTOCOMMIT);
+        if (value != null) {
+            poolProperties.setDefaultAutoCommit(Boolean.valueOf(value));
+        }
+
+        value = properties.getProperty(PROP_DEFAULTREADONLY);
+        if (value != null) {
+            poolProperties.setDefaultReadOnly(Boolean.valueOf(value));
+        }
+
+        value = properties.getProperty(PROP_DEFAULTTRANSACTIONISOLATION);
+        if (value != null) {
+            int level = UNKNOWN_TRANSACTIONISOLATION;
+            if ("NONE".equalsIgnoreCase(value)) {
+                level = Connection.TRANSACTION_NONE;
+            } else if ("READ_COMMITTED".equalsIgnoreCase(value)) {
+                level = Connection.TRANSACTION_READ_COMMITTED;
+            } else if ("READ_UNCOMMITTED".equalsIgnoreCase(value)) {
+                level = Connection.TRANSACTION_READ_UNCOMMITTED;
+            } else if ("REPEATABLE_READ".equalsIgnoreCase(value)) {
+                level = Connection.TRANSACTION_REPEATABLE_READ;
+            } else if ("SERIALIZABLE".equalsIgnoreCase(value)) {
+                level = Connection.TRANSACTION_SERIALIZABLE;
+            } else {
+                try {
+                    level = Integer.parseInt(value);
+                } catch (NumberFormatException e) {
+                    System.err.println("Could not parse defaultTransactionIsolation: " + value);
+                    System.err.println("WARNING: defaultTransactionIsolation not set");
+                    System.err.println("using default value of database driver");
+                    level = UNKNOWN_TRANSACTIONISOLATION;
+                }
+            }
+            poolProperties.setDefaultTransactionIsolation(level);
+        }
+
+        value = properties.getProperty(PROP_DEFAULTCATALOG);
+        if (value != null) {
+            poolProperties.setDefaultCatalog(value);
+        }
+
+        value = properties.getProperty(PROP_DRIVERCLASSNAME);
+        if (value != null) {
+            poolProperties.setDriverClassName(value);
+        }
+
+        value = properties.getProperty(PROP_MAXACTIVE);
+        if (value != null) {
+            poolProperties.setMaxActive(Integer.parseInt(value));
+        }
+
+        value = properties.getProperty(PROP_MAXIDLE);
+        if (value != null) {
+            poolProperties.setMaxIdle(Integer.parseInt(value));
+        }
+
+        value = properties.getProperty(PROP_MINIDLE);
+        if (value != null) {
+            poolProperties.setMinIdle(Integer.parseInt(value));
+        }
+
+        value = properties.getProperty(PROP_INITIALSIZE);
+        if (value != null) {
+            poolProperties.setInitialSize(Integer.parseInt(value));
+        }
+
+        value = properties.getProperty(PROP_MAXWAIT);
+        if (value != null) {
+            poolProperties.setMaxWait(Integer.parseInt(value));
+        }
+
+        value = properties.getProperty(PROP_TESTONBORROW);
+        if (value != null) {
+            poolProperties.setTestOnBorrow(Boolean.parseBoolean(value));
+        }
+
+        value = properties.getProperty(PROP_TESTONRETURN);
+        if (value != null) {
+            poolProperties.setTestOnReturn(Boolean.parseBoolean(value));
+        }
+
+        value = properties.getProperty(PROP_TESTONCONNECT);
+        if (value != null) {
+            poolProperties.setTestOnConnect(Boolean.parseBoolean(value));
+        }
+
+        value = properties.getProperty(PROP_TIMEBETWEENEVICTIONRUNSMILLIS);
+        if (value != null) {
+            poolProperties.setTimeBetweenEvictionRunsMillis(Integer.parseInt(value));
+        }
+
+        value = properties.getProperty(PROP_NUMTESTSPEREVICTIONRUN);
+        if (value != null) {
+            poolProperties.setNumTestsPerEvictionRun(Integer.parseInt(value));
+        }
+
+        value = properties.getProperty(PROP_MINEVICTABLEIDLETIMEMILLIS);
+        if (value != null) {
+            poolProperties.setMinEvictableIdleTimeMillis(Integer.parseInt(value));
+        }
+
+        value = properties.getProperty(PROP_TESTWHILEIDLE);
+        if (value != null) {
+            poolProperties.setTestWhileIdle(Boolean.parseBoolean(value));
+        }
+
+        value = properties.getProperty(PROP_PASSWORD);
+        if (value != null) {
+            poolProperties.setPassword(value);
+        }
+
+        value = properties.getProperty(PROP_URL);
+        if (value != null) {
+            poolProperties.setUrl(value);
+        }
+
+        value = properties.getProperty(PROP_USERNAME);
+        if (value != null) {
+            poolProperties.setUsername(value);
+        }
+
+        value = properties.getProperty(PROP_VALIDATIONQUERY);
+        if (value != null) {
+            poolProperties.setValidationQuery(value);
+        }
+
+        value = properties.getProperty(PROP_VALIDATIONQUERY_TIMEOUT);
+        if (value != null) {
+            poolProperties.setValidationQueryTimeout(Integer.parseInt(value));
+        }
+
+        value = properties.getProperty(PROP_VALIDATOR_CLASS_NAME);
+        if (value != null) {
+            poolProperties.setValidatorClassName(value);
+        }
+
+        value = properties.getProperty(PROP_VALIDATIONINTERVAL);
+        if (value != null) {
+            poolProperties.setValidationInterval(Long.parseLong(value));
+        }
+
+        value = properties.getProperty(PROP_ACCESSTOUNDERLYINGCONNECTIONALLOWED);
+        if (value != null) {
+            poolProperties.setAccessToUnderlyingConnectionAllowed(Boolean.parseBoolean(value));
+        }
+
+        value = properties.getProperty(PROP_REMOVEABANDONED);
+        if (value != null) {
+            poolProperties.setRemoveAbandoned(Boolean.parseBoolean(value));
+        }
+
+        value = properties.getProperty(PROP_REMOVEABANDONEDTIMEOUT);
+        if (value != null) {
+            poolProperties.setRemoveAbandonedTimeout(Integer.parseInt(value));
+        }
+
+        value = properties.getProperty(PROP_LOGABANDONED);
+        if (value != null) {
+            poolProperties.setLogAbandoned(Boolean.parseBoolean(value));
+        }
+
+        value = properties.getProperty(PROP_POOLPREPAREDSTATEMENTS);
+        if (value != null) {
+            log.warn(PROP_POOLPREPAREDSTATEMENTS + " is not a valid setting, it will have no effect.");
+        }
+
+        value = properties.getProperty(PROP_MAXOPENPREPAREDSTATEMENTS);
+        if (value != null) {
+            log.warn(PROP_MAXOPENPREPAREDSTATEMENTS + " is not a valid setting, it will have no effect.");
+        }
+
+        value = properties.getProperty(PROP_CONNECTIONPROPERTIES);
+        if (value != null) {
+            Properties p = getProperties(value);
+            poolProperties.setDbProperties(p);
+        } else {
+            poolProperties.setDbProperties(new Properties());
+        }
+
+        if (poolProperties.getUsername()!=null) {
+            poolProperties.getDbProperties().setProperty("user",poolProperties.getUsername());
+        }
+        if (poolProperties.getPassword()!=null) {
+            poolProperties.getDbProperties().setProperty("password",poolProperties.getPassword());
+        }
+
+        value = properties.getProperty(PROP_INITSQL);
+        if (value != null) {
+            poolProperties.setInitSQL(value);
+        }
+
+        value = properties.getProperty(PROP_INTERCEPTORS);
+        if (value != null) {
+            poolProperties.setJdbcInterceptors(value);
+        }
+
+        value = properties.getProperty(PROP_JMX_ENABLED);
+        if (value != null) {
+            poolProperties.setJmxEnabled(Boolean.parseBoolean(value));
+        }
+
+        value = properties.getProperty(PROP_FAIR_QUEUE);
+        if (value != null) {
+            poolProperties.setFairQueue(Boolean.parseBoolean(value));
+        }
+
+        value = properties.getProperty(PROP_USE_EQUALS);
+        if (value != null) {
+            poolProperties.setUseEquals(Boolean.parseBoolean(value));
+        }
+
+        value = properties.getProperty(OBJECT_NAME);
+        if (value != null) {
+            poolProperties.setName(ObjectName.quote(value));
+        }
+
+        value = properties.getProperty(PROP_ABANDONWHENPERCENTAGEFULL);
+        if (value != null) {
+            poolProperties.setAbandonWhenPercentageFull(Integer.parseInt(value));
+        }
+
+        value = properties.getProperty(PROP_MAXAGE);
+        if (value != null) {
+            poolProperties.setMaxAge(Long.parseLong(value));
+        }
+
+        value = properties.getProperty(PROP_USE_CON_LOCK);
+        if (value != null) {
+            poolProperties.setUseLock(Boolean.parseBoolean(value));
+        }
+
+        value = properties.getProperty(PROP_DATASOURCE);
+        if (value != null) {
+            //this should never happen
+            throw new IllegalArgumentException("Can't set dataSource property as a string, this must be a javax.sql.DataSource object.");
+
+        }
+
+        value = properties.getProperty(PROP_DATASOURCE_JNDI);
+        if (value != null) {
+            poolProperties.setDataSourceJNDI(value);
+        }
+
+        value = properties.getProperty(PROP_SUSPECT_TIMEOUT);
+        if (value != null) {
+            poolProperties.setSuspectTimeout(Integer.parseInt(value));
+        }
+
+        value = properties.getProperty(PROP_ALTERNATE_USERNAME_ALLOWED);
+        if (value != null) {
+            poolProperties.setAlternateUsernameAllowed(Boolean.parseBoolean(value));
+        }
+
+        value = properties.getProperty(PROP_COMMITONRETURN);
+        if (value != null) {
+            poolProperties.setCommitOnReturn(Boolean.parseBoolean(value));
+        }
+
+        value = properties.getProperty(PROP_ROLLBACKONRETURN);
+        if (value != null) {
+            poolProperties.setRollbackOnReturn(Boolean.parseBoolean(value));
+        }
+
+        value = properties.getProperty(PROP_USEDISPOSABLECONNECTIONFACADE);
+        if (value != null) {
+            poolProperties.setUseDisposableConnectionFacade(Boolean.parseBoolean(value));
+        }
+
+        value = properties.getProperty(PROP_LOGVALIDATIONERRORS);
+        if (value != null) {
+            poolProperties.setLogValidationErrors(Boolean.parseBoolean(value));
+        }
+
+        value = properties.getProperty(PROP_PROPAGATEINTERRUPTSTATE);
+        if (value != null) {
+            poolProperties.setPropagateInterruptState(Boolean.parseBoolean(value));
+        }
+
+        value = properties.getProperty(PROP_IGNOREEXCEPTIONONPRELOAD);
+        if (value != null) {
+            poolProperties.setIgnoreExceptionOnPreLoad(Boolean.parseBoolean(value));
+        }
+
+        return poolProperties;
+    }
+
+    /**
+     * Creates and configures a {@link DataSource} instance based on the
+     * given properties.
+     *
+     * @param properties the datasource configuration properties
+     * @return the datasource
+     * @throws Exception if an error occurs creating the data source
+     */
+    public DataSource createDataSource(Properties properties) throws Exception {
+        return createDataSource(properties,null,false);
+    }
+    public DataSource createDataSource(Properties properties,Context context, boolean XA) throws Exception {
+        PoolConfiguration poolProperties = DataSourceFactory.parsePoolProperties(properties);
+        if (poolProperties.getDataSourceJNDI()!=null && poolProperties.getDataSource()==null) {
+            performJNDILookup(context, poolProperties);
+        }
+        org.apache.tomcat.jdbc.pool.DataSource dataSource = XA?
+                new org.apache.tomcat.jdbc.pool.XADataSource(poolProperties) :
+                new org.apache.tomcat.jdbc.pool.DataSource(poolProperties);
+        //initialise the pool itself
+        dataSource.createPool();
+        // Return the configured DataSource instance
+        return dataSource;
+    }
+
+    public void performJNDILookup(Context context, PoolConfiguration poolProperties) {
+        Object jndiDS = null;
+        try {
+            if (context!=null) {
+                jndiDS = context.lookup(poolProperties.getDataSourceJNDI());
+            } else {
+                log.warn("dataSourceJNDI property is configured, but local JNDI context is null.");
+            }
+        } catch (NamingException e) {
+            log.debug("The name \""+poolProperties.getDataSourceJNDI()+"\" cannot be found in the local context.");
+        }
+        if (jndiDS==null) {
+            try {
+                context = new InitialContext();
+                jndiDS = context.lookup(poolProperties.getDataSourceJNDI());
+            } catch (NamingException e) {
+                log.warn("The name \""+poolProperties.getDataSourceJNDI()+"\" cannot be found in the InitialContext.");
+            }
+        }
+        if (jndiDS!=null) {
+            poolProperties.setDataSource(jndiDS);
+        }
+    }
+
+    /**
+     * Parse properties from the string. Format of the string must be [propertyName=property;]*.
+     * @param propText The properties string
+     * @return the properties
+     */
+    protected static Properties getProperties(String propText) {
+        return PoolProperties.getProperties(propText,null);
+    }
+
+}
diff --git a/dblib/common/src/main/java/org/apache/tomcat/jdbc/pool/DataSourceProxy.java b/dblib/common/src/main/java/org/apache/tomcat/jdbc/pool/DataSourceProxy.java
new file mode 100644
index 0000000..3e9b8ae
--- /dev/null
+++ b/dblib/common/src/main/java/org/apache/tomcat/jdbc/pool/DataSourceProxy.java
@@ -0,0 +1,1496 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * openecomp
+ * ================================================================================
+ * Copyright (C) 2016 - 2017 AT&T
+ * ================================================================================
+ * Licensed 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.
+ * ============LICENSE_END=========================================================
+ */
+
+/*
+ * 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.tomcat.jdbc.pool;
+
+import java.io.PrintWriter;
+import java.sql.Connection;
+import java.sql.SQLException;
+import java.sql.SQLFeatureNotSupportedException;
+import java.util.Iterator;
+import java.util.Properties;
+import java.util.concurrent.Future;
+import java.util.logging.Logger;
+
+import javax.sql.XAConnection;
+
+import org.apache.juli.logging.Log;
+import org.apache.juli.logging.LogFactory;
+import org.apache.tomcat.jdbc.pool.PoolProperties.InterceptorDefinition;
+
+/**
+ *
+ * The DataSource proxy lets us implements methods that don't exist in the current
+ * compiler JDK but might be methods that are part of a future JDK DataSource interface.
+ * <br>
+ * It's a trick to work around compiler issues when implementing interfaces. For example,
+ * I could put in Java 6 methods of javax.sql.DataSource here, and compile it with JDK 1.5
+ * and still be able to run under Java 6 without getting NoSuchMethodException.
+ *
+ * @version 1.0
+ */
+
+public class DataSourceProxy implements PoolConfiguration {
+    private static final Log log = LogFactory.getLog(DataSourceProxy.class);
+
+    protected volatile ConnectionPool pool = null;
+
+    protected volatile PoolConfiguration poolProperties = null;
+
+    public DataSourceProxy() {
+        this(new PoolProperties());
+    }
+
+    public DataSourceProxy(PoolConfiguration poolProperties) {
+        if (poolProperties == null) throw new NullPointerException("PoolConfiguration cannot be null.");
+        this.poolProperties = poolProperties;
+    }
+
+
+    @SuppressWarnings("unused") // Has to match signature in DataSource
+    public boolean isWrapperFor(Class<?> iface) throws SQLException {
+        // we are not a wrapper of anything
+        return false;
+    }
+
+
+    @SuppressWarnings("unused") // Has to match signature in DataSource
+    public <T> T unwrap(Class<T> iface) throws SQLException {
+        //we can't unwrap anything
+        return null;
+    }
+
+    /**
+     * Get a database connection.
+     * {@link javax.sql.DataSource#getConnection()}
+     * @param username The user name
+     * @param password The password
+     * @return the connection
+     * @throws SQLException Connection error
+     */
+    public Connection getConnection(String username, String password) throws SQLException {
+        if (this.getPoolProperties().isAlternateUsernameAllowed()) {
+            if (pool == null)
+                return createPool().getConnection(username,password);
+            return pool.getConnection(username,password);
+        } else {
+            return getConnection();
+        }
+    }
+
+    public PoolConfiguration getPoolProperties() {
+        return poolProperties;
+    }
+
+    /**
+     * Sets up the connection pool, by creating a pooling driver.
+     * @return the connection pool
+     * @throws SQLException Error creating pool
+     */
+    public ConnectionPool createPool() throws SQLException {
+        if (pool != null) {
+            return pool;
+        } else {
+            return pCreatePool();
+        }
+    }
+
+    /**
+     * Sets up the connection pool, by creating a pooling driver.
+     */
+    private synchronized ConnectionPool pCreatePool() throws SQLException {
+        if (pool != null) {
+            return pool;
+        } else {
+            pool = new ConnectionPool(poolProperties);
+            return pool;
+        }
+    }
+
+    /**
+     * Get a database connection.
+     * {@link javax.sql.DataSource#getConnection()}
+     * @return the connection
+     * @throws SQLException Connection error
+     */
+    public Connection getConnection() throws SQLException {
+        if (pool == null)
+            return createPool().getConnection();
+        return pool.getConnection();
+    }
+
+    /**
+     * Invokes an sync operation to retrieve the connection.
+     * @return a Future containing a reference to the connection when it becomes available
+     * @throws SQLException Connection error
+     */
+    public Future<Connection> getConnectionAsync() throws SQLException {
+        if (pool == null)
+            return createPool().getConnectionAsync();
+        return pool.getConnectionAsync();
+    }
+
+    /**
+     * Get a database connection.
+     * {@link javax.sql.XADataSource#getXAConnection()}
+     * @return the connection
+     * @throws SQLException Connection error
+     */
+    public XAConnection getXAConnection() throws SQLException {
+        Connection con = getConnection();
+        if (con instanceof XAConnection) {
+            return (XAConnection)con;
+        } else {
+            try {
+                con.close();
+            } catch (Exception ignore) {
+                // Ignore
+            }
+            throw new SQLException("Connection from pool does not implement javax.sql.XAConnection");
+        }
+    }
+
+    /**
+     * Get a database connection.
+     * {@link javax.sql.XADataSource#getXAConnection(String, String)}
+     * @param username The user name
+     * @param password The password
+     * @return the connection
+     * @throws SQLException Connection error
+     */
+    public XAConnection getXAConnection(String username, String password) throws SQLException {
+        Connection con = getConnection(username, password);
+        if (con instanceof XAConnection) {
+            return (XAConnection)con;
+        } else {
+            try {
+                con.close();
+            } catch (Exception ignore) {
+                // Ignore
+            }
+            throw new SQLException("Connection from pool does not implement javax.sql.XAConnection");
+        }
+    }
+
+
+    /**
+     * Get a database connection.
+     * {@link javax.sql.DataSource#getConnection()}
+     * @return the connection
+     * @throws SQLException Connection error
+     */
+    public javax.sql.PooledConnection getPooledConnection() throws SQLException {
+        return (javax.sql.PooledConnection) getConnection();
+    }
+
+    /**
+     * Get a database connection.
+     * {@link javax.sql.DataSource#getConnection()}
+     * @param username unused
+     * @param password unused
+     * @return the connection
+     * @throws SQLException Connection error
+     */
+    public javax.sql.PooledConnection getPooledConnection(String username,
+            String password) throws SQLException {
+        return (javax.sql.PooledConnection) getConnection();
+    }
+
+    public ConnectionPool getPool() {
+        try {
+            return createPool();
+        }catch (SQLException x) {
+            log.error("Error during connection pool creation.", x);
+            return null;
+        }
+    }
+
+
+    public void close() {
+        close(false);
+    }
+    public void close(boolean all) {
+        try {
+            if (pool != null) {
+                final ConnectionPool p = pool;
+                pool = null;
+                if (p!=null) {
+                    p.close(all);
+                }
+            }
+        }catch (Exception x) {
+            log.warn("Error during connection pool closure.", x);
+        }
+    }
+
+    public int getPoolSize() {
+        final ConnectionPool p = pool;
+        if (p == null) return 0;
+        else return p.getSize();
+    }
+
+
+    @Override
+    public String toString() {
+        return super.toString()+"{"+getPoolProperties()+"}";
+    }
+
+
+/*-----------------------------------------------------------------------*/
+//      PROPERTIES WHEN NOT USED WITH FACTORY
+/*------------------------------------------------------------------------*/
+
+    /**
+     * {@inheritDoc}
+     */
+
+    @Override
+    public String getPoolName() {
+        return pool.getName();
+    }
+
+
+    public void setPoolProperties(PoolConfiguration poolProperties) {
+        this.poolProperties = poolProperties;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+
+    @Override
+    public void setDriverClassName(String driverClassName) {
+        this.poolProperties.setDriverClassName(driverClassName);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+
+    @Override
+    public void setInitialSize(int initialSize) {
+        this.poolProperties.setInitialSize(initialSize);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+
+    @Override
+    public void setInitSQL(String initSQL) {
+        this.poolProperties.setInitSQL(initSQL);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+
+    @Override
+    public void setLogAbandoned(boolean logAbandoned) {
+        this.poolProperties.setLogAbandoned(logAbandoned);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+
+    @Override
+    public void setMaxActive(int maxActive) {
+        this.poolProperties.setMaxActive(maxActive);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+
+    @Override
+    public void setMaxIdle(int maxIdle) {
+        this.poolProperties.setMaxIdle(maxIdle);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+
+    @Override
+    public void setMaxWait(int maxWait) {
+        this.poolProperties.setMaxWait(maxWait);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+
+    @Override
+    public void setMinEvictableIdleTimeMillis(int minEvictableIdleTimeMillis) {
+        this.poolProperties.setMinEvictableIdleTimeMillis(minEvictableIdleTimeMillis);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+
+    @Override
+    public void setMinIdle(int minIdle) {
+        this.poolProperties.setMinIdle(minIdle);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+
+    @Override
+    public void setNumTestsPerEvictionRun(int numTestsPerEvictionRun) {
+        this.poolProperties.setNumTestsPerEvictionRun(numTestsPerEvictionRun);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+
+    @Override
+    public void setPassword(String password) {
+        this.poolProperties.setPassword(password);
+        this.poolProperties.getDbProperties().setProperty("password",this.poolProperties.getPassword());
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+
+    @Override
+    public void setRemoveAbandoned(boolean removeAbandoned) {
+        this.poolProperties.setRemoveAbandoned(removeAbandoned);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+
+    @Override
+    public void setRemoveAbandonedTimeout(int removeAbandonedTimeout) {
+        this.poolProperties.setRemoveAbandonedTimeout(removeAbandonedTimeout);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+
+    @Override
+    public void setTestOnBorrow(boolean testOnBorrow) {
+        this.poolProperties.setTestOnBorrow(testOnBorrow);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+
+    @Override
+    public void setTestOnConnect(boolean testOnConnect) {
+        this.poolProperties.setTestOnConnect(testOnConnect);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+
+    @Override
+    public void setTestOnReturn(boolean testOnReturn) {
+        this.poolProperties.setTestOnReturn(testOnReturn);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+
+    @Override
+    public void setTestWhileIdle(boolean testWhileIdle) {
+        this.poolProperties.setTestWhileIdle(testWhileIdle);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+
+    @Override
+    public void setTimeBetweenEvictionRunsMillis(int timeBetweenEvictionRunsMillis) {
+        this.poolProperties.setTimeBetweenEvictionRunsMillis(timeBetweenEvictionRunsMillis);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+
+    @Override
+    public void setUrl(String url) {
+        this.poolProperties.setUrl(url);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+
+    @Override
+    public void setUsername(String username) {
+        this.poolProperties.setUsername(username);
+        this.poolProperties.getDbProperties().setProperty("user",getPoolProperties().getUsername());
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+
+    @Override
+    public void setValidationInterval(long validationInterval) {
+        this.poolProperties.setValidationInterval(validationInterval);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+
+    @Override
+    public void setValidationQuery(String validationQuery) {
+        this.poolProperties.setValidationQuery(validationQuery);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+
+    @Override
+    public void setValidatorClassName(String className) {
+        this.poolProperties.setValidatorClassName(className);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+
+    @Override
+    public void setValidationQueryTimeout(int validationQueryTimeout) {
+        this.poolProperties.setValidationQueryTimeout(validationQueryTimeout);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+
+    @Override
+    public void setJdbcInterceptors(String interceptors) {
+        this.getPoolProperties().setJdbcInterceptors(interceptors);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+
+    @Override
+    public void setJmxEnabled(boolean enabled) {
+        this.getPoolProperties().setJmxEnabled(enabled);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+
+    @Override
+    public void setFairQueue(boolean fairQueue) {
+        this.getPoolProperties().setFairQueue(fairQueue);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+
+    @Override
+    public void setUseLock(boolean useLock) {
+        this.getPoolProperties().setUseLock(useLock);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+
+    @Override
+    public void setDefaultCatalog(String catalog) {
+        this.getPoolProperties().setDefaultCatalog(catalog);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+
+    @Override
+    public void setDefaultAutoCommit(Boolean autocommit) {
+        this.getPoolProperties().setDefaultAutoCommit(autocommit);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+
+    @Override
+    public void setDefaultTransactionIsolation(int defaultTransactionIsolation) {
+        this.getPoolProperties().setDefaultTransactionIsolation(defaultTransactionIsolation);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+
+    @Override
+    public void setConnectionProperties(String properties) {
+        try {
+            java.util.Properties prop = DataSourceFactory
+                    .getProperties(properties);
+            Iterator<?> i = prop.keySet().iterator();
+            while (i.hasNext()) {
+                String key = (String) i.next();
+                String value = prop.getProperty(key);
+                getPoolProperties().getDbProperties().setProperty(key, value);
+            }
+
+        } catch (Exception x) {
+            log.error("Unable to parse connection properties.", x);
+            throw new RuntimeException(x);
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+
+    @Override
+    public void setUseEquals(boolean useEquals) {
+        this.getPoolProperties().setUseEquals(useEquals);
+    }
+
+    /**
+     * no-op
+     * {@link javax.sql.DataSource#getParentLogger}
+     * @return no return value
+     * @throws SQLFeatureNotSupportedException Unsupported
+     */
+    public Logger getParentLogger() throws SQLFeatureNotSupportedException {
+        throw new SQLFeatureNotSupportedException();
+    }
+
+    /**
+     * no-op
+     * {@link javax.sql.DataSource#getLogWriter}
+     * @return null
+     * @throws SQLException No exception
+     */
+    public PrintWriter getLogWriter() throws SQLException {
+        return null;
+    }
+
+
+    /**
+     * no-op
+     * {@link javax.sql.DataSource#setLogWriter(PrintWriter)}
+     * @param out Ignored
+     * @throws SQLException No exception
+     */
+    public void setLogWriter(PrintWriter out) throws SQLException {
+        // NOOP
+    }
+
+    /**
+     * no-op
+     * {@link javax.sql.DataSource#getLoginTimeout}
+     * @return the timeout
+     */
+    public int getLoginTimeout() {
+        if (poolProperties == null) {
+            return 0;
+        } else {
+            return poolProperties.getMaxWait() / 1000;
+        }
+    }
+
+    /**
+     * {@link javax.sql.DataSource#setLoginTimeout(int)}
+     * @param i The timeout value
+     */
+    public void setLoginTimeout(int i) {
+        if (poolProperties == null) {
+            return;
+        } else {
+            poolProperties.setMaxWait(1000 * i);
+        }
+
+    }
+
+
+    /**
+     * {@inheritDoc}
+     */
+
+    @Override
+    public int getSuspectTimeout() {
+        return getPoolProperties().getSuspectTimeout();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+
+    @Override
+    public void setSuspectTimeout(int seconds) {
+        getPoolProperties().setSuspectTimeout(seconds);
+    }
+
+  //===============================================================================
+//  Expose JMX attributes through Tomcat's dynamic reflection
+//===============================================================================
+    /**
+     * If the pool has not been created, it will be created during this call.
+     * @return the number of established but idle connections
+     */
+    public int getIdle() {
+        try {
+            return createPool().getIdle();
+        }catch (SQLException x) {
+            throw new RuntimeException(x);
+        }
+    }
+
+    /**
+     * {@link #getIdle()}
+     * @return the number of established but idle connections
+     */
+    public int getNumIdle() {
+        return getIdle();
+    }
+
+    /**
+     * Forces an abandon check on the connection pool.
+     * If connections that have been abandoned exists, they will be closed during this run
+     */
+    public void checkAbandoned() {
+        try {
+            createPool().checkAbandoned();
+        }catch (SQLException x) {
+            throw new RuntimeException(x);
+        }
+    }
+
+    /**
+     * Forces a check for resizing of the idle connections
+     */
+    public void checkIdle() {
+        try {
+            createPool().checkIdle();
+        }catch (SQLException x) {
+            throw new RuntimeException(x);
+        }
+    }
+
+    /**
+     * @return number of connections in use by the application
+     */
+    public int getActive() {
+        try {
+            return createPool().getActive();
+        }catch (SQLException x) {
+            throw new RuntimeException(x);
+        }
+    }
+
+    /**
+     * @return number of connections in use by the application
+     * {@link DataSource#getActive()}
+     */
+    public int getNumActive() {
+        return getActive();
+    }
+
+    /**
+     * @return number of threads waiting for a connection
+     */
+    public int getWaitCount() {
+        try {
+            return createPool().getWaitCount();
+        }catch (SQLException x) {
+            throw new RuntimeException(x);
+        }
+    }
+
+    /**
+     * @return the current size of the pool
+     */
+    public int getSize() {
+        try {
+            return createPool().getSize();
+        }catch (SQLException x) {
+            throw new RuntimeException(x);
+        }
+    }
+
+    /**
+     * Performs a validation on idle connections
+     */
+    public void testIdle() {
+        try {
+            createPool().testAllIdle();
+        }catch (SQLException x) {
+            throw new RuntimeException(x);
+        }
+    }
+
+    /**
+     * The total number of connections borrowed from this pool.
+     * @return the borrowed connection count
+     */
+    public long getBorrowedCount() {
+        try {
+            return createPool().getBorrowedCount();
+        } catch (SQLException x) {
+            throw new RuntimeException(x);
+        }
+    }
+
+    /**
+     * The total number of connections returned to this pool.
+     * @return the returned connection count
+     */
+    public long getReturnedCount() {
+        try {
+            return createPool().getReturnedCount();
+        } catch (SQLException x) {
+            throw new RuntimeException(x);
+        }
+    }
+
+    /**
+     * The total number of connections created by this pool.
+     * @return the created connection count
+     */
+    public long getCreatedCount() {
+        try {
+            return createPool().getCreatedCount();
+        } catch (SQLException x) {
+            throw new RuntimeException(x);
+        }
+    }
+
+    /**
+     * The total number of connections released from this pool.
+     * @return the released connection count
+     */
+    public long getReleasedCount() {
+        try {
+            return createPool().getReleasedCount();
+        } catch (SQLException x) {
+            throw new RuntimeException(x);
+        }
+    }
+
+    /**
+     * The total number of connections reconnected by this pool.
+     * @return the reconnected connection count
+     */
+    public long getReconnectedCount() {
+        try {
+            return createPool().getReconnectedCount();
+        } catch (SQLException x) {
+            throw new RuntimeException(x);
+        }
+    }
+
+    /**
+     * The total number of connections released by remove abandoned.
+     * @return the PoolCleaner removed abandoned connection count
+     */
+    public long getRemoveAbandonedCount() {
+        try {
+            return createPool().getRemoveAbandonedCount();
+        } catch (SQLException x) {
+            throw new RuntimeException(x);
+        }
+    }
+
+    /**
+     * The total number of connections released by eviction.
+     * @return the PoolCleaner evicted idle connection count
+     */
+    public long getReleasedIdleCount() {
+        try {
+            return createPool().getReleasedIdleCount();
+        } catch (SQLException x) {
+            throw new RuntimeException(x);
+        }
+    }
+
+    /**
+     * reset the statistics of this pool.
+     */
+    public void resetStats() {
+        try {
+            createPool().resetStats();
+        } catch (SQLException x) {
+            throw new RuntimeException(x);
+        }
+    }
+
+    //=========================================================
+    //  PROPERTIES / CONFIGURATION
+    //=========================================================
+
+    /**
+     * {@inheritDoc}
+     */
+
+    @Override
+    public String getConnectionProperties() {
+        return getPoolProperties().getConnectionProperties();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+
+    @Override
+    public Properties getDbProperties() {
+        return getPoolProperties().getDbProperties();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+
+    @Override
+    public String getDefaultCatalog() {
+        return getPoolProperties().getDefaultCatalog();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+
+    @Override
+    public int getDefaultTransactionIsolation() {
+        return getPoolProperties().getDefaultTransactionIsolation();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+
+    @Override
+    public String getDriverClassName() {
+        return getPoolProperties().getDriverClassName();
+    }
+
+
+    /**
+     * {@inheritDoc}
+     */
+
+    @Override
+    public int getInitialSize() {
+        return getPoolProperties().getInitialSize();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+
+    @Override
+    public String getInitSQL() {
+        return getPoolProperties().getInitSQL();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+
+    @Override
+    public String getJdbcInterceptors() {
+        return getPoolProperties().getJdbcInterceptors();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+
+    @Override
+    public int getMaxActive() {
+        return getPoolProperties().getMaxActive();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+
+    @Override
+    public int getMaxIdle() {
+        return getPoolProperties().getMaxIdle();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+
+    @Override
+    public int getMaxWait() {
+        return getPoolProperties().getMaxWait();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+
+    @Override
+    public int getMinEvictableIdleTimeMillis() {
+        return getPoolProperties().getMinEvictableIdleTimeMillis();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+
+    @Override
+    public int getMinIdle() {
+        return getPoolProperties().getMinIdle();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+
+    @Override
+    public long getMaxAge() {
+        return getPoolProperties().getMaxAge();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+
+    @Override
+    public String getName() {
+        return getPoolProperties().getName();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+
+    @Override
+    public int getNumTestsPerEvictionRun() {
+        return getPoolProperties().getNumTestsPerEvictionRun();
+    }
+
+    /**
+     * @return DOES NOT RETURN THE PASSWORD, IT WOULD SHOW UP IN JMX
+     */
+    @Override
+    public String getPassword() {
+        return "Password not available as DataSource/JMX operation.";
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+
+    @Override
+    public int getRemoveAbandonedTimeout() {
+        return getPoolProperties().getRemoveAbandonedTimeout();
+    }
+
+
+    /**
+     * {@inheritDoc}
+     */
+
+    @Override
+    public int getTimeBetweenEvictionRunsMillis() {
+        return getPoolProperties().getTimeBetweenEvictionRunsMillis();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+
+    @Override
+    public String getUrl() {
+        return getPoolProperties().getUrl();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+
+    @Override
+    public String getUsername() {
+        return getPoolProperties().getUsername();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+
+    @Override
+    public long getValidationInterval() {
+        return getPoolProperties().getValidationInterval();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+
+    @Override
+    public String getValidationQuery() {
+        return getPoolProperties().getValidationQuery();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+
+    @Override
+    public int getValidationQueryTimeout() {
+        return getPoolProperties().getValidationQueryTimeout();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+
+    @Override
+    public String getValidatorClassName() {
+        return getPoolProperties().getValidatorClassName();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+
+    @Override
+    public Validator getValidator() {
+        return getPoolProperties().getValidator();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void setValidator(Validator validator) {
+        getPoolProperties().setValidator(validator);
+    }
+
+
+    /**
+     * {@inheritDoc}
+     */
+
+    @Override
+    public boolean isAccessToUnderlyingConnectionAllowed() {
+        return getPoolProperties().isAccessToUnderlyingConnectionAllowed();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+
+    @Override
+    public Boolean isDefaultAutoCommit() {
+        return getPoolProperties().isDefaultAutoCommit();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+
+    @Override
+    public Boolean isDefaultReadOnly() {
+        return getPoolProperties().isDefaultReadOnly();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+
+    @Override
+    public boolean isLogAbandoned() {
+        return getPoolProperties().isLogAbandoned();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+
+    @Override
+    public boolean isPoolSweeperEnabled() {
+        return getPoolProperties().isPoolSweeperEnabled();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+
+    @Override
+    public boolean isRemoveAbandoned() {
+        return getPoolProperties().isRemoveAbandoned();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+
+    @Override
+    public int getAbandonWhenPercentageFull() {
+        return getPoolProperties().getAbandonWhenPercentageFull();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+
+    @Override
+    public boolean isTestOnBorrow() {
+        return getPoolProperties().isTestOnBorrow();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+
+    @Override
+    public boolean isTestOnConnect() {
+        return getPoolProperties().isTestOnConnect();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+
+    @Override
+    public boolean isTestOnReturn() {
+        return getPoolProperties().isTestOnReturn();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+
+    @Override
+    public boolean isTestWhileIdle() {
+        return getPoolProperties().isTestWhileIdle();
+    }
+
+
+    /**
+     * {@inheritDoc}
+     */
+
+    @Override
+    public Boolean getDefaultAutoCommit() {
+        return getPoolProperties().getDefaultAutoCommit();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+
+    @Override
+    public Boolean getDefaultReadOnly() {
+        return getPoolProperties().getDefaultReadOnly();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+
+    @Override
+    public InterceptorDefinition[] getJdbcInterceptorsAsArray() {
+        return getPoolProperties().getJdbcInterceptorsAsArray();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+
+    @Override
+    public boolean getUseLock() {
+        return getPoolProperties().getUseLock();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+
+    @Override
+    public boolean isFairQueue() {
+        return getPoolProperties().isFairQueue();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+
+    @Override
+    public boolean isJmxEnabled() {
+        return getPoolProperties().isJmxEnabled();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+
+    @Override
+    public boolean isUseEquals() {
+        return getPoolProperties().isUseEquals();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+
+    @Override
+    public void setAbandonWhenPercentageFull(int percentage) {
+        getPoolProperties().setAbandonWhenPercentageFull(percentage);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+
+    @Override
+    public void setAccessToUnderlyingConnectionAllowed(boolean accessToUnderlyingConnectionAllowed) {
+        getPoolProperties().setAccessToUnderlyingConnectionAllowed(accessToUnderlyingConnectionAllowed);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+
+    @Override
+    public void setDbProperties(Properties dbProperties) {
+        getPoolProperties().setDbProperties(dbProperties);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+
+    @Override
+    public void setDefaultReadOnly(Boolean defaultReadOnly) {
+        getPoolProperties().setDefaultReadOnly(defaultReadOnly);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+
+    @Override
+    public void setMaxAge(long maxAge) {
+        getPoolProperties().setMaxAge(maxAge);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+
+    @Override
+    public void setName(String name) {
+        getPoolProperties().setName(name);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void setDataSource(Object ds) {
+        getPoolProperties().setDataSource(ds);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public Object getDataSource() {
+        return getPoolProperties().getDataSource();
+    }
+
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void setDataSourceJNDI(String jndiDS) {
+        getPoolProperties().setDataSourceJNDI(jndiDS);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public String getDataSourceJNDI() {
+        return getPoolProperties().getDataSourceJNDI();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public boolean isAlternateUsernameAllowed() {
+        return getPoolProperties().isAlternateUsernameAllowed();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void setAlternateUsernameAllowed(boolean alternateUsernameAllowed) {
+        getPoolProperties().setAlternateUsernameAllowed(alternateUsernameAllowed);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void setCommitOnReturn(boolean commitOnReturn) {
+        getPoolProperties().setCommitOnReturn(commitOnReturn);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public boolean getCommitOnReturn() {
+        return getPoolProperties().getCommitOnReturn();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void setRollbackOnReturn(boolean rollbackOnReturn) {
+        getPoolProperties().setRollbackOnReturn(rollbackOnReturn);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public boolean getRollbackOnReturn() {
+        return getPoolProperties().getRollbackOnReturn();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void setUseDisposableConnectionFacade(boolean useDisposableConnectionFacade) {
+        getPoolProperties().setUseDisposableConnectionFacade(useDisposableConnectionFacade);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public boolean getUseDisposableConnectionFacade() {
+        return getPoolProperties().getUseDisposableConnectionFacade();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void setLogValidationErrors(boolean logValidationErrors) {
+        getPoolProperties().setLogValidationErrors(logValidationErrors);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public boolean getLogValidationErrors() {
+        return getPoolProperties().getLogValidationErrors();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public boolean getPropagateInterruptState() {
+        return getPoolProperties().getPropagateInterruptState();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void setPropagateInterruptState(boolean propagateInterruptState) {
+        getPoolProperties().setPropagateInterruptState(propagateInterruptState);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public boolean isIgnoreExceptionOnPreLoad() {
+        return getPoolProperties().isIgnoreExceptionOnPreLoad();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void setIgnoreExceptionOnPreLoad(boolean ignoreExceptionOnPreLoad) {
+        getPoolProperties().setIgnoreExceptionOnPreLoad(ignoreExceptionOnPreLoad);
+    }
+
+    public void purge()  {
+        try {
+            createPool().purge();
+        }catch (SQLException x) {
+            log.error("Unable to purge pool.",x);
+        }
+    }
+
+    public void purgeOnReturn() {
+        try {
+            createPool().purgeOnReturn();
+        }catch (SQLException x) {
+            log.error("Unable to purge pool.",x);
+        }
+    }
+}
diff --git a/dblib/common/src/main/java/org/apache/tomcat/jdbc/pool/DisposableConnectionFacade.java b/dblib/common/src/main/java/org/apache/tomcat/jdbc/pool/DisposableConnectionFacade.java
new file mode 100644
index 0000000..ed0e9db
--- /dev/null
+++ b/dblib/common/src/main/java/org/apache/tomcat/jdbc/pool/DisposableConnectionFacade.java
@@ -0,0 +1,118 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * openecomp
+ * ================================================================================
+ * Copyright (C) 2016 - 2017 AT&T
+ * ================================================================================
+ * Licensed 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.
+ * ============LICENSE_END=========================================================
+ */
+
+/*
+ * 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.tomcat.jdbc.pool;
+
+import java.lang.reflect.Method;
+import java.lang.reflect.Proxy;
+import java.sql.SQLException;
+
+/**
+ * A DisposableConnectionFacade object is the top most interceptor that wraps an
+ * object of type {@link PooledConnection}. The ProxyCutOffConnection intercepts
+ * two methods:
+ * <ul>
+ *   <li>{@link java.sql.Connection#close()} - returns the connection to the
+ *       pool then breaks the link between cutoff and the next interceptor.
+ *       May be called multiple times.</li>
+ *   <li>{@link java.lang.Object#toString()} - returns a custom string for this
+ *       object</li>
+ * </ul>
+ * By default method comparisons is done on a String reference level, unless the
+ * {@link PoolConfiguration#setUseEquals(boolean)} has been called with a
+ * <code>true</code> argument.
+ */
+public class DisposableConnectionFacade extends JdbcInterceptor {
+    protected DisposableConnectionFacade(JdbcInterceptor interceptor) {
+        setUseEquals(interceptor.isUseEquals());
+        setNext(interceptor);
+    }
+
+    @Override
+    public void reset(ConnectionPool parent, PooledConnection con) {
+    }
+
+
+
+    @Override
+    public int hashCode() {
+        return System.identityHashCode(this);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        return this==obj;
+    }
+
+    @Override
+    public Object invoke(Object proxy, Method method, Object[] args)
+            throws Throwable {
+        if (compare(EQUALS_VAL, method)) {
+            return Boolean.valueOf(
+                    this.equals(Proxy.getInvocationHandler(args[0])));
+        } else if (compare(HASHCODE_VAL, method)) {
+            return Integer.valueOf(this.hashCode());
+        } else if (getNext()==null) {
+            if (compare(ISCLOSED_VAL, method)) {
+                return Boolean.TRUE;
+            }
+            else if (compare(CLOSE_VAL, method)) {
+                return null;
+            }
+            else if (compare(ISVALID_VAL, method)) {
+                return Boolean.FALSE;
+            }
+        }
+
+        try {
+            return super.invoke(proxy, method, args);
+        } catch (NullPointerException e) {
+            if (getNext() == null) {
+                if (compare(TOSTRING_VAL, method)) {
+                    return "DisposableConnectionFacade[null]";
+                }
+                throw new SQLException(
+                        "PooledConnection has already been closed.");
+            }
+
+            throw e;
+        } finally {
+            if (compare(CLOSE_VAL, method)) {
+                setNext(null);
+            }
+        }
+    }
+}
diff --git a/dblib/common/src/main/java/org/apache/tomcat/jdbc/pool/FairBlockingQueue.java b/dblib/common/src/main/java/org/apache/tomcat/jdbc/pool/FairBlockingQueue.java
new file mode 100644
index 0000000..c02bfa3
--- /dev/null
+++ b/dblib/common/src/main/java/org/apache/tomcat/jdbc/pool/FairBlockingQueue.java
@@ -0,0 +1,579 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * openecomp
+ * ================================================================================
+ * Copyright (C) 2016 - 2017 AT&T
+ * ================================================================================
+ * Licensed 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.
+ * ============LICENSE_END=========================================================
+ */
+
+/*
+ * 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.tomcat.jdbc.pool;
+
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.NoSuchElementException;
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Future;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+import java.util.concurrent.locks.ReentrantLock;
+
+/**
+ *
+ * A simple implementation of a blocking queue with fairness waiting.
+ * invocations to method poll(...) will get handed out in the order they were received.
+ * Locking is fine grained, a shared lock is only used during the first level of contention, waiting is done in a
+ * lock per thread basis so that order is guaranteed once the thread goes into a suspended monitor state.
+ * <br>
+ * Not all of the methods of the {@link java.util.concurrent.BlockingQueue} are implemented.
+ *
+ * @param <E> Type of element in the queue
+ */
+
+public class FairBlockingQueue<E> implements BlockingQueue<E> {
+
+    /**
+     * This little sucker is used to reorder the way to do
+     * {@link java.util.concurrent.locks.Lock#lock()},
+     * {@link java.util.concurrent.locks.Lock#unlock()}
+     * and
+     * {@link java.util.concurrent.CountDownLatch#countDown()}
+     * during the {@link #poll(long, TimeUnit)} operation.
+     * On Linux, it performs much better if we count down while we hold the global
+     * lock, on Solaris its the other way around.
+     * Until we have tested other platforms we only check for Linux.
+     */
+    static final boolean isLinux = "Linux".equals(System.getProperty("os.name")) &&
+                                   (!Boolean.getBoolean(FairBlockingQueue.class.getName()+".ignoreOS"));
+
+    /**
+     * Phase one entry lock in order to give out
+     * per-thread-locks for the waiting phase we have
+     * a phase one lock during the contention period.
+     */
+    final ReentrantLock lock = new ReentrantLock(false);
+
+    /**
+     * All the objects in the pool are stored in a simple linked list
+     */
+    final LinkedList<E> items;
+
+    /**
+     * All threads waiting for an object are stored in a linked list
+     */
+    final LinkedList<ExchangeCountDownLatch<E>> waiters;
+
+    /**
+     * Creates a new fair blocking queue.
+     */
+    public FairBlockingQueue() {
+        items = new LinkedList<>();
+        waiters = new LinkedList<>();
+    }
+
+    //------------------------------------------------------------------
+    // USED BY CONPOOL IMPLEMENTATION
+    //------------------------------------------------------------------
+    /**
+     * Will always return true, queue is unbounded.
+     * {@inheritDoc}
+     */
+    @Override
+    public boolean offer(E e) {
+        //during the offer, we will grab the main lock
+        final ReentrantLock lock = this.lock;
+        lock.lock();
+        ExchangeCountDownLatch<E> c = null;
+        try {
+            //check to see if threads are waiting for an object
+            if (waiters.size() > 0) {
+                //if threads are waiting grab the latch for that thread
+                c = waiters.poll();
+                //give the object to the thread instead of adding it to the pool
+                c.setItem(e);
+                if (isLinux) c.countDown();
+            } else {
+                //we always add first, so that the most recently used object will be given out
+                items.addFirst(e);
+            }
+        } finally {
+            lock.unlock();
+        }
+        //if we exchanged an object with another thread, wake it up.
+        if (!isLinux && c!=null) c.countDown();
+        //we have an unbounded queue, so always return true
+        return true;
+    }
+
+    /**
+     * Will never timeout, as it invokes the {@link #offer(Object)} method.
+     * Once a lock has been acquired, the
+     * {@inheritDoc}
+     */
+    @Override
+    public boolean offer(E e, long timeout, TimeUnit unit) throws InterruptedException {
+        return offer(e);
+    }
+
+    /**
+     * Fair retrieval of an object in the queue.
+     * Objects are returned in the order the threads requested them.
+     * {@inheritDoc}
+     */
+    @Override
+    public E poll(long timeout, TimeUnit unit) throws InterruptedException {
+        E result = null;
+        final ReentrantLock lock = this.lock;
+        //acquire the global lock until we know what to do
+        lock.lock();
+        try {
+            //check to see if we have objects
+            result = items.poll();
+            if (result==null && timeout>0) {
+                //the queue is empty we will wait for an object
+                ExchangeCountDownLatch<E> c = new ExchangeCountDownLatch<>(1);
+                //add to the bottom of the wait list
+                waiters.addLast(c);
+                //unlock the global lock
+                lock.unlock();
+                boolean didtimeout = true;
+                InterruptedException interruptedException = null;
+                try {
+                    //wait for the specified timeout
+                    didtimeout = !c.await(timeout, unit);
+                } catch (InterruptedException ix) {
+                    interruptedException = ix;
+                }
+                if (didtimeout) {
+                    //if we timed out, or got interrupted
+                    // remove ourselves from the waitlist
+                    lock.lock();
+                    try {
+                        waiters.remove(c);
+                    } finally {
+                        lock.unlock();
+                    }
+                }
+                //return the item we received, can be null if we timed out
+                result = c.getItem();
+                if (null!=interruptedException) {
+                    //we got interrupted
+                    if ( null!=result) {
+                        //we got a result - clear the interrupt status
+                        //don't propagate cause we have removed a connection from pool
+                        Thread.interrupted();
+                    } else {
+                        throw interruptedException;
+                    }
+                }
+            } else {
+                //we have an object, release
+                lock.unlock();
+            }
+        } finally {
+            if (lock.isHeldByCurrentThread()) {
+                lock.unlock();
+            }
+        }
+        return result;
+    }
+
+    /**
+     * Request an item from the queue asynchronously
+     * @return - a future pending the result from the queue poll request
+     */
+    public Future<E> pollAsync() {
+        Future<E> result = null;
+        final ReentrantLock lock = this.lock;
+        //grab the global lock
+        lock.lock();
+        try {
+            //check to see if we have objects in the queue
+            E item = items.poll();
+            if (item==null) {
+                //queue is empty, add ourselves as waiters
+                ExchangeCountDownLatch<E> c = new ExchangeCountDownLatch<>(1);
+                waiters.addLast(c);
+                //return a future that will wait for the object
+                result = new ItemFuture<>(c);
+            } else {
+                //return a future with the item
+                result = new ItemFuture<>(item);
+            }
+        } finally {
+            lock.unlock();
+        }
+        return result;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public boolean remove(Object e) {
+        final ReentrantLock lock = this.lock;
+        lock.lock();
+        try {
+            return items.remove(e);
+        } finally {
+            lock.unlock();
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public int size() {
+        return items.size();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public Iterator<E> iterator() {
+        return new FairIterator();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public E poll() {
+        final ReentrantLock lock = this.lock;
+        lock.lock();
+        try {
+            return items.poll();
+        } finally {
+            lock.unlock();
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public boolean contains(Object e) {
+        final ReentrantLock lock = this.lock;
+        lock.lock();
+        try {
+            return items.contains(e);
+        } finally {
+            lock.unlock();
+        }
+    }
+
+
+    //------------------------------------------------------------------
+    // NOT USED BY CONPOOL IMPLEMENTATION
+    //------------------------------------------------------------------
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public boolean add(E e) {
+        return offer(e);
+    }
+
+    /**
+     * {@inheritDoc}
+     * @throws UnsupportedOperationException - this operation is not supported
+     */
+    @Override
+    public int drainTo(Collection<? super E> c, int maxElements) {
+        throw new UnsupportedOperationException("int drainTo(Collection<? super E> c, int maxElements)");
+    }
+
+    /**
+     * {@inheritDoc}
+     * @throws UnsupportedOperationException - this operation is not supported
+     */
+
+    @Override
+    public int drainTo(Collection<? super E> c) {
+        return drainTo(c,Integer.MAX_VALUE);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void put(E e) throws InterruptedException {
+        offer(e);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public int remainingCapacity() {
+        return Integer.MAX_VALUE - size();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public E take() throws InterruptedException {
+        return this.poll(Long.MAX_VALUE, TimeUnit.MILLISECONDS);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public boolean addAll(Collection<? extends E> c) {
+        Iterator<? extends E> i = c.iterator();
+        while (i.hasNext()) {
+            E e = i.next();
+            offer(e);
+        }
+        return true;
+    }
+
+    /**
+     * {@inheritDoc}
+     * @throws UnsupportedOperationException - this operation is not supported
+     */
+    @Override
+    public void clear() {
+        throw new UnsupportedOperationException("void clear()");
+
+    }
+
+    /**
+     * {@inheritDoc}
+     * @throws UnsupportedOperationException - this operation is not supported
+     */
+    @Override
+    public boolean containsAll(Collection<?> c) {
+        throw new UnsupportedOperationException("boolean containsAll(Collection<?> c)");
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public boolean isEmpty() {
+        return size() == 0;
+    }
+
+    /**
+     * {@inheritDoc}
+     * @throws UnsupportedOperationException - this operation is not supported
+     */
+    @Override
+    public boolean removeAll(Collection<?> c) {
+        throw new UnsupportedOperationException("boolean removeAll(Collection<?> c)");
+    }
+
+    /**
+     * {@inheritDoc}
+     * @throws UnsupportedOperationException - this operation is not supported
+     */
+    @Override
+    public boolean retainAll(Collection<?> c) {
+        throw new UnsupportedOperationException("boolean retainAll(Collection<?> c)");
+    }
+
+    /**
+     * {@inheritDoc}
+     * @throws UnsupportedOperationException - this operation is not supported
+     */
+    @Override
+    public Object[] toArray() {
+        throw new UnsupportedOperationException("Object[] toArray()");
+    }
+
+    /**
+     * {@inheritDoc}
+     * @throws UnsupportedOperationException - this operation is not supported
+     */
+    @Override
+    public <T> T[] toArray(T[] a) {
+        throw new UnsupportedOperationException("<T> T[] toArray(T[] a)");
+    }
+
+    /**
+     * {@inheritDoc}
+     * @throws UnsupportedOperationException - this operation is not supported
+     */
+    @Override
+    public E element() {
+        throw new UnsupportedOperationException("E element()");
+    }
+
+    /**
+     * {@inheritDoc}
+     * @throws UnsupportedOperationException - this operation is not supported
+     */
+    @Override
+    public E peek() {
+        throw new UnsupportedOperationException("E peek()");
+    }
+
+    /**
+     * {@inheritDoc}
+     * @throws UnsupportedOperationException - this operation is not supported
+     */
+    @Override
+    public E remove() {
+        throw new UnsupportedOperationException("E remove()");
+    }
+
+
+
+    //------------------------------------------------------------------
+    // Non cancellable Future used to check and see if a connection has been made available
+    //------------------------------------------------------------------
+    protected class ItemFuture<T> implements Future<T> {
+        protected volatile T item = null;
+        protected volatile ExchangeCountDownLatch<T> latch = null;
+        protected volatile boolean canceled = false;
+
+        public ItemFuture(T item) {
+            this.item = item;
+        }
+
+        public ItemFuture(ExchangeCountDownLatch<T> latch) {
+            this.latch = latch;
+        }
+
+        @Override
+        public boolean cancel(boolean mayInterruptIfRunning) {
+            return false; //don't allow cancel for now
+        }
+
+        @Override
+        public T get() throws InterruptedException, ExecutionException {
+            if (item!=null) {
+                return item;
+            } else if (latch!=null) {
+                latch.await();
+                return latch.getItem();
+            } else {
+                throw new ExecutionException("ItemFuture incorrectly instantiated. Bug in the code?", new Exception());
+            }
+        }
+
+        @Override
+        public T get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException {
+            if (item!=null) {
+                return item;
+            } else if (latch!=null) {
+                boolean timedout = !latch.await(timeout, unit);
+                if (timedout) throw new TimeoutException();
+                else return latch.getItem();
+            } else {
+                throw new ExecutionException("ItemFuture incorrectly instantiated. Bug in the code?", new Exception());
+            }
+        }
+
+        @Override
+        public boolean isCancelled() {
+            return false;
+        }
+
+        @Override
+        public boolean isDone() {
+            return (item!=null || latch.getItem()!=null);
+        }
+
+    }
+
+    //------------------------------------------------------------------
+    // Count down latch that can be used to exchange information
+    //------------------------------------------------------------------
+    protected class ExchangeCountDownLatch<T> extends CountDownLatch {
+        protected volatile T item;
+        public ExchangeCountDownLatch(int i) {
+            super(i);
+        }
+        public T getItem() {
+            return item;
+        }
+        public void setItem(T item) {
+            this.item = item;
+        }
+    }
+
+    //------------------------------------------------------------------
+    // Iterator safe from concurrent modification exceptions
+    //------------------------------------------------------------------
+    protected class FairIterator implements Iterator<E> {
+        E[] elements = null;
+        int index;
+        E element = null;
+
+        @SuppressWarnings("unchecked") // Can't create arrays of generic types
+        public FairIterator() {
+            final ReentrantLock lock = FairBlockingQueue.this.lock;
+            lock.lock();
+            try {
+                elements = (E[]) new Object[FairBlockingQueue.this.items.size()];
+                FairBlockingQueue.this.items.toArray(elements);
+                index = 0;
+            } finally {
+                lock.unlock();
+            }
+        }
+        @Override
+        public boolean hasNext() {
+            return index<elements.length;
+        }
+
+        @Override
+        public E next() {
+            if (!hasNext()) {
+                throw new NoSuchElementException();
+            }
+            element = elements[index++];
+            return element;
+        }
+
+        @Override
+        public void remove() {
+            final ReentrantLock lock = FairBlockingQueue.this.lock;
+            lock.lock();
+            try {
+                if (element!=null) {
+                    FairBlockingQueue.this.items.remove(element);
+                }
+            } finally {
+                lock.unlock();
+            }
+        }
+
+    }
+}
diff --git a/dblib/common/src/main/java/org/apache/tomcat/jdbc/pool/JdbcInterceptor.java b/dblib/common/src/main/java/org/apache/tomcat/jdbc/pool/JdbcInterceptor.java
new file mode 100644
index 0000000..46bc0b1
--- /dev/null
+++ b/dblib/common/src/main/java/org/apache/tomcat/jdbc/pool/JdbcInterceptor.java
@@ -0,0 +1,259 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * openecomp
+ * ================================================================================
+ * Copyright (C) 2016 - 2017 AT&T
+ * ================================================================================
+ * Licensed 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.
+ * ============LICENSE_END=========================================================
+ */
+
+/*
+ * 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.tomcat.jdbc.pool;
+
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.Method;
+import java.util.Map;
+
+import org.apache.tomcat.jdbc.pool.PoolProperties.InterceptorProperty;
+
+/**
+ * Abstract class that is to be extended for implementations of interceptors.
+ * Everytime an operation is called on the {@link java.sql.Connection} object the
+ * {@link #invoke(Object, Method, Object[])} method on the interceptor will be called.
+ * Interceptors are useful to change or improve behavior of the connection pool.<br>
+ * Interceptors can receive a set of properties. Each sub class is responsible for parsing the properties during runtime when they
+ * are needed or simply override the {@link #setProperties(Map)} method.
+ * Properties arrive in a key-value pair of Strings as they were received through the configuration.
+ * This method is called once per cached connection object when the object is first configured.
+ *
+ * @version 1.0
+ */
+public abstract class JdbcInterceptor implements InvocationHandler {
+    /**
+     * {@link java.sql.Connection#close()} method name
+     */
+    public static final String CLOSE_VAL = "close";
+    /**
+     * {@link Object#toString()} method name
+     */
+    public static final String TOSTRING_VAL = "toString";
+    /**
+     * {@link java.sql.Connection#isClosed()} method name
+     */
+    public static final String ISCLOSED_VAL = "isClosed";
+    /**
+     * {@link javax.sql.PooledConnection#getConnection()} method name
+     */
+    public static final String GETCONNECTION_VAL = "getConnection";
+    /**
+     * {@link java.sql.Wrapper#unwrap(Class)} method name
+     */
+    public static final String UNWRAP_VAL = "unwrap";
+    /**
+     * {@link java.sql.Wrapper#isWrapperFor(Class)} method name
+     */
+    public static final String ISWRAPPERFOR_VAL = "isWrapperFor";
+
+    /**
+     * {@link java.sql.Connection#isValid(int)} method name
+     */
+    public static final String ISVALID_VAL = "isValid";
+
+    /**
+     * {@link java.lang.Object#equals(Object)}
+     */
+    public static final String EQUALS_VAL = "equals";
+
+    /**
+     * {@link java.lang.Object#hashCode()}
+     */
+    public static final String HASHCODE_VAL = "hashCode";
+
+    /**
+     * Properties for this interceptor.
+     */
+    protected Map<String,InterceptorProperty> properties = null;
+
+    /**
+     * The next interceptor in the chain
+     */
+    private volatile JdbcInterceptor next = null;
+    /**
+     * Property that decides how we do string comparison, default is to use
+     * {@link String#equals(Object)}. If set to <code>false</code> then the
+     * equality operator (==) is used.
+     */
+    private boolean useEquals = true;
+
+    /**
+     * Public constructor for instantiation through reflection
+     */
+    public JdbcInterceptor() {
+        // NOOP
+    }
+
+    /**
+     * Gets invoked each time an operation on {@link java.sql.Connection} is invoked.
+     * {@inheritDoc}
+     */
+
+    @Override
+    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
+        if (getNext()!=null) return getNext().invoke(proxy,method,args);
+        else throw new NullPointerException();
+    }
+
+    /**
+     * Returns the next interceptor in the chain
+     * @return the next interceptor in the chain
+     */
+    public JdbcInterceptor getNext() {
+        return next;
+    }
+
+    /**
+     * configures the next interceptor in the chain
+     * @param next The next chain item
+     */
+    public void setNext(JdbcInterceptor next) {
+        this.next = next;
+    }
+
+    /**
+     * Performs a string comparison, using references unless the useEquals property is set to true.
+     * @param name1 The first name
+     * @param name2 The second name
+     * @return true if name1 is equal to name2 based on {@link #useEquals}
+     */
+    public boolean compare(String name1, String name2) {
+        if (isUseEquals()) {
+            return name1.equals(name2);
+        } else {
+            return name1==name2;
+        }
+    }
+
+    /**
+     * Compares a method name (String) to a method (Method)
+     * {@link #compare(String,String)}
+     * Uses reference comparison unless the useEquals property is set to true
+     * @param methodName The method name
+     * @param method The method
+     * @return <code>true</code> if the name matches
+     */
+    public boolean compare(String methodName, Method method) {
+        return compare(methodName, method.getName());
+    }
+
+    /**
+     * Gets called each time the connection is borrowed from the pool
+     * This means that if an interceptor holds a reference to the connection
+     * the interceptor can be reused for another connection.
+     * <br>
+     * This method may be called with null as both arguments when we are closing down the connection.
+     * @param parent - the connection pool owning the connection
+     * @param con - the pooled connection
+     */
+    public abstract void reset(ConnectionPool parent, PooledConnection con);
+
+    /**
+     * Called when {@link java.sql.Connection#close()} is called on the underlying connection.
+     * This is to notify the interceptors, that the physical connection has been released.
+     * Implementation of this method should be thought through with care, as no actions should trigger an exception.
+     * @param parent - the connection pool that this connection belongs to
+     * @param con    - the pooled connection that holds this connection
+     * @param finalizing - if this connection is finalizing. True means that the pooled connection will not reconnect the underlying connection
+     */
+    public void disconnected(ConnectionPool parent, PooledConnection con, boolean finalizing) {
+    }
+
+
+    /**
+     * Returns the properties configured for this interceptor
+     * @return the configured properties for this interceptor
+     */
+    public Map<String,InterceptorProperty> getProperties() {
+        return properties;
+    }
+
+    /**
+     * Called during the creation of an interceptor
+     * The properties can be set during the configuration of an interceptor
+     * Override this method to perform type casts between string values and object properties
+     * @param properties The properties
+     */
+    public void setProperties(Map<String,InterceptorProperty> properties) {
+        this.properties = properties;
+        final String useEquals = "useEquals";
+        InterceptorProperty p = properties.get(useEquals);
+        if (p!=null) {
+            setUseEquals(Boolean.parseBoolean(p.getValue()));
+        }
+    }
+
+    /**
+     * @return true if the compare method uses the Object.equals(Object) method
+     *         false if comparison is done on a reference level
+     */
+    public boolean isUseEquals() {
+        return useEquals;
+    }
+
+    /**
+     * Set to true if string comparisons (for the {@link #compare(String, Method)} and {@link #compare(String, String)} methods) should use the Object.equals(Object) method
+     * The default is false
+     * @param useEquals <code>true</code> if equals will be used for comparisons
+     */
+    public void setUseEquals(boolean useEquals) {
+        this.useEquals = useEquals;
+    }
+
+    /**
+     * This method is invoked by a connection pool when the pool is closed.
+     * Interceptor classes can override this method if they keep static
+     * variables or other tracking means around.
+     * <b>This method is only invoked on a single instance of the interceptor, and not on every instance created.</b>
+     * @param pool - the pool that is being closed.
+     */
+    public void poolClosed(ConnectionPool pool) {
+        // NOOP
+    }
+
+    /**
+     * This method is invoked by a connection pool when the pool is first started up, usually when the first connection is requested.
+     * Interceptor classes can override this method if they keep static
+     * variables or other tracking means around.
+     * <b>This method is only invoked on a single instance of the interceptor, and not on every instance created.</b>
+     * @param pool - the pool that is being closed.
+     */
+    public void poolStarted(ConnectionPool pool) {
+        // NOOP
+    }
+
+}
diff --git a/dblib/common/src/main/java/org/apache/tomcat/jdbc/pool/MultiLockFairBlockingQueue.java b/dblib/common/src/main/java/org/apache/tomcat/jdbc/pool/MultiLockFairBlockingQueue.java
new file mode 100644
index 0000000..a4b1f73
--- /dev/null
+++ b/dblib/common/src/main/java/org/apache/tomcat/jdbc/pool/MultiLockFairBlockingQueue.java
@@ -0,0 +1,584 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * openecomp
+ * ================================================================================
+ * Copyright (C) 2016 - 2017 AT&T
+ * ================================================================================
+ * Licensed 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.
+ * ============LICENSE_END=========================================================
+ */
+
+/*
+ * 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.tomcat.jdbc.pool;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.NoSuchElementException;
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Future;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.concurrent.locks.ReentrantLock;
+
+/**
+ * <b>EXPERIMENTAL AND NOT YET COMPLETE!</b>
+ *
+ *
+ * An implementation of a blocking queue with fairness waiting and lock dispersal to avoid contention.
+ * invocations to method poll(...) will get handed out in the order they were received.
+ * Locking is fine grained, a shared lock is only used during the first level of contention, waiting is done in a
+ * lock per thread basis so that order is guaranteed once the thread goes into a suspended monitor state.
+ * <br>
+ * Not all of the methods of the {@link java.util.concurrent.BlockingQueue} are implemented.
+ *
+ * @param <E> Type of element in the queue
+ */
+
+public class MultiLockFairBlockingQueue<E> implements BlockingQueue<E> {
+
+    final int LOCK_COUNT = Runtime.getRuntime().availableProcessors();
+
+    final AtomicInteger putQueue = new AtomicInteger(0);
+    final AtomicInteger pollQueue = new AtomicInteger(0);
+
+    public int getNextPut() {
+        int idx = Math.abs(putQueue.incrementAndGet()) % LOCK_COUNT;
+        return idx;
+    }
+
+    public int getNextPoll() {
+        int idx = Math.abs(pollQueue.incrementAndGet()) % LOCK_COUNT;
+        return idx;
+    }
+    /**
+     * Phase one entry lock in order to give out
+     * per-thread-locks for the waiting phase we have
+     * a phase one lock during the contention period.
+     */
+    private final ReentrantLock[] locks = new ReentrantLock[LOCK_COUNT];
+
+    /**
+     * All the objects in the pool are stored in a simple linked list
+     */
+    final LinkedList<E>[] items;
+
+    /**
+     * All threads waiting for an object are stored in a linked list
+     */
+    final LinkedList<ExchangeCountDownLatch<E>>[] waiters;
+
+    /**
+     * Creates a new fair blocking queue.
+     */
+    @SuppressWarnings("unchecked") // Can create arrays of generic types
+    public MultiLockFairBlockingQueue() {
+        items = new LinkedList[LOCK_COUNT];
+        waiters = new LinkedList[LOCK_COUNT];
+        for (int i=0; i<LOCK_COUNT; i++) {
+            items[i] = new LinkedList<>();
+            waiters[i] = new LinkedList<>();
+            locks[i] = new ReentrantLock(false);
+        }
+    }
+
+    //------------------------------------------------------------------
+    // USED BY CONPOOL IMPLEMENTATION
+    //------------------------------------------------------------------
+    /**
+     * Will always return true, queue is unbounded.
+     * {@inheritDoc}
+     */
+    @Override
+    public boolean offer(E e) {
+        int idx = getNextPut();
+        //during the offer, we will grab the main lock
+        final ReentrantLock lock = this.locks[idx];
+        lock.lock();
+        ExchangeCountDownLatch<E> c = null;
+        try {
+            //check to see if threads are waiting for an object
+            if (waiters[idx].size() > 0) {
+                //if threads are waiting grab the latch for that thread
+                c = waiters[idx].poll();
+                //give the object to the thread instead of adding it to the pool
+                c.setItem(e);
+            } else {
+                //we always add first, so that the most recently used object will be given out
+                items[idx].addFirst(e);
+            }
+        } finally {
+            lock.unlock();
+        }
+        //if we exchanged an object with another thread, wake it up.
+        if (c!=null) c.countDown();
+        //we have an unbounded queue, so always return true
+        return true;
+    }
+
+    /**
+     * Will never timeout, as it invokes the {@link #offer(Object)} method.
+     * Once a lock has been acquired, the
+     * {@inheritDoc}
+     */
+    @Override
+    public boolean offer(E e, long timeout, TimeUnit unit) throws InterruptedException {
+        return offer(e);
+    }
+
+    /**
+     * Fair retrieval of an object in the queue.
+     * Objects are returned in the order the threads requested them.
+     * {@inheritDoc}
+     */
+    @Override
+    public E poll(long timeout, TimeUnit unit) throws InterruptedException {
+        int idx = getNextPoll();
+        E result = null;
+        final ReentrantLock lock = this.locks[idx];
+        try {
+            //acquire the global lock until we know what to do
+            lock.lock();
+            //check to see if we have objects
+            result = items[idx].poll();
+            if (result==null && timeout>0) {
+                //the queue is empty we will wait for an object
+                ExchangeCountDownLatch<E> c = new ExchangeCountDownLatch<>(1);
+                //add to the bottom of the wait list
+                waiters[idx].addLast(c);
+                //unlock the global lock
+                lock.unlock();
+                //wait for the specified timeout
+                if (!c.await(timeout, unit)) {
+                    //if we timed out, remove ourselves from the waitlist
+                    lock.lock();
+                    waiters[idx].remove(c);
+                    lock.unlock();
+                }
+                //return the item we received, can be null if we timed out
+                result = c.getItem();
+            } else {
+                //we have an object, release
+                lock.unlock();
+            }
+        } finally {
+            if (lock.isHeldByCurrentThread()) {
+                lock.unlock();
+            }
+        }
+        return result;
+    }
+
+    /**
+     * Request an item from the queue asynchronously
+     * @return - a future pending the result from the queue poll request
+     */
+    public Future<E> pollAsync() {
+        int idx = getNextPoll();
+        Future<E> result = null;
+        final ReentrantLock lock = this.locks[idx];
+        try {
+            //grab the global lock
+            lock.lock();
+            //check to see if we have objects in the queue
+            E item = items[idx].poll();
+            if (item==null) {
+                //queue is empty, add ourselves as waiters
+                ExchangeCountDownLatch<E> c = new ExchangeCountDownLatch<>(1);
+                waiters[idx].addLast(c);
+                //return a future that will wait for the object
+                result = new ItemFuture<>(c);
+            } else {
+                //return a future with the item
+                result = new ItemFuture<>(item);
+            }
+        } finally {
+            lock.unlock();
+        }
+        return result;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public boolean remove(Object e) {
+        for (int idx=0; idx<LOCK_COUNT; idx++) {
+            final ReentrantLock lock = this.locks[idx];
+            lock.lock();
+            try {
+                boolean result = items[idx].remove(e);
+                if (result) return result;
+            } finally {
+                lock.unlock();
+            }
+        }
+        return false;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public int size() {
+        int size = 0;
+        for (int idx=0; idx<LOCK_COUNT; idx++) {
+            size += items[idx].size();
+        }
+        return size;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public Iterator<E> iterator() {
+        return new FairIterator();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public E poll() {
+        int idx = getNextPoll();
+        final ReentrantLock lock = this.locks[idx];
+        lock.lock();
+        try {
+            return items[idx].poll();
+        } finally {
+            lock.unlock();
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public boolean contains(Object e) {
+        for (int idx=0; idx<LOCK_COUNT; idx++) {
+            boolean result = items[idx].contains(e);
+            if (result) return result;
+        }
+        return false;
+    }
+
+
+    //------------------------------------------------------------------
+    // NOT USED BY CONPOOL IMPLEMENTATION
+    //------------------------------------------------------------------
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public boolean add(E e) {
+        return offer(e);
+    }
+
+    /**
+     * {@inheritDoc}
+     * @throws UnsupportedOperationException - this operation is not supported
+     */
+    @Override
+    public int drainTo(Collection<? super E> c, int maxElements) {
+        throw new UnsupportedOperationException("int drainTo(Collection<? super E> c, int maxElements)");
+    }
+
+    /**
+     * {@inheritDoc}
+     * @throws UnsupportedOperationException - this operation is not supported
+     */
+    @Override
+    public int drainTo(Collection<? super E> c) {
+        return drainTo(c,Integer.MAX_VALUE);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void put(E e) throws InterruptedException {
+        offer(e);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public int remainingCapacity() {
+        return Integer.MAX_VALUE - size();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public E take() throws InterruptedException {
+        return this.poll(Long.MAX_VALUE, TimeUnit.MILLISECONDS);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public boolean addAll(Collection<? extends E> c) {
+        Iterator<? extends E> i = c.iterator();
+        while (i.hasNext()) {
+            E e = i.next();
+            offer(e);
+        }
+        return true;
+    }
+
+    /**
+     * {@inheritDoc}
+     * @throws UnsupportedOperationException - this operation is not supported
+     */
+    @Override
+    public void clear() {
+        throw new UnsupportedOperationException("void clear()");
+
+    }
+
+    /**
+     * {@inheritDoc}
+     * @throws UnsupportedOperationException - this operation is not supported
+     */
+    @Override
+    public boolean containsAll(Collection<?> c) {
+        throw new UnsupportedOperationException("boolean containsAll(Collection<?> c)");
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public boolean isEmpty() {
+        return size() == 0;
+    }
+
+    /**
+     * {@inheritDoc}
+     * @throws UnsupportedOperationException - this operation is not supported
+     */
+    @Override
+    public boolean removeAll(Collection<?> c) {
+        throw new UnsupportedOperationException("boolean removeAll(Collection<?> c)");
+    }
+
+    /**
+     * {@inheritDoc}
+     * @throws UnsupportedOperationException - this operation is not supported
+     */
+    @Override
+    public boolean retainAll(Collection<?> c) {
+        throw new UnsupportedOperationException("boolean retainAll(Collection<?> c)");
+    }
+
+    /**
+     * {@inheritDoc}
+     * @throws UnsupportedOperationException - this operation is not supported
+     */
+    @Override
+    public Object[] toArray() {
+        throw new UnsupportedOperationException("Object[] toArray()");
+    }
+
+    /**
+     * {@inheritDoc}
+     * @throws UnsupportedOperationException - this operation is not supported
+     */
+    @Override
+    public <T> T[] toArray(T[] a) {
+        throw new UnsupportedOperationException("<T> T[] toArray(T[] a)");
+    }
+
+    /**
+     * {@inheritDoc}
+     * @throws UnsupportedOperationException - this operation is not supported
+     */
+    @Override
+    public E element() {
+        throw new UnsupportedOperationException("E element()");
+    }
+
+    /**
+     * {@inheritDoc}
+     * @throws UnsupportedOperationException - this operation is not supported
+     */
+    @Override
+    public E peek() {
+        throw new UnsupportedOperationException("E peek()");
+    }
+
+    /**
+     * {@inheritDoc}
+     * @throws UnsupportedOperationException - this operation is not supported
+     */
+    @Override
+    public E remove() {
+        throw new UnsupportedOperationException("E remove()");
+    }
+
+
+
+    //------------------------------------------------------------------
+    // Non cancellable Future used to check and see if a connection has been made available
+    //------------------------------------------------------------------
+    protected class ItemFuture<T> implements Future<T> {
+        protected volatile T item = null;
+        protected volatile ExchangeCountDownLatch<T> latch = null;
+        protected volatile boolean canceled = false;
+
+        public ItemFuture(T item) {
+            this.item = item;
+        }
+
+        public ItemFuture(ExchangeCountDownLatch<T> latch) {
+            this.latch = latch;
+        }
+
+        @Override
+        public boolean cancel(boolean mayInterruptIfRunning) {
+            return false; //don't allow cancel for now
+        }
+
+        @Override
+        public T get() throws InterruptedException, ExecutionException {
+            if (item!=null) {
+                return item;
+            } else if (latch!=null) {
+                latch.await();
+                return latch.getItem();
+            } else {
+                throw new ExecutionException("ItemFuture incorrectly instantiated. Bug in the code?", new Exception());
+            }
+        }
+
+        @Override
+        public T get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException {
+            if (item!=null) {
+                return item;
+            } else if (latch!=null) {
+                boolean timedout = !latch.await(timeout, unit);
+                if (timedout) throw new TimeoutException();
+                else return latch.getItem();
+            } else {
+                throw new ExecutionException("ItemFuture incorrectly instantiated. Bug in the code?", new Exception());
+            }
+        }
+
+        @Override
+        public boolean isCancelled() {
+            return false;
+        }
+
+        @Override
+        public boolean isDone() {
+            return (item!=null || latch.getItem()!=null);
+        }
+
+    }
+
+    //------------------------------------------------------------------
+    // Count down latch that can be used to exchange information
+    //------------------------------------------------------------------
+    protected class ExchangeCountDownLatch<T> extends CountDownLatch {
+        protected volatile T item;
+        public ExchangeCountDownLatch(int i) {
+            super(i);
+        }
+        public T getItem() {
+            return item;
+        }
+        public void setItem(T item) {
+            this.item = item;
+        }
+    }
+
+    //------------------------------------------------------------------
+    // Iterator safe from concurrent modification exceptions
+    //------------------------------------------------------------------
+    protected class FairIterator implements Iterator<E> {
+        E[] elements = null;
+        int index;
+        E element = null;
+
+        @SuppressWarnings("unchecked") // Can't create arrays of generic types
+        public FairIterator() {
+            ArrayList<E> list = new ArrayList<>(MultiLockFairBlockingQueue.this.size());
+            for (int idx=0; idx<LOCK_COUNT; idx++) {
+                final ReentrantLock lock = MultiLockFairBlockingQueue.this.locks[idx];
+                lock.lock();
+                try {
+                    elements = (E[]) new Object[MultiLockFairBlockingQueue.this.items[idx].size()];
+                    MultiLockFairBlockingQueue.this.items[idx].toArray(elements);
+
+                } finally {
+                    lock.unlock();
+                }
+            }
+            index = 0;
+            elements = (E[]) new Object[list.size()];
+            list.toArray(elements);
+        }
+        @Override
+        public boolean hasNext() {
+            return index<elements.length;
+        }
+
+        @Override
+        public E next() {
+            if (!hasNext()) {
+                throw new NoSuchElementException();
+            }
+            element = elements[index++];
+            return element;
+        }
+
+        @Override
+        public void remove() {
+            for (int idx=0; idx<LOCK_COUNT; idx++) {
+                final ReentrantLock lock = MultiLockFairBlockingQueue.this.locks[idx];
+                lock.lock();
+                try {
+                    boolean result = MultiLockFairBlockingQueue.this.items[idx].remove(elements[index]);
+                    if (result) break;
+                } finally {
+                    lock.unlock();
+                }
+            }
+
+        }
+
+    }
+}
diff --git a/dblib/common/src/main/java/org/apache/tomcat/jdbc/pool/PoolConfiguration.java b/dblib/common/src/main/java/org/apache/tomcat/jdbc/pool/PoolConfiguration.java
new file mode 100644
index 0000000..42cf11d
--- /dev/null
+++ b/dblib/common/src/main/java/org/apache/tomcat/jdbc/pool/PoolConfiguration.java
@@ -0,0 +1,917 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * openecomp
+ * ================================================================================
+ * Copyright (C) 2016 - 2017 AT&T
+ * ================================================================================
+ * Licensed 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.
+ * ============LICENSE_END=========================================================
+ */
+
+/*
+ * 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.tomcat.jdbc.pool;
+
+import java.util.Properties;
+
+import org.apache.tomcat.jdbc.pool.PoolProperties.InterceptorDefinition;
+
+/**
+ * A list of properties that are configurable for a connection pool.
+ * The {@link DataSource} object also implements this interface so that it can be easily configured through
+ * an IoC container without having to specify a secondary object with a setter method.
+ *
+ */
+
+public interface PoolConfiguration {
+
+    /**
+     * JMX prefix for interceptors that register themselves with JMX
+     */
+    public static final String PKG_PREFIX = "org.apache.tomcat.jdbc.pool.interceptor.";
+
+    /**
+     * Connections that have been abandoned (timed out) wont get closed and reported up unless the number of connections in use are
+     * above the percentage defined by abandonWhenPercentageFull.
+     * The value should be between 0-100.
+     * The default value is 0, which implies that connections are eligible for
+     * closure as soon as removeAbandonedTimeout has been reached.
+     * @param percentage a value between 0 and 100 to indicate when connections that have been abandoned/timed out are considered abandoned
+     */
+    public void setAbandonWhenPercentageFull(int percentage);
+
+    /**
+     * Connections that have been abandoned (timed out) wont get closed and reported up unless the number of connections in use are
+     * above the percentage defined by abandonWhenPercentageFull.
+     * The value should be between 0-100.
+     * The default value is 0, which implies that connections are eligible for
+     * closure as soon as removeAbandonedTimeout has been reached.
+     * @return percentage - a value between 0 and 100 to indicate when connections that have been abandoned/timed out are considered abandoned
+     */
+    public int getAbandonWhenPercentageFull();
+
+    /**
+     * Returns <code>true</code> if a fair queue is being used by the connection pool
+     * @return <code>true</code> if a fair waiting queue is being used
+     */
+    public boolean isFairQueue();
+
+    /**
+     * Set to true if you wish that calls to getConnection
+     * should be treated fairly in a true FIFO fashion.
+     * This uses the {@link FairBlockingQueue} implementation for the list of the idle connections.
+     * The default value is true.
+     * This flag is required when you want to use asynchronous connection retrieval.
+     * @param fairQueue <code>true</code> to use a fair queue
+     */
+    public void setFairQueue(boolean fairQueue);
+
+    /**
+     * Property not used. Access is always allowed.
+     * Access can be achieved by calling unwrap on the pooled connection. see {@link javax.sql.DataSource} interface
+     * or call getConnection through reflection or cast the object as {@link javax.sql.PooledConnection}
+     * @return <code>true</code>
+     */
+    public boolean isAccessToUnderlyingConnectionAllowed();
+
+    /**
+     * No-op
+     * @param accessToUnderlyingConnectionAllowed parameter ignored
+     */
+    public void setAccessToUnderlyingConnectionAllowed(boolean accessToUnderlyingConnectionAllowed);
+
+    /**
+     * The connection properties that will be sent to the JDBC driver when establishing new connections.
+     * Format of the string is [propertyName=property;] <br>
+     * NOTE - The "user" and "password" properties will be passed explicitly, so they do not need to be included here.
+     * The default value is null.
+     * @return the connection properties
+     */
+    public String getConnectionProperties();
+
+    /**
+     * The properties that will be passed into {@link java.sql.Driver#connect(String, Properties)} method.
+     * Username and password do not need to be stored here, they will be passed into the properties right before the connection is established.
+     * @param connectionProperties properties - Format of the string is [propertyName=property;]*
+     * Example: prop1=value1;prop2=value2
+     */
+    public void setConnectionProperties(String connectionProperties);
+
+    /**
+     * Returns the database properties that are passed into the {@link java.sql.Driver#connect(String, Properties)} method.
+     * @return database properties that are passed into the {@link java.sql.Driver#connect(String, Properties)} method.
+     */
+    public Properties getDbProperties();
+
+    /**
+     * Overrides the database properties passed into the  {@link java.sql.Driver#connect(String, Properties)} method.
+     * @param dbProperties The database properties
+     */
+    public void setDbProperties(Properties dbProperties);
+
+    /**
+     * The default auto-commit state of connections created by this pool.
+     * If not set (null), default is JDBC driver default (If set to null then the {@link java.sql.Connection#setAutoCommit(boolean)} method will not be called.)
+     * @return the default auto commit setting, null is Driver default.
+     */
+    public Boolean isDefaultAutoCommit();
+
+    /**
+     * The default auto-commit state of connections created by this pool.
+     * If not set (null), default is JDBC driver default (If set to null then the {@link java.sql.Connection#setAutoCommit(boolean)} method will not be called.)
+     * @return the default auto commit setting, null is Driver default.
+     */
+    public Boolean getDefaultAutoCommit();
+
+    /**
+     * The default auto-commit state of connections created by this pool.
+     * If not set (null), default is JDBC driver default (If set to null then the {@link java.sql.Connection#setAutoCommit(boolean)} method will not be called.)
+     * @param defaultAutoCommit default auto commit setting, null is Driver default.
+     */
+    public void setDefaultAutoCommit(Boolean defaultAutoCommit);
+
+    /**
+     * If non null, during connection creation the method {@link java.sql.Connection#setCatalog(String)} will be called with the set value.
+     * @return the default catalog, null if not set and accepting the driver default.
+     */
+    public String getDefaultCatalog();
+
+    /**
+     * If non null, during connection creation the method {@link java.sql.Connection#setCatalog(String)} will be called with the set value.
+     * @param defaultCatalog null if not set and accepting the driver default.
+     */
+    public void setDefaultCatalog(String defaultCatalog);
+
+    /**
+     * If non null, during connection creation the method {@link java.sql.Connection#setReadOnly(boolean)} will be called with the set value.
+     * @return null if not set and accepting the driver default otherwise the read only value
+     */
+    public Boolean isDefaultReadOnly();
+
+    /**
+     * If non null, during connection creation the method {@link java.sql.Connection#setReadOnly(boolean)} will be called with the set value.
+     * @return null if not set and accepting the driver default otherwise the read only value
+     */
+    public Boolean getDefaultReadOnly();
+
+    /**
+     * If non null, during connection creation the method {@link java.sql.Connection#setReadOnly(boolean)} will be called with the set value.
+     * @param defaultReadOnly null if not set and accepting the driver default.
+     */
+    public void setDefaultReadOnly(Boolean defaultReadOnly);
+
+
+    /**
+     * Returns the default transaction isolation level. If set to {@link DataSourceFactory#UNKNOWN_TRANSACTIONISOLATION} the method
+     * {@link java.sql.Connection#setTransactionIsolation(int)} will not be called during connection creation.
+     * @return driver transaction isolation level, or -1 {@link DataSourceFactory#UNKNOWN_TRANSACTIONISOLATION} if not set.
+     */
+    public int getDefaultTransactionIsolation();
+
+    /**
+     * If set to {@link DataSourceFactory#UNKNOWN_TRANSACTIONISOLATION} the method
+     * {@link java.sql.Connection#setTransactionIsolation(int)} will not be called during connection creation. Otherwise the method
+     * will be called with the isolation level set by this property.
+     * @param defaultTransactionIsolation a value of {@link java.sql.Connection#TRANSACTION_NONE}, {@link java.sql.Connection#TRANSACTION_READ_COMMITTED},
+     * {@link java.sql.Connection#TRANSACTION_READ_UNCOMMITTED}, {@link java.sql.Connection#TRANSACTION_REPEATABLE_READ},
+     * {@link java.sql.Connection#TRANSACTION_SERIALIZABLE} or {@link DataSourceFactory#UNKNOWN_TRANSACTIONISOLATION}
+     * The last value will not be set on the connection.
+     */
+    public void setDefaultTransactionIsolation(int defaultTransactionIsolation);
+
+    /**
+     * The fully qualified Java class name of the JDBC driver to be used. The driver has to be accessible from the same classloader as tomcat-jdbc.jar
+     * @return fully qualified JDBC driver name.
+     */
+    public String getDriverClassName();
+
+    /**
+     * The fully qualified Java class name of the JDBC driver to be used. The driver has to be accessible from the same classloader as tomcat-jdbc.jar
+     * @param driverClassName a fully qualified Java class name of a {@link java.sql.Driver} implementation.
+     */
+    public void setDriverClassName(String driverClassName);
+
+    /**
+     * Returns the number of connections that will be established when the connection pool is started.
+     * Default value is 10
+     * @return number of connections to be started when pool is started
+     */
+    public int getInitialSize();
+
+    /**
+     * Set the number of connections that will be established when the connection pool is started.
+     * Default value is 10.
+     * If this value exceeds {@link #setMaxActive(int)} it will automatically be lowered.
+     * @param initialSize the number of connections to be established.
+     *
+     */
+    public void setInitialSize(int initialSize);
+
+    /**
+     * boolean flag to set if stack traces should be logged for application code which abandoned a Connection.
+     * Logging of abandoned Connections adds overhead for every Connection borrow because a stack trace has to be generated.
+     * The default value is false.
+     * @return true if the connection pool logs stack traces when connections are borrowed from the pool.
+     */
+    public boolean isLogAbandoned();
+
+    /**
+     * boolean flag to set if stack traces should be logged for application code which abandoned a Connection.
+     * Logging of abandoned Connections adds overhead for every Connection borrow because a stack trace has to be generated.
+     * The default value is false.
+     * @param logAbandoned set to true if stack traces should be recorded when {@link DataSource#getConnection()} is called.
+     */
+    public void setLogAbandoned(boolean logAbandoned);
+
+    /**
+     * The maximum number of active connections that can be allocated from this pool at the same time. The default value is 100
+     * @return the maximum number of connections used by this pool
+     */
+    public int getMaxActive();
+
+    /**
+     * The maximum number of active connections that can be allocated from this pool at the same time. The default value is 100
+     * @param maxActive hard limit for number of managed connections by this pool
+     */
+    public void setMaxActive(int maxActive);
+
+
+    /**
+     * The maximum number of connections that should be kept in the idle pool if {@link #isPoolSweeperEnabled()} returns false.
+     * If the If {@link #isPoolSweeperEnabled()} returns true, then the idle pool can grow up to {@link #getMaxActive}
+     * and will be shrunk according to {@link #getMinEvictableIdleTimeMillis()} setting.
+     * Default value is maxActive:100
+     * @return the maximum number of idle connections.
+     */
+    public int getMaxIdle();
+
+    /**
+     * The maximum number of connections that should be kept in the idle pool if {@link #isPoolSweeperEnabled()} returns false.
+     * If the If {@link #isPoolSweeperEnabled()} returns true, then the idle pool can grow up to {@link #getMaxActive}
+     * and will be shrunk according to {@link #getMinEvictableIdleTimeMillis()} setting.
+     * Default value is maxActive:100
+     * @param maxIdle the maximum size of the idle pool
+     */
+    public void setMaxIdle(int maxIdle);
+
+    /**
+     * The maximum number of milliseconds that the pool will wait (when there are no available connections and the
+     * {@link #getMaxActive} has been reached) for a connection to be returned
+     * before throwing an exception. Default value is 30000 (30 seconds)
+     * @return the number of milliseconds to wait for a connection to become available if the pool is maxed out.
+     */
+    public int getMaxWait();
+
+    /**
+     * The maximum number of milliseconds that the pool will wait (when there are no available connections and the
+     * {@link #getMaxActive} has been reached) for a connection to be returned
+     * before throwing an exception. Default value is 30000 (30 seconds)
+     * @param maxWait the maximum number of milliseconds to wait.
+     */
+    public void setMaxWait(int maxWait);
+
+    /**
+     * The minimum amount of time an object must sit idle in the pool before it is eligible for eviction.
+     * The default value is 60000 (60 seconds).
+     * @return the minimum amount of idle time in milliseconds before a connection is considered idle and eligible for eviction.
+     */
+    public int getMinEvictableIdleTimeMillis();
+
+    /**
+     * The minimum amount of time an object must sit idle in the pool before it is eligible for eviction.
+     * The default value is 60000 (60 seconds).
+     * @param minEvictableIdleTimeMillis the number of milliseconds a connection must be idle to be eligible for eviction.
+     */
+    public void setMinEvictableIdleTimeMillis(int minEvictableIdleTimeMillis);
+
+    /**
+     * The minimum number of established connections that should be kept in the pool at all times.
+     * The connection pool can shrink below this number if validation queries fail and connections get closed.
+     * Default value is derived from {@link #getInitialSize()} (also see {@link #setTestWhileIdle(boolean)}
+     * The idle pool will not shrink below this value during an eviction run, hence the number of actual connections
+     * can be between {@link #getMinIdle()} and somewhere between {@link #getMaxIdle()} and {@link #getMaxActive()}
+     * @return the minimum number of idle or established connections
+     */
+    public int getMinIdle();
+
+    /**
+     * The minimum number of established connections that should be kept in the pool at all times.
+     * The connection pool can shrink below this number if validation queries fail and connections get closed.
+     * Default value is derived from {@link #getInitialSize()} (also see {@link #setTestWhileIdle(boolean)}
+     * The idle pool will not shrink below this value during an eviction run, hence the number of actual connections
+     * can be between {@link #getMinIdle()} and somewhere between {@link #getMaxIdle()} and {@link #getMaxActive()}
+     *
+     * @param minIdle the minimum number of idle or established connections
+     */
+    public void setMinIdle(int minIdle);
+
+    /**
+     * Returns the name of the connection pool. By default a JVM unique random name is assigned.
+     * @return the name of the pool, should be unique in a JVM
+     */
+    public String getName();
+
+    /**
+     * Sets the name of the connection pool
+     * @param name the name of the pool, should be unique in a runtime JVM
+     */
+    public void setName(String name);
+
+    /**
+     * Property not used
+     * @return unknown value
+     */
+    public int getNumTestsPerEvictionRun();
+
+    /**
+     * Property not used
+     * @param numTestsPerEvictionRun parameter ignored.
+     */
+    public void setNumTestsPerEvictionRun(int numTestsPerEvictionRun);
+
+    /**
+     * Returns the password used when establishing connections to the database.
+     * @return the password in string format
+     */
+    public String getPassword();
+
+    /**
+     * Sets the password to establish the connection with.
+     * The password will be included as a database property with the name 'password'.
+     * @param password The password
+     * @see #getDbProperties()
+     */
+    public void setPassword(String password);
+
+    /**
+     * @see #getName()
+     * @return the pool name
+     */
+    public String getPoolName();
+
+    /**
+     * Returns the username used to establish the connection with
+     * @return the username used to establish the connection with
+     */
+    public String getUsername();
+
+    /**
+     * Sets the username used to establish the connection with
+     * It will also be a property called 'user' in the database properties.
+     * @param username The user name
+     * @see #getDbProperties()
+     */
+    public void setUsername(String username);
+
+
+    /**
+     * boolean flag to remove abandoned connections if they exceed the removeAbandonedTimout.
+     * If set to true a connection is considered abandoned and eligible for removal if it has
+     * been in use longer than the {@link #getRemoveAbandonedTimeout()} and the condition for
+     * {@link #getAbandonWhenPercentageFull()} is met.
+     * Setting this to true can recover db connections from applications that fail to close a connection.
+     * See also {@link #isLogAbandoned()} The default value is false.
+     * @return true if abandoned connections can be closed and expelled out of the pool
+     */
+    public boolean isRemoveAbandoned();
+
+    /**
+     * boolean flag to remove abandoned connections if they exceed the removeAbandonedTimout.
+     * If set to true a connection is considered abandoned and eligible for removal if it has
+     * been in use longer than the {@link #getRemoveAbandonedTimeout()} and the condition for
+     * {@link #getAbandonWhenPercentageFull()} is met.
+     * Setting this to true can recover db connections from applications that fail to close a connection.
+     * See also {@link #isLogAbandoned()} The default value is false.
+     * @param removeAbandoned set to true if abandoned connections can be closed and expelled out of the pool
+     */
+    public void setRemoveAbandoned(boolean removeAbandoned);
+
+    /**
+     * The time in seconds before a connection can be considered abandoned.
+     * The timer can be reset upon queries using an interceptor.
+     * @param removeAbandonedTimeout the time in seconds before a used connection can be considered abandoned
+     * @see org.apache.tomcat.jdbc.pool.interceptor.ResetAbandonedTimer
+     */
+    public void setRemoveAbandonedTimeout(int removeAbandonedTimeout);
+
+    /**
+     * The time in seconds before a connection can be considered abandoned.
+     * The timer can be reset upon queries using an interceptor.
+     * @see org.apache.tomcat.jdbc.pool.interceptor.ResetAbandonedTimer
+     * @return the time in seconds before a used connection can be considered abandoned
+     */
+    public int getRemoveAbandonedTimeout();
+
+    /**
+     * 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.
+     * NOTE - for a true value to have any effect, the validationQuery parameter must be set to a non-null string.
+     * Default value is false
+     * In order to have a more efficient validation, see {@link #setValidationInterval(long)}
+     * @return true if the connection is to be validated upon borrowing a connection from the pool
+     * @see #getValidationInterval()
+     */
+    public boolean isTestOnBorrow();
+
+    /**
+     * 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.
+     * NOTE - for a true value to have any effect, the validationQuery parameter must be set to a non-null string.
+     * Default value is false
+     * In order to have a more efficient validation, see {@link #setValidationInterval(long)}
+     * @param testOnBorrow set to true if validation should take place before a connection is handed out to the application
+     * @see #getValidationInterval()
+     */
+    public void setTestOnBorrow(boolean testOnBorrow);
+
+    /**
+     * The indication of whether objects will be validated after being returned to the pool.
+     * If the object fails to validate, it will be dropped from the pool.
+     * NOTE - for a true value to have any effect, the validationQuery parameter must be set to a non-null string.
+     * Default value is false
+     * In order to have a more efficient validation, see {@link #setValidationInterval(long)}
+     * @return true if validation should take place after a connection is returned to the pool
+     * @see #getValidationInterval()
+     */
+    public boolean isTestOnReturn();
+
+    /**
+     * The indication of whether objects will be validated after being returned to the pool.
+     * If the object fails to validate, it will be dropped from the pool.
+     * NOTE - for a true value to have any effect, the validationQuery parameter must be set to a non-null string.
+     * Default value is false
+     * In order to have a more efficient validation, see {@link #setValidationInterval(long)}
+     * @param testOnReturn true if validation should take place after a connection is returned to the pool
+     * @see #getValidationInterval()
+     */
+    public void setTestOnReturn(boolean testOnReturn);
+
+
+    /**
+     * Set to true if query validation should take place while the connection is idle.
+     * @return true if validation should take place during idle checks
+     * @see #setTimeBetweenEvictionRunsMillis(int)
+     */
+    public boolean isTestWhileIdle();
+
+    /**
+     * Set to true if query validation should take place while the connection is idle.
+     * @param testWhileIdle true if validation should take place during idle checks
+     * @see #setTimeBetweenEvictionRunsMillis(int)
+     */
+    public void setTestWhileIdle(boolean testWhileIdle);
+
+    /**
+     * The number of milliseconds to sleep between runs of the idle connection validation, abandoned cleaner
+     * and idle pool resizing. This value should not be set under 1 second.
+     * It dictates how often we check for idle, abandoned connections, and how often we validate idle connection and resize the idle pool.
+     * The default value is 5000 (5 seconds)
+     * @return the sleep time in between validations in milliseconds
+     */
+    public int getTimeBetweenEvictionRunsMillis();
+
+    /**
+     * The number of milliseconds to sleep between runs of the idle connection validation, abandoned cleaner
+     * and idle pool resizing. This value should not be set under 1 second.
+     * It dictates how often we check for idle, abandoned connections, and how often we validate idle connection and resize the idle pool.
+     * The default value is 5000 (5 seconds)
+     * @param timeBetweenEvictionRunsMillis the sleep time in between validations in milliseconds
+     */
+    public void setTimeBetweenEvictionRunsMillis(int timeBetweenEvictionRunsMillis);
+
+    /**
+     * The URL used to connect to the database
+     * @return the configured URL for this connection pool
+     * @see java.sql.Driver#connect(String, Properties)
+     */
+    public String getUrl();
+
+    /**
+     * Sets the URL used to connect to the database
+     * @param url the configured URL for this connection pool
+     * @see java.sql.Driver#connect(String, Properties)
+     */
+    public void setUrl(String url);
+
+    /**
+     * The SQL query that will be used to validate connections from this
+     * pool before returning them to the caller or pool.
+     * If specified, this query does not have to return any data,
+     * it just can't throw a SQLException.
+     * The default value is null.
+     * Example values are SELECT 1(mysql),
+     * select 1 from dual(oracle),
+     * SELECT 1(MS Sql Server)
+     * @return the query used for validation or null if no validation is performed
+     */
+    public String getValidationQuery();
+
+    /**
+     * The SQL query that will be used to validate connections from this
+     * pool before returning them to the caller or pool.
+     * If specified, this query does not have to return any data,
+     * it just can't throw a SQLException.
+     * The default value is null.
+     * Example values are SELECT 1(mysql),
+     * select 1 from dual(oracle),
+     * SELECT 1(MS Sql Server)
+     * @param validationQuery the query used for validation or null if no validation is performed
+     */
+    public void setValidationQuery(String validationQuery);
+
+    /**
+     * The timeout in seconds before a connection validation queries fail.
+     * A value less than or equal to zero will disable this feature.  Defaults to -1.
+     * @return the timeout value in seconds
+     */
+    public int getValidationQueryTimeout();
+
+    /**
+     * The timeout in seconds before a connection validation queries fail.
+     * A value less than or equal to zero will disable this feature.  Defaults to -1.
+     * @param validationQueryTimeout The timeout value
+     */
+    public void setValidationQueryTimeout(int validationQueryTimeout);
+
+    /**
+     * Return the name of the optional validator class - may be null.
+     *
+     * @return the name of the optional validator class - may be null
+     */
+    public String getValidatorClassName();
+
+    /**
+     * Set the name for an optional validator class which will be used in place of test queries. If set to
+     * null, standard validation will be used.
+     *
+     * @param className the name of the optional validator class
+     */
+    public void setValidatorClassName(String className);
+
+    /**
+     * @return the optional validator object - may be null
+     */
+    public Validator getValidator();
+
+    /**
+     * Sets the validator object
+     * If this is a non null object, it will be used as a validator instead of the validationQuery
+     * If this is null, remove the usage of the validator.
+     * @param validator The validator object
+     */
+    public void setValidator(Validator validator);
+
+    /**
+     * avoid excess validation, only run validation at most at this frequency - time in milliseconds.
+     * If a connection is due for validation, but has been validated previously
+     * within this interval, it will not be validated again.
+     * The default value is 3000 (3 seconds).
+     * @return the validation interval in milliseconds
+     */
+    public long getValidationInterval();
+
+    /**
+     * avoid excess validation, only run validation at most at this frequency - time in milliseconds.
+     * If a connection is due for validation, but has been validated previously
+     * within this interval, it will not be validated again.
+     * The default value is 3000 (3 seconds).
+     * @param validationInterval the validation interval in milliseconds
+     */
+    public void setValidationInterval(long validationInterval);
+
+    /**
+     * A custom query to be run when a connection is first created. The default value is null.
+     * This query only runs once per connection, and that is when a new connection is established to the database.
+     * If this value is non null, it will replace the validation query during connection creation.
+     * @return the init SQL used to run against the DB or null if not set
+     */
+    public String getInitSQL();
+
+    /**
+     * A custom query to be run when a connection is first created. The default value is null.
+     * This query only runs once per connection, and that is when a new connection is established to the database.
+     * If this value is non null, it will replace the validation query during connection creation.
+     * @param initSQL the init SQL used to run against the DB or null if no query should be executed
+     */
+    public void setInitSQL(String initSQL);
+
+    /**
+     * Returns true if we should run the validation query when connecting to the database for the first time on a connection.
+     * Normally this is always set to false, unless one wants to use the validationQuery as an init query.
+     * @return true if we should run the validation query upon connect
+     */
+    public boolean isTestOnConnect();
+
+    /**
+     * Set to true if we should run the validation query when connecting to the database for the first time on a connection.
+     * Normally this is always set to false, unless one wants to use the validationQuery as an init query.
+     * Setting an {@link #setInitSQL(String)} will override this setting, as the init SQL will be used instead of the validation query
+     * @param testOnConnect set to true if we should run the validation query upon connect
+     */
+    public void setTestOnConnect(boolean testOnConnect);
+
+    /**
+     * A semicolon separated list of classnames extending {@link org.apache.tomcat.jdbc.pool.JdbcInterceptor} class.
+     * These interceptors will be inserted as an interceptor into the chain of operations on a java.sql.Connection object.
+     * Example interceptors are {@link org.apache.tomcat.jdbc.pool.interceptor.StatementFinalizer StatementFinalizer} to close all
+     * used statements during the session.
+     * {@link org.apache.tomcat.jdbc.pool.interceptor.ResetAbandonedTimer ResetAbandonedTimer} resets the timer upon every operation
+     * on the connection or a statement.
+     * {@link org.apache.tomcat.jdbc.pool.interceptor.ConnectionState ConnectionState} caches the auto commit, read only and catalog settings to avoid round trips to the DB.
+     * The default value is null.
+     * @return the interceptors that are used for connections.
+     * Example format: 'ConnectionState(useEquals=true,fast=yes);ResetAbandonedTimer'
+     */
+    public String getJdbcInterceptors();
+
+    /**
+     * A semicolon separated list of classnames extending {@link org.apache.tomcat.jdbc.pool.JdbcInterceptor} class.
+     * These interceptors will be inserted as an interceptor into the chain of operations on a java.sql.Connection object.
+     * Example interceptors are {@link org.apache.tomcat.jdbc.pool.interceptor.StatementFinalizer StatementFinalizer} to close all
+     * used statements during the session.
+     * {@link org.apache.tomcat.jdbc.pool.interceptor.ResetAbandonedTimer ResetAbandonedTimer} resets the timer upon every operation
+     * on the connection or a statement.
+     * {@link org.apache.tomcat.jdbc.pool.interceptor.ConnectionState ConnectionState} caches the auto commit, read only and catalog settings to avoid round trips to the DB.
+     * The default value is null.
+     * @param jdbcInterceptors the interceptors that are used for connections.
+     * Example format: 'ConnectionState(useEquals=true,fast=yes);ResetAbandonedTimer'
+     */
+    public void setJdbcInterceptors(String jdbcInterceptors);
+
+    /**
+     * Returns the {@link #getJdbcInterceptors()} as an array of objects with properties and the classes.
+     * @return an array of interceptors that have been configured
+     */
+    public InterceptorDefinition[] getJdbcInterceptorsAsArray();
+
+
+    /**
+     * If set to true, the connection pool creates a {@link org.apache.tomcat.jdbc.pool.jmx.ConnectionPoolMBean} object
+     * that can be registered with JMX to receive notifications and state about the pool.
+     * The ConnectionPool object doesn't register itself, as there is no way to keep a static non changing ObjectName across JVM restarts.
+     * @return true if the mbean object will be created upon startup.
+     */
+    public boolean isJmxEnabled();
+
+    /**
+     * If set to true, the connection pool creates a {@link org.apache.tomcat.jdbc.pool.jmx.ConnectionPoolMBean} object
+     * that can be registered with JMX to receive notifications and state about the pool.
+     * The ConnectionPool object doesn't register itself, as there is no way to keep a static non changing ObjectName across JVM restarts.
+     * @param jmxEnabled set to to if the mbean object should be created upon startup.
+     */
+    public void setJmxEnabled(boolean jmxEnabled);
+
+    /**
+     * Returns true if the pool sweeper is enabled for the connection pool.
+     * The pool sweeper is enabled if any settings that require async intervention in the pool are turned on
+     * <code>
+        boolean result = getTimeBetweenEvictionRunsMillis()&gt;0;
+        result = result &amp;&amp; (isRemoveAbandoned() &amp;&amp; getRemoveAbandonedTimeout()&gt;0);
+        result = result || (isTestWhileIdle() &amp;&amp; getValidationQuery()!=null);
+        return result;
+       </code>
+     *
+     * @return true if a background thread is or will be enabled for this pool
+     */
+    public boolean isPoolSweeperEnabled();
+
+    /**
+     * Set to true if you wish the <code>ProxyConnection</code> class to use <code>String.equals</code> instead of
+     * <code>==</code> when comparing method names.
+     * This property does not apply to added interceptors as those are configured individually.
+     * The default value is <code>false</code>.
+     * @return true if pool uses {@link String#equals(Object)} instead of == when comparing method names on {@link java.sql.Connection} methods
+     */
+    public boolean isUseEquals();
+
+    /**
+     * Set to true if you wish the <code>ProxyConnection</code> class to use <code>String.equals</code> instead of
+     * <code>==</code> when comparing method names.
+     * This property does not apply to added interceptors as those are configured individually.
+     * The default value is <code>false</code>.
+     * @param useEquals set to true if the pool should use {@link String#equals(Object)} instead of ==
+     * when comparing method names on {@link java.sql.Connection} methods
+     */
+    public void setUseEquals(boolean useEquals);
+
+    /**
+     * Time in milliseconds to keep this connection alive even when used.
+     * When a connection is returned to the pool, the pool will check to see if the
+     * ((now - time-when-connected) &gt; maxAge) has been reached, and if so,
+     * it closes the connection rather than returning it to the pool.
+     * The default value is 0, which implies that connections will be left open and no
+     * age check will be done upon returning the connection to the pool.
+     * This is a useful setting for database sessions that leak memory as it ensures that the session
+     * will have a finite life span.
+     * @return the time in milliseconds a connection will be open for when used
+     */
+    public long getMaxAge();
+
+    /**
+     * Time in milliseconds to keep this connection alive even when used.
+     * When a connection is returned to the pool, the pool will check to see if the
+     * ((now - time-when-connected) &gt; maxAge) has been reached, and if so,
+     * it closes the connection rather than returning it to the pool.
+     * The default value is 0, which implies that connections will be left open and no
+     * age check will be done upon returning the connection to the pool.
+     * This is a useful setting for database sessions that leak memory as it ensures that the session
+     * will have a finite life span.
+     * @param maxAge the time in milliseconds a connection will be open for when used
+     */
+    public void setMaxAge(long maxAge);
+
+    /**
+     * Return true if a lock should be used when operations are performed on the connection object.
+     * Should be set to false unless you plan to have a background thread of your own doing idle and abandon checking
+     * such as JMX clients. If the pool sweeper is enabled, then the lock will automatically be used regardless of this setting.
+     * @return true if a lock is used.
+     */
+    public boolean getUseLock();
+
+    /**
+     * Set to true if a lock should be used when operations are performed on the connection object.
+     * Should be set to false unless you plan to have a background thread of your own doing idle and abandon checking
+     * such as JMX clients. If the pool sweeper is enabled, then the lock will automatically be used regardless of this setting.
+     * @param useLock set to true if a lock should be used on connection operations
+     */
+    public void setUseLock(boolean useLock);
+
+    /**
+     * Similar to {@link #setRemoveAbandonedTimeout(int)} but instead of treating the connection
+     * as abandoned, and potentially closing the connection, this simply logs the warning if
+     * {@link #isLogAbandoned()} returns true. If this value is equal or less than 0, no suspect
+     * checking will be performed. Suspect checking only takes place if the timeout value is larger than 0 and
+     * the connection was not abandoned or if abandon check is disabled. If a connection is suspect a WARN message gets
+     * logged and a JMX notification gets sent once.
+     * @param seconds - the amount of time in seconds that has to pass before a connection is marked suspect.
+     */
+    public void setSuspectTimeout(int seconds);
+
+    /**
+     * Returns the time in seconds to pass before a connection is marked an abandoned suspect.
+     * Any value lesser than or equal to 0 means the check is disabled.
+     * @return Returns the time in seconds to pass before a connection is marked an abandoned suspect.
+     */
+    public int getSuspectTimeout();
+
+    /**
+     * Injects a datasource that will be used to retrieve/create connections.
+     * If a data source is set, the {@link PoolConfiguration#getUrl()} and {@link PoolConfiguration#getDriverClassName()} methods are ignored
+     * and not used by the pool. If the {@link PoolConfiguration#getUsername()} and {@link PoolConfiguration#getPassword()}
+     * values are set, the method {@link javax.sql.DataSource#getConnection(String, String)} method will be called instead of the
+     * {@link javax.sql.DataSource#getConnection()} method.
+     * If the data source implements {@link javax.sql.XADataSource} the methods
+     * {@link javax.sql.XADataSource#getXAConnection()} and {@link javax.sql.XADataSource#getXAConnection(String,String)}
+     * will be invoked.
+     * @param ds the {@link javax.sql.DataSource} to be used for creating connections to be pooled.
+     */
+    public void setDataSource(Object ds);
+
+    /**
+     * Returns a datasource, if one exists that is being used to create connections.
+     * This method will return null if the pool is using a {@link java.sql.Driver}
+     * @return the {@link javax.sql.DataSource} to be used for creating connections to be pooled or null if a Driver is used.
+     */
+    public Object getDataSource();
+
+    /**
+     * Configure the connection pool to use a DataSource according to {@link PoolConfiguration#setDataSource(Object)}
+     * But instead of injecting the object, specify the JNDI location.
+     * After a successful JNDI look, the {@link PoolConfiguration#getDataSource()} will not return null.
+     * @param jndiDS -the JNDI string @TODO specify the rules here.
+     */
+    public void setDataSourceJNDI(String jndiDS);
+
+    /**
+     * Returns the JNDI string configured for data source usage.
+     * @return the JNDI string or null if not set
+     */
+    public String getDataSourceJNDI();
+
+    /**
+     * Returns true if the call {@link DataSource#getConnection(String, String) getConnection(username,password)} is
+     * allowed. This is used for when the pool is used by an application accessing multiple schemas.
+     * There is a performance impact turning this option on.
+     * @return true if {@link DataSource#getConnection(String, String) getConnection(username,password)} is honored, false if it is ignored.
+     */
+    public boolean isAlternateUsernameAllowed();
+
+    /**
+     * Set to true if the call {@link DataSource#getConnection(String, String) getConnection(username,password)} is
+     * allowed and honored.. This is used for when the pool is used by an application accessing multiple schemas.
+     * There is a performance impact turning this option on, even when not used due to username checks.
+     * @param alternateUsernameAllowed - set true if {@link DataSource#getConnection(String, String) getConnection(username,password)} is honored,
+     * false if it is to be ignored.
+     */
+    public void setAlternateUsernameAllowed(boolean alternateUsernameAllowed);
+    /**
+     * Set to true if you want the connection pool to commit any pending transaction when a connection is returned.
+     * The default value is false, as this could result in committing data.
+     * This parameter is only looked at if the {@link #getDefaultAutoCommit()} returns false
+     * @param commitOnReturn set to true if the pool should call {@link java.sql.Connection#commit()} when a connection is returned to the pool.
+     * Default is false
+     */
+    public void setCommitOnReturn(boolean commitOnReturn);
+
+    /**
+     * @see PoolConfiguration#setCommitOnReturn(boolean)
+     * @return <code>true</code> if the pool should commit when a connection is returned to it
+     */
+    public boolean getCommitOnReturn();
+
+    /**
+     * Set to true if you want the connection pool to rollback any pending transaction when a connection is returned.
+     * The default value is false, as this could result in committing data.
+     * This parameter is only looked at if the {@link #getDefaultAutoCommit()} returns false
+     * @param rollbackOnReturn set to true if the pool should call {@link java.sql.Connection#rollback()} when a connection is returned to the pool.
+     * Default is false
+     */
+    public void setRollbackOnReturn(boolean rollbackOnReturn);
+
+    /**
+     * @see PoolConfiguration#setRollbackOnReturn(boolean)
+     * @return <code>true</code> if the pool should rollback when a connection is returned to it
+     */
+    public boolean getRollbackOnReturn();
+
+    /**
+     * If set to <code>true</code>, the connection will be wrapped with facade that will disallow the connection to be used after
+     * {@link java.sql.Connection#close()} is called. If set to <code>true</code>, after {@link java.sql.Connection#close()} all calls except
+     * {@link java.sql.Connection#close()} and {@link java.sql.Connection#isClosed()} will throw an exception.
+     * @param useDisposableConnectionFacade <code>true</code> to use a facade
+     */
+    public void setUseDisposableConnectionFacade(boolean useDisposableConnectionFacade);
+    /**
+     * Returns <code>true</code> if this connection pool is configured to use a connection facade to prevent re-use of connection after
+     * {@link java.sql.Connection#close()} has been invoked
+     * @return <code>true</code> if {@link java.sql.Connection#close()} has been invoked.
+     */
+    public boolean getUseDisposableConnectionFacade();
+
+    /**
+     * Set to true if you wish that errors from validation should be logged as error messages.
+     * @param logValidationErrors set to true to log validation errors
+     */
+    public void setLogValidationErrors(boolean logValidationErrors);
+
+    /**
+     * Returns true if errors that happen during validation will be logged
+     * @return true if errors that happen during validation will be logged
+     */
+    public boolean getLogValidationErrors();
+
+    /**
+     * Returns true if the pool is configured to propagate interrupt state of a thread.
+     * A thread waiting for a connection, can have its wait interrupted, and by default
+     * will clear the interrupt flag and throw a {@link PoolExhaustedException}
+     * @return true if the pool is configured to propagate and not clear the thread interrupt state
+     */
+    public boolean getPropagateInterruptState();
+
+    /**
+     * Configure the pool to propagate interrupt state for interrupted threads waiting for a connection
+     * A thread waiting for a connection, can have its wait interrupted, and by default
+     * will clear the interrupt flag and throw a {@link PoolExhaustedException}
+     * If set to true, this behavior will change, while the {@link PoolExhaustedException} is still thrown, the threads interrupted state is still set.
+     * @param propagateInterruptState - set to true to not clear, but propagate, a threads interrupted state.
+     */
+    public void setPropagateInterruptState(boolean propagateInterruptState);
+
+    /**
+     * Set to true if you want to ignore error of connection creation while initializing the pool.
+     * Set to false if you want to fail the initialization of the pool by throwing exception.
+     * @param ignoreExceptionOnPreLoad set to true if you want to ignore error of connection creation while initializing the pool.
+     */
+    public void setIgnoreExceptionOnPreLoad(boolean ignoreExceptionOnPreLoad);
+
+    /**
+     * @return <code>true</code> to ignore exceptions
+     * @see PoolConfiguration#setIgnoreExceptionOnPreLoad(boolean)
+     */
+    public boolean isIgnoreExceptionOnPreLoad();
+
+}
diff --git a/dblib/common/src/main/java/org/apache/tomcat/jdbc/pool/PoolExhaustedException.java b/dblib/common/src/main/java/org/apache/tomcat/jdbc/pool/PoolExhaustedException.java
new file mode 100644
index 0000000..9352581
--- /dev/null
+++ b/dblib/common/src/main/java/org/apache/tomcat/jdbc/pool/PoolExhaustedException.java
@@ -0,0 +1,76 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * openecomp
+ * ================================================================================
+ * Copyright (C) 2016 - 2017 AT&T
+ * ================================================================================
+ * Licensed 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.
+ * ============LICENSE_END=========================================================
+ */
+
+/*
+ * 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.tomcat.jdbc.pool;
+
+import java.sql.SQLException;
+
+public class PoolExhaustedException extends SQLException {
+
+    private static final long serialVersionUID = 3501536931777262475L;
+
+    public PoolExhaustedException() {
+    }
+
+    public PoolExhaustedException(String reason) {
+        super(reason);
+    }
+
+    public PoolExhaustedException(Throwable cause) {
+        super(cause);
+    }
+
+    public PoolExhaustedException(String reason, String SQLState) {
+        super(reason, SQLState);
+    }
+
+    public PoolExhaustedException(String reason, Throwable cause) {
+        super(reason, cause);
+    }
+
+    public PoolExhaustedException(String reason, String SQLState, int vendorCode) {
+        super(reason, SQLState, vendorCode);
+    }
+
+    public PoolExhaustedException(String reason, String sqlState, Throwable cause) {
+        super(reason, sqlState, cause);
+    }
+
+    public PoolExhaustedException(String reason, String sqlState, int vendorCode, Throwable cause) {
+        super(reason, sqlState, vendorCode, cause);
+    }
+
+}
diff --git a/dblib/common/src/main/java/org/apache/tomcat/jdbc/pool/PoolProperties.java b/dblib/common/src/main/java/org/apache/tomcat/jdbc/pool/PoolProperties.java
new file mode 100644
index 0000000..9d64c26
--- /dev/null
+++ b/dblib/common/src/main/java/org/apache/tomcat/jdbc/pool/PoolProperties.java
@@ -0,0 +1,1332 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * openecomp
+ * ================================================================================
+ * Copyright (C) 2016 - 2017 AT&T
+ * ================================================================================
+ * Licensed 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.
+ * ============LICENSE_END=========================================================
+ */
+
+/*
+ * 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.tomcat.jdbc.pool;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.Serializable;
+import java.lang.reflect.Method;
+import java.util.HashMap;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Properties;
+import java.util.concurrent.atomic.AtomicInteger;
+
+
+import org.apache.juli.logging.Log;
+import org.apache.juli.logging.LogFactory;
+
+public class PoolProperties implements PoolConfiguration, Cloneable, Serializable {
+
+    private static final long serialVersionUID = -8519283440854213745L;
+    private static final Log log = LogFactory.getLog(PoolProperties.class);
+
+    public static final int DEFAULT_MAX_ACTIVE = 100;
+
+    protected static final AtomicInteger poolCounter = new AtomicInteger(0);
+    private volatile Properties dbProperties = new Properties();
+    private volatile String url = null;
+    private volatile String driverClassName = null;
+    private volatile Boolean defaultAutoCommit = null;
+    private volatile Boolean defaultReadOnly = null;
+    private volatile int defaultTransactionIsolation = DataSourceFactory.UNKNOWN_TRANSACTIONISOLATION;
+    private volatile String defaultCatalog = null;
+    private volatile String connectionProperties;
+    private volatile int initialSize = 10;
+    private volatile int maxActive = DEFAULT_MAX_ACTIVE;
+    private volatile int maxIdle = maxActive;
+    private volatile int minIdle = initialSize;
+    private volatile int maxWait = 30000;
+    private volatile String validationQuery;
+    private volatile int validationQueryTimeout = -1;
+    private volatile String validatorClassName;
+    private volatile Validator validator;
+    private volatile boolean testOnBorrow = false;
+    private volatile boolean testOnReturn = false;
+    private volatile boolean testWhileIdle = false;
+    private volatile int timeBetweenEvictionRunsMillis = 5000;
+    private volatile int numTestsPerEvictionRun;
+    private volatile int minEvictableIdleTimeMillis = 60000;
+    private volatile boolean accessToUnderlyingConnectionAllowed = true;
+    private volatile boolean removeAbandoned = false;
+    private volatile int removeAbandonedTimeout = 60;
+    private volatile boolean logAbandoned = false;
+    private volatile String name = "Tomcat Connection Pool["+(poolCounter.addAndGet(1))+"-"+System.identityHashCode(PoolProperties.class)+"]";
+    private volatile String password;
+    private volatile String username;
+    private volatile long validationInterval = 3000;
+    private volatile boolean jmxEnabled = true;
+    private volatile String initSQL;
+    private volatile boolean testOnConnect =false;
+    private volatile String jdbcInterceptors=null;
+    private volatile boolean fairQueue = true;
+    private volatile boolean useEquals = true;
+    private volatile int abandonWhenPercentageFull = 0;
+    private volatile long maxAge = 0;
+    private volatile boolean useLock = false;
+    private volatile InterceptorDefinition[] interceptors = null;
+    private volatile int suspectTimeout = 0;
+    private volatile Object dataSource = null;
+    private volatile String dataSourceJNDI = null;
+    private volatile boolean alternateUsernameAllowed = false;
+    private volatile boolean commitOnReturn = false;
+    private volatile boolean rollbackOnReturn = false;
+    private volatile boolean useDisposableConnectionFacade = true;
+    private volatile boolean logValidationErrors = false;
+    private volatile boolean propagateInterruptState = false;
+    private volatile boolean ignoreExceptionOnPreLoad = false;
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void setAbandonWhenPercentageFull(int percentage) {
+        if (percentage<0) abandonWhenPercentageFull = 0;
+        else if (percentage>100) abandonWhenPercentageFull = 100;
+        else abandonWhenPercentageFull = percentage;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public int getAbandonWhenPercentageFull() {
+        return abandonWhenPercentageFull;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public boolean isFairQueue() {
+        return fairQueue;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void setFairQueue(boolean fairQueue) {
+        this.fairQueue = fairQueue;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public boolean isAccessToUnderlyingConnectionAllowed() {
+        return accessToUnderlyingConnectionAllowed;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+
+    @Override
+    public String getConnectionProperties() {
+        return connectionProperties;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+
+    @Override
+    public Properties getDbProperties() {
+        return dbProperties;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+
+    @Override
+    public Boolean isDefaultAutoCommit() {
+        return defaultAutoCommit;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+
+    @Override
+    public String getDefaultCatalog() {
+        return defaultCatalog;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+
+    @Override
+    public Boolean isDefaultReadOnly() {
+        return defaultReadOnly;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+
+    @Override
+    public int getDefaultTransactionIsolation() {
+        return defaultTransactionIsolation;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+
+    @Override
+    public String getDriverClassName() {
+        return driverClassName;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+
+    @Override
+    public int getInitialSize() {
+        return initialSize;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+
+    @Override
+    public boolean isLogAbandoned() {
+        return logAbandoned;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+
+    @Override
+    public int getMaxActive() {
+        return maxActive;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+
+    @Override
+    public int getMaxIdle() {
+        return maxIdle;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+
+    @Override
+    public int getMaxWait() {
+        return maxWait;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+
+    @Override
+    public int getMinEvictableIdleTimeMillis() {
+        return minEvictableIdleTimeMillis;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+
+    @Override
+    public int getMinIdle() {
+        return minIdle;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+
+    @Override
+    public String getName() {
+        return name;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+
+    @Override
+    public int getNumTestsPerEvictionRun() {
+        return numTestsPerEvictionRun;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+
+    @Override
+    public String getPassword() {
+        return password;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+
+    @Override
+    public String getPoolName() {
+        return getName();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+
+    @Override
+    public boolean isRemoveAbandoned() {
+        return removeAbandoned;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+
+    @Override
+    public int getRemoveAbandonedTimeout() {
+        return removeAbandonedTimeout;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+
+    @Override
+    public boolean isTestOnBorrow() {
+        return testOnBorrow;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+
+    @Override
+    public boolean isTestOnReturn() {
+        return testOnReturn;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+
+    @Override
+    public boolean isTestWhileIdle() {
+        return testWhileIdle;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+
+    @Override
+    public int getTimeBetweenEvictionRunsMillis() {
+        return timeBetweenEvictionRunsMillis;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+
+    @Override
+    public String getUrl() {
+        return url;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+
+    @Override
+    public String getUsername() {
+        return username;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+
+    @Override
+    public String getValidationQuery() {
+        return validationQuery;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public int getValidationQueryTimeout() {
+        return validationQueryTimeout;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void setValidationQueryTimeout(int validationQueryTimeout) {
+        this.validationQueryTimeout = validationQueryTimeout;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+
+    @Override
+    public String getValidatorClassName() {
+        return validatorClassName;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+
+    @Override
+    public Validator getValidator() {
+        return validator;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void setValidator(Validator validator) {
+        this.validator = validator;
+        if (validator!=null) {
+            this.validatorClassName = validator.getClass().getName();
+        } else {
+            this.validatorClassName = null;
+        }
+    }
+
+
+    /**
+     * {@inheritDoc}
+     */
+
+    @Override
+    public long getValidationInterval() {
+        return validationInterval;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+
+    @Override
+    public String getInitSQL() {
+        return initSQL;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+
+    @Override
+    public boolean isTestOnConnect() {
+        return testOnConnect;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+
+    @Override
+    public String getJdbcInterceptors() {
+        return jdbcInterceptors;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+
+    @Override
+    public InterceptorDefinition[] getJdbcInterceptorsAsArray() {
+        if (interceptors == null) {
+            if (jdbcInterceptors==null) {
+                interceptors = new InterceptorDefinition[0];
+            } else {
+                String[] interceptorValues = jdbcInterceptors.split(";");
+                InterceptorDefinition[] definitions = new InterceptorDefinition[interceptorValues.length+1];
+                //always add the trap interceptor to the mix
+                definitions[0] = new InterceptorDefinition(TrapException.class);
+                for (int i=0; i<interceptorValues.length; i++) {
+                    int propIndex = interceptorValues[i].indexOf('(');
+                    int endIndex = interceptorValues[i].indexOf(')');
+                    if (propIndex<0 || endIndex<0 || endIndex <= propIndex) {
+                        definitions[i+1] = new InterceptorDefinition(interceptorValues[i].trim());
+                    } else {
+                        String name = interceptorValues[i].substring(0,propIndex).trim();
+                        definitions[i+1] = new InterceptorDefinition(name);
+                        String propsAsString = interceptorValues[i].substring(propIndex+1, endIndex);
+                        String[] props = propsAsString.split(",");
+                        for (int j=0; j<props.length; j++) {
+                            int pidx = props[j].indexOf('=');
+                            String propName = props[j].substring(0,pidx).trim();
+                            String propValue = props[j].substring(pidx+1).trim();
+                            definitions[i+1].addProperty(new InterceptorProperty(propName,propValue));
+                        }
+                    }
+                }
+                interceptors = definitions;
+            }
+        }
+        return interceptors;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+
+    @Override
+    public void setAccessToUnderlyingConnectionAllowed(boolean accessToUnderlyingConnectionAllowed) {
+        // NOOP
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+
+    @Override
+    public void setConnectionProperties(String connectionProperties) {
+        this.connectionProperties = connectionProperties;
+        getProperties(connectionProperties, getDbProperties());
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+
+    @Override
+    public void setDbProperties(Properties dbProperties) {
+        this.dbProperties = dbProperties;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+
+    @Override
+    public void setDefaultAutoCommit(Boolean defaultAutoCommit) {
+        this.defaultAutoCommit = defaultAutoCommit;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+
+    @Override
+    public void setDefaultCatalog(String defaultCatalog) {
+        this.defaultCatalog = defaultCatalog;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+
+    @Override
+    public void setDefaultReadOnly(Boolean defaultReadOnly) {
+        this.defaultReadOnly = defaultReadOnly;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+
+    @Override
+    public void setDefaultTransactionIsolation(int defaultTransactionIsolation) {
+        this.defaultTransactionIsolation = defaultTransactionIsolation;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+
+    @Override
+    public void setDriverClassName(String driverClassName) {
+        this.driverClassName = driverClassName;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+
+    @Override
+    public void setInitialSize(int initialSize) {
+        this.initialSize = initialSize;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+
+    @Override
+    public void setLogAbandoned(boolean logAbandoned) {
+        this.logAbandoned = logAbandoned;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+
+    @Override
+    public void setMaxActive(int maxActive) {
+        this.maxActive = maxActive;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+
+    @Override
+    public void setMaxIdle(int maxIdle) {
+        this.maxIdle = maxIdle;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+
+    @Override
+    public void setMaxWait(int maxWait) {
+        this.maxWait = maxWait;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+
+    @Override
+    public void setMinEvictableIdleTimeMillis(int minEvictableIdleTimeMillis) {
+        this.minEvictableIdleTimeMillis = minEvictableIdleTimeMillis;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+
+    @Override
+    public void setMinIdle(int minIdle) {
+        this.minIdle = minIdle;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+
+    @Override
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+
+    @Override
+    public void setNumTestsPerEvictionRun(int numTestsPerEvictionRun) {
+        this.numTestsPerEvictionRun = numTestsPerEvictionRun;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+
+    @Override
+    public void setPassword(String password) {
+        this.password = password;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+
+    @Override
+    public void setRemoveAbandoned(boolean removeAbandoned) {
+        this.removeAbandoned = removeAbandoned;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+
+    @Override
+    public void setRemoveAbandonedTimeout(int removeAbandonedTimeout) {
+        this.removeAbandonedTimeout = removeAbandonedTimeout;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+
+    @Override
+    public void setTestOnBorrow(boolean testOnBorrow) {
+        this.testOnBorrow = testOnBorrow;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+
+    @Override
+    public void setTestWhileIdle(boolean testWhileIdle) {
+        this.testWhileIdle = testWhileIdle;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+
+    @Override
+    public void setTestOnReturn(boolean testOnReturn) {
+        this.testOnReturn = testOnReturn;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+
+    @Override
+    public void setTimeBetweenEvictionRunsMillis(int
+                                                 timeBetweenEvictionRunsMillis) {
+        this.timeBetweenEvictionRunsMillis = timeBetweenEvictionRunsMillis;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+
+    @Override
+    public void setUrl(String url) {
+        this.url = url;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+
+    @Override
+    public void setUsername(String username) {
+        this.username = username;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+
+    @Override
+    public void setValidationInterval(long validationInterval) {
+        this.validationInterval = validationInterval;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+
+    @Override
+    public void setValidationQuery(String validationQuery) {
+        this.validationQuery = validationQuery;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+
+    @Override
+    public void setValidatorClassName(String className) {
+        this.validatorClassName = className;
+
+        validator = null;
+
+        if (className == null) {
+            return;
+        }
+
+        try {
+            @SuppressWarnings("unchecked")
+            Class<Validator> validatorClass = (Class<Validator>)ClassLoaderUtil.loadClass(
+                className,
+                PoolProperties.class.getClassLoader(),
+                Thread.currentThread().getContextClassLoader()
+            );
+            validator = validatorClass.newInstance();
+        } catch (ClassNotFoundException e) {
+            log.warn("The class "+className+" cannot be found.", e);
+        } catch (ClassCastException e) {
+            log.warn("The class "+className+" does not implement the Validator interface.", e);
+        } catch (InstantiationException e) {
+            log.warn("An object of class "+className+" cannot be instantiated. Make sure that "+
+                     "it includes an implicit or explicit no-arg constructor.", e);
+        } catch (IllegalAccessException e) {
+            log.warn("The class "+className+" or its no-arg constructor are inaccessible.", e);
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+
+    @Override
+    public void setInitSQL(String initSQL) {
+        this.initSQL = initSQL!=null && initSQL.trim().length()>0 ? initSQL : null;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+
+    @Override
+    public void setTestOnConnect(boolean testOnConnect) {
+        this.testOnConnect = testOnConnect;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+
+    @Override
+    public void setJdbcInterceptors(String jdbcInterceptors) {
+        this.jdbcInterceptors = jdbcInterceptors;
+        this.interceptors = null;
+    }
+
+
+    @Override
+    public String toString() {
+        StringBuilder buf = new StringBuilder("ConnectionPool[");
+        try {
+            String[] fields = DataSourceFactory.ALL_PROPERTIES;
+            for (String field: fields) {
+                final String[] prefix = new String[] {"get","is"};
+                for (int j=0; j<prefix.length; j++) {
+
+                    String name = prefix[j]
+                            + field.substring(0, 1).toUpperCase(Locale.ENGLISH)
+                            + field.substring(1);
+                    Method m = null;
+                    try {
+                        m = getClass().getMethod(name);
+                    }catch (NoSuchMethodException nm) {
+                        continue;
+                    }
+                    buf.append(field);
+                    buf.append("=");
+                    if (DataSourceFactory.PROP_PASSWORD.equals(field)) {
+                        buf.append("********");
+                    } else {
+                        buf.append(m.invoke(this, new Object[0]));
+                    }
+                    buf.append("; ");
+                    break;
+                }
+            }
+        }catch (Exception x) {
+            //shouldn't happen
+            log.debug("toString() call failed", x);
+        }
+        return buf.toString();
+    }
+
+    public static int getPoolCounter() {
+        return poolCounter.get();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+
+    @Override
+    public boolean isJmxEnabled() {
+        return jmxEnabled;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+
+    @Override
+    public void setJmxEnabled(boolean jmxEnabled) {
+        this.jmxEnabled = jmxEnabled;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+
+    @Override
+    public Boolean getDefaultAutoCommit() {
+        return defaultAutoCommit;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+
+    @Override
+    public Boolean getDefaultReadOnly() {
+        return defaultReadOnly;
+    }
+
+
+    /**
+     * {@inheritDoc}
+     */
+
+    @Override
+    public int getSuspectTimeout() {
+        return this.suspectTimeout;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+
+    @Override
+    public void setSuspectTimeout(int seconds) {
+        this.suspectTimeout = seconds;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+
+    @Override
+    public boolean isPoolSweeperEnabled() {
+        boolean timer = getTimeBetweenEvictionRunsMillis()>0;
+        boolean result = timer && (isRemoveAbandoned() && getRemoveAbandonedTimeout()>0);
+        result = result || (timer && getSuspectTimeout()>0);
+        result = result || (timer && isTestWhileIdle() && getValidationQuery()!=null);
+        result = result || (timer && getMinEvictableIdleTimeMillis()>0);
+        return result;
+    }
+
+
+    public static class InterceptorDefinition implements Serializable {
+        private static final long serialVersionUID = 1L;
+        protected String className;
+        protected Map<String,InterceptorProperty> properties = new HashMap<>();
+        protected volatile Class<?> clazz = null;
+        public InterceptorDefinition(String className) {
+            this.className = className;
+        }
+
+        public InterceptorDefinition(Class<?> cl) {
+            this(cl.getName());
+            clazz = cl;
+        }
+
+        public String getClassName() {
+            return className;
+        }
+        public void addProperty(String name, String value) {
+            InterceptorProperty p = new InterceptorProperty(name,value);
+            addProperty(p);
+        }
+
+        public void addProperty(InterceptorProperty p) {
+            properties.put(p.getName(), p);
+        }
+
+        public Map<String,InterceptorProperty> getProperties() {
+            return properties;
+        }
+
+        @SuppressWarnings("unchecked")
+        public Class<? extends JdbcInterceptor> getInterceptorClass() throws ClassNotFoundException {
+            if (clazz==null) {
+                if (getClassName().indexOf('.')<0) {
+                    if (log.isDebugEnabled()) {
+                        log.debug("Loading interceptor class:"+PoolConfiguration.PKG_PREFIX+getClassName());
+                    }
+                    clazz = ClassLoaderUtil.loadClass(
+                        PoolConfiguration.PKG_PREFIX+getClassName(),
+                        PoolProperties.class.getClassLoader(),
+                        Thread.currentThread().getContextClassLoader()
+                    );
+                } else {
+                    if (log.isDebugEnabled()) {
+                        log.debug("Loading interceptor class:"+getClassName());
+                    }
+                    clazz = ClassLoaderUtil.loadClass(
+                        getClassName(),
+                        PoolProperties.class.getClassLoader(),
+                        Thread.currentThread().getContextClassLoader()
+                    );
+                }
+            }
+            return (Class<? extends JdbcInterceptor>)clazz;
+        }
+    }
+
+    public static class InterceptorProperty implements Serializable {
+        private static final long serialVersionUID = 1L;
+        String name;
+        String value;
+        public InterceptorProperty(String name, String value) {
+            assert(name!=null);
+            this.name = name;
+            this.value = value;
+        }
+        public String getName() {
+            return name;
+        }
+        public String getValue() {
+            return value;
+        }
+
+        public boolean getValueAsBoolean(boolean def) {
+            if (value==null) return def;
+            if ("true".equals(value)) return true;
+            if ("false".equals(value)) return false;
+            return def;
+        }
+
+        public int getValueAsInt(int def) {
+            if (value==null) return def;
+            try {
+                int v = Integer.parseInt(value);
+                return v;
+            }catch (NumberFormatException nfe) {
+                return def;
+            }
+        }
+
+        public long getValueAsLong(long def) {
+            if (value==null) return def;
+            try {
+                return Long.parseLong(value);
+            }catch (NumberFormatException nfe) {
+                return def;
+            }
+        }
+
+        public byte getValueAsByte(byte def) {
+            if (value==null) return def;
+            try {
+                return Byte.parseByte(value);
+            }catch (NumberFormatException nfe) {
+                return def;
+            }
+        }
+
+        public short getValueAsShort(short def) {
+            if (value==null) return def;
+            try {
+                return Short.parseShort(value);
+            }catch (NumberFormatException nfe) {
+                return def;
+            }
+        }
+
+        public float getValueAsFloat(float def) {
+            if (value==null) return def;
+            try {
+                return Float.parseFloat(value);
+            }catch (NumberFormatException nfe) {
+                return def;
+            }
+        }
+
+        public double getValueAsDouble(double def) {
+            if (value==null) return def;
+            try {
+                return Double.parseDouble(value);
+            }catch (NumberFormatException nfe) {
+                return def;
+            }
+        }
+
+        public char getValueAschar(char def) {
+            if (value==null) return def;
+            try {
+                return value.charAt(0);
+            }catch (StringIndexOutOfBoundsException nfe) {
+                return def;
+            }
+        }
+
+        @Override
+        public int hashCode() {
+            return name.hashCode();
+        }
+
+        @Override
+        public boolean equals(Object o) {
+            if (o==this) return true;
+            if (o instanceof InterceptorProperty) {
+                InterceptorProperty other = (InterceptorProperty)o;
+                return other.name.equals(this.name);
+            }
+            return false;
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+
+    @Override
+    public boolean isUseEquals() {
+        return useEquals;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+
+    @Override
+    public void setUseEquals(boolean useEquals) {
+        this.useEquals = useEquals;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+
+    @Override
+    public long getMaxAge() {
+        return maxAge;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+
+    @Override
+    public void setMaxAge(long maxAge) {
+        this.maxAge = maxAge;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+
+    @Override
+    public boolean getUseLock() {
+        return useLock;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+
+    @Override
+    public void setUseLock(boolean useLock) {
+        this.useLock = useLock;
+    }
+
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void setDataSource(Object ds) {
+        if (ds instanceof DataSourceProxy) {
+            throw new IllegalArgumentException("Layered pools are not allowed.");
+        }
+        this.dataSource = ds;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public Object getDataSource() {
+        return dataSource;
+    }
+
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void setDataSourceJNDI(String jndiDS) {
+        this.dataSourceJNDI = jndiDS;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public String getDataSourceJNDI() {
+        return this.dataSourceJNDI;
+    }
+
+
+    public static Properties getProperties(String propText, Properties props) {
+        if (props==null) props = new Properties();
+        if (propText != null) {
+            try {
+                props.load(new ByteArrayInputStream(propText.replace(';', '\n').getBytes()));
+            }catch (IOException x) {
+                throw new RuntimeException(x);
+            }
+        }
+        return props;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public boolean isAlternateUsernameAllowed() {
+        return alternateUsernameAllowed;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void setAlternateUsernameAllowed(boolean alternateUsernameAllowed) {
+        this.alternateUsernameAllowed = alternateUsernameAllowed;
+    }
+
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void setCommitOnReturn(boolean commitOnReturn) {
+        this.commitOnReturn = commitOnReturn;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public boolean getCommitOnReturn() {
+        return this.commitOnReturn;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void setRollbackOnReturn(boolean rollbackOnReturn) {
+        this.rollbackOnReturn = rollbackOnReturn;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public boolean getRollbackOnReturn() {
+        return this.rollbackOnReturn;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void setUseDisposableConnectionFacade(boolean useDisposableConnectionFacade) {
+        this.useDisposableConnectionFacade = useDisposableConnectionFacade;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public boolean getUseDisposableConnectionFacade() {
+        return useDisposableConnectionFacade;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void setLogValidationErrors(boolean logValidationErrors) {
+        this.logValidationErrors = logValidationErrors;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public boolean getLogValidationErrors() {
+        return this.logValidationErrors;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public boolean getPropagateInterruptState() {
+        return propagateInterruptState;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void setPropagateInterruptState(boolean propagateInterruptState) {
+        this.propagateInterruptState = propagateInterruptState;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public boolean isIgnoreExceptionOnPreLoad() {
+        return ignoreExceptionOnPreLoad;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void setIgnoreExceptionOnPreLoad(boolean ignoreExceptionOnPreLoad) {
+        this.ignoreExceptionOnPreLoad = ignoreExceptionOnPreLoad;
+    }
+
+    @Override
+    protected Object clone() throws CloneNotSupportedException {
+        // TODO Auto-generated method stub
+        return super.clone();
+    }
+
+
+
+}
diff --git a/dblib/common/src/main/java/org/apache/tomcat/jdbc/pool/PoolUtilities.java b/dblib/common/src/main/java/org/apache/tomcat/jdbc/pool/PoolUtilities.java
new file mode 100644
index 0000000..cd0d3b2
--- /dev/null
+++ b/dblib/common/src/main/java/org/apache/tomcat/jdbc/pool/PoolUtilities.java
@@ -0,0 +1,58 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * openecomp
+ * ================================================================================
+ * Copyright (C) 2016 - 2017 AT&T
+ * ================================================================================
+ * Licensed 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.
+ * ============LICENSE_END=========================================================
+ */
+
+/*
+ * 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.tomcat.jdbc.pool;
+
+import java.util.Properties;
+
+public class PoolUtilities {
+
+    public static final String PROP_USER = "user";
+
+    public static final String PROP_PASSWORD = "password";
+
+    public static Properties clone(Properties p) {
+        Properties c = new Properties();
+        c.putAll(p);
+        return c;
+    }
+
+    public static Properties cloneWithoutPassword(Properties p) {
+        Properties result = clone(p);
+        result.remove(PROP_PASSWORD);
+        return result;
+    }
+}
diff --git a/dblib/common/src/main/java/org/apache/tomcat/jdbc/pool/PooledConnection.java b/dblib/common/src/main/java/org/apache/tomcat/jdbc/pool/PooledConnection.java
new file mode 100644
index 0000000..b704c7f
--- /dev/null
+++ b/dblib/common/src/main/java/org/apache/tomcat/jdbc/pool/PooledConnection.java
@@ -0,0 +1,795 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * openecomp
+ * ================================================================================
+ * Copyright (C) 2016 - 2017 AT&T
+ * ================================================================================
+ * Licensed 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.
+ * ============LICENSE_END=========================================================
+ */
+
+/*
+ * 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.tomcat.jdbc.pool;
+
+
+import java.sql.DriverManager;
+import java.sql.SQLException;
+import java.sql.Statement;
+import java.util.HashMap;
+import java.util.Properties;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.locks.ReentrantReadWriteLock;
+
+import org.apache.juli.logging.Log;
+import org.apache.juli.logging.LogFactory;
+import org.apache.tomcat.jdbc.pool.interceptor.ConnectionState;
+
+import com.mysql.jdbc.Driver;
+
+/**
+ * Represents a pooled connection
+ * and holds a reference to the {@link java.sql.Connection} object
+ * @version 1.0
+ */
+public class PooledConnection {
+    /**
+     * Logger
+     */
+    private static final Log log = LogFactory.getLog(PooledConnection.class);
+
+    public static final String PROP_USER = PoolUtilities.PROP_USER;
+
+    public static final String PROP_PASSWORD = PoolUtilities.PROP_PASSWORD;
+
+    /**
+     * Validate when connection is borrowed flag
+     */
+    public static final int VALIDATE_BORROW = 1;
+    /**
+     * Validate when connection is returned flag
+     */
+    public static final int VALIDATE_RETURN = 2;
+    /**
+     * Validate when connection is idle flag
+     */
+    public static final int VALIDATE_IDLE = 3;
+    /**
+     * Validate when connection is initialized flag
+     */
+    public static final int VALIDATE_INIT = 4;
+    /**
+     * The properties for the connection pool
+     */
+    protected PoolConfiguration poolProperties;
+    /**
+     * The underlying database connection
+     */
+    private volatile java.sql.Connection connection;
+
+    /**
+     * If using a XAConnection underneath.
+     */
+    protected volatile javax.sql.XAConnection xaConnection;
+    /**
+     * When we track abandon traces, this string holds the thread dump
+     */
+    private String abandonTrace = null;
+    /**
+     * Timestamp the connection was last 'touched' by the pool
+     */
+    private volatile long timestamp;
+    /**
+     * Lock for this connection only
+     */
+    private final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(false);
+    /**
+     * Set to true if this connection has been discarded by the pool
+     */
+    private volatile boolean discarded = false;
+    /**
+     * The Timestamp when the last time the connect() method was called successfully
+     */
+    private volatile long lastConnected = -1;
+    /**
+     * timestamp to keep track of validation intervals
+     */
+    private volatile long lastValidated = System.currentTimeMillis();
+    /**
+     * The parent
+     */
+    protected ConnectionPool parent;
+
+    private HashMap<Object, Object> attributes = new HashMap<>();
+
+    private volatile long connectionVersion=0;
+
+    /**
+     * Weak reference to cache the list of interceptors for this connection
+     * so that we don't create a new list of interceptors each time we borrow
+     * the connection
+     */
+    private volatile JdbcInterceptor handler = null;
+
+    private AtomicBoolean released = new AtomicBoolean(false);
+
+    private volatile boolean suspect = false;
+
+    private java.sql.Driver driver = null;
+
+    /**
+     * Constructor
+     * @param prop - pool properties
+     * @param parent - the parent connection pool
+     */
+    public PooledConnection(PoolConfiguration prop, ConnectionPool parent) {
+        poolProperties = prop;
+        this.parent = parent;
+        connectionVersion = parent.getPoolVersion();
+    }
+
+    public long getConnectionVersion() {
+        return connectionVersion;
+    }
+
+    /**
+     * @deprecated use {@link #shouldForceReconnect(String, String)}
+     * method kept since it was public, to avoid changing interface.
+     * @param username The user name
+     * @param password The password
+     * @return <code>true</code>if the pool does not need to reconnect
+     */
+    @Deprecated
+    public boolean checkUser(String username, String password) {
+        return !shouldForceReconnect(username, password);
+    }
+
+    /**
+     * Returns true if we must force reconnect based on credentials passed in.
+     * Returns false if {@link PoolConfiguration#isAlternateUsernameAllowed()} method returns false.
+     * Returns false if the username/password has not changed since this connection was connected
+     * @param username the username you wish to connect with, pass in null to accept the default username from {@link PoolConfiguration#getUsername()}
+     * @param password the password you wish to connect with, pass in null to accept the default username from {@link org.apache.tomcat.jdbc.pool.PoolConfiguration#getPassword()}
+     * @return true is the pool must reconnect
+     */
+    public boolean shouldForceReconnect(String username, String password) {
+
+        if (!getPoolProperties().isAlternateUsernameAllowed()) return false;
+
+        if (username==null) username = poolProperties.getUsername();
+        if (password==null) password = poolProperties.getPassword();
+
+        String storedUsr = (String)getAttributes().get(PROP_USER);
+        String storedPwd = (String)getAttributes().get(PROP_PASSWORD);
+
+        boolean noChangeInCredentials = (username==null && storedUsr==null);
+        noChangeInCredentials = (noChangeInCredentials || (username!=null && username.equals(storedUsr)));
+
+        noChangeInCredentials = noChangeInCredentials && ((password==null && storedPwd==null) || (password!=null && password.equals(storedPwd)));
+
+        if (username==null)  getAttributes().remove(PROP_USER); else getAttributes().put(PROP_USER, username);
+        if (password==null)  getAttributes().remove(PROP_PASSWORD); else getAttributes().put(PROP_PASSWORD, password);
+
+        return !noChangeInCredentials;
+    }
+
+    /**
+     * Connects the underlying connection to the database.
+     * @throws SQLException if the method {@link #release()} has been called.
+     * @throws SQLException if driver instantiation fails
+     * @throws SQLException if a call to {@link java.sql.Driver#connect(String, java.util.Properties)} fails.
+     * @throws SQLException if default properties are configured and a call to
+     * {@link java.sql.Connection#setAutoCommit(boolean)}, {@link java.sql.Connection#setCatalog(String)},
+     * {@link java.sql.Connection#setTransactionIsolation(int)} or {@link java.sql.Connection#setReadOnly(boolean)} fails.
+     */
+    public void connect() throws SQLException {
+        if (released.get()) throw new SQLException("A connection once released, can't be reestablished.");
+        if (connection != null) {
+            try {
+                this.disconnect(false);
+            } catch (Exception x) {
+                log.debug("Unable to disconnect previous connection.", x);
+            } //catch
+        } //end if
+        if (poolProperties.getDataSource()==null && poolProperties.getDataSourceJNDI()!=null) {
+            //TODO lookup JNDI name
+        }
+
+        if (poolProperties.getDataSource()!=null) {
+            connectUsingDataSource();
+        } else {
+            connectUsingDriver();
+        }
+
+        //set up the default state, unless we expect the interceptor to do it
+        if (poolProperties.getJdbcInterceptors()==null || poolProperties.getJdbcInterceptors().indexOf(ConnectionState.class.getName())<0 ||
+                poolProperties.getJdbcInterceptors().indexOf(ConnectionState.class.getSimpleName())<0) {
+            if (poolProperties.getDefaultTransactionIsolation()!=DataSourceFactory.UNKNOWN_TRANSACTIONISOLATION) connection.setTransactionIsolation(poolProperties.getDefaultTransactionIsolation());
+            if (poolProperties.getDefaultReadOnly()!=null) connection.setReadOnly(poolProperties.getDefaultReadOnly().booleanValue());
+            if (poolProperties.getDefaultAutoCommit()!=null) connection.setAutoCommit(poolProperties.getDefaultAutoCommit().booleanValue());
+            if (poolProperties.getDefaultCatalog()!=null) connection.setCatalog(poolProperties.getDefaultCatalog());
+        }
+        this.discarded = false;
+        this.lastConnected = System.currentTimeMillis();
+    }
+
+    protected void connectUsingDataSource() throws SQLException {
+        String usr = null;
+        String pwd = null;
+        if (getAttributes().containsKey(PROP_USER)) {
+            usr = (String) getAttributes().get(PROP_USER);
+        } else {
+            usr = poolProperties.getUsername();
+            getAttributes().put(PROP_USER, usr);
+        }
+        if (getAttributes().containsKey(PROP_PASSWORD)) {
+            pwd = (String) getAttributes().get(PROP_PASSWORD);
+        } else {
+            pwd = poolProperties.getPassword();
+            getAttributes().put(PROP_PASSWORD, pwd);
+        }
+        if (poolProperties.getDataSource() instanceof javax.sql.XADataSource) {
+            javax.sql.XADataSource xds = (javax.sql.XADataSource)poolProperties.getDataSource();
+            if (usr!=null && pwd!=null) {
+                xaConnection = xds.getXAConnection(usr, pwd);
+                connection = xaConnection.getConnection();
+            } else {
+                xaConnection = xds.getXAConnection();
+                connection = xaConnection.getConnection();
+            }
+        } else if (poolProperties.getDataSource() instanceof javax.sql.DataSource){
+            javax.sql.DataSource ds = (javax.sql.DataSource)poolProperties.getDataSource();
+            if (usr!=null && pwd!=null) {
+                connection = ds.getConnection(usr, pwd);
+            } else {
+                connection = ds.getConnection();
+            }
+        } else if (poolProperties.getDataSource() instanceof javax.sql.ConnectionPoolDataSource){
+            javax.sql.ConnectionPoolDataSource ds = (javax.sql.ConnectionPoolDataSource)poolProperties.getDataSource();
+            if (usr!=null && pwd!=null) {
+                connection = ds.getPooledConnection(usr, pwd).getConnection();
+            } else {
+                connection = ds.getPooledConnection().getConnection();
+            }
+        } else {
+            throw new SQLException("DataSource is of unknown class:"+(poolProperties.getDataSource()!=null?poolProperties.getDataSource().getClass():"null"));
+        }
+    }
+    protected void connectUsingDriver() throws SQLException {
+    	
+		try {
+			Class.forName("com.mysql.jdbc.Driver") ;
+			Driver dr = new com.mysql.jdbc.Driver();
+			if(dr == null)
+				log.warn("Driver NOT CREATED");
+		} catch (ClassNotFoundException e) {
+			log.warn("Driver NOT CREATED", e);
+		}
+
+        try {
+            if (driver==null) {
+                if (log.isDebugEnabled()) {
+                    log.debug("Instantiating driver using class: "+poolProperties.getDriverClassName()+" [url="+poolProperties.getUrl()+"]");
+                }
+                if (poolProperties.getDriverClassName()==null) {
+                    //rely on DriverManager
+                    log.warn("Not loading a JDBC driver as driverClassName property is null.");
+                } else {
+                    driver = (java.sql.Driver)
+                        ClassLoaderUtil.loadClass(
+                            poolProperties.getDriverClassName(),
+                            PooledConnection.class.getClassLoader(),
+                            Thread.currentThread().getContextClassLoader()
+                        ).newInstance();
+                }
+            }
+        } catch (java.lang.Exception cn) {
+            if (log.isDebugEnabled()) {
+                log.debug("Unable to instantiate JDBC driver.", cn);
+            }
+            SQLException ex = new SQLException(cn.getMessage());
+            ex.initCause(cn);
+            throw ex;
+        }
+        String driverURL = poolProperties.getUrl();
+        String usr = null;
+        String pwd = null;
+        if (getAttributes().containsKey(PROP_USER)) {
+            usr = (String) getAttributes().get(PROP_USER);
+        } else {
+            usr = poolProperties.getUsername();
+            getAttributes().put(PROP_USER, usr);
+        }
+        if (getAttributes().containsKey(PROP_PASSWORD)) {
+            pwd = (String) getAttributes().get(PROP_PASSWORD);
+        } else {
+            pwd = poolProperties.getPassword();
+            getAttributes().put(PROP_PASSWORD, pwd);
+        }
+        Properties properties = PoolUtilities.clone(poolProperties.getDbProperties());
+        if (usr != null) properties.setProperty(PROP_USER, usr);
+        if (pwd != null) properties.setProperty(PROP_PASSWORD, pwd);
+
+        try {
+            if (driver==null) {
+                connection = DriverManager.getConnection(driverURL, properties);
+            } else {
+                connection = driver.connect(driverURL, properties);
+            }
+        } catch (Exception x) {
+            if (log.isDebugEnabled()) {
+                log.debug("Unable to connect to database.", x);
+            }
+            if (parent.jmxPool!=null) {
+                parent.jmxPool.notify(org.apache.tomcat.jdbc.pool.jmx.ConnectionPool.NOTIFY_CONNECT,
+                        ConnectionPool.getStackTrace(x));
+            }
+            if (x instanceof SQLException) {
+                throw (SQLException)x;
+            } else {
+                SQLException ex = new SQLException(x.getMessage());
+                ex.initCause(x);
+                throw ex;
+            }
+        }
+        if (connection==null) {
+            throw new SQLException("Driver:"+driver+" returned null for URL:"+driverURL);
+        }
+    }
+
+    /**
+     *
+     * @return true if connect() was called successfully and disconnect has not yet been called
+     */
+    public boolean isInitialized() {
+        return connection!=null;
+    }
+
+    /**
+     * Returns true if the connection has been connected more than
+     * {@link PoolConfiguration#getMaxAge()} milliseconds. false otherwise.
+     * @return Returns true if the connection has been connected more than
+     * {@link PoolConfiguration#getMaxAge()} milliseconds. false otherwise.
+     */
+    public boolean isMaxAgeExpired() {
+        if (getPoolProperties().getMaxAge()>0 ) {
+            return (System.currentTimeMillis() - getLastConnected()) > getPoolProperties().getMaxAge();
+        } else {
+            return false;
+        }
+    }
+    /**
+     * Issues a call to {@link #disconnect(boolean)} with the argument false followed by a call to
+     * {@link #connect()}
+     * @throws SQLException if the call to {@link #connect()} fails.
+     */
+    public void reconnect() throws SQLException {
+        this.disconnect(false);
+        this.connect();
+    } //reconnect
+
+    /**
+     * Disconnects the connection. All exceptions are logged using debug level.
+     * @param finalize if set to true, a call to {@link ConnectionPool#finalize(PooledConnection)} is called.
+     */
+    private void disconnect(boolean finalize) {
+        if (isDiscarded() && connection == null) {
+            return;
+        }
+        setDiscarded(true);
+        if (connection != null) {
+            try {
+                parent.disconnectEvent(this, finalize);
+                if (xaConnection == null) {
+                    connection.close();
+                } else {
+                    xaConnection.close();
+                }
+            }catch (Exception ignore) {
+                if (log.isDebugEnabled()) {
+                    log.debug("Unable to close underlying SQL connection",ignore);
+                }
+            }
+        }
+        connection = null;
+        xaConnection = null;
+        lastConnected = -1;
+        if (finalize) parent.finalize(this);
+    }
+
+
+//============================================================================
+//
+//============================================================================
+
+    /**
+     * Returns abandon timeout in milliseconds
+     * @return abandon timeout in milliseconds
+     */
+    public long getAbandonTimeout() {
+        if (poolProperties.getRemoveAbandonedTimeout() <= 0) {
+            return Long.MAX_VALUE;
+        } else {
+            return poolProperties.getRemoveAbandonedTimeout() * 1000L;
+        } //end if
+    }
+
+    /**
+     * Returns <code>true</code> if the connection pool is configured
+     * to do validation for a certain action.
+     * @param action The validation action
+     */
+    private boolean doValidate(int action) {
+        if (action == PooledConnection.VALIDATE_BORROW &&
+            poolProperties.isTestOnBorrow())
+            return true;
+        else if (action == PooledConnection.VALIDATE_RETURN &&
+                 poolProperties.isTestOnReturn())
+            return true;
+        else if (action == PooledConnection.VALIDATE_IDLE &&
+                 poolProperties.isTestWhileIdle())
+            return true;
+        else if (action == PooledConnection.VALIDATE_INIT &&
+                 poolProperties.isTestOnConnect())
+            return true;
+        else if (action == PooledConnection.VALIDATE_INIT &&
+                 poolProperties.getInitSQL()!=null)
+           return true;
+        else
+            return false;
+    }
+
+    /**
+     * Returns <code>true</code> if the object is still valid. if not
+     * the pool will call the getExpiredAction() and follow up with one
+     * of the four expired methods
+     * @param validateAction The value
+     * @return <code>true</code> if the connection is valid
+     */
+    public boolean validate(int validateAction) {
+        return validate(validateAction,null);
+    }
+
+    /**
+     * Validates a connection.
+     * @param validateAction the action used. One of {@link #VALIDATE_BORROW}, {@link #VALIDATE_IDLE},
+     * {@link #VALIDATE_INIT} or {@link #VALIDATE_RETURN}
+     * @param sql the SQL to be used during validation. If the {@link PoolConfiguration#setInitSQL(String)} has been called with a non null
+     * value and the action is {@link #VALIDATE_INIT} the init SQL will be used for validation.
+     *
+     * @return true if the connection was validated successfully. It returns true even if validation was not performed, such as when
+     * {@link PoolConfiguration#setValidationInterval(long)} has been called with a positive value.
+     * <p>
+     * false if the validation failed. The caller should close the connection if false is returned since a session could have been left in
+     * an unknown state during initialization.
+     */
+    public boolean validate(int validateAction,String sql) {
+        if (this.isDiscarded()) {
+            return false;
+        }
+
+        if (!doValidate(validateAction)) {
+            //no validation required, no init sql and props not set
+            return true;
+        }
+
+        //Don't bother validating if already have recently enough
+        long now = System.currentTimeMillis();
+        if (validateAction!=VALIDATE_INIT &&
+            poolProperties.getValidationInterval() > 0 &&
+            (now - this.lastValidated) <
+            poolProperties.getValidationInterval()) {
+            return true;
+        }
+
+        if (poolProperties.getValidator() != null) {
+            if (poolProperties.getValidator().validate(connection, validateAction)) {
+                this.lastValidated = now;
+                return true;
+            } else {
+                if (getPoolProperties().getLogValidationErrors()) {
+                    log.error("Custom validation through "+poolProperties.getValidator()+" failed.");
+                }
+                return false;
+            }
+        }
+
+        String query = sql;
+
+        if (validateAction == VALIDATE_INIT && poolProperties.getInitSQL() != null) {
+            query = poolProperties.getInitSQL();
+        }
+
+        if (query == null) {
+            query = poolProperties.getValidationQuery();
+        }
+
+        if (query == null) {
+            int validationQueryTimeout = poolProperties.getValidationQueryTimeout();
+            if (validationQueryTimeout < 0) validationQueryTimeout = 0;
+            try {
+                if (connection.isValid(validationQueryTimeout)) {
+                    this.lastValidated = now;
+                    return true;
+                } else {
+                    if (getPoolProperties().getLogValidationErrors()) {
+                        log.error("isValid() returned false.");
+                    }
+                    return false;
+                }
+            } catch (SQLException e) {
+                if (getPoolProperties().getLogValidationErrors()) {
+                    log.error("isValid() failed.", e);
+                } else if (log.isDebugEnabled()) {
+                    log.debug("isValid() failed.", e);
+                }
+                return false;
+            }
+        }
+
+        Statement stmt = null;
+        try {
+            stmt = connection.createStatement();
+
+            int validationQueryTimeout = poolProperties.getValidationQueryTimeout();
+            if (validationQueryTimeout > 0) {
+                stmt.setQueryTimeout(validationQueryTimeout);
+            }
+
+            stmt.execute(query);
+            stmt.close();
+            this.lastValidated = now;
+            return true;
+        } catch (Exception ex) {
+            if (getPoolProperties().getLogValidationErrors()) {
+                log.warn("SQL Validation error", ex);
+            } else if (log.isDebugEnabled()) {
+                log.debug("Unable to validate object:",ex);
+            }
+            if (stmt!=null)
+                try { stmt.close();} catch (Exception ignore2){/*NOOP*/}
+        }
+        return false;
+    } //validate
+
+    /**
+     * The time limit for how long the object
+     * can remain unused before it is released
+     * @return {@link PoolConfiguration#getMinEvictableIdleTimeMillis()}
+     */
+    public long getReleaseTime() {
+        return this.poolProperties.getMinEvictableIdleTimeMillis();
+    }
+
+    /**
+     * This method is called if (Now - timeCheckedIn &gt; getReleaseTime())
+     * This method disconnects the connection, logs an error in debug mode if it happens
+     * then sets the {@link #released} flag to false. Any attempts to connect this cached object again
+     * will fail per {@link #connect()}
+     * The connection pool uses the atomic return value to decrement the pool size counter.
+     * @return true if this is the first time this method has been called. false if this method has been called before.
+     */
+    public boolean release() {
+        try {
+            disconnect(true);
+        } catch (Exception x) {
+            if (log.isDebugEnabled()) {
+                log.debug("Unable to close SQL connection",x);
+            }
+        }
+        return released.compareAndSet(false, true);
+
+    }
+
+    /**
+     * The pool will set the stack trace when it is check out and
+     * checked in
+     * @param trace the stack trace for this connection
+     */
+
+    public void setStackTrace(String trace) {
+        abandonTrace = trace;
+    }
+
+    /**
+     * Returns the stack trace from when this connection was borrowed. Can return null if no stack trace was set.
+     * @return the stack trace or null of no trace was set
+     */
+    public String getStackTrace() {
+        return abandonTrace;
+    }
+
+    /**
+     * Sets a timestamp on this connection. A timestamp usually means that some operation
+     * performed successfully.
+     * @param timestamp the timestamp as defined by {@link System#currentTimeMillis()}
+     */
+    public void setTimestamp(long timestamp) {
+        this.timestamp = timestamp;
+        setSuspect(false);
+    }
+
+
+    public boolean isSuspect() {
+        return suspect;
+    }
+
+    public void setSuspect(boolean suspect) {
+        this.suspect = suspect;
+    }
+
+    /**
+     * An interceptor can call this method with the value true, and the connection will be closed when it is returned to the pool.
+     * @param discarded - only valid value is true
+     * @throws IllegalStateException if this method is called with the value false and the value true has already been set.
+     */
+    public void setDiscarded(boolean discarded) {
+        if (this.discarded && !discarded) throw new IllegalStateException("Unable to change the state once the connection has been discarded");
+        this.discarded = discarded;
+    }
+
+    /**
+     * Set the timestamp the connection was last validated.
+     * This flag is used to keep track when we are using a {@link PoolConfiguration#setValidationInterval(long) validation-interval}.
+     * @param lastValidated a timestamp as defined by {@link System#currentTimeMillis()}
+     */
+    public void setLastValidated(long lastValidated) {
+        this.lastValidated = lastValidated;
+    }
+
+    /**
+     * Sets the pool configuration for this connection and connection pool.
+     * Object is shared with the {@link ConnectionPool}
+     * @param poolProperties The pool properties
+     */
+    public void setPoolProperties(PoolConfiguration poolProperties) {
+        this.poolProperties = poolProperties;
+    }
+
+    /**
+     * Return the timestamps of last pool action. Timestamps are typically set when connections
+     * are borrowed from the pool. It is used to keep track of {@link PoolConfiguration#setRemoveAbandonedTimeout(int) abandon-timeouts}.
+     * This timestamp can also be reset by the {@link org.apache.tomcat.jdbc.pool.interceptor.ResetAbandonedTimer#invoke(Object, java.lang.reflect.Method, Object[])}
+     * @return the timestamp of the last pool action as defined by {@link System#currentTimeMillis()}
+     */
+    public long getTimestamp() {
+        return timestamp;
+    }
+
+    /**
+     * Returns the discarded flag.
+     * @return the discarded flag. If the value is true,
+     * either {@link #disconnect(boolean)} has been called or it will be called when the connection is returned to the pool.
+     */
+    public boolean isDiscarded() {
+        return discarded;
+    }
+
+    /**
+     * Returns the timestamp of the last successful validation query execution.
+     * @return the timestamp of the last successful validation query execution as defined by {@link System#currentTimeMillis()}
+     */
+    public long getLastValidated() {
+        return lastValidated;
+    }
+
+    /**
+     * Returns the configuration for this connection and pool
+     * @return the configuration for this connection and pool
+     */
+    public PoolConfiguration getPoolProperties() {
+        return poolProperties;
+    }
+
+    /**
+     * Locks the connection only if either {@link PoolConfiguration#isPoolSweeperEnabled()} or
+     * {@link PoolConfiguration#getUseLock()} return true. The per connection lock ensures thread safety is
+     * multiple threads are performing operations on the connection.
+     * Otherwise this is a noop for performance
+     */
+    public void lock() {
+        if (poolProperties.getUseLock() || this.poolProperties.isPoolSweeperEnabled()) {
+            //optimized, only use a lock when there is concurrency
+            lock.writeLock().lock();
+        }
+    }
+
+    /**
+     * Unlocks the connection only if the sweeper is enabled
+     * Otherwise this is a noop for performance
+     */
+    public void unlock() {
+        if (poolProperties.getUseLock() || this.poolProperties.isPoolSweeperEnabled()) {
+          //optimized, only use a lock when there is concurrency
+            lock.writeLock().unlock();
+        }
+    }
+
+    /**
+     * Returns the underlying connection
+     * @return the underlying JDBC connection as it was returned from the JDBC driver
+     * @see javax.sql.PooledConnection#getConnection()
+     */
+    public java.sql.Connection getConnection() {
+        return this.connection;
+    }
+
+    /**
+     * Returns the underlying XA connection
+     * @return the underlying XA connection as it was returned from the Datasource
+     */
+    public javax.sql.XAConnection getXAConnection() {
+        return this.xaConnection;
+    }
+
+
+    /**
+     * Returns the timestamp of when the connection was last connected to the database.
+     * ie, a successful call to {@link java.sql.Driver#connect(String, java.util.Properties)}.
+     * @return the timestamp when this connection was created as defined by {@link System#currentTimeMillis()}
+     */
+    public long getLastConnected() {
+        return lastConnected;
+    }
+
+    /**
+     * Returns the first handler in the interceptor chain
+     * @return the first interceptor for this connection
+     */
+    public JdbcInterceptor getHandler() {
+        return handler;
+    }
+
+    public void setHandler(JdbcInterceptor handler) {
+        if (this.handler!=null && this.handler!=handler) {
+            JdbcInterceptor interceptor = this.handler;
+            while (interceptor!=null) {
+                interceptor.reset(null, null);
+                interceptor = interceptor.getNext();
+            }//while
+        }//end if
+        this.handler = handler;
+    }
+
+    @Override
+    public String toString() {
+        return "PooledConnection["+(connection!=null?connection.toString():"null")+"]";
+    }
+
+    /**
+     * Returns true if this connection has been released and wont be reused.
+     * @return true if the method {@link #release()} has been called
+     */
+    public boolean isReleased() {
+        return released.get();
+    }
+
+    public HashMap<Object,Object> getAttributes() {
+        return attributes;
+    }
+
+}
diff --git a/dblib/common/src/main/java/org/apache/tomcat/jdbc/pool/ProxyConnection.java b/dblib/common/src/main/java/org/apache/tomcat/jdbc/pool/ProxyConnection.java
new file mode 100644
index 0000000..0a67e8e
--- /dev/null
+++ b/dblib/common/src/main/java/org/apache/tomcat/jdbc/pool/ProxyConnection.java
@@ -0,0 +1,176 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * openecomp
+ * ================================================================================
+ * Copyright (C) 2016 - 2017 AT&T
+ * ================================================================================
+ * Licensed 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.
+ * ============LICENSE_END=========================================================
+ */
+
+/*
+ * 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.tomcat.jdbc.pool;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.sql.SQLException;
+
+import javax.sql.XAConnection;
+/**
+ * A ProxyConnection object is the bottom most interceptor that wraps an object of type
+ * {@link PooledConnection}. The ProxyConnection intercepts three methods:
+ * <ul>
+ *   <li>{@link java.sql.Connection#close()} - returns the connection to the pool. May be called multiple times.</li>
+ *   <li>{@link java.lang.Object#toString()} - returns a custom string for this object</li>
+ *   <li>{@link javax.sql.PooledConnection#getConnection()} - returns the underlying connection</li>
+ * </ul>
+ * By default method comparisons is done on a String reference level, unless the {@link PoolConfiguration#setUseEquals(boolean)} has been called
+ * with a <code>true</code> argument.
+ */
+public class ProxyConnection extends JdbcInterceptor {
+
+    protected PooledConnection connection = null;
+
+    protected ConnectionPool pool = null;
+
+    public PooledConnection getConnection() {
+        return connection;
+    }
+
+    public void setConnection(PooledConnection connection) {
+        this.connection = connection;
+    }
+
+    public ConnectionPool getPool() {
+        return pool;
+    }
+
+    public void setPool(ConnectionPool pool) {
+        this.pool = pool;
+    }
+
+    protected ProxyConnection(ConnectionPool parent, PooledConnection con,
+            boolean useEquals) {
+        pool = parent;
+        connection = con;
+        setUseEquals(useEquals);
+    }
+
+    @Override
+    public void reset(ConnectionPool parent, PooledConnection con) {
+        this.pool = parent;
+        this.connection = con;
+    }
+
+    public boolean isWrapperFor(Class<?> iface) {
+        if (iface == XAConnection.class && connection.getXAConnection()!=null) {
+            return true;
+        } else {
+            return (iface.isInstance(connection.getConnection()));
+        }
+    }
+
+
+    public Object unwrap(Class<?> iface) throws SQLException {
+        if (iface == PooledConnection.class) {
+            return connection;
+        }else if (iface == XAConnection.class) {
+            return connection.getXAConnection();
+        } else if (isWrapperFor(iface)) {
+            return connection.getConnection();
+        } else {
+            throw new SQLException("Not a wrapper of "+iface.getName());
+        }
+    }
+
+    @Override
+    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
+        if (compare(ISCLOSED_VAL,method)) {
+            return Boolean.valueOf(isClosed());
+        }
+        if (compare(CLOSE_VAL,method)) {
+            if (connection==null) return null; //noop for already closed.
+            PooledConnection poolc = this.connection;
+            this.connection = null;
+            pool.returnConnection(poolc);
+            return null;
+        } else if (compare(TOSTRING_VAL,method)) {
+            return this.toString();
+        } else if (compare(GETCONNECTION_VAL,method) && connection!=null) {
+            return connection.getConnection();
+        } else if (method.getDeclaringClass().equals(XAConnection.class)) {
+            try {
+                return method.invoke(connection.getXAConnection(),args);
+            }catch (Throwable t) {
+                if (t instanceof InvocationTargetException) {
+                    throw t.getCause() != null ? t.getCause() : t;
+                } else {
+                    throw t;
+                }
+            }
+        }
+        if (isClosed()) throw new SQLException("Connection has already been closed.");
+        if (compare(UNWRAP_VAL,method)) {
+            return unwrap((Class<?>)args[0]);
+        } else if (compare(ISWRAPPERFOR_VAL,method)) {
+            return Boolean.valueOf(this.isWrapperFor((Class<?>)args[0]));
+        }
+        try {
+            PooledConnection poolc = connection;
+            if (poolc!=null) {
+                return method.invoke(poolc.getConnection(),args);
+            } else {
+                throw new SQLException("Connection has already been closed.");
+            }
+        }catch (Throwable t) {
+            if (t instanceof InvocationTargetException) {
+                throw t.getCause() != null ? t.getCause() : t;
+            } else {
+                throw t;
+            }
+        }
+    }
+
+    public boolean isClosed() {
+        return connection==null || connection.isDiscarded();
+    }
+
+    public PooledConnection getDelegateConnection() {
+        return connection;
+    }
+
+    public ConnectionPool getParentPool() {
+        return pool;
+    }
+
+    @Override
+    public String toString() {
+        return "ProxyConnection["+(connection!=null?connection.toString():"null")+"]";
+    }
+
+}
diff --git a/dblib/common/src/main/java/org/apache/tomcat/jdbc/pool/TrapException.java b/dblib/common/src/main/java/org/apache/tomcat/jdbc/pool/TrapException.java
new file mode 100644
index 0000000..5c597f3
--- /dev/null
+++ b/dblib/common/src/main/java/org/apache/tomcat/jdbc/pool/TrapException.java
@@ -0,0 +1,101 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * openecomp
+ * ================================================================================
+ * Copyright (C) 2016 - 2017 AT&T
+ * ================================================================================
+ * Licensed 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.
+ * ============LICENSE_END=========================================================
+ */
+
+/*
+ * 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.tomcat.jdbc.pool;
+
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.sql.SQLException;
+/**
+ * Interceptor that traps any unhandled exception types and throws an exception that has been declared by the method
+ * called, or throw a SQLException if it is declared.
+ * If the caught exception is not declared, and the method doesn't throw SQLException, then this interceptor will
+ * throw a RuntimeException
+ *
+ */
+public class TrapException extends JdbcInterceptor {
+
+
+    public TrapException() {
+    }
+
+    @Override
+    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
+        try {
+            return super.invoke(proxy, method, args);
+        }catch (Exception t) {
+            Throwable exception = t;
+            if (t instanceof InvocationTargetException && t.getCause() != null) {
+                exception = t.getCause();
+                if (exception instanceof Error) {
+                    throw exception;
+                }
+            }
+            Class<?> exceptionClass = exception.getClass();
+            if (!isDeclaredException(method, exceptionClass)) {
+                if (isDeclaredException(method,SQLException.class)) {
+                    SQLException sqlx = new SQLException("Uncaught underlying exception.");
+                    sqlx.initCause(exception);
+                    exception = sqlx;
+                } else {
+                    RuntimeException rx = new RuntimeException("Uncaught underlying exception.");
+                    rx.initCause(exception);
+                    exception = rx;
+                }
+            }
+            throw exception;
+        }
+
+    }
+
+    public boolean isDeclaredException(Method m, Class<?> clazz) {
+        for (Class<?> cl : m.getExceptionTypes()) {
+            if (cl.equals(clazz) || cl.isAssignableFrom(clazz)) return true;
+        }
+        return false;
+    }
+
+    /**
+     * no-op for this interceptor. no state is stored.
+     */
+    @Override
+    public void reset(ConnectionPool parent, PooledConnection con) {
+        // NOOP
+    }
+
+}
diff --git a/dblib/common/src/main/java/org/apache/tomcat/jdbc/pool/Validator.java b/dblib/common/src/main/java/org/apache/tomcat/jdbc/pool/Validator.java
new file mode 100644
index 0000000..70cef5a
--- /dev/null
+++ b/dblib/common/src/main/java/org/apache/tomcat/jdbc/pool/Validator.java
@@ -0,0 +1,57 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * openecomp
+ * ================================================================================
+ * Copyright (C) 2016 - 2017 AT&T
+ * ================================================================================
+ * Licensed 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.
+ * ============LICENSE_END=========================================================
+ */
+
+/*
+ * 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.tomcat.jdbc.pool;
+
+import java.sql.Connection;
+
+/**
+ * Interface to be implemented by custom validator classes.
+ *
+ * @author mpassell
+ */
+public interface Validator {
+    /**
+     * Validate a connection and return a boolean to indicate if it's valid.
+     *
+     * @param connection the Connection object to test
+     * @param validateAction the action used. One of {@link PooledConnection#VALIDATE_BORROW},
+     *   {@link PooledConnection#VALIDATE_IDLE}, {@link PooledConnection#VALIDATE_INIT} or
+     *   {@link PooledConnection#VALIDATE_RETURN}
+     * @return true if the connection is valid
+     */
+    public boolean validate(Connection connection, int validateAction);
+}
diff --git a/dblib/common/src/main/java/org/apache/tomcat/jdbc/pool/XADataSource.java b/dblib/common/src/main/java/org/apache/tomcat/jdbc/pool/XADataSource.java
new file mode 100644
index 0000000..4bdb198
--- /dev/null
+++ b/dblib/common/src/main/java/org/apache/tomcat/jdbc/pool/XADataSource.java
@@ -0,0 +1,57 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * openecomp
+ * ================================================================================
+ * Copyright (C) 2016 - 2017 AT&T
+ * ================================================================================
+ * Licensed 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.
+ * ============LICENSE_END=========================================================
+ */
+
+/*
+ * 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.tomcat.jdbc.pool;
+
+public class XADataSource extends DataSource implements javax.sql.XADataSource {
+
+    /**
+     * Constructor for reflection only. A default set of pool properties will be created.
+     */
+    public XADataSource() {
+        super();
+    }
+
+    /**
+     * Constructs a DataSource object wrapping a connection
+     * @param poolProperties The pool configuration
+     */
+    public XADataSource(PoolConfiguration poolProperties) {
+        super(poolProperties);
+    }
+
+}
diff --git a/dblib/common/src/main/java/org/apache/tomcat/jdbc/pool/interceptor/AbstractCreateStatementInterceptor.java b/dblib/common/src/main/java/org/apache/tomcat/jdbc/pool/interceptor/AbstractCreateStatementInterceptor.java
new file mode 100644
index 0000000..e2f1414
--- /dev/null
+++ b/dblib/common/src/main/java/org/apache/tomcat/jdbc/pool/interceptor/AbstractCreateStatementInterceptor.java
@@ -0,0 +1,158 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * openecomp
+ * ================================================================================
+ * Copyright (C) 2016 - 2017 AT&T
+ * ================================================================================
+ * Licensed 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.
+ * ============LICENSE_END=========================================================
+ */
+
+/*
+ * 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.tomcat.jdbc.pool.interceptor;
+
+import java.lang.reflect.Method;
+
+import org.apache.tomcat.jdbc.pool.ConnectionPool;
+import org.apache.tomcat.jdbc.pool.JdbcInterceptor;
+import org.apache.tomcat.jdbc.pool.PooledConnection;
+
+/**
+ * Abstraction interceptor. This component intercepts all calls to create some type of SQL statement.
+ * By extending this class, one can intercept queries and update statements by overriding the {@link #createStatement(Object, Method, Object[], Object, long)}
+ * method.
+ * @version 1.0
+ */
+public abstract class  AbstractCreateStatementInterceptor extends JdbcInterceptor {
+    protected static final String CREATE_STATEMENT      = "createStatement";
+    protected static final int    CREATE_STATEMENT_IDX  = 0;
+    protected static final String PREPARE_STATEMENT     = "prepareStatement";
+    protected static final int    PREPARE_STATEMENT_IDX = 1;
+    protected static final String PREPARE_CALL          = "prepareCall";
+    protected static final int    PREPARE_CALL_IDX      = 2;
+
+    protected static final String[] STATEMENT_TYPES = {CREATE_STATEMENT, PREPARE_STATEMENT, PREPARE_CALL};
+    protected static final int    STATEMENT_TYPE_COUNT = STATEMENT_TYPES.length;
+
+    protected static final String EXECUTE        = "execute";
+    protected static final String EXECUTE_QUERY  = "executeQuery";
+    protected static final String EXECUTE_UPDATE = "executeUpdate";
+    protected static final String EXECUTE_BATCH  = "executeBatch";
+
+    protected static final String[] EXECUTE_TYPES = {EXECUTE, EXECUTE_QUERY, EXECUTE_UPDATE, EXECUTE_BATCH};
+
+    public  AbstractCreateStatementInterceptor() {
+        super();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
+        if (compare(CLOSE_VAL,method)) {
+            closeInvoked();
+            return super.invoke(proxy, method, args);
+        } else {
+            boolean process = false;
+            process = isStatement(method, process);
+            if (process) {
+                long start = System.currentTimeMillis();
+                Object statement = super.invoke(proxy,method,args);
+                long delta = System.currentTimeMillis() - start;
+                return createStatement(proxy,method,args,statement, delta);
+            } else {
+                return super.invoke(proxy,method,args);
+            }
+        }
+    }
+
+    /**
+     * This method will be invoked after a successful statement creation. This method can choose to return a wrapper
+     * around the statement or return the statement itself.
+     * If this method returns a wrapper then it should return a wrapper object that implements one of the following interfaces.
+     * {@link java.sql.Statement}, {@link java.sql.PreparedStatement} or {@link java.sql.CallableStatement}
+     * @param proxy the actual proxy object
+     * @param method the method that was called. It will be one of the methods defined in {@link #STATEMENT_TYPES}
+     * @param args the arguments to the method
+     * @param statement the statement that the underlying connection created
+     * @param time Elapsed time
+     * @return a {@link java.sql.Statement} object
+     */
+    public abstract Object createStatement(Object proxy, Method method, Object[] args, Object statement, long time);
+
+    /**
+     * Method invoked when the operation {@link java.sql.Connection#close()} is invoked.
+     */
+    public abstract void closeInvoked();
+
+    /**
+     * Returns true if the method that is being invoked matches one of the statement types.
+     *
+     * @param method the method being invoked on the proxy
+     * @param process boolean result used for recursion
+     * @return returns true if the method name matched
+     */
+    protected boolean isStatement(Method method, boolean process){
+        return process(STATEMENT_TYPES, method, process);
+    }
+
+    /**
+     * Returns true if the method that is being invoked matches one of the execute types.
+     *
+     * @param method the method being invoked on the proxy
+     * @param process boolean result used for recursion
+     * @return returns true if the method name matched
+     */
+    protected boolean isExecute(Method method, boolean process){
+        return process(EXECUTE_TYPES, method, process);
+    }
+
+    /*
+     * Returns true if the method that is being invoked matches one of the method names passed in
+     * @param names list of method names that we want to intercept
+     * @param method the method being invoked on the proxy
+     * @param process boolean result used for recursion
+     * @return returns true if the method name matched
+     */
+    protected boolean process(String[] names, Method method, boolean process) {
+        final String name = method.getName();
+        for (int i=0; (!process) && i<names.length; i++) {
+            process = compare(names[i],name);
+        }
+        return process;
+    }
+
+    /**
+     * no-op for this interceptor. no state is stored.
+     */
+    @Override
+    public void reset(ConnectionPool parent, PooledConnection con) {
+        // NOOP
+    }
+}
diff --git a/dblib/common/src/main/java/org/apache/tomcat/jdbc/pool/interceptor/AbstractQueryReport.java b/dblib/common/src/main/java/org/apache/tomcat/jdbc/pool/interceptor/AbstractQueryReport.java
new file mode 100644
index 0000000..374969d
--- /dev/null
+++ b/dblib/common/src/main/java/org/apache/tomcat/jdbc/pool/interceptor/AbstractQueryReport.java
@@ -0,0 +1,285 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * openecomp
+ * ================================================================================
+ * Copyright (C) 2016 - 2017 AT&T
+ * ================================================================================
+ * Licensed 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.
+ * ============LICENSE_END=========================================================
+ */
+
+/*
+ *  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.tomcat.jdbc.pool.interceptor;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.lang.reflect.Proxy;
+import java.sql.CallableStatement;
+import java.sql.PreparedStatement;
+import java.sql.SQLException;
+import java.sql.Statement;
+
+import org.apache.juli.logging.Log;
+import org.apache.juli.logging.LogFactory;
+import org.apache.tomcat.jdbc.pool.JdbcInterceptor;
+/**
+ * Abstract class that wraps statements and intercepts query executions.
+ *
+ */
+public abstract class AbstractQueryReport extends AbstractCreateStatementInterceptor {
+    //logger
+    private static final Log log = LogFactory.getLog(AbstractQueryReport.class);
+
+    /**
+     * The threshold in milliseconds. If the query is faster than this, we don't measure it
+     */
+    protected long threshold = 1000; //don't report queries less than this
+
+    /**
+     * the constructors that are used to create statement proxies
+     */
+    protected static final Constructor<?>[] constructors =
+        new Constructor[AbstractCreateStatementInterceptor.STATEMENT_TYPE_COUNT];
+
+
+    public AbstractQueryReport() {
+        super();
+    }
+
+    /**
+     * Invoked when prepareStatement has been called and completed.
+     * @param sql - the string used to prepare the statement with
+     * @param time - the time it took to invoke prepare
+     */
+    protected abstract void prepareStatement(String sql, long time);
+
+    /**
+     * Invoked when prepareCall has been called and completed.
+     * @param query - the string used to prepare the statement with
+     * @param time - the time it took to invoke prepare
+     */
+    protected abstract void prepareCall(String query, long time);
+
+    /**
+     * Invoked when a query execution, a call to execute/executeQuery or executeBatch failed.
+     * @param query the query that was executed and failed
+     * @param args the arguments to the execution
+     * @param name the name of the method used to execute {@link AbstractCreateStatementInterceptor#isExecute(Method, boolean)}
+     * @param start the time the query execution started
+     * @param t the exception that happened
+     * @return - the SQL that was executed or the string &quot;batch&quot; if it was a batch execution
+     */
+    protected String reportFailedQuery(String query, Object[] args, final String name, long start, Throwable t) {
+        //extract the query string
+        String sql = (query==null && args!=null &&  args.length>0)?(String)args[0]:query;
+        //if we do batch execution, then we name the query 'batch'
+        if (sql==null && compare(EXECUTE_BATCH,name)) {
+            sql = "batch";
+        }
+        return sql;
+    }
+
+    /**
+     * Invoked when a query execution, a call to execute/executeQuery or executeBatch succeeded and was within the timing threshold
+     * @param query the query that was executed and failed
+     * @param args the arguments to the execution
+     * @param name the name of the method used to execute {@link AbstractCreateStatementInterceptor#isExecute(Method, boolean)}
+     * @param start the time the query execution started
+     * @param delta the time the execution took
+     * @return - the SQL that was executed or the string &quot;batch&quot; if it was a batch execution
+     */
+    protected String reportQuery(String query, Object[] args, final String name, long start, long delta) {
+        //extract the query string
+        String sql = (query==null && args!=null &&  args.length>0)?(String)args[0]:query;
+        //if we do batch execution, then we name the query 'batch'
+        if (sql==null && compare(EXECUTE_BATCH,name)) {
+            sql = "batch";
+        }
+        return sql;
+    }
+
+    /**
+     * Invoked when a query execution, a call to execute/executeQuery or executeBatch succeeded and was exceeded the timing threshold
+     * @param query the query that was executed and failed
+     * @param args the arguments to the execution
+     * @param name the name of the method used to execute {@link AbstractCreateStatementInterceptor#isExecute(Method, boolean)}
+     * @param start the time the query execution started
+     * @param delta the time the execution took
+     * @return - the SQL that was executed or the string &quot;batch&quot; if it was a batch execution
+     */
+    protected String reportSlowQuery(String query, Object[] args, final String name, long start, long delta) {
+        //extract the query string
+        String sql = (query==null && args!=null &&  args.length>0)?(String)args[0]:query;
+        //if we do batch execution, then we name the query 'batch'
+        if (sql==null && compare(EXECUTE_BATCH,name)) {
+            sql = "batch";
+        }
+        return sql;
+    }
+
+    /**
+     * returns the query measure threshold.
+     * This value is in milliseconds. If the query is faster than this threshold than it wont be accounted for
+     * @return the threshold in milliseconds
+     */
+    public long getThreshold() {
+        return threshold;
+    }
+
+    /**
+     * Sets the query measurement threshold. The value is in milliseconds.
+     * If the query goes faster than this threshold it will not be recorded.
+     * @param threshold set to -1 to record every query. Value is in milliseconds.
+     */
+    public void setThreshold(long threshold) {
+        this.threshold = threshold;
+    }
+
+    /**
+     * Creates a constructor for a proxy class, if one doesn't already exist
+     * @param idx - the index of the constructor
+     * @param clazz - the interface that the proxy will implement
+     * @return - returns a constructor used to create new instances
+     * @throws NoSuchMethodException Constructor not found
+     */
+    protected Constructor<?> getConstructor(int idx, Class<?> clazz) throws NoSuchMethodException {
+        if (constructors[idx]==null) {
+            Class<?> proxyClass = Proxy.getProxyClass(SlowQueryReport.class.getClassLoader(), new Class[] {clazz});
+            constructors[idx] = proxyClass.getConstructor(new Class[] { InvocationHandler.class });
+        }
+        return constructors[idx];
+    }
+
+    /**
+     * Creates a statement interceptor to monitor query response times
+     */
+    @Override
+    public Object createStatement(Object proxy, Method method, Object[] args, Object statement, long time) {
+        try {
+            Object result = null;
+            String name = method.getName();
+            String sql = null;
+            Constructor<?> constructor = null;
+            if (compare(CREATE_STATEMENT,name)) {
+                //createStatement
+                constructor = getConstructor(CREATE_STATEMENT_IDX,Statement.class);
+            }else if (compare(PREPARE_STATEMENT,name)) {
+                //prepareStatement
+                sql = (String)args[0];
+                constructor = getConstructor(PREPARE_STATEMENT_IDX,PreparedStatement.class);
+                if (sql!=null) {
+                    prepareStatement(sql, time);
+                }
+            }else if (compare(PREPARE_CALL,name)) {
+                //prepareCall
+                sql = (String)args[0];
+                constructor = getConstructor(PREPARE_CALL_IDX,CallableStatement.class);
+                prepareCall(sql,time);
+            }else {
+                //do nothing, might be a future unsupported method
+                //so we better bail out and let the system continue
+                return statement;
+            }
+            result = constructor.newInstance(new Object[] { new StatementProxy(statement,sql) });
+            return result;
+        }catch (Exception x) {
+            log.warn("Unable to create statement proxy for slow query report.",x);
+        }
+        return statement;
+    }
+
+
+    /**
+     * Class to measure query execute time
+     *
+     */
+    protected class StatementProxy implements InvocationHandler {
+        protected boolean closed = false;
+        protected Object delegate;
+        protected final String query;
+        public StatementProxy(Object parent, String query) {
+            this.delegate = parent;
+            this.query = query;
+        }
+
+        @Override
+        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
+            //get the name of the method for comparison
+            final String name = method.getName();
+            //was close invoked?
+            boolean close = compare(JdbcInterceptor.CLOSE_VAL,name);
+            //allow close to be called multiple times
+            if (close && closed) return null;
+            //are we calling isClosed?
+            if (compare(JdbcInterceptor.ISCLOSED_VAL,name)) return Boolean.valueOf(closed);
+            //if we are calling anything else, bail out
+            if (closed) throw new SQLException("Statement closed.");
+            boolean process = false;
+            //check to see if we are about to execute a query
+            process = isExecute( method, process);
+            //if we are executing, get the current time
+            long start = (process)?System.currentTimeMillis():0;
+            Object result =  null;
+            try {
+                //execute the query
+                result =  method.invoke(delegate,args);
+            }catch (Throwable t) {
+                reportFailedQuery(query,args,name,start,t);
+                if (t instanceof InvocationTargetException
+                        && t.getCause() != null) {
+                    throw t.getCause();
+                } else {
+                    throw t;
+                }
+            }
+            //measure the time
+            long delta = (process)?(System.currentTimeMillis()-start):Long.MIN_VALUE;
+            //see if we meet the requirements to measure
+            if (delta>threshold) {
+                try {
+                    //report the slow query
+                    reportSlowQuery(query, args, name, start, delta);
+                }catch (Exception t) {
+                    if (log.isWarnEnabled()) log.warn("Unable to process slow query",t);
+                }
+            } else if (process) {
+                reportQuery(query, args, name, start, delta);
+            }
+            //perform close cleanup
+            if (close) {
+                closed=true;
+                delegate = null;
+            }
+            return result;
+        }
+    }
+
+}
diff --git a/dblib/common/src/main/java/org/apache/tomcat/jdbc/pool/interceptor/ConnectionState.java b/dblib/common/src/main/java/org/apache/tomcat/jdbc/pool/interceptor/ConnectionState.java
new file mode 100644
index 0000000..95049c6
--- /dev/null
+++ b/dblib/common/src/main/java/org/apache/tomcat/jdbc/pool/interceptor/ConnectionState.java
@@ -0,0 +1,184 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * openecomp
+ * ================================================================================
+ * Copyright (C) 2016 - 2017 AT&T
+ * ================================================================================
+ * Licensed 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.
+ * ============LICENSE_END=========================================================
+ */
+
+/*
+ * 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.tomcat.jdbc.pool.interceptor;
+
+import java.lang.reflect.Method;
+import java.sql.SQLException;
+
+import org.apache.juli.logging.Log;
+import org.apache.juli.logging.LogFactory;
+import org.apache.tomcat.jdbc.pool.ConnectionPool;
+import org.apache.tomcat.jdbc.pool.DataSourceFactory;
+import org.apache.tomcat.jdbc.pool.JdbcInterceptor;
+import org.apache.tomcat.jdbc.pool.PoolConfiguration;
+import org.apache.tomcat.jdbc.pool.PooledConnection;
+
+/**
+ * Interceptor that keep track of connection state to avoid roundtrips to the database.
+ * The {@link org.apache.tomcat.jdbc.pool.ConnectionPool} is optimized to do as little work as possible.
+ * The pool itself doesn't remember settings like {@link java.sql.Connection#setAutoCommit(boolean)},
+ * {@link java.sql.Connection#setReadOnly(boolean)}, {@link java.sql.Connection#setCatalog(String)} or
+ * {@link java.sql.Connection#setTransactionIsolation(int)}. It relies on the application to remember how and when
+ * these settings have been applied.
+ * In the cases where the application code doesn't know or want to keep track of the state, this interceptor helps cache the
+ * state, and it also avoids roundtrips to the database asking for it.
+ *
+ */
+
+public class ConnectionState extends JdbcInterceptor  {
+    private static final Log log = LogFactory.getLog(ConnectionState.class);
+
+    protected final String[] readState = {"getAutoCommit","getTransactionIsolation","isReadOnly","getCatalog"};
+    protected final String[] writeState = {"setAutoCommit","setTransactionIsolation","setReadOnly","setCatalog"};
+
+    protected Boolean autoCommit = null;
+    protected Integer transactionIsolation = null;
+    protected Boolean readOnly = null;
+    protected String catalog = null;
+
+
+    @Override
+    public void reset(ConnectionPool parent, PooledConnection con) {
+        if (parent==null || con==null) {
+            //we are resetting, reset our defaults
+            autoCommit = null;
+            transactionIsolation = null;
+            readOnly = null;
+            catalog = null;
+            return;
+        }
+        PoolConfiguration poolProperties = parent.getPoolProperties();
+        if (poolProperties.getDefaultTransactionIsolation()!=DataSourceFactory.UNKNOWN_TRANSACTIONISOLATION) {
+            try {
+                if (transactionIsolation==null || transactionIsolation.intValue()!=poolProperties.getDefaultTransactionIsolation()) {
+                    con.getConnection().setTransactionIsolation(poolProperties.getDefaultTransactionIsolation());
+                    transactionIsolation = Integer.valueOf(poolProperties.getDefaultTransactionIsolation());
+                }
+            }catch (SQLException x) {
+                transactionIsolation = null;
+                log.error("Unable to reset transaction isolation state to connection.",x);
+            }
+        }
+        if (poolProperties.getDefaultReadOnly()!=null) {
+            try {
+                if (readOnly==null || readOnly.booleanValue()!=poolProperties.getDefaultReadOnly().booleanValue()) {
+                    con.getConnection().setReadOnly(poolProperties.getDefaultReadOnly().booleanValue());
+                    readOnly = poolProperties.getDefaultReadOnly();
+                }
+            }catch (SQLException x) {
+                readOnly = null;
+                log.error("Unable to reset readonly state to connection.",x);
+            }
+        }
+        if (poolProperties.getDefaultAutoCommit()!=null) {
+            try {
+                if (autoCommit==null || autoCommit.booleanValue()!=poolProperties.getDefaultAutoCommit().booleanValue()) {
+                    con.getConnection().setAutoCommit(poolProperties.getDefaultAutoCommit().booleanValue());
+                    autoCommit = poolProperties.getDefaultAutoCommit();
+                }
+            }catch (SQLException x) {
+                autoCommit = null;
+                log.error("Unable to reset autocommit state to connection.",x);
+            }
+        }
+        if (poolProperties.getDefaultCatalog()!=null) {
+            try {
+                if (catalog==null || (!catalog.equals(poolProperties.getDefaultCatalog()))) {
+                    con.getConnection().setCatalog(poolProperties.getDefaultCatalog());
+                    catalog = poolProperties.getDefaultCatalog();
+                }
+            }catch (SQLException x) {
+                catalog = null;
+                log.error("Unable to reset default catalog state to connection.",x);
+            }
+        }
+
+    }
+
+
+    @Override
+    public void disconnected(ConnectionPool parent, PooledConnection con, boolean finalizing) {
+        //we are resetting, reset our defaults
+        autoCommit = null;
+        transactionIsolation = null;
+        readOnly = null;
+        catalog = null;
+        super.disconnected(parent, con, finalizing);
+    }
+
+
+
+    @Override
+    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
+        String name = method.getName();
+        boolean read = false;
+        int index = -1;
+        for (int i=0; (!read) && i<readState.length; i++) {
+            read = compare(name,readState[i]);
+            if (read) index = i;
+        }
+        boolean write = false;
+        for (int i=0; (!write) && (!read) && i<writeState.length; i++) {
+            write = compare(name,writeState[i]);
+            if (write) index = i;
+        }
+        Object result = null;
+        if (read) {
+            switch (index) {
+                case 0:{result = autoCommit; break;}
+                case 1:{result = transactionIsolation; break;}
+                case 2:{result = readOnly; break;}
+                case 3:{result = catalog; break;}
+                default: // NOOP
+            }
+            //return cached result, if we have it
+            if (result!=null) return result;
+        }
+
+        result = super.invoke(proxy, method, args);
+        if (read || write) {
+            switch (index) {
+                case 0:{autoCommit = (Boolean) (read?result:args[0]); break;}
+                case 1:{transactionIsolation = (Integer)(read?result:args[0]); break;}
+                case 2:{readOnly = (Boolean)(read?result:args[0]); break;}
+                case 3:{catalog = (String)(read?result:args[0]); break;}
+            }
+        }
+        return result;
+    }
+
+}
diff --git a/dblib/common/src/main/java/org/apache/tomcat/jdbc/pool/interceptor/QueryTimeoutInterceptor.java b/dblib/common/src/main/java/org/apache/tomcat/jdbc/pool/interceptor/QueryTimeoutInterceptor.java
new file mode 100644
index 0000000..7aec0b4
--- /dev/null
+++ b/dblib/common/src/main/java/org/apache/tomcat/jdbc/pool/interceptor/QueryTimeoutInterceptor.java
@@ -0,0 +1,77 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * openecomp
+ * ================================================================================
+ * Copyright (C) 2016 - 2017 AT&T
+ * ================================================================================
+ * Licensed 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.
+ * ============LICENSE_END=========================================================
+ */
+
+/*
+ *  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.tomcat.jdbc.pool.interceptor;
+
+import java.lang.reflect.Method;
+import java.sql.SQLException;
+import java.sql.Statement;
+import java.util.Map;
+
+import org.apache.juli.logging.Log;
+import org.apache.juli.logging.LogFactory;
+import org.apache.tomcat.jdbc.pool.PoolProperties.InterceptorProperty;
+
+public class QueryTimeoutInterceptor extends AbstractCreateStatementInterceptor {
+    private static Log log = LogFactory.getLog(QueryTimeoutInterceptor.class);
+    int timeout = 1;
+
+    @Override
+    public void setProperties(Map<String,InterceptorProperty> properties) {
+        super.setProperties(properties);
+        InterceptorProperty p = properties.get("queryTimeout");
+        if (p!=null) timeout = p.getValueAsInt(timeout);
+    }
+
+    @Override
+    public Object createStatement(Object proxy, Method method, Object[] args, Object statement, long time) {
+        if (statement instanceof Statement && timeout > 0) {
+            Statement s = (Statement)statement;
+            try {
+                s.setQueryTimeout(timeout);
+            }catch (SQLException x) {
+                log.warn("[QueryTimeoutInterceptor] Unable to set query timeout:"+x.getMessage(),x);
+            }
+        }
+        return statement;
+    }
+
+    @Override
+    public void closeInvoked() {
+    }
+
+}
diff --git a/dblib/common/src/main/java/org/apache/tomcat/jdbc/pool/interceptor/ResetAbandonedTimer.java b/dblib/common/src/main/java/org/apache/tomcat/jdbc/pool/interceptor/ResetAbandonedTimer.java
new file mode 100644
index 0000000..6c6981e
--- /dev/null
+++ b/dblib/common/src/main/java/org/apache/tomcat/jdbc/pool/interceptor/ResetAbandonedTimer.java
@@ -0,0 +1,112 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * openecomp
+ * ================================================================================
+ * Copyright (C) 2016 - 2017 AT&T
+ * ================================================================================
+ * Licensed 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.
+ * ============LICENSE_END=========================================================
+ */
+
+/*
+ *  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.tomcat.jdbc.pool.interceptor;
+
+import java.lang.reflect.Method;
+
+import org.apache.tomcat.jdbc.pool.JdbcInterceptor;
+import org.apache.tomcat.jdbc.pool.PooledConnection;
+import org.apache.tomcat.jdbc.pool.ProxyConnection;
+
+/**
+ * Class that resets the abandoned timer on any activity on the
+ * Connection or any successful query executions.
+ * This interceptor is useful for when you have a {@link org.apache.tomcat.jdbc.pool.PoolConfiguration#setRemoveAbandonedTimeout(int)}
+ * that is fairly low, and you want to reset the abandoned time each time any operation on the connection is performed
+ * This is useful for batch processing programs that use connections for extensive amount of times.
+ *
+ */
+public class ResetAbandonedTimer extends AbstractQueryReport {
+
+    public ResetAbandonedTimer() {
+    }
+
+    public boolean resetTimer() {
+        boolean result = false;
+        JdbcInterceptor interceptor = this.getNext();
+        while (interceptor!=null && result==false) {
+            if (interceptor instanceof ProxyConnection) {
+                PooledConnection con = ((ProxyConnection)interceptor).getConnection();
+                if (con!=null) {
+                    con.setTimestamp(System.currentTimeMillis());
+                    result = true;
+                } else {
+                    break;
+                }
+            }
+            interceptor = interceptor.getNext();
+        }
+        return result;
+    }
+
+
+    @Override
+    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
+        Object result = super.invoke(proxy, method, args);
+        resetTimer();
+        return result;
+    }
+
+    @Override
+    protected void prepareCall(String query, long time) {
+        resetTimer();
+    }
+
+    @Override
+    protected void prepareStatement(String sql, long time) {
+        resetTimer();
+
+    }
+
+    @Override
+    public void closeInvoked() {
+        resetTimer();
+    }
+
+    @Override
+    protected String reportQuery(String query, Object[] args, String name,long start, long delta) {
+        resetTimer();
+        return super.reportQuery(query, args, name, start, delta);
+    }
+
+    @Override
+    protected String reportSlowQuery(String query, Object[] args, String name,long start, long delta) {
+        resetTimer();
+        return super.reportSlowQuery(query, args, name, start, delta);
+    }
+}
diff --git a/dblib/common/src/main/java/org/apache/tomcat/jdbc/pool/interceptor/SlowQueryReport.java b/dblib/common/src/main/java/org/apache/tomcat/jdbc/pool/interceptor/SlowQueryReport.java
new file mode 100644
index 0000000..23fa3fa
--- /dev/null
+++ b/dblib/common/src/main/java/org/apache/tomcat/jdbc/pool/interceptor/SlowQueryReport.java
@@ -0,0 +1,516 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * openecomp
+ * ================================================================================
+ * Copyright (C) 2016 - 2017 AT&T
+ * ================================================================================
+ * Licensed 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.
+ * ============LICENSE_END=========================================================
+ */
+
+/*
+ * 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.tomcat.jdbc.pool.interceptor;
+
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.Locale;
+import java.util.Map;
+import java.util.TimeZone;
+import java.util.concurrent.ConcurrentHashMap;
+
+import javax.management.openmbean.CompositeDataSupport;
+import javax.management.openmbean.CompositeType;
+import javax.management.openmbean.OpenDataException;
+import javax.management.openmbean.OpenType;
+import javax.management.openmbean.SimpleType;
+
+import org.apache.juli.logging.Log;
+import org.apache.juli.logging.LogFactory;
+import org.apache.tomcat.jdbc.pool.ConnectionPool;
+import org.apache.tomcat.jdbc.pool.PoolProperties.InterceptorProperty;
+import org.apache.tomcat.jdbc.pool.PooledConnection;
+
+/**
+ * Slow query report interceptor. Tracks timing of query executions.
+ * @version 1.0
+ */
+public class SlowQueryReport extends AbstractQueryReport  {
+    //logger
+    private static final Log log = LogFactory.getLog(SlowQueryReport.class);
+
+    /**
+     * we will be keeping track of query stats on a per pool basis
+     */
+    protected static final ConcurrentHashMap<String,ConcurrentHashMap<String,QueryStats>> perPoolStats =
+        new ConcurrentHashMap<>();
+    /**
+     * the queries that are used for this interceptor.
+     */
+    protected volatile ConcurrentHashMap<String,QueryStats> queries = null;
+    /**
+     * Maximum number of queries we will be storing
+     */
+    protected int  maxQueries= 1000; //don't store more than this amount of queries
+
+    /**
+     * Flag to enable disable logging of slow queries
+     */
+    protected boolean logSlow = true;
+
+    /**
+     * Flag to enable disable logging of failed queries
+     */
+    protected boolean logFailed = false;
+
+    /**
+     * Sort QueryStats by last invocation time
+     */
+    protected final Comparator<QueryStats> queryStatsComparator = new QueryStatsComparator();
+
+    /**
+     * Returns the query stats for a given pool
+     * @param poolname - the name of the pool we want to retrieve stats for
+     * @return a hash map containing statistics for 0 to maxQueries
+     */
+    public static ConcurrentHashMap<String,QueryStats> getPoolStats(String poolname) {
+        return perPoolStats.get(poolname);
+    }
+
+    /**
+     * Creates a slow query report interceptor
+     */
+    public SlowQueryReport() {
+        super();
+    }
+
+    public void setMaxQueries(int maxQueries) {
+        this.maxQueries = maxQueries;
+    }
+
+
+    @Override
+    protected String reportFailedQuery(String query, Object[] args, String name, long start, Throwable t) {
+        String sql = super.reportFailedQuery(query, args, name, start, t);
+        if (this.maxQueries > 0 ) {
+            long now = System.currentTimeMillis();
+            long delta = now - start;
+            QueryStats qs = this.getQueryStats(sql);
+            if (qs != null) {
+                qs.failure(delta, now);
+                if (isLogFailed() && log.isWarnEnabled()) {
+                    log.warn("Failed Query Report SQL="+sql+"; time="+delta+" ms;");
+                }
+            }
+        }
+        return sql;
+    }
+
+    @Override
+    protected String reportQuery(String query, Object[] args, final String name, long start, long delta) {
+        String sql = super.reportQuery(query, args, name, start, delta);
+        if (this.maxQueries > 0 ) {
+            QueryStats qs = this.getQueryStats(sql);
+            if (qs != null) qs.add(delta, start);
+        }
+        return sql;
+    }
+
+    @Override
+    protected String reportSlowQuery(String query, Object[] args, String name, long start, long delta) {
+        String sql = super.reportSlowQuery(query, args, name, start, delta);
+        if (this.maxQueries > 0 ) {
+            QueryStats qs = this.getQueryStats(sql);
+            if (qs != null) {
+                qs.add(delta, start);
+                if (isLogSlow() && log.isWarnEnabled()) {
+                    log.warn("Slow Query Report SQL="+sql+"; time="+delta+" ms;");
+                }
+            }
+        }
+        return sql;
+    }
+
+    /**
+     * invoked when the connection receives the close request
+     * Not used for now.
+     */
+    @Override
+    public void closeInvoked() {
+        // NOOP
+    }
+
+    @Override
+    public void prepareStatement(String sql, long time) {
+        if (this.maxQueries > 0 ) {
+            QueryStats qs = getQueryStats(sql);
+            if (qs != null) qs.prepare(time);
+        }
+    }
+
+    @Override
+    public void prepareCall(String sql, long time) {
+        if (this.maxQueries > 0 ) {
+            QueryStats qs = getQueryStats(sql);
+            if (qs != null) qs.prepare(time);
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void poolStarted(ConnectionPool pool) {
+        super.poolStarted(pool);
+        //see if we already created a map for this pool
+        queries = SlowQueryReport.perPoolStats.get(pool.getName());
+        if (queries==null) {
+            //create the map to hold our stats
+            //however TODO we need to improve the eviction
+            //selection
+            queries = new ConcurrentHashMap<>();
+            if (perPoolStats.putIfAbsent(pool.getName(), queries)!=null) {
+                //there already was one
+                queries = SlowQueryReport.perPoolStats.get(pool.getName());
+            }
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void poolClosed(ConnectionPool pool) {
+        perPoolStats.remove(pool.getName());
+        super.poolClosed(pool);
+    }
+
+    protected QueryStats getQueryStats(String sql) {
+        if (sql==null) sql = "";
+        ConcurrentHashMap<String,QueryStats> queries = SlowQueryReport.this.queries;
+        if (queries==null) {
+            if (log.isWarnEnabled()) log.warn("Connection has already been closed or abandoned");
+            return null;
+        }
+        QueryStats qs = queries.get(sql);
+        if (qs == null) {
+            qs = new QueryStats(sql);
+            if (queries.putIfAbsent(sql,qs)!=null) {
+                qs = queries.get(sql);
+            } else {
+                //we added a new element, see if we need to remove the oldest
+                if (queries.size() > maxQueries) {
+                    removeOldest(queries);
+                }
+            }
+        }
+        return qs;
+    }
+
+    /**
+     * Sort QueryStats by last invocation time
+     * @param queries The queries map
+     */
+    protected void removeOldest(ConcurrentHashMap<String,QueryStats> queries) {
+        ArrayList<QueryStats> list = new ArrayList<>(queries.values());
+        Collections.sort(list, queryStatsComparator);
+        int removeIndex = 0;
+        while (queries.size() > maxQueries) {
+            String sql = list.get(removeIndex).getQuery();
+            queries.remove(sql);
+            if (log.isDebugEnabled()) log.debug("Removing slow query, capacity reached:"+sql);
+            removeIndex++;
+        }
+    }
+
+
+    @Override
+    public void reset(ConnectionPool parent, PooledConnection con) {
+        super.reset(parent, con);
+        if (parent!=null)
+            queries = SlowQueryReport.perPoolStats.get(parent.getName());
+        else
+            queries = null;
+    }
+
+
+    public boolean isLogSlow() {
+        return logSlow;
+    }
+
+    public void setLogSlow(boolean logSlow) {
+        this.logSlow = logSlow;
+    }
+
+    public boolean isLogFailed() {
+        return logFailed;
+    }
+
+    public void setLogFailed(boolean logFailed) {
+        this.logFailed = logFailed;
+    }
+
+    @Override
+    public void setProperties(Map<String, InterceptorProperty> properties) {
+        super.setProperties(properties);
+        final String threshold = "threshold";
+        final String maxqueries= "maxQueries";
+        final String logslow = "logSlow";
+        final String logfailed = "logFailed";
+        InterceptorProperty p1 = properties.get(threshold);
+        InterceptorProperty p2 = properties.get(maxqueries);
+        InterceptorProperty p3 = properties.get(logslow);
+        InterceptorProperty p4 = properties.get(logfailed);
+        if (p1!=null) {
+            setThreshold(Long.parseLong(p1.getValue()));
+        }
+        if (p2!=null) {
+            setMaxQueries(Integer.parseInt(p2.getValue()));
+        }
+        if (p3!=null) {
+            setLogSlow(Boolean.parseBoolean(p3.getValue()));
+        }
+        if (p4!=null) {
+            setLogFailed(Boolean.parseBoolean(p4.getValue()));
+        }
+    }
+
+
+    public static class QueryStats {
+        static final String[] FIELD_NAMES = new String[] {
+            "query",
+            "nrOfInvocations",
+            "maxInvocationTime",
+            "maxInvocationDate",
+            "minInvocationTime",
+            "minInvocationDate",
+            "totalInvocationTime",
+            "failures",
+            "prepareCount",
+            "prepareTime",
+            "lastInvocation"
+        };
+
+        static final  String[] FIELD_DESCRIPTIONS = new String[] {
+            "The SQL query",
+            "The number of query invocations, a call to executeXXX",
+            "The longest time for this query in milliseconds",
+            "The time and date for when the longest query took place",
+            "The shortest time for this query in milliseconds",
+            "The time and date for when the shortest query took place",
+            "The total amount of milliseconds spent executing this query",
+            "The number of failures for this query",
+            "The number of times this query was prepared (prepareStatement/prepareCall)",
+            "The total number of milliseconds spent preparing this query",
+            "The date and time of the last invocation"
+        };
+
+        static final OpenType<?>[] FIELD_TYPES = new OpenType[] {
+            SimpleType.STRING,
+            SimpleType.INTEGER,
+            SimpleType.LONG,
+            SimpleType.LONG,
+            SimpleType.LONG,
+            SimpleType.LONG,
+            SimpleType.LONG,
+            SimpleType.LONG,
+            SimpleType.INTEGER,
+            SimpleType.LONG,
+            SimpleType.LONG
+        };
+
+        private final String query;
+        private volatile int nrOfInvocations;
+        private volatile long maxInvocationTime = Long.MIN_VALUE;
+        private volatile long maxInvocationDate;
+        private volatile long minInvocationTime = Long.MAX_VALUE;
+        private volatile long minInvocationDate;
+        private volatile long totalInvocationTime;
+        private volatile long failures;
+        private volatile int prepareCount;
+        private volatile long prepareTime;
+        private volatile long lastInvocation = 0;
+
+        public static String[] getFieldNames() {
+            return FIELD_NAMES;
+        }
+
+        public static String[] getFieldDescriptions() {
+            return FIELD_DESCRIPTIONS;
+        }
+
+        public static OpenType<?>[] getFieldTypes() {
+            return FIELD_TYPES;
+        }
+
+        @Override
+        public String toString() {
+            SimpleDateFormat sdf =
+                    new SimpleDateFormat("d MMM yyyy HH:mm:ss z", Locale.US);
+            sdf.setTimeZone(TimeZone.getTimeZone("GMT"));
+            StringBuilder buf = new StringBuilder("QueryStats[query:");
+            buf.append(query);
+            buf.append(", nrOfInvocations:");
+            buf.append(nrOfInvocations);
+            buf.append(", maxInvocationTime:");
+            buf.append(maxInvocationTime);
+            buf.append(", maxInvocationDate:");
+            buf.append(sdf.format(new java.util.Date(maxInvocationDate)));
+            buf.append(", minInvocationTime:");
+            buf.append(minInvocationTime);
+            buf.append(", minInvocationDate:");
+            buf.append(sdf.format(new java.util.Date(minInvocationDate)));
+            buf.append(", totalInvocationTime:");
+            buf.append(totalInvocationTime);
+            buf.append(", averageInvocationTime:");
+            buf.append((float)totalInvocationTime / (float)nrOfInvocations);
+            buf.append(", failures:");
+            buf.append(failures);
+            buf.append(", prepareCount:");
+            buf.append(prepareCount);
+            buf.append(", prepareTime:");
+            buf.append(prepareTime);
+            buf.append("]");
+            return buf.toString();
+        }
+
+        public CompositeDataSupport getCompositeData(final CompositeType type) throws OpenDataException{
+            Object[] values = new Object[] {
+                    query,
+                    Integer.valueOf(nrOfInvocations),
+                    Long.valueOf(maxInvocationTime),
+                    Long.valueOf(maxInvocationDate),
+                    Long.valueOf(minInvocationTime),
+                    Long.valueOf(minInvocationDate),
+                    Long.valueOf(totalInvocationTime),
+                    Long.valueOf(failures),
+                    Integer.valueOf(prepareCount),
+                    Long.valueOf(prepareTime),
+                    Long.valueOf(lastInvocation)
+            };
+            return new CompositeDataSupport(type,FIELD_NAMES,values);
+        }
+
+        public QueryStats(String query) {
+            this.query = query;
+        }
+
+        public void prepare(long invocationTime) {
+            prepareCount++;
+            prepareTime+=invocationTime;
+
+        }
+
+        public void add(long invocationTime, long now) {
+            //not thread safe, but don't sacrifice performance for this kind of stuff
+            maxInvocationTime = Math.max(invocationTime, maxInvocationTime);
+            if (maxInvocationTime == invocationTime) {
+                maxInvocationDate = now;
+            }
+            minInvocationTime = Math.min(invocationTime, minInvocationTime);
+            if (minInvocationTime==invocationTime) {
+                minInvocationDate = now;
+            }
+            nrOfInvocations++;
+            totalInvocationTime+=invocationTime;
+            lastInvocation = now;
+        }
+
+        public void failure(long invocationTime, long now) {
+            add(invocationTime,now);
+            failures++;
+
+        }
+
+        public String getQuery() {
+            return query;
+        }
+
+        public int getNrOfInvocations() {
+            return nrOfInvocations;
+        }
+
+        public long getMaxInvocationTime() {
+            return maxInvocationTime;
+        }
+
+        public long getMaxInvocationDate() {
+            return maxInvocationDate;
+        }
+
+        public long getMinInvocationTime() {
+            return minInvocationTime;
+        }
+
+        public long getMinInvocationDate() {
+            return minInvocationDate;
+        }
+
+        public long getTotalInvocationTime() {
+            return totalInvocationTime;
+        }
+
+        @Override
+        public int hashCode() {
+            return query.hashCode();
+        }
+
+        @Override
+        public boolean equals(Object other) {
+            if (other instanceof QueryStats) {
+                QueryStats qs = (QueryStats)other;
+                return qs.query.equals(this.query);
+            }
+            return false;
+        }
+
+        public boolean isOlderThan(QueryStats other) {
+            return this.lastInvocation < other.lastInvocation;
+        }
+    }
+
+    /** Compare QueryStats by their lastInvocation value. QueryStats that
+     * have never been updated, have a lastInvocation value of {@code 0}
+     * which should be handled as the newest possible invocation.
+     */
+    private static class QueryStatsComparator implements Comparator<QueryStats> {
+
+        @Override
+        public int compare(QueryStats stats1, QueryStats stats2) {
+            return Long.compare(handleZero(stats1.lastInvocation),
+                    handleZero(stats2.lastInvocation));
+        }
+
+        private static long handleZero(long value) {
+            return value == 0 ? Long.MAX_VALUE : value;
+        }
+
+    }
+
+}
diff --git a/dblib/common/src/main/java/org/apache/tomcat/jdbc/pool/interceptor/SlowQueryReportJmx.java b/dblib/common/src/main/java/org/apache/tomcat/jdbc/pool/interceptor/SlowQueryReportJmx.java
new file mode 100644
index 0000000..60b48a0
--- /dev/null
+++ b/dblib/common/src/main/java/org/apache/tomcat/jdbc/pool/interceptor/SlowQueryReportJmx.java
@@ -0,0 +1,338 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * openecomp
+ * ================================================================================
+ * Copyright (C) 2016 - 2017 AT&T
+ * ================================================================================
+ * Licensed 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.
+ * ============LICENSE_END=========================================================
+ */
+
+/*
+ * 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.tomcat.jdbc.pool.interceptor;
+
+import java.lang.management.ManagementFactory;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.atomic.AtomicLong;
+
+import javax.management.InstanceAlreadyExistsException;
+import javax.management.InstanceNotFoundException;
+import javax.management.ListenerNotFoundException;
+import javax.management.MBeanException;
+import javax.management.MBeanNotificationInfo;
+import javax.management.MBeanRegistrationException;
+import javax.management.MalformedObjectNameException;
+import javax.management.NotCompliantMBeanException;
+import javax.management.Notification;
+import javax.management.NotificationBroadcasterSupport;
+import javax.management.NotificationEmitter;
+import javax.management.NotificationFilter;
+import javax.management.NotificationListener;
+import javax.management.ObjectName;
+import javax.management.RuntimeOperationsException;
+import javax.management.openmbean.CompositeData;
+import javax.management.openmbean.CompositeDataSupport;
+import javax.management.openmbean.CompositeType;
+import javax.management.openmbean.OpenDataException;
+
+import org.apache.juli.logging.Log;
+import org.apache.juli.logging.LogFactory;
+import org.apache.tomcat.jdbc.pool.ConnectionPool;
+import org.apache.tomcat.jdbc.pool.PoolProperties.InterceptorProperty;
+import org.apache.tomcat.jdbc.pool.PooledConnection;
+/**
+ * Publishes data to JMX and provides notifications
+ * when failures happen.
+ *
+ */
+public class SlowQueryReportJmx extends SlowQueryReport implements NotificationEmitter, SlowQueryReportJmxMBean{
+    public static final String SLOW_QUERY_NOTIFICATION = "SLOW QUERY";
+    public static final String FAILED_QUERY_NOTIFICATION = "FAILED QUERY";
+
+    public static final String objectNameAttribute = "objectName";
+
+    protected static volatile CompositeType SLOW_QUERY_TYPE;
+
+    private static final Log log = LogFactory.getLog(SlowQueryReportJmx.class);
+
+
+    protected static final ConcurrentHashMap<String,SlowQueryReportJmxMBean> mbeans =
+        new ConcurrentHashMap<>();
+
+
+    //==============================JMX STUFF========================
+    protected volatile NotificationBroadcasterSupport notifier = new NotificationBroadcasterSupport();
+
+    @Override
+    public void addNotificationListener(NotificationListener listener, NotificationFilter filter, Object handback) throws IllegalArgumentException {
+        notifier.addNotificationListener(listener, filter, handback);
+    }
+
+
+    @Override
+    public MBeanNotificationInfo[] getNotificationInfo() {
+        return notifier.getNotificationInfo();
+    }
+
+    @Override
+    public void removeNotificationListener(NotificationListener listener) throws ListenerNotFoundException {
+        notifier.removeNotificationListener(listener);
+
+    }
+
+    @Override
+    public void removeNotificationListener(NotificationListener listener, NotificationFilter filter, Object handback) throws ListenerNotFoundException {
+        notifier.removeNotificationListener(listener, filter, handback);
+
+    }
+
+
+    //==============================JMX STUFF========================
+
+    protected String poolName = null;
+
+    protected static final AtomicLong notifySequence = new AtomicLong(0);
+
+    protected boolean notifyPool = true;
+
+    protected ConnectionPool pool = null;
+
+    protected static CompositeType getCompositeType() {
+        if (SLOW_QUERY_TYPE==null) {
+            try {
+                SLOW_QUERY_TYPE = new CompositeType(
+                        SlowQueryReportJmx.class.getName(),
+                        "Composite data type for query statistics",
+                        QueryStats.getFieldNames(),
+                        QueryStats.getFieldDescriptions(),
+                        QueryStats.getFieldTypes());
+            }catch (OpenDataException x) {
+                log.warn("Unable to initialize composite data type for JMX stats and notifications.",x);
+            }
+        }
+        return SLOW_QUERY_TYPE;
+    }
+
+    @Override
+    public void reset(ConnectionPool parent, PooledConnection con) {
+        super.reset(parent, con);
+        if (parent!=null) {
+            poolName = parent.getName();
+            pool = parent;
+            registerJmx();
+        }
+    }
+
+
+    @Override
+    public void poolClosed(ConnectionPool pool) {
+        this.poolName = pool.getName();
+        deregisterJmx();
+        super.poolClosed(pool);
+    }
+
+    @Override
+    public void poolStarted(ConnectionPool pool) {
+        this.pool = pool;
+        super.poolStarted(pool);
+        this.poolName = pool.getName();
+    }
+
+    @Override
+    protected String reportFailedQuery(String query, Object[] args, String name, long start, Throwable t) {
+        query = super.reportFailedQuery(query, args, name, start, t);
+        if (isLogFailed()) notifyJmx(query,FAILED_QUERY_NOTIFICATION);
+        return query;
+    }
+
+    protected void notifyJmx(String query, String type) {
+        try {
+            long sequence = notifySequence.incrementAndGet();
+
+            if (isNotifyPool()) {
+                if (this.pool!=null && this.pool.getJmxPool()!=null) {
+                    this.pool.getJmxPool().notify(type, query);
+                }
+            } else {
+                if (notifier!=null) {
+                    Notification notification =
+                        new Notification(type,
+                                         this,
+                                         sequence,
+                                         System.currentTimeMillis(),
+                                         query);
+
+                    notifier.sendNotification(notification);
+                }
+            }
+        } catch (RuntimeOperationsException e) {
+            if (log.isDebugEnabled()) {
+                log.debug("Unable to send failed query notification.",e);
+            }
+        }
+    }
+
+    @Override
+    protected String reportSlowQuery(String query, Object[] args, String name, long start, long delta) {
+        query = super.reportSlowQuery(query, args, name, start, delta);
+        if (isLogSlow()) notifyJmx(query,SLOW_QUERY_NOTIFICATION);
+        return query;
+    }
+
+    /**
+     * JMX operation - return the names of all the pools
+     * @return - all the names of pools that we have stored data for
+     */
+    public String[] getPoolNames() {
+        Set<String> keys = perPoolStats.keySet();
+        return keys.toArray(new String[0]);
+    }
+
+    /**
+     * JMX operation - return the name of the pool
+     * @return the name of the pool, unique within the JVM
+     */
+    public String getPoolName() {
+        return poolName;
+    }
+
+
+    public boolean isNotifyPool() {
+        return notifyPool;
+    }
+
+    public void setNotifyPool(boolean notifyPool) {
+        this.notifyPool = notifyPool;
+    }
+
+    /**
+     * JMX operation - remove all stats for this connection pool
+     */
+    public void resetStats() {
+        ConcurrentHashMap<String,QueryStats> queries = perPoolStats.get(poolName);
+        if (queries!=null) {
+            Iterator<String> it = queries.keySet().iterator();
+            while (it.hasNext()) it.remove();
+        }
+    }
+
+    /**
+     * JMX operation - returns all the queries we have collected.
+     * @return - the slow query report as composite data.
+     */
+    @Override
+    public CompositeData[] getSlowQueriesCD() throws OpenDataException {
+        CompositeDataSupport[] result = null;
+        ConcurrentHashMap<String,QueryStats> queries = perPoolStats.get(poolName);
+        if (queries!=null) {
+            Set<Map.Entry<String,QueryStats>> stats = queries.entrySet();
+            if (stats!=null) {
+                result = new CompositeDataSupport[stats.size()];
+                Iterator<Map.Entry<String,QueryStats>> it = stats.iterator();
+                int pos = 0;
+                while (it.hasNext()) {
+                    Map.Entry<String,QueryStats> entry = it.next();
+                    QueryStats qs = entry.getValue();
+                    result[pos++] = qs.getCompositeData(getCompositeType());
+                }
+            }
+        }
+        return result;
+    }
+
+    protected void deregisterJmx() {
+        try {
+            if (mbeans.remove(poolName)!=null) {
+                ObjectName oname = getObjectName(getClass(),poolName);
+                ManagementFactory.getPlatformMBeanServer().unregisterMBean(oname);
+            }
+        } catch (MBeanRegistrationException e) {
+            log.debug("Jmx deregistration failed.",e);
+        } catch (InstanceNotFoundException e) {
+            log.debug("Jmx deregistration failed.",e);
+        } catch (MalformedObjectNameException e) {
+            log.warn("Jmx deregistration failed.",e);
+        } catch (RuntimeOperationsException e) {
+            log.warn("Jmx deregistration failed.",e);
+        }
+
+    }
+
+
+    public ObjectName getObjectName(Class<?> clazz, String poolName) throws MalformedObjectNameException {
+        ObjectName oname;
+        Map<String,InterceptorProperty> properties = getProperties();
+        if (properties != null && properties.containsKey(objectNameAttribute)) {
+            oname = new ObjectName(properties.get(objectNameAttribute).getValue());
+        } else {
+            oname = new ObjectName(ConnectionPool.POOL_JMX_TYPE_PREFIX+clazz.getName()+",name=" + poolName);
+        }
+        return oname;
+    }
+
+    protected void registerJmx() {
+        try {
+            //only if we notify the pool itself
+            if (isNotifyPool()) {
+
+            } else if (getCompositeType()!=null) {
+                ObjectName oname = getObjectName(getClass(),poolName);
+                if (mbeans.putIfAbsent(poolName, this)==null) {
+                    ManagementFactory.getPlatformMBeanServer().registerMBean(this, oname);
+                }
+            } else {
+                log.warn(SlowQueryReport.class.getName()+ "- No JMX support, composite type was not found.");
+            }
+        } catch (MalformedObjectNameException e) {
+            log.error("Jmx registration failed, no JMX data will be exposed for the query stats.",e);
+        } catch (RuntimeOperationsException e) {
+            log.error("Jmx registration failed, no JMX data will be exposed for the query stats.",e);
+        } catch (MBeanException e) {
+            log.error("Jmx registration failed, no JMX data will be exposed for the query stats.",e);
+        } catch (InstanceAlreadyExistsException e) {
+            log.error("Jmx registration failed, no JMX data will be exposed for the query stats.",e);
+        } catch (NotCompliantMBeanException e) {
+            log.error("Jmx registration failed, no JMX data will be exposed for the query stats.",e);
+        }
+    }
+
+    @Override
+    public void setProperties(Map<String, InterceptorProperty> properties) {
+        super.setProperties(properties);
+        final String threshold = "notifyPool";
+        InterceptorProperty p1 = properties.get(threshold);
+        if (p1!=null) {
+            this.setNotifyPool(Boolean.parseBoolean(p1.getValue()));
+        }
+    }
+
+
+}
diff --git a/dblib/common/src/main/java/org/apache/tomcat/jdbc/pool/interceptor/SlowQueryReportJmxMBean.java b/dblib/common/src/main/java/org/apache/tomcat/jdbc/pool/interceptor/SlowQueryReportJmxMBean.java
new file mode 100644
index 0000000..202d06e
--- /dev/null
+++ b/dblib/common/src/main/java/org/apache/tomcat/jdbc/pool/interceptor/SlowQueryReportJmxMBean.java
@@ -0,0 +1,43 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * openecomp
+ * ================================================================================
+ * Copyright (C) 2016 - 2017 AT&T
+ * ================================================================================
+ * Licensed 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.
+ * ============LICENSE_END=========================================================
+ */
+
+/* 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.tomcat.jdbc.pool.interceptor;
+
+import javax.management.openmbean.CompositeData;
+import javax.management.openmbean.OpenDataException;
+
+public interface SlowQueryReportJmxMBean {
+    public CompositeData[] getSlowQueriesCD() throws OpenDataException;
+}
diff --git a/dblib/common/src/main/java/org/apache/tomcat/jdbc/pool/interceptor/StatementCache.java b/dblib/common/src/main/java/org/apache/tomcat/jdbc/pool/interceptor/StatementCache.java
new file mode 100644
index 0000000..e98d3b6
--- /dev/null
+++ b/dblib/common/src/main/java/org/apache/tomcat/jdbc/pool/interceptor/StatementCache.java
@@ -0,0 +1,358 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * openecomp
+ * ================================================================================
+ * Copyright (C) 2016 - 2017 AT&T
+ * ================================================================================
+ * Licensed 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.
+ * ============LICENSE_END=========================================================
+ */
+
+/* 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.tomcat.jdbc.pool.interceptor;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.sql.ResultSet;
+import java.sql.Statement;
+import java.util.Arrays;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import org.apache.tomcat.jdbc.pool.ConnectionPool;
+import org.apache.tomcat.jdbc.pool.PoolProperties.InterceptorProperty;
+import org.apache.tomcat.jdbc.pool.PooledConnection;
+
+/**
+ * Interceptor that caches {@code PreparedStatement} and/or
+ * {@code CallableStatement} instances on a connection.
+ */
+public class StatementCache extends StatementDecoratorInterceptor {
+    protected static final String[] ALL_TYPES = new String[] {PREPARE_STATEMENT,PREPARE_CALL};
+    protected static final String[] CALLABLE_TYPE = new String[] {PREPARE_CALL};
+    protected static final String[] PREPARED_TYPE = new String[] {PREPARE_STATEMENT};
+    protected static final String[] NO_TYPE = new String[] {};
+
+    protected static final String STATEMENT_CACHE_ATTR = StatementCache.class.getName() + ".cache";
+
+    /*begin properties for the statement cache*/
+    private boolean cachePrepared = true;
+    private boolean cacheCallable = false;
+    private int maxCacheSize = 50;
+    private PooledConnection pcon;
+    private String[] types;
+
+
+    public boolean isCachePrepared() {
+        return cachePrepared;
+    }
+
+    public boolean isCacheCallable() {
+        return cacheCallable;
+    }
+
+    public int getMaxCacheSize() {
+        return maxCacheSize;
+    }
+
+    public String[] getTypes() {
+        return types;
+    }
+
+    public AtomicInteger getCacheSize() {
+        return cacheSize;
+    }
+
+    @Override
+    public void setProperties(Map<String, InterceptorProperty> properties) {
+        super.setProperties(properties);
+        InterceptorProperty p = properties.get("prepared");
+        if (p!=null) cachePrepared = p.getValueAsBoolean(cachePrepared);
+        p = properties.get("callable");
+        if (p!=null) cacheCallable = p.getValueAsBoolean(cacheCallable);
+        p = properties.get("max");
+        if (p!=null) maxCacheSize = p.getValueAsInt(maxCacheSize);
+        if (cachePrepared && cacheCallable) {
+            this.types = ALL_TYPES;
+        } else if (cachePrepared) {
+            this.types = PREPARED_TYPE;
+        } else if (cacheCallable) {
+            this.types = CALLABLE_TYPE;
+        } else {
+            this.types = NO_TYPE;
+        }
+
+    }
+    /*end properties for the statement cache*/
+
+    /*begin the cache size*/
+    private static ConcurrentHashMap<ConnectionPool,AtomicInteger> cacheSizeMap =
+        new ConcurrentHashMap<>();
+
+    private AtomicInteger cacheSize;
+
+    @Override
+    public void poolStarted(ConnectionPool pool) {
+        cacheSizeMap.putIfAbsent(pool, new AtomicInteger(0));
+        super.poolStarted(pool);
+    }
+
+    @Override
+    public void poolClosed(ConnectionPool pool) {
+        cacheSizeMap.remove(pool);
+        super.poolClosed(pool);
+    }
+    /*end the cache size*/
+
+    /*begin the actual statement cache*/
+    @Override
+    public void reset(ConnectionPool parent, PooledConnection con) {
+        super.reset(parent, con);
+        if (parent==null) {
+            cacheSize = null;
+            this.pcon = null;
+        } else {
+            cacheSize = cacheSizeMap.get(parent);
+            this.pcon = con;
+            if (!pcon.getAttributes().containsKey(STATEMENT_CACHE_ATTR)) {
+                ConcurrentHashMap<CacheKey,CachedStatement> cache =
+                        new ConcurrentHashMap<>();
+                pcon.getAttributes().put(STATEMENT_CACHE_ATTR,cache);
+            }
+        }
+    }
+
+    @Override
+    public void disconnected(ConnectionPool parent, PooledConnection con, boolean finalizing) {
+        @SuppressWarnings("unchecked")
+        ConcurrentHashMap<CacheKey,CachedStatement> statements =
+            (ConcurrentHashMap<CacheKey,CachedStatement>)con.getAttributes().get(STATEMENT_CACHE_ATTR);
+
+        if (statements!=null) {
+            for (Map.Entry<CacheKey, CachedStatement> p : statements.entrySet()) {
+                closeStatement(p.getValue());
+            }
+            statements.clear();
+        }
+
+        super.disconnected(parent, con, finalizing);
+    }
+
+    public void closeStatement(CachedStatement st) {
+        if (st==null) return;
+        st.forceClose();
+    }
+
+    @Override
+    protected Object createDecorator(Object proxy, Method method, Object[] args,
+                                     Object statement, Constructor<?> constructor, String sql)
+    throws InstantiationException, IllegalAccessException, InvocationTargetException {
+        boolean process = process(this.types, method, false);
+        if (process) {
+            Object result = null;
+            CachedStatement statementProxy = new CachedStatement((Statement)statement,sql);
+            result = constructor.newInstance(new Object[] { statementProxy });
+            statementProxy.setActualProxy(result);
+            statementProxy.setConnection(proxy);
+            statementProxy.setConstructor(constructor);
+            statementProxy.setCacheKey(createCacheKey(method, args));
+            return result;
+        } else {
+            return super.createDecorator(proxy, method, args, statement, constructor, sql);
+        }
+    }
+
+    @Override
+    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
+        boolean process = process(this.types, method, false);
+        if (process && args.length>0 && args[0] instanceof String) {
+            CachedStatement statement = isCached(method, args);
+            if (statement!=null) {
+                //remove it from the cache since it is used
+                removeStatement(statement);
+                return statement.getActualProxy();
+            } else {
+                return super.invoke(proxy, method, args);
+            }
+        } else {
+            return super.invoke(proxy,method,args);
+        }
+    }
+
+    public CachedStatement isCached(Method method, Object[] args) {
+        @SuppressWarnings("unchecked")
+        ConcurrentHashMap<CacheKey,CachedStatement> cache =
+            (ConcurrentHashMap<CacheKey,CachedStatement>)pcon.getAttributes().get(STATEMENT_CACHE_ATTR);
+        return cache.get(createCacheKey(method, args));
+    }
+
+    public boolean cacheStatement(CachedStatement proxy) {
+        @SuppressWarnings("unchecked")
+        ConcurrentHashMap<CacheKey,CachedStatement> cache =
+            (ConcurrentHashMap<CacheKey,CachedStatement>)pcon.getAttributes().get(STATEMENT_CACHE_ATTR);
+        if (proxy.getCacheKey()==null) {
+            return false;
+        } else if (cache.containsKey(proxy.getCacheKey())) {
+            return false;
+        } else if (cacheSize.get()>=maxCacheSize) {
+            return false;
+        } else if (cacheSize.incrementAndGet()>maxCacheSize) {
+            cacheSize.decrementAndGet();
+            return false;
+        } else {
+            //cache the statement
+            cache.put(proxy.getCacheKey(), proxy);
+            return true;
+        }
+    }
+
+    public boolean removeStatement(CachedStatement proxy) {
+        @SuppressWarnings("unchecked")
+        ConcurrentHashMap<CacheKey,CachedStatement> cache =
+            (ConcurrentHashMap<CacheKey,CachedStatement>)pcon.getAttributes().get(STATEMENT_CACHE_ATTR);
+        if (cache.remove(proxy.getCacheKey()) != null) {
+            cacheSize.decrementAndGet();
+            return true;
+        } else {
+            return false;
+        }
+    }
+    /*end the actual statement cache*/
+
+
+    protected class CachedStatement extends StatementDecoratorInterceptor.StatementProxy<Statement> {
+        boolean cached = false;
+        CacheKey key;
+        public CachedStatement(Statement parent, String sql) {
+            super(parent, sql);
+        }
+
+        @Override
+        public void closeInvoked() {
+            //should we cache it
+            boolean shouldClose = true;
+            if (cacheSize.get() < maxCacheSize) {
+                //cache a proxy so that we don't reuse the facade
+                CachedStatement proxy = new CachedStatement(getDelegate(),getSql());
+                proxy.setCacheKey(getCacheKey());
+                try {
+                    // clear Resultset
+                    ResultSet result = getDelegate().getResultSet();
+                    if (result != null && !result.isClosed()) {
+                        result.close();
+                    }
+                    //create a new facade
+                    Object actualProxy = getConstructor().newInstance(new Object[] { proxy });
+                    proxy.setActualProxy(actualProxy);
+                    proxy.setConnection(getConnection());
+                    proxy.setConstructor(getConstructor());
+                    if (cacheStatement(proxy)) {
+                        proxy.cached = true;
+                        shouldClose = false;
+                    }
+                } catch (Exception x) {
+                    removeStatement(proxy);
+                }
+            }
+            if (shouldClose) {
+                super.closeInvoked();
+            }
+            closed = true;
+            delegate = null;
+
+        }
+
+        public void forceClose() {
+            removeStatement(this);
+            super.closeInvoked();
+        }
+
+        public CacheKey getCacheKey() {
+            return key;
+        }
+
+        public void setCacheKey(CacheKey cacheKey) {
+            key = cacheKey;
+        }
+
+    }
+
+    protected CacheKey createCacheKey(Method method, Object[] args) {
+        return createCacheKey(method.getName(), args);
+    }
+
+    protected CacheKey createCacheKey(String methodName, Object[] args) {
+        CacheKey key = null;
+        if (compare(PREPARE_STATEMENT, methodName)) {
+            key = new CacheKey(PREPARE_STATEMENT, args);
+        } else if (compare(PREPARE_CALL, methodName)) {
+            key = new CacheKey(PREPARE_CALL, args);
+        }
+        return key;
+    }
+
+
+    private static final class CacheKey {
+        private final String stmtType;
+        private final Object[] args;
+        private CacheKey(String type, Object[] methodArgs) {
+            stmtType = type;
+            args = methodArgs;
+        }
+
+        @Override
+        public int hashCode() {
+            final int prime = 31;
+            int result = 1;
+            result = prime * result + Arrays.hashCode(args);
+            result = prime * result
+                    + ((stmtType == null) ? 0 : stmtType.hashCode());
+            return result;
+        }
+
+        @Override
+        public boolean equals(Object obj) {
+            if (this == obj)
+                return true;
+            if (obj == null)
+                return false;
+            if (getClass() != obj.getClass())
+                return false;
+            CacheKey other = (CacheKey) obj;
+            if (!Arrays.equals(args, other.args))
+                return false;
+            if (stmtType == null) {
+                if (other.stmtType != null)
+                    return false;
+            } else if (!stmtType.equals(other.stmtType))
+                return false;
+            return true;
+        }
+    }
+}
diff --git a/dblib/common/src/main/java/org/apache/tomcat/jdbc/pool/interceptor/StatementDecoratorInterceptor.java b/dblib/common/src/main/java/org/apache/tomcat/jdbc/pool/interceptor/StatementDecoratorInterceptor.java
new file mode 100644
index 0000000..e3b160b
--- /dev/null
+++ b/dblib/common/src/main/java/org/apache/tomcat/jdbc/pool/interceptor/StatementDecoratorInterceptor.java
@@ -0,0 +1,342 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * openecomp
+ * ================================================================================
+ * Copyright (C) 2016 - 2017 AT&T
+ * ================================================================================
+ * Licensed 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.
+ * ============LICENSE_END=========================================================
+ */
+
+/*
+ * 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.tomcat.jdbc.pool.interceptor;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.lang.reflect.Proxy;
+import java.sql.CallableStatement;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Statement;
+
+import org.apache.juli.logging.Log;
+import org.apache.juli.logging.LogFactory;
+
+/**
+ * Implementation of <b>JdbcInterceptor</b> that proxies resultSets and statements.
+ * @author Guillermo Fernandes
+ */
+public class StatementDecoratorInterceptor extends AbstractCreateStatementInterceptor {
+
+    private static final Log logger = LogFactory.getLog(StatementDecoratorInterceptor.class);
+
+    protected static final String EXECUTE_QUERY  = "executeQuery";
+    protected static final String GET_GENERATED_KEYS = "getGeneratedKeys";
+    protected static final String GET_RESULTSET  = "getResultSet";
+
+    protected static final String[] RESULTSET_TYPES = {EXECUTE_QUERY, GET_GENERATED_KEYS, GET_RESULTSET};
+
+    /**
+     * the constructors that are used to create statement proxies
+     */
+    protected static final Constructor<?>[] constructors = new Constructor[AbstractCreateStatementInterceptor.STATEMENT_TYPE_COUNT];
+
+    /**
+     * the constructor to create the resultSet proxies
+     */
+    protected static Constructor<?> resultSetConstructor = null;
+
+    @Override
+    public void closeInvoked() {
+        // nothing to do
+    }
+
+    /**
+     * Creates a constructor for a proxy class, if one doesn't already exist
+     *
+     * @param idx
+     *            - the index of the constructor
+     * @param clazz
+     *            - the interface that the proxy will implement
+     * @return - returns a constructor used to create new instances
+     * @throws NoSuchMethodException Constructor not found
+     */
+    protected Constructor<?> getConstructor(int idx, Class<?> clazz) throws NoSuchMethodException {
+        if (constructors[idx] == null) {
+            Class<?> proxyClass = Proxy.getProxyClass(StatementDecoratorInterceptor.class.getClassLoader(),
+                    new Class[] { clazz });
+            constructors[idx] = proxyClass.getConstructor(new Class[] { InvocationHandler.class });
+        }
+        return constructors[idx];
+    }
+
+    protected Constructor<?> getResultSetConstructor() throws NoSuchMethodException {
+        if (resultSetConstructor == null) {
+            Class<?> proxyClass = Proxy.getProxyClass(StatementDecoratorInterceptor.class.getClassLoader(),
+                    new Class[] { ResultSet.class });
+            resultSetConstructor = proxyClass.getConstructor(new Class[] { InvocationHandler.class });
+        }
+        return resultSetConstructor;
+    }
+
+    /**
+     * Creates a statement interceptor to monitor query response times
+     */
+    @Override
+    public Object createStatement(Object proxy, Method method, Object[] args, Object statement, long time) {
+        try {
+            String name = method.getName();
+            Constructor<?> constructor = null;
+            String sql = null;
+            if (compare(CREATE_STATEMENT, name)) {
+                // createStatement
+                constructor = getConstructor(CREATE_STATEMENT_IDX, Statement.class);
+            } else if (compare(PREPARE_STATEMENT, name)) {
+                // prepareStatement
+                constructor = getConstructor(PREPARE_STATEMENT_IDX, PreparedStatement.class);
+                sql = (String)args[0];
+            } else if (compare(PREPARE_CALL, name)) {
+                // prepareCall
+                constructor = getConstructor(PREPARE_CALL_IDX, CallableStatement.class);
+                sql = (String)args[0];
+            } else {
+                // do nothing, might be a future unsupported method
+                // so we better bail out and let the system continue
+                return statement;
+            }
+            return createDecorator(proxy, method, args, statement, constructor, sql);
+        } catch (Exception x) {
+            if (x instanceof InvocationTargetException) {
+                Throwable cause = x.getCause();
+                if (cause instanceof ThreadDeath) {
+                    throw (ThreadDeath) cause;
+                }
+                if (cause instanceof VirtualMachineError) {
+                    throw (VirtualMachineError) cause;
+                }
+            }
+            logger.warn("Unable to create statement proxy for slow query report.", x);
+        }
+        return statement;
+    }
+
+    /**
+     * Creates a proxy for a Statement.
+     *
+     * @param proxy         The proxy object on which the method that triggered
+     *                          the creation of the statement was called.
+     * @param method        The method that was called on the proxy
+     * @param args          The arguments passed as part of the method call to
+     *                          the proxy
+     * @param statement     The statement object that is to be proxied
+     * @param constructor   The constructor for the desired proxy
+     * @param sql           The sql of of the statement
+     *
+     * @return  A new proxy for the Statement
+     * @throws InstantiationException Couldn't instantiate object
+     * @throws IllegalAccessException Inaccessible constructor
+     * @throws InvocationTargetException Exception thrown from constructor
+     */
+    protected Object createDecorator(Object proxy, Method method, Object[] args,
+                                     Object statement, Constructor<?> constructor, String sql)
+    throws InstantiationException, IllegalAccessException, InvocationTargetException {
+        Object result = null;
+        StatementProxy<Statement> statementProxy =
+                new StatementProxy<>((Statement)statement,sql);
+        result = constructor.newInstance(new Object[] { statementProxy });
+        statementProxy.setActualProxy(result);
+        statementProxy.setConnection(proxy);
+        statementProxy.setConstructor(constructor);
+        return result;
+    }
+
+    protected boolean isExecuteQuery(String methodName) {
+        return EXECUTE_QUERY.equals(methodName);
+    }
+
+    protected boolean isExecuteQuery(Method method) {
+        return isExecuteQuery(method.getName());
+    }
+
+    protected boolean isResultSet(Method method, boolean process) {
+        return process(RESULTSET_TYPES, method, process);
+    }
+
+    /**
+     * Class to measure query execute time.
+     */
+    protected class StatementProxy<T extends java.sql.Statement> implements InvocationHandler {
+
+        protected boolean closed = false;
+        protected T delegate;
+        private Object actualProxy;
+        private Object connection;
+        private String sql;
+        private Constructor<?> constructor;
+
+        public StatementProxy(T delegate, String sql) {
+            this.delegate = delegate;
+            this.sql = sql;
+        }
+        public T getDelegate() {
+            return this.delegate;
+        }
+
+        public String getSql() {
+            return sql;
+        }
+
+        public void setConnection(Object proxy) {
+            this.connection = proxy;
+        }
+        public Object getConnection() {
+            return this.connection;
+        }
+
+        public void setActualProxy(Object proxy){
+            this.actualProxy = proxy;
+        }
+        public Object getActualProxy() {
+            return this.actualProxy;
+        }
+
+
+        public Constructor<?> getConstructor() {
+            return constructor;
+        }
+        public void setConstructor(Constructor<?> constructor) {
+            this.constructor = constructor;
+        }
+        public void closeInvoked() {
+            if (getDelegate()!=null) {
+                try {
+                    getDelegate().close();
+                }catch (SQLException ignore) {
+                }
+            }
+            closed = true;
+            delegate = null;
+        }
+
+        @Override
+        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
+            if (compare(TOSTRING_VAL,method)) {
+                return toString();
+            }
+            // was close invoked?
+            boolean close = compare(CLOSE_VAL, method);
+            // allow close to be called multiple times
+            if (close && closed)
+                return null;
+            // are we calling isClosed?
+            if (compare(ISCLOSED_VAL, method))
+                return Boolean.valueOf(closed);
+            // if we are calling anything else, bail out
+            if (closed)
+                throw new SQLException("Statement closed.");
+            if (compare(GETCONNECTION_VAL,method)){
+                return connection;
+            }
+            boolean process = false;
+            process = isResultSet(method, process);
+            // check to see if we are about to execute a query
+            // if we are executing, get the current time
+            Object result = null;
+            try {
+                // perform close cleanup
+                if (close) {
+                    closeInvoked();
+                } else {
+                    // execute the query
+                    result = method.invoke(delegate, args);
+                }
+            } catch (Throwable t) {
+                if (t instanceof InvocationTargetException
+                        && t.getCause() != null) {
+                    throw t.getCause();
+                } else {
+                    throw t;
+                }
+            }
+            if (process && result != null) {
+                Constructor<?> cons = getResultSetConstructor();
+                result = cons.newInstance(new Object[]{new ResultSetProxy(actualProxy, result)});
+            }
+            return result;
+        }
+
+        @Override
+        public String toString() {
+            StringBuffer buf = new StringBuffer(StatementProxy.class.getName());
+            buf.append("[Proxy=");
+            buf.append(System.identityHashCode(this));
+            buf.append("; Sql=");
+            buf.append(getSql());
+            buf.append("; Delegate=");
+            buf.append(getDelegate());
+            buf.append("; Connection=");
+            buf.append(getConnection());
+            buf.append("]");
+            return buf.toString();
+        }
+    }
+
+    protected class ResultSetProxy implements InvocationHandler {
+
+        private Object st;
+        private Object delegate;
+
+        public ResultSetProxy(Object st, Object delegate) {
+            this.st = st;
+            this.delegate = delegate;
+        }
+
+        @Override
+        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
+            if (method.getName().equals("getStatement")) {
+                return this.st;
+            } else {
+                try {
+                    return method.invoke(this.delegate, args);
+                } catch (Throwable t) {
+                    if (t instanceof InvocationTargetException
+                            && t.getCause() != null) {
+                        throw t.getCause();
+                    } else {
+                        throw t;
+                    }
+                }
+            }
+        }
+    }
+}
diff --git a/dblib/common/src/main/java/org/apache/tomcat/jdbc/pool/interceptor/StatementFinalizer.java b/dblib/common/src/main/java/org/apache/tomcat/jdbc/pool/interceptor/StatementFinalizer.java
new file mode 100644
index 0000000..6535139
--- /dev/null
+++ b/dblib/common/src/main/java/org/apache/tomcat/jdbc/pool/interceptor/StatementFinalizer.java
@@ -0,0 +1,136 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * openecomp
+ * ================================================================================
+ * Copyright (C) 2016 - 2017 AT&T
+ * ================================================================================
+ * Licensed 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.
+ * ============LICENSE_END=========================================================
+ */
+
+/*
+ * 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.tomcat.jdbc.pool.interceptor;
+
+import java.lang.ref.WeakReference;
+import java.lang.reflect.Method;
+import java.sql.Statement;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.juli.logging.Log;
+import org.apache.juli.logging.LogFactory;
+import org.apache.tomcat.jdbc.pool.ConnectionPool;
+import org.apache.tomcat.jdbc.pool.PoolProperties;
+import org.apache.tomcat.jdbc.pool.PooledConnection;
+
+/**
+ * Keeps track of statements associated with a connection and invokes close upon {@link java.sql.Connection#close()}
+ * Useful for applications that dont close the associated statements after being done with a connection.
+ *
+ */
+public class StatementFinalizer extends AbstractCreateStatementInterceptor {
+    private static final Log log = LogFactory.getLog(StatementFinalizer.class);
+
+    protected List<StatementEntry> statements = new LinkedList<>();
+
+    private boolean logCreationStack = false;
+
+    @Override
+    public Object createStatement(Object proxy, Method method, Object[] args, Object statement, long time) {
+        try {
+            if (statement instanceof Statement)
+                statements.add(new StatementEntry((Statement)statement));
+        }catch (ClassCastException x) {
+            //ignore this one
+        }
+        return statement;
+    }
+
+    @SuppressWarnings("null") // st is not null when used
+    @Override
+    public void closeInvoked() {
+        while (statements.size()>0) {
+            StatementEntry ws = statements.remove(0);
+            Statement st = ws.getStatement();
+            boolean shallClose = false;
+            try {
+                shallClose = st!=null && (!st.isClosed());
+                if (shallClose) {
+                    st.close();
+                }
+            } catch (Exception ignore) {
+                if (log.isDebugEnabled()) {
+                    log.debug("Unable to closed statement upon connection close.",ignore);
+                }
+            } finally {
+                if (logCreationStack && shallClose) {
+                    log.warn("Statement created, but was not closed at:", ws.getAllocationStack());
+                }
+            }
+        }
+    }
+
+    @Override
+    public void setProperties(Map<String, PoolProperties.InterceptorProperty> properties) {
+        super.setProperties(properties);
+
+        PoolProperties.InterceptorProperty logProperty = properties.get("trace");
+        if (null != logProperty) {
+            logCreationStack = logProperty.getValueAsBoolean(logCreationStack);
+        }
+    }
+
+    @Override
+    public void reset(ConnectionPool parent, PooledConnection con) {
+        statements.clear();
+        super.reset(parent, con);
+    }
+
+    protected class StatementEntry {
+        private WeakReference<Statement> statement;
+        private Throwable allocationStack;
+
+        public StatementEntry(Statement statement) {
+            this.statement = new WeakReference<>(statement);
+            if (logCreationStack) {
+                this.allocationStack = new Throwable();
+            }
+        }
+
+        public Statement getStatement() {
+            return statement.get();
+        }
+
+        public Throwable getAllocationStack() {
+            return allocationStack;
+        }
+    }
+
+
+}
diff --git a/dblib/common/src/main/java/org/apache/tomcat/jdbc/pool/interceptor/mbeans-descriptors.xml b/dblib/common/src/main/java/org/apache/tomcat/jdbc/pool/interceptor/mbeans-descriptors.xml
new file mode 100644
index 0000000..0cca7ad
--- /dev/null
+++ b/dblib/common/src/main/java/org/apache/tomcat/jdbc/pool/interceptor/mbeans-descriptors.xml
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ============LICENSE_START=======================================================
+  openecomp
+  ================================================================================
+  Copyright (C) 2016 - 2017 AT&T
+  ================================================================================
+  Licensed 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.
+  ============LICENSE_END=========================================================
+  -->
+
+<!--
+ 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.
+-->
+<mbeans-descriptors>
+
+  <mbean description="Reports " domain="tomcat.jdbc" group="jdbc-pool" name="SlowQueryReportJmx"
+         type="org.apache.tomcat.jdbc.pool.interceptor.SlowQueryReportJmx">
+
+    <attribute description="The name of the connection pool this Jmx bean is representing" name="poolName" type="java.lang.String" writeable="false"/>
+    <attribute description="List of all registered connections pools" name="poolNames" type="[java.lang.String;" writeable="false"/>
+    <attribute description="All the recorded query stats. " name="slowQueriesCD" type="[javax.management.openmbean.CompositeData;" writeable="false"/>
+    <operation description="Clears all the query stats" impact="ACTION" name="resetStats" returnType="void"/>
+
+    <notification description="Notification sent out by the slow query report when a query exceeds the threshold" name="slow-query">
+      <notification-type>Slow query</notification-type>
+    </notification>
+
+    <notification description="Notification sent out by the slow query report when a query fails execution" name="failed-query">
+      <notification-type>Failed query execution</notification-type>
+    </notification>
+  </mbean>
+</mbeans-descriptors>
diff --git a/dblib/common/src/main/java/org/apache/tomcat/jdbc/pool/jmx/ConnectionPool.java b/dblib/common/src/main/java/org/apache/tomcat/jdbc/pool/jmx/ConnectionPool.java
new file mode 100644
index 0000000..9044bae
--- /dev/null
+++ b/dblib/common/src/main/java/org/apache/tomcat/jdbc/pool/jmx/ConnectionPool.java
@@ -0,0 +1,960 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * openecomp
+ * ================================================================================
+ * Copyright (C) 2016 - 2017 AT&T
+ * ================================================================================
+ * Licensed 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.
+ * ============LICENSE_END=========================================================
+ */
+
+/* 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.tomcat.jdbc.pool.jmx;
+
+import java.util.Properties;
+import java.util.concurrent.ConcurrentLinkedQueue;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import javax.management.MBeanNotificationInfo;
+import javax.management.Notification;
+import javax.management.NotificationBroadcasterSupport;
+import javax.management.NotificationListener;
+
+import org.apache.juli.logging.Log;
+import org.apache.juli.logging.LogFactory;
+import org.apache.tomcat.jdbc.pool.PoolConfiguration;
+import org.apache.tomcat.jdbc.pool.PoolProperties.InterceptorDefinition;
+import org.apache.tomcat.jdbc.pool.PoolUtilities;
+import org.apache.tomcat.jdbc.pool.Validator;
+
+public class ConnectionPool extends NotificationBroadcasterSupport implements ConnectionPoolMBean  {
+    /**
+     * logger
+     */
+    private static final Log log = LogFactory.getLog(ConnectionPool.class);
+
+    /**
+     * the connection pool
+     */
+    protected org.apache.tomcat.jdbc.pool.ConnectionPool pool = null;
+    /**
+     * sequence for JMX notifications
+     */
+    protected AtomicInteger sequence = new AtomicInteger(0);
+
+    /**
+     * Listeners that are local and interested in our notifications, no need for JMX
+     */
+    protected ConcurrentLinkedQueue<NotificationListener> listeners =
+            new ConcurrentLinkedQueue<>();
+
+    public ConnectionPool(org.apache.tomcat.jdbc.pool.ConnectionPool pool) {
+        super();
+        this.pool = pool;
+    }
+
+    public org.apache.tomcat.jdbc.pool.ConnectionPool getPool() {
+        return pool;
+    }
+
+    public PoolConfiguration getPoolProperties() {
+        return pool.getPoolProperties();
+    }
+
+    //=================================================================
+    //       NOTIFICATION INFO
+    //=================================================================
+    public static final String NOTIFY_INIT = "INIT FAILED";
+    public static final String NOTIFY_CONNECT = "CONNECTION FAILED";
+    public static final String NOTIFY_ABANDON = "CONNECTION ABANDONED";
+    public static final String SLOW_QUERY_NOTIFICATION = "SLOW QUERY";
+    public static final String FAILED_QUERY_NOTIFICATION = "FAILED QUERY";
+    public static final String SUSPECT_ABANDONED_NOTIFICATION = "SUSPECT CONNECTION ABANDONED";
+    public static final String POOL_EMPTY = "POOL EMPTY";
+    public static final String SUSPECT_RETURNED_NOTIFICATION = "SUSPECT CONNECTION RETURNED";
+
+    @Override
+    public MBeanNotificationInfo[] getNotificationInfo() {
+        MBeanNotificationInfo[] pres = super.getNotificationInfo();
+        MBeanNotificationInfo[] loc = getDefaultNotificationInfo();
+        MBeanNotificationInfo[] aug = new MBeanNotificationInfo[pres.length + loc.length];
+        if (pres.length>0) System.arraycopy(pres, 0, aug, 0, pres.length);
+        if (loc.length >0) System.arraycopy(loc, 0, aug, pres.length, loc.length);
+        return aug;
+    }
+
+    public static MBeanNotificationInfo[] getDefaultNotificationInfo() {
+        String[] types = new String[] {NOTIFY_INIT, NOTIFY_CONNECT, NOTIFY_ABANDON, SLOW_QUERY_NOTIFICATION,
+                FAILED_QUERY_NOTIFICATION, SUSPECT_ABANDONED_NOTIFICATION, POOL_EMPTY, SUSPECT_RETURNED_NOTIFICATION};
+        String name = Notification.class.getName();
+        String description = "A connection pool error condition was met.";
+        MBeanNotificationInfo info = new MBeanNotificationInfo(types, name, description);
+        return new MBeanNotificationInfo[] {info};
+    }
+
+    /**
+     * Return true if the notification was sent successfully, false otherwise.
+     * @param type The notification type
+     * @param message The message
+     * @return true if the notification succeeded
+     */
+    public boolean notify(final String type, String message) {
+        try {
+            Notification n = new Notification(
+                    type,
+                    this,
+                    sequence.incrementAndGet(),
+                    System.currentTimeMillis(),
+                    "["+type+"] "+message);
+            sendNotification(n);
+            for (NotificationListener listener : listeners) {
+                listener.handleNotification(n,this);
+            }
+            return true;
+        }catch (Exception x) {
+            if (log.isDebugEnabled()) {
+                log.debug("Notify failed. Type="+type+"; Message="+message,x);
+            }
+            return false;
+        }
+
+    }
+
+    public void addListener(NotificationListener list) {
+        listeners.add(list);
+    }
+
+    public boolean removeListener(NotificationListener list) {
+        return listeners.remove(list);
+    }
+
+    //=================================================================
+    //       POOL STATS
+    //=================================================================
+
+    @Override
+    public int getSize() {
+        return pool.getSize();
+    }
+
+    @Override
+    public int getIdle() {
+        return pool.getIdle();
+    }
+
+    @Override
+    public int getActive() {
+        return pool.getActive();
+    }
+
+    @Override
+    public int getNumIdle() {
+        return getIdle();
+    }
+
+    @Override
+    public int getNumActive() {
+        return getActive();
+    }
+
+    @Override
+    public int getWaitCount() {
+        return pool.getWaitCount();
+    }
+
+    @Override
+    public long getBorrowedCount() {
+        return pool.getBorrowedCount();
+    }
+
+    @Override
+    public long getReturnedCount() {
+        return pool.getReturnedCount();
+    }
+
+    @Override
+    public long getCreatedCount() {
+        return pool.getCreatedCount();
+    }
+
+    @Override
+    public long getReleasedCount() {
+        return pool.getReleasedCount();
+    }
+
+    @Override
+    public long getReconnectedCount() {
+        return pool.getReconnectedCount();
+    }
+
+    @Override
+    public long getRemoveAbandonedCount() {
+        return pool.getRemoveAbandonedCount();
+    }
+
+    @Override
+    public long getReleasedIdleCount() {
+        return pool.getReleasedIdleCount();
+    }
+
+    //=================================================================
+    //       POOL OPERATIONS
+    //=================================================================
+    @Override
+    public void checkIdle() {
+        pool.checkIdle();
+    }
+
+    @Override
+    public void checkAbandoned() {
+        pool.checkAbandoned();
+    }
+
+    @Override
+    public void testIdle() {
+        pool.testAllIdle();
+    }
+
+    @Override
+    public void resetStats() {
+        pool.resetStats();
+    }
+
+    //=================================================================
+    //       POOL PROPERTIES
+    //=================================================================
+    //=========================================================
+    //  PROPERTIES / CONFIGURATION
+    //=========================================================
+
+
+    @Override
+    public String getConnectionProperties() {
+        return getPoolProperties().getConnectionProperties();
+    }
+
+    @Override
+    public Properties getDbProperties() {
+        return PoolUtilities.cloneWithoutPassword(getPoolProperties().getDbProperties());
+    }
+
+    @Override
+    public String getDefaultCatalog() {
+        return getPoolProperties().getDefaultCatalog();
+    }
+
+    @Override
+    public int getDefaultTransactionIsolation() {
+        return getPoolProperties().getDefaultTransactionIsolation();
+    }
+
+    @Override
+    public String getDriverClassName() {
+        return getPoolProperties().getDriverClassName();
+    }
+
+
+    @Override
+    public int getInitialSize() {
+        return getPoolProperties().getInitialSize();
+    }
+
+    @Override
+    public String getInitSQL() {
+        return getPoolProperties().getInitSQL();
+    }
+
+    @Override
+    public String getJdbcInterceptors() {
+        return getPoolProperties().getJdbcInterceptors();
+    }
+
+    @Override
+    public int getMaxActive() {
+        return getPoolProperties().getMaxActive();
+    }
+
+    @Override
+    public int getMaxIdle() {
+        return getPoolProperties().getMaxIdle();
+    }
+
+    @Override
+    public int getMaxWait() {
+        return getPoolProperties().getMaxWait();
+    }
+
+    @Override
+    public int getMinEvictableIdleTimeMillis() {
+        return getPoolProperties().getMinEvictableIdleTimeMillis();
+    }
+
+    @Override
+    public int getMinIdle() {
+        return getPoolProperties().getMinIdle();
+    }
+
+    @Override
+    public long getMaxAge() {
+        return getPoolProperties().getMaxAge();
+    }
+
+    @Override
+    public String getName() {
+        return this.getPoolName();
+    }
+
+    @Override
+    public int getNumTestsPerEvictionRun() {
+        return getPoolProperties().getNumTestsPerEvictionRun();
+    }
+
+    /**
+     * @return DOES NOT RETURN THE PASSWORD, IT WOULD SHOW UP IN JMX
+     */
+    @Override
+    public String getPassword() {
+        return "Password not available as DataSource/JMX operation.";
+    }
+
+    @Override
+    public int getRemoveAbandonedTimeout() {
+        return getPoolProperties().getRemoveAbandonedTimeout();
+    }
+
+
+    @Override
+    public int getTimeBetweenEvictionRunsMillis() {
+        return getPoolProperties().getTimeBetweenEvictionRunsMillis();
+    }
+
+    @Override
+    public String getUrl() {
+        return getPoolProperties().getUrl();
+    }
+
+    @Override
+    public String getUsername() {
+        return getPoolProperties().getUsername();
+    }
+
+    @Override
+    public long getValidationInterval() {
+        return getPoolProperties().getValidationInterval();
+    }
+
+    @Override
+    public String getValidationQuery() {
+        return getPoolProperties().getValidationQuery();
+    }
+
+    @Override
+    public int getValidationQueryTimeout() {
+        return getPoolProperties().getValidationQueryTimeout();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+
+    @Override
+    public String getValidatorClassName() {
+        return getPoolProperties().getValidatorClassName();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+
+    @Override
+    public Validator getValidator() {
+        return getPoolProperties().getValidator();
+    }
+
+    @Override
+    public boolean isAccessToUnderlyingConnectionAllowed() {
+        return getPoolProperties().isAccessToUnderlyingConnectionAllowed();
+    }
+
+    @Override
+    public Boolean isDefaultAutoCommit() {
+        return getPoolProperties().isDefaultAutoCommit();
+    }
+
+    @Override
+    public Boolean isDefaultReadOnly() {
+        return getPoolProperties().isDefaultReadOnly();
+    }
+
+    @Override
+    public boolean isLogAbandoned() {
+        return getPoolProperties().isLogAbandoned();
+    }
+
+    @Override
+    public boolean isPoolSweeperEnabled() {
+        return getPoolProperties().isPoolSweeperEnabled();
+    }
+
+    @Override
+    public boolean isRemoveAbandoned() {
+        return getPoolProperties().isRemoveAbandoned();
+    }
+
+    @Override
+    public int getAbandonWhenPercentageFull() {
+        return getPoolProperties().getAbandonWhenPercentageFull();
+    }
+
+    @Override
+    public boolean isTestOnBorrow() {
+        return getPoolProperties().isTestOnBorrow();
+    }
+
+    @Override
+    public boolean isTestOnConnect() {
+        return getPoolProperties().isTestOnConnect();
+    }
+
+    @Override
+    public boolean isTestOnReturn() {
+        return getPoolProperties().isTestOnReturn();
+    }
+
+    @Override
+    public boolean isTestWhileIdle() {
+        return getPoolProperties().isTestWhileIdle();
+    }
+
+
+    @Override
+    public Boolean getDefaultAutoCommit() {
+        return getPoolProperties().getDefaultAutoCommit();
+    }
+
+    @Override
+    public Boolean getDefaultReadOnly() {
+        return getPoolProperties().getDefaultReadOnly();
+    }
+
+    @Override
+    public InterceptorDefinition[] getJdbcInterceptorsAsArray() {
+        return getPoolProperties().getJdbcInterceptorsAsArray();
+    }
+
+    @Override
+    public boolean getUseLock() {
+        return getPoolProperties().getUseLock();
+    }
+
+    @Override
+    public boolean isFairQueue() {
+        return getPoolProperties().isFairQueue();
+    }
+
+    @Override
+    public boolean isJmxEnabled() {
+        return getPoolProperties().isJmxEnabled();
+    }
+
+    @Override
+    public boolean isUseEquals() {
+        return getPoolProperties().isUseEquals();
+    }
+
+    @Override
+    public void setAbandonWhenPercentageFull(int percentage) {
+        getPoolProperties().setAbandonWhenPercentageFull(percentage);
+    }
+
+    @Override
+    public void setAccessToUnderlyingConnectionAllowed(boolean accessToUnderlyingConnectionAllowed) {
+        getPoolProperties().setAccessToUnderlyingConnectionAllowed(accessToUnderlyingConnectionAllowed);
+    }
+
+    @Override
+    public void setDbProperties(Properties dbProperties) {
+        getPoolProperties().setDbProperties(dbProperties);
+    }
+
+    @Override
+    public void setDefaultReadOnly(Boolean defaultReadOnly) {
+        getPoolProperties().setDefaultReadOnly(defaultReadOnly);
+    }
+
+    @Override
+    public void setMaxAge(long maxAge) {
+        getPoolProperties().setMaxAge(maxAge);
+    }
+
+    @Override
+    public void setName(String name) {
+        getPoolProperties().setName(name);
+    }
+
+    @Override
+    public String getPoolName() {
+        return getPoolProperties().getName();
+    }
+
+
+    @Override
+    public void setConnectionProperties(String connectionProperties) {
+        getPoolProperties().setConnectionProperties(connectionProperties);
+
+    }
+
+    @Override
+    public void setDefaultAutoCommit(Boolean defaultAutoCommit) {
+        getPoolProperties().setDefaultAutoCommit(defaultAutoCommit);
+    }
+
+    @Override
+    public void setDefaultCatalog(String defaultCatalog) {
+        getPoolProperties().setDefaultCatalog(defaultCatalog);
+    }
+
+    @Override
+    public void setDefaultTransactionIsolation(int defaultTransactionIsolation) {
+        getPoolProperties().setDefaultTransactionIsolation(defaultTransactionIsolation);
+    }
+
+    @Override
+    public void setDriverClassName(String driverClassName) {
+        getPoolProperties().setDriverClassName(driverClassName);
+    }
+
+
+    @Override
+    public void setFairQueue(boolean fairQueue) {
+        // noop - this pool is already running
+        throw new UnsupportedOperationException();
+    }
+
+
+    @Override
+    public void setInitialSize(int initialSize) {
+        // noop - this pool is already running
+        throw new UnsupportedOperationException();
+
+    }
+
+
+    @Override
+    public void setInitSQL(String initSQL) {
+        getPoolProperties().setInitSQL(initSQL);
+
+    }
+
+
+    @Override
+    public void setJdbcInterceptors(String jdbcInterceptors) {
+        // noop - this pool is already running
+        throw new UnsupportedOperationException();
+    }
+
+
+    @Override
+    public void setJmxEnabled(boolean jmxEnabled) {
+        // noop - this pool is already running and obviously jmx enabled
+        throw new UnsupportedOperationException();
+    }
+
+
+    @Override
+    public void setLogAbandoned(boolean logAbandoned) {
+        getPoolProperties().setLogAbandoned(logAbandoned);
+    }
+
+
+    @Override
+    public void setMaxActive(int maxActive) {
+        getPoolProperties().setMaxActive(maxActive);
+        //make sure the pool is properly configured
+        pool.checkPoolConfiguration(getPoolProperties());
+    }
+
+
+    @Override
+    public void setMaxIdle(int maxIdle) {
+        getPoolProperties().setMaxIdle(maxIdle);
+        //make sure the pool is properly configured
+        pool.checkPoolConfiguration(getPoolProperties());
+
+    }
+
+
+    @Override
+    public void setMaxWait(int maxWait) {
+        getPoolProperties().setMaxWait(maxWait);
+    }
+
+
+    @Override
+    public void setMinEvictableIdleTimeMillis(int minEvictableIdleTimeMillis) {
+        boolean wasEnabled = getPoolProperties().isPoolSweeperEnabled();
+        getPoolProperties().setMinEvictableIdleTimeMillis(minEvictableIdleTimeMillis);
+        boolean shouldBeEnabled = getPoolProperties().isPoolSweeperEnabled();
+        //make sure pool cleaner starts/stops when it should
+        if (!wasEnabled && shouldBeEnabled) pool.initializePoolCleaner(getPoolProperties());
+        else if (wasEnabled && !shouldBeEnabled) pool.terminatePoolCleaner();
+    }
+
+
+    @Override
+    public void setMinIdle(int minIdle) {
+        getPoolProperties().setMinIdle(minIdle);
+        //make sure the pool is properly configured
+        pool.checkPoolConfiguration(getPoolProperties());
+    }
+
+
+    @Override
+    public void setNumTestsPerEvictionRun(int numTestsPerEvictionRun) {
+        getPoolProperties().setNumTestsPerEvictionRun(numTestsPerEvictionRun);
+    }
+
+
+    @Override
+    public void setPassword(String password) {
+        getPoolProperties().setPassword(password);
+    }
+
+
+    @Override
+    public void setRemoveAbandoned(boolean removeAbandoned) {
+        boolean wasEnabled = getPoolProperties().isPoolSweeperEnabled();
+        getPoolProperties().setRemoveAbandoned(removeAbandoned);
+        boolean shouldBeEnabled = getPoolProperties().isPoolSweeperEnabled();
+        //make sure pool cleaner starts/stops when it should
+        if (!wasEnabled && shouldBeEnabled) pool.initializePoolCleaner(getPoolProperties());
+        else if (wasEnabled && !shouldBeEnabled) pool.terminatePoolCleaner();
+    }
+
+
+    @Override
+    public void setRemoveAbandonedTimeout(int removeAbandonedTimeout) {
+        boolean wasEnabled = getPoolProperties().isPoolSweeperEnabled();
+        getPoolProperties().setRemoveAbandonedTimeout(removeAbandonedTimeout);
+        boolean shouldBeEnabled = getPoolProperties().isPoolSweeperEnabled();
+        //make sure pool cleaner starts/stops when it should
+        if (!wasEnabled && shouldBeEnabled) pool.initializePoolCleaner(getPoolProperties());
+        else if (wasEnabled && !shouldBeEnabled) pool.terminatePoolCleaner();
+    }
+
+
+    @Override
+    public void setTestOnBorrow(boolean testOnBorrow) {
+        getPoolProperties().setTestOnBorrow(testOnBorrow);
+    }
+
+
+    @Override
+    public void setTestOnConnect(boolean testOnConnect) {
+        getPoolProperties().setTestOnConnect(testOnConnect);
+    }
+
+
+    @Override
+    public void setTestOnReturn(boolean testOnReturn) {
+        getPoolProperties().setTestOnReturn(testOnReturn);
+    }
+
+
+    @Override
+    public void setTestWhileIdle(boolean testWhileIdle) {
+        boolean wasEnabled = getPoolProperties().isPoolSweeperEnabled();
+        getPoolProperties().setTestWhileIdle(testWhileIdle);
+        boolean shouldBeEnabled = getPoolProperties().isPoolSweeperEnabled();
+        //make sure pool cleaner starts/stops when it should
+        if (!wasEnabled && shouldBeEnabled) pool.initializePoolCleaner(getPoolProperties());
+        else if (wasEnabled && !shouldBeEnabled) pool.terminatePoolCleaner();
+    }
+
+
+    @Override
+    public void setTimeBetweenEvictionRunsMillis(int timeBetweenEvictionRunsMillis) {
+        boolean wasEnabled = getPoolProperties().isPoolSweeperEnabled();
+        getPoolProperties().setTimeBetweenEvictionRunsMillis(timeBetweenEvictionRunsMillis);
+        boolean shouldBeEnabled = getPoolProperties().isPoolSweeperEnabled();
+        //make sure pool cleaner starts/stops when it should
+        if (!wasEnabled && shouldBeEnabled) {
+            pool.initializePoolCleaner(getPoolProperties());
+        } else if (wasEnabled) {
+            pool.terminatePoolCleaner();
+            if (shouldBeEnabled) {
+                pool.initializePoolCleaner(getPoolProperties());
+            }
+        }
+    }
+
+
+    @Override
+    public void setUrl(String url) {
+        getPoolProperties().setUrl(url);
+    }
+
+
+    @Override
+    public void setUseEquals(boolean useEquals) {
+        getPoolProperties().setUseEquals(useEquals);
+    }
+
+
+    @Override
+    public void setUseLock(boolean useLock) {
+        getPoolProperties().setUseLock(useLock);
+    }
+
+
+    @Override
+    public void setUsername(String username) {
+        getPoolProperties().setUsername(username);
+    }
+
+
+    @Override
+    public void setValidationInterval(long validationInterval) {
+        getPoolProperties().setValidationInterval(validationInterval);
+    }
+
+
+    @Override
+    public void setValidationQuery(String validationQuery) {
+        getPoolProperties().setValidationQuery(validationQuery);
+    }
+
+    @Override
+    public void setValidationQueryTimeout(int validationQueryTimeout) {
+        getPoolProperties().setValidationQueryTimeout(validationQueryTimeout);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+
+    @Override
+    public void setValidatorClassName(String className) {
+        getPoolProperties().setValidatorClassName(className);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+
+    @Override
+    public int getSuspectTimeout() {
+        return getPoolProperties().getSuspectTimeout();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+
+    @Override
+    public void setSuspectTimeout(int seconds) {
+        getPoolProperties().setSuspectTimeout(seconds);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void setDataSource(Object ds) {
+        getPoolProperties().setDataSource(ds);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public Object getDataSource() {
+        return getPoolProperties().getDataSource();
+    }
+
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void setDataSourceJNDI(String jndiDS) {
+        getPoolProperties().setDataSourceJNDI(jndiDS);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public String getDataSourceJNDI() {
+        return getPoolProperties().getDataSourceJNDI();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public boolean isAlternateUsernameAllowed() {
+        return getPoolProperties().isAlternateUsernameAllowed();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void setAlternateUsernameAllowed(boolean alternateUsernameAllowed) {
+        getPoolProperties().setAlternateUsernameAllowed(alternateUsernameAllowed);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void setValidator(Validator validator) {
+        getPoolProperties().setValidator(validator);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void setCommitOnReturn(boolean commitOnReturn) {
+        getPoolProperties().setCommitOnReturn(commitOnReturn);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public boolean getCommitOnReturn() {
+        return getPoolProperties().getCommitOnReturn();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void setRollbackOnReturn(boolean rollbackOnReturn) {
+        getPoolProperties().setRollbackOnReturn(rollbackOnReturn);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public boolean getRollbackOnReturn() {
+        return getPoolProperties().getRollbackOnReturn();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void setUseDisposableConnectionFacade(boolean useDisposableConnectionFacade) {
+        getPoolProperties().setUseDisposableConnectionFacade(useDisposableConnectionFacade);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public boolean getUseDisposableConnectionFacade() {
+        return getPoolProperties().getUseDisposableConnectionFacade();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void setLogValidationErrors(boolean logValidationErrors) {
+        getPoolProperties().setLogValidationErrors(logValidationErrors);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public boolean getLogValidationErrors() {
+        return getPoolProperties().getLogValidationErrors();
+    }
+
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public boolean getPropagateInterruptState() {
+        return getPoolProperties().getPropagateInterruptState();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void setPropagateInterruptState(boolean propagateInterruptState) {
+        getPoolProperties().setPropagateInterruptState(propagateInterruptState);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public boolean isIgnoreExceptionOnPreLoad() {
+        return getPoolProperties().isIgnoreExceptionOnPreLoad();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void setIgnoreExceptionOnPreLoad(boolean ignoreExceptionOnPreLoad) {
+        // noop - this pool is already running
+        throw new UnsupportedOperationException();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void purge() {
+        pool.purge();
+
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void purgeOnReturn() {
+        pool.purgeOnReturn();
+
+    }
+
+
+
+
+
+}
diff --git a/dblib/common/src/main/java/org/apache/tomcat/jdbc/pool/jmx/ConnectionPoolMBean.java b/dblib/common/src/main/java/org/apache/tomcat/jdbc/pool/jmx/ConnectionPoolMBean.java
new file mode 100644
index 0000000..bc3bbca
--- /dev/null
+++ b/dblib/common/src/main/java/org/apache/tomcat/jdbc/pool/jmx/ConnectionPoolMBean.java
@@ -0,0 +1,107 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * openecomp
+ * ================================================================================
+ * Copyright (C) 2016 - 2017 AT&T
+ * ================================================================================
+ * Licensed 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.
+ * ============LICENSE_END=========================================================
+ */
+
+/* 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.tomcat.jdbc.pool.jmx;
+
+import org.apache.tomcat.jdbc.pool.PoolConfiguration;
+
+public interface ConnectionPoolMBean extends PoolConfiguration  {
+
+    //=================================================================
+    //       POOL STATS
+    //=================================================================
+
+    public int getSize();
+
+    public int getIdle();
+
+    public int getActive();
+
+    public int getNumIdle();
+
+    public int getNumActive();
+
+    public int getWaitCount();
+
+    public long getBorrowedCount();
+
+    public long getReturnedCount();
+
+    public long getCreatedCount();
+
+    public long getReleasedCount();
+
+    public long getReconnectedCount();
+
+    public long getRemoveAbandonedCount();
+
+    public long getReleasedIdleCount();
+
+    //=================================================================
+    //       POOL OPERATIONS
+    //=================================================================
+    public void checkIdle();
+
+    public void checkAbandoned();
+
+    public void testIdle();
+
+    /**
+     * Purges all connections in the pool.
+     * For connections currently in use, these connections will be
+     * purged when returned on the pool. This call also
+     * purges connections that are idle and in the pool
+     * To only purge used/active connections see {@link #purgeOnReturn()}
+     */
+    public void purge();
+
+    /**
+     * Purges connections when they are returned from the pool.
+     * This call does not purge idle connections until they are used.
+     * To purge idle connections see {@link #purge()}
+     */
+    public void purgeOnReturn();
+
+    /**
+     * reset the statistics of this pool.
+     */
+    public void resetStats();
+
+    //=================================================================
+    //       POOL NOTIFICATIONS
+    //=================================================================
+
+
+}
diff --git a/dblib/common/src/main/java/org/apache/tomcat/jdbc/pool/mbeans-descriptors.xml b/dblib/common/src/main/java/org/apache/tomcat/jdbc/pool/mbeans-descriptors.xml
new file mode 100644
index 0000000..591c1d1
--- /dev/null
+++ b/dblib/common/src/main/java/org/apache/tomcat/jdbc/pool/mbeans-descriptors.xml
@@ -0,0 +1,420 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ============LICENSE_START=======================================================
+  openecomp
+  ================================================================================
+  Copyright (C) 2016 - 2017 AT&T
+  ================================================================================
+  Licensed 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.
+  ============LICENSE_END=========================================================
+  -->
+
+<!--
+  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.
+-->
+<mbeans-descriptors>
+
+    <mbean        name="TomcatJDBCPool"
+           description="Provides per diagnostic metrics and notifications for JDBC operations"
+                domain="tomcat"
+                 group="jdbc"
+                  type="org.apache.tomcat.jdbc.pool.DataSource">
+
+    <attribute    name="className"
+           description="Fully qualified class name of the managed object"
+                  type="java.lang.String"
+             writeable="false"/>
+
+    <attribute    name="size"
+           description="The number of established connections in the pool, idle and in use"
+                  type="java.lang.Integer"
+             writeable="false"/>
+
+    <attribute    name="idle"
+           description="The number of established connections in the pool that are idle"
+                  type="java.lang.Integer"
+             writeable="false"/>
+
+    <attribute    name="numIdle"
+           description="Same as the idle attribute"
+                  type="java.lang.Integer"
+             writeable="false"/>
+
+    <attribute    name="active"
+           description="The number of established connections in the pool that are in use"
+                  type="java.lang.Integer"
+             writeable="false"/>
+
+    <attribute    name="numActive"
+           description="Same as the active attribute"
+                  type="java.lang.Integer"
+             writeable="false"/>
+
+    <attribute    name="poolSweeperEnabled"
+           description="Returns true if the pool has a background thread running"
+                  type="java.lang.Boolean"
+                    is="true"
+             writeable="false"/>
+
+    <attribute    name="url"
+           description="The JDBC url for this connection pool"
+                  type="java.lang.String"
+             writeable="false"/>
+
+    <attribute    name="driverClassName"
+           description="The JDBC driver class for this connection pool"
+                  type="java.lang.String"
+             writeable="false"/>
+
+    <attribute    name="defaultAutoCommit"
+           description="The JDBC auto commit setting for new connections"
+                  type="java.lang.Boolean"
+                    is="true"
+             writeable="false"/>
+
+    <attribute    name="defaultReadOnly"
+           description="The JDBC read only setting for new connections"
+                  type="java.lang.Boolean"
+                    is="true"
+             writeable="false"/>
+
+    <attribute    name="defaultTransactionIsolation"
+           description="The JDBC transaction isolation setting for new connections"
+                  type="java.lang.Integer"
+             writeable="false"/>
+
+    <attribute    name="connectionProperties"
+           description="The connection properties that will be set for new connections. Format of the string will be [propertyName=property;]*"
+                  type="java.lang.String"
+             writeable="false"/>
+
+    <attribute    name="defaultCatalog"
+           description="The JDBC transaction isolation setting for new connections"
+                  type="java.lang.String"
+             writeable="false"/>
+
+    <attribute    name="initialSize"
+           description="The number of connections opened at pool startup"
+                  type="java.lang.Integer"
+             writeable="false"/>
+
+    <attribute    name="maxActive"
+           description="The maximum number of open connections"
+                  type="java.lang.Integer"
+             writeable="false"/>
+
+    <attribute    name="maxIdle"
+           description="The max number of idle connections"
+                  type="java.lang.Integer"
+             writeable="false"/>
+
+    <attribute    name="minIdle"
+           description="The minimum number of open connections"
+                  type="java.lang.Integer"
+             writeable="false"/>
+
+    <attribute    name="maxWait"
+           description="The time to wait in milliseconds before a SQLException is thrown when a connection is requested"
+                  type="java.lang.Integer"
+             writeable="false"/>
+
+    <attribute    name="validationQuery"
+           description="The query to run during validation"
+                  type="java.lang.String"
+             writeable="false"/>
+
+    <attribute    name="validationQueryTimeout"
+           description="The timeout in seconds before a connection validation queries fail"
+                  type="java.lang.Integer"
+             writeable="false" />
+
+    <attribute    name="testOnBorrow"
+           description="True if validation happens when a connection is requested"
+                  type="java.lang.Boolean"
+                    is="true"
+             writeable="false"/>
+
+    <attribute    name="testOnReturn"
+           description="True if validation happens when a connection is returned"
+                  type="java.lang.Boolean"
+                    is="true"
+             writeable="false"/>
+
+    <attribute    name="testWhileIdle"
+           description="True if validation happens when a connection is not in use (idle)"
+                  type="java.lang.Boolean"
+                    is="true"
+             writeable="false"/>
+
+    <attribute    name="timeBetweenEvictionRunsMillis"
+           description="Sleep time for background thread in between pool checks"
+                  type="java.lang.Integer"
+             writeable="false"/>
+
+    <attribute    name="numTestsPerEvictionRun"
+           description="Not in use"
+                  type="java.lang.Integer"
+             writeable="false"/>
+
+    <attribute    name="minEvictableIdleTimeMillis"
+           description="Minimum amount of time a connection stays idle before it is evicted"
+                  type="java.lang.Integer"
+             writeable="false"/>
+
+    <attribute    name="accessToUnderlyingConnectionAllowed"
+           description="Returns true if one can retrieve the actual JDBC connection"
+                  type="java.lang.Boolean"
+                    is="true"
+             writeable="false"/>
+
+    <attribute    name="removeAbandoned"
+           description="Returns true if connection in use can be timed out"
+                  type="java.lang.Boolean"
+                    is="true"
+             writeable="false"/>
+
+    <attribute    name="removeAbandonedTimeout"
+           description="Timeout in seconds for connections in use"
+                  type="java.lang.Integer"
+             writeable="false"/>
+
+    <attribute    name="logAbandoned"
+           description="If true, stack trace will be recorded and printed out for timed out connection"
+                  type="java.lang.Boolean"
+                    is="true"
+             writeable="false"/>
+
+    <attribute    name="loginTimeout"
+           description="Not in use"
+                  type="java.lang.Integer"
+             writeable="false"/>
+
+
+    <attribute    name="name"
+           description="The name of the connection pool, will be used in the ObjectName of the actual pool"
+                  type="java.lang.String"
+             writeable="false"/>
+
+    <attribute    name="password"
+           description="For security purposes,this doesn't return anything"
+                  type="java.lang.String"
+             writeable="false"/>
+
+    <attribute    name="username"
+           description="The username used to open connections"
+                  type="java.lang.String"
+             writeable="false"/>
+
+    <attribute    name="validationInterval"
+           description="If larger than zero than validation will only occur after the interval milliseconds has passed"
+                  type="java.lang.Long"
+             writeable="false"/>
+
+    <attribute    name="initSQL"
+           description="A SQL executed once per connection, when it is established"
+                  type="java.lang.String"
+             writeable="false"/>
+
+    <attribute    name="testOnConnect"
+           description="Validate connection after connection has been established"
+                  type="java.lang.Boolean"
+                    is="true"
+             writeable="false"/>
+
+    <attribute    name="jdbcInterceptors"
+           description="The interceptors configured for this pool"
+                  type="java.lang.String"
+             writeable="false"/>
+
+    <attribute    name="jmxEnabled"
+           description="Register the pool with JMX or not"
+                  type="java.lang.Boolean"
+                    is="true"
+             writeable="false"/>
+
+    <attribute    name="fairQueue"
+           description="a fair queue is being used by the connection pool"
+                  type="java.lang.Boolean"
+                    is="true"
+             writeable="false"/>
+
+    <attribute    name="abandonWhenPercentageFull"
+           description="Connections that have been abandoned isn't closed unless connections in use are above this percentage"
+                  type="java.lang.Integer"
+             writeable="false"/>
+
+    <attribute    name="maxAge"
+           description="Time in milliseconds to keep this connection alive even when used"
+                  type="java.lang.Long"
+             writeable="false"/>
+
+    <attribute    name="useEquals"
+           description="Set to true if you wish the ProxyConnection class to use String.equals and set to false when you wish to use == when comparing method names"
+                  type="java.lang.Boolean"
+                    is="true"
+             writeable="false"/>
+
+    <attribute    name="useLock"
+           description="If true, use a lock when operations are performed on the connection object"
+                  type="java.lang.Boolean"
+                    is="false"
+             writeable="false"/>
+
+    <attribute    name="suspectTimeout"
+           description="Timeout in seconds for connection that suspected to have been abandoned"
+                  type="java.lang.Integer"
+             writeable="false"/>
+
+    <attribute    name="rollbackOnReturn"
+           description="If autoCommit==false then the pool can terminate the transaction by calling rollback on the connection as it is returned to the pool"
+                  type="java.lang.Boolean"
+                    is="false"
+             writeable="false"/>
+
+    <attribute    name="commitOnReturn"
+           description="If autoCommit==false then the pool can complete the transaction by calling commit on the connection as it is returned to the pool"
+                  type="java.lang.Boolean"
+                    is="false"
+             writeable="false"/>
+
+    <attribute    name="alternateUsernameAllowed"
+           description="If true, getConnection(username,password) is allowed"
+                  type="java.lang.Boolean"
+                    is="true"
+             writeable="false"/>
+
+    <attribute    name="dataSource"
+           description="Data source that is injected into the pool"
+                  type="javax.sql.DataSource"
+             writeable="false"/>
+
+    <attribute    name="dataSourceJNDI"
+           description="The JNDI name for a data source to be looked up"
+                  type="java.lang.String"
+             writeable="false"/>
+
+    <attribute    name="useDisposableConnectionFacade"
+           description="If true, connection pool is configured to use a connection facade to prevent re-use of connection after close() has been invoked"
+                  type="java.lang.Boolean"
+                    is="false"
+             writeable="false"/>
+
+    <attribute    name="logValidationErrors"
+           description="Log errors during the validation phase to the log file"
+                  type="java.lang.Boolean"
+                    is="false"
+             writeable="false"/>
+
+    <attribute    name="validatorClassName"
+           description="The name of validator class which implements org.apache.tomcat.jdbc.pool.Validator interface"
+                  type="java.lang.String"
+             writeable="false"/>
+
+    <attribute    name="waitCount"
+           description="The number of threads waiting for a connection"
+                  type="java.lang.Integer"
+             writeable="false"/>
+
+    <attribute    name="propagateInterruptState"
+           description="If true, propagate the interrupt state for a thread that has been interrupted"
+                  type="java.lang.Boolean"
+                    is="false"
+             writeable="false"/>
+
+    <attribute    name="ignoreExceptionOnPreLoad"
+           description="If true, ignore error of connection creation while initializing the pool"
+                  type="java.lang.Boolean"
+                    is="true"
+             writeable="false"/>
+
+    <attribute    name="borrowedCount"
+           description="The total number of connections borrowed from this pool"
+                  type="java.lang.Long"
+             writeable="false"/>
+
+    <attribute    name="createdCount"
+           description="The total number of connections created by this pool"
+                  type="java.lang.Long"
+             writeable="false"/>
+
+    <attribute    name="returnedCount"
+           description="The total number of connections returned to this pool"
+                  type="java.lang.Long"
+             writeable="false"/>
+
+    <attribute    name="releasedCount"
+           description="The total number of connections released from this pool"
+                  type="java.lang.Long"
+             writeable="false"/>
+
+    <attribute    name="reconnectedCount"
+           description="The total number of connections reconnected by this pool."
+                  type="java.lang.Long"
+             writeable="false"/>
+
+    <attribute    name="removeAbandonedCount"
+           description="The total number of connections released by remove abandoned."
+                  type="java.lang.Long"
+             writeable="false"/>
+
+    <attribute    name="releasedIdleCount"
+           description="The total number of connections released by eviction."
+                  type="java.lang.Long"
+             writeable="false"/>
+
+    <operation    name="checkIdle"
+                  description="forces a check of idle connections"
+                  impact="ACTION"
+                  returnType="void" />
+
+    <operation    name="checkAbandoned"
+                  description="forces a check of abandoned connections"
+                  impact="ACTION"
+                  returnType="void" />
+
+    <operation    name="testIdle"
+                  description="forces a validation of abandoned connections"
+                  impact="ACTION"
+                  returnType="void" />
+
+    <operation    name="purge"
+                  description="Purges all connections in the pool"
+                  impact="ACTION"
+                  returnType="void" />
+
+    <operation    name="purgeOnReturn"
+                  description="Purges connections when they are returned from the pool"
+                  impact="ACTION"
+                  returnType="void" />
+
+    <operation    name="resetStats"
+                  description="reset the statistics of this pool."
+                  impact="ACTION"
+                  returnType="void" />
+
+  </mbean>
+
+</mbeans-descriptors>
diff --git a/dblib/common/src/main/java/org/openecomp/sdnc/sli/resource/common/CommonActivator.java b/dblib/common/src/main/java/org/openecomp/sdnc/sli/resource/common/CommonActivator.java
new file mode 100644
index 0000000..6a0ed06
--- /dev/null
+++ b/dblib/common/src/main/java/org/openecomp/sdnc/sli/resource/common/CommonActivator.java
@@ -0,0 +1,40 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * openecomp
+ * ================================================================================
+ * Copyright (C) 2016 - 2017 AT&T
+ * ================================================================================
+ * Licensed 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.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.sdnc.sli.resource.common;
+
+import org.osgi.framework.BundleActivator;
+import org.osgi.framework.BundleContext;
+
+public class CommonActivator implements BundleActivator {
+
+	@Override
+	public void start(BundleContext context) throws Exception {
+		// TODO Auto-generated method stub
+
+	}
+
+	@Override
+	public void stop(BundleContext context) throws Exception {
+		// TODO Auto-generated method stub
+
+	}
+
+}
diff --git a/dblib/features/src/main/resources/features.xml b/dblib/features/src/main/resources/features.xml
index cc080aa..d7f0030 100755
--- a/dblib/features/src/main/resources/features.xml
+++ b/dblib/features/src/main/resources/features.xml
@@ -10,6 +10,7 @@
     <feature name='sdnc-dblib' description="sdnc-dblib" version='${project.version}'>
         <!-- Most applications will have a dependency on the ODL MD-SAL Broker -->
         <feature version="${odl.mdsal.version}">odl-mdsal-broker</feature>
+        <bundle>mvn:org.openecomp.sdnc.core/dblib-common/${project.version}</bundle>
         <bundle>mvn:org.openecomp.sdnc.core/dblib-provider/${project.version}</bundle>
         <bundle>mvn:mysql/mysql-connector-java/${mysql.connector.version}</bundle>
     </feature>
diff --git a/dblib/pom.xml b/dblib/pom.xml
index 0534e07..5adb663 100755
--- a/dblib/pom.xml
+++ b/dblib/pom.xml
@@ -119,6 +119,7 @@
         <name>AT&amp;T</name>
     </organization>
   <modules>
+    <module>common</module>
     <module>provider</module>
     <module>features</module>
     <module>installer</module>
diff --git a/dblib/provider/pom.xml b/dblib/provider/pom.xml
index 71de996..913adf3 100755
--- a/dblib/provider/pom.xml
+++ b/dblib/provider/pom.xml
@@ -47,6 +47,11 @@
 			<artifactId>mysql-connector-java</artifactId>
 			<version>${mysql.connector.version}</version>
 		</dependency>
+		<dependency>
+			<groupId>org.openecomp.sdnc.core</groupId>
+			<artifactId>dblib-common</artifactId>
+			<version>${project.version}</version>
+		</dependency>
 	</dependencies>
 
 	<build>
@@ -61,7 +66,10 @@
 						<Bundle-SymbolicName>org.openecomp.sdnc.sli.resource.dblib</Bundle-SymbolicName>
 						<Bundle-Activator>org.openecomp.sdnc.sli.resource.dblib.DBLIBResourceActivator</Bundle-Activator>
 						<Export-Package>org.openecomp.sdnc.sli.resource.dblib;version=${project.version}</Export-Package>
-						<Import-Package>org.openecomp.sdnc.sli.*,org.osgi.framework.*,org.slf4j.*,com.mysql.jdbc.*,javax.sql.*</Import-Package>
+						<!--
+						<Import-Package>org.openecomp.sdnc.sli.*,org.osgi.framework.*,org.slf4j.*,com.mysql.jdbc.*,javax.sql.*,org.apache.tomcat.*</Import-Package>
+						-->
+						<Import-Package>*</Import-Package>
 						<Embed-Transitive>true</Embed-Transitive>
 					</instructions>
 				</configuration>
diff --git a/dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/CachedDataSourceFactory.java b/dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/CachedDataSourceFactory.java
index f774748..3e51ed9 100644
--- a/dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/CachedDataSourceFactory.java
+++ b/dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/CachedDataSourceFactory.java
@@ -23,9 +23,8 @@
 
 import org.openecomp.sdnc.sli.resource.dblib.config.BaseDBConfiguration;
 import org.openecomp.sdnc.sli.resource.dblib.config.JDBCConfiguration;
-import org.openecomp.sdnc.sli.resource.dblib.config.JndiConfiguration;
+import org.openecomp.sdnc.sli.resource.dblib.jdbc.JdbcDBCachedDataSource;
 import org.openecomp.sdnc.sli.resource.dblib.jdbc.MySQLCachedDataSource;
-import org.openecomp.sdnc.sli.resource.dblib.jndi.JndiCachedDataSource;
 
 /**
  * @version $Revision: 1.1 $
@@ -38,9 +37,8 @@
 
 	public static CachedDataSource createDataSource(BaseDBConfiguration config) {
 		if(config instanceof JDBCConfiguration)
-			return MySQLCachedDataSource.createInstance(config);
-		if(config instanceof JndiConfiguration)
-			return JndiCachedDataSource.createInstance(config);
+			return JdbcDBCachedDataSource.createInstance(config);
+
 		return (CachedDataSource)null;
 	}
 
diff --git a/dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/DBResourceManager.java b/dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/DBResourceManager.java
index 7f85c42..401c013 100644
--- a/dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/DBResourceManager.java
+++ b/dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/DBResourceManager.java
@@ -53,7 +53,6 @@
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import com.sun.rowset.providers.RIOptimisticProvider;
 
 /**
  * @version $Revision: 1.15 $
@@ -87,7 +86,7 @@
 			}
 			return 0;
 		}
-		
+
 	});
 	protected final Set<CachedDataSource> broken = Collections.synchronizedSet(new HashSet<CachedDataSource>());
 	protected final Object monitor = new Object();
@@ -131,17 +130,6 @@
 		worker.setName("DBResourcemanagerWatchThread");
 		worker.setDaemon(true);
 		worker.start();
-		
-		try {
-			RIOptimisticProvider rio  = new RIOptimisticProvider();
-			LOGGER.info("Class " + rio.getClass().getName() + " found.");
-			Class clas = this.getClass().getClassLoader().loadClass("com.sun.rowset.providers.RIOptimisticProvider");
-			if(clas != null) {
-				LOGGER.info("Class " + rio.getClass().getName() + " found by classloader.");
-			}
-		} catch(Exception exc) {
-			LOGGER.info("Failed resolving RIOptimisticProvider class", exc);
-		}
 	}
 
 	private void config(Properties ctx) throws Exception {
@@ -320,7 +308,7 @@
 			Collections.reverse(sources);
 		}
 
-		
+
 		// loop through available data sources to retrieve data.
 		while(!sources.isEmpty())
 		{
@@ -428,7 +416,7 @@
 	public boolean writeData(String statement, ArrayList<String> arguments, String preferredDS) throws SQLException {
 		return writeDataNoRecovery(statement, arguments, preferredDS);
 	}
-	
+
 	CachedDataSource findMaster() {
 		CachedDataSource master = null;
 		CachedDataSource[] dss = this.dsQueue.toArray(new CachedDataSource[0]);
@@ -468,7 +456,7 @@
 						active = master;
 					}
 				}
-				
+
 				return active.writeData(statement, arguments);
 			} catch(Throwable exc){
 				String message = exc.getMessage();
diff --git a/dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/config/DbConfigPool.java b/dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/config/DbConfigPool.java
index 90ea6bc..117f932 100644
--- a/dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/config/DbConfigPool.java
+++ b/dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/config/DbConfigPool.java
@@ -46,10 +46,6 @@
 		return type;
 	}
 
-	public JndiConfiguration[] getJndiDbSourceArray() {
-		return configurations.toArray(new JndiConfiguration[configurations.size()]);
-	}
-
 	public JDBCConfiguration[] getJDBCbSourceArray() {
 		return configurations.toArray(new JDBCConfiguration[configurations.size()]);
 	}
diff --git a/dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/factory/AbstractDBResourceManagerFactory.java b/dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/factory/AbstractDBResourceManagerFactory.java
index e6b1a35..f4291a7 100644
--- a/dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/factory/AbstractDBResourceManagerFactory.java
+++ b/dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/factory/AbstractDBResourceManagerFactory.java
@@ -21,7 +21,6 @@
 package org.openecomp.sdnc.sli.resource.dblib.factory;
 
 import org.openecomp.sdnc.sli.resource.dblib.jdbc.JdbcDbResourceManagerFactory;
-import org.openecomp.sdnc.sli.resource.dblib.jndi.JNDIDbResourceManagerFactory;
 
 /**
  * @version $Revision: 1.1 $
@@ -33,13 +32,7 @@
 public class AbstractDBResourceManagerFactory {
 
 	public static AbstractResourceManagerFactory getFactory(String type) throws FactoryNotDefinedException {
-		
-		if("JNDI".equals(type)){
-			try {
-				return JNDIDbResourceManagerFactory.createIntstance();
-			} catch (Exception e) {
-			}
-		}
+
 		// JDBC
 		return JdbcDbResourceManagerFactory.createIntstance();
 	}
diff --git a/dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/factory/AbstractResourceManagerFactory.java b/dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/factory/AbstractResourceManagerFactory.java
index 148ddac..29ec061 100644
--- a/dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/factory/AbstractResourceManagerFactory.java
+++ b/dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/factory/AbstractResourceManagerFactory.java
@@ -32,7 +32,6 @@
 import org.openecomp.sdnc.sli.resource.dblib.config.BaseDBConfiguration;
 import org.openecomp.sdnc.sli.resource.dblib.config.DbConfigPool;
 import org.openecomp.sdnc.sli.resource.dblib.config.JDBCConfiguration;
-import org.openecomp.sdnc.sli.resource.dblib.config.JndiConfiguration;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -49,20 +48,15 @@
 	public abstract CachedDataSource[] initDBResourceManager(DbConfigPool dbConfig, DBResourceManager manager) throws Exception;
 	public abstract CachedDataSource[] initDBResourceManager(DbConfigPool dbConfig,	DBResourceManager dbResourceManager, String sourceName) throws SQLException ;
 
-	
+
 	public static AbstractResourceManagerFactory createIntstance() throws FactoryNotDefinedException {
 		throw new FactoryNotDefinedException("Factory method 'createIntstance' needs to be overriden in DBResourceManagerFactory");
 	}
 
-	public class DBInitTask implements Callable<CachedDataSource> 
+	public class DBInitTask implements Callable<CachedDataSource>
 	{
 		private BaseDBConfiguration config = null;
 		private Set<DBInitTask> activeTasks;
-		
-		public DBInitTask(JndiConfiguration jndiConfig, Set<DBInitTask> tasks){
-			this.config = jndiConfig;
-			this.activeTasks = tasks;
-		}
 
 		public DBInitTask(JDBCConfiguration jdbcconfig, Set<DBInitTask> tasks) {
 			this.config = jdbcconfig;
@@ -97,6 +91,7 @@
 						worker.start();
 					} else {
 						if(LOGGER.isDebugEnabled())
+							if(ds != null)
 							LOGGER.debug("Completed CachedDataSource.Call from "+ds.getDbConnectionName());
 					}
 				}
diff --git a/dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/factory/DBConfigFactory.java b/dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/factory/DBConfigFactory.java
index 7044082..3530459 100644
--- a/dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/factory/DBConfigFactory.java
+++ b/dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/factory/DBConfigFactory.java
@@ -25,10 +25,11 @@
 import java.util.Iterator;
 import java.util.Properties;
 
+import org.slf4j.LoggerFactory;
+
 import org.openecomp.sdnc.sli.resource.dblib.config.BaseDBConfiguration;
 import org.openecomp.sdnc.sli.resource.dblib.config.DbConfigPool;
 import org.openecomp.sdnc.sli.resource.dblib.config.JDBCConfiguration;
-import org.openecomp.sdnc.sli.resource.dblib.config.JndiConfiguration;
 
 /**
  * @version $Revision: 1.1 $
@@ -44,7 +45,7 @@
 	}
 
 	static DbConfigPool getConfigparams(Properties properties){
-		org.slf4j.LoggerFactory.getLogger(DBConfigFactory.class).info(properties.toString());
+		LoggerFactory.getLogger(DBConfigFactory.class).info(properties.toString());
 		DbConfigPool xmlConfig = new DbConfigPool(properties);
 		ArrayList<Properties> propertySets = new ArrayList<Properties>();
 
@@ -78,7 +79,7 @@
 			}
 
 		} catch (Exception e) {
-			org.slf4j.LoggerFactory.getLogger(DBConfigFactory.class).warn("",e);
+			LoggerFactory.getLogger(DBConfigFactory.class).warn("",e);
 		}
 
 		return xmlConfig;
@@ -89,15 +90,12 @@
 		String type = props.getProperty(BaseDBConfiguration.DATABASE_TYPE);
 
 		BaseDBConfiguration config = null;
-		
-		if("JNDI".equalsIgnoreCase(type)) {
-			config = new JndiConfiguration(props);
-		}
+
 		if("JDBC".equalsIgnoreCase(type)) {
 			config = new JDBCConfiguration(props);
 		}
 
 		return config;
-		
+
 	}
 }
diff --git a/dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/jdbc/JdbcDBCachedDataSource.java b/dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/jdbc/JdbcDBCachedDataSource.java
new file mode 100644
index 0000000..ee3d4ff
--- /dev/null
+++ b/dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/jdbc/JdbcDBCachedDataSource.java
@@ -0,0 +1,252 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * openecomp
+ * ================================================================================
+ * Copyright (C) 2016 - 2017 AT&T
+ * ================================================================================
+ * Licensed 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.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.sdnc.sli.resource.dblib.jdbc;
+
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLFeatureNotSupportedException;
+
+import org.apache.tomcat.jdbc.pool.DataSource;
+import org.apache.tomcat.jdbc.pool.PoolProperties;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.openecomp.sdnc.sli.resource.dblib.CachedDataSource;
+import org.openecomp.sdnc.sli.resource.dblib.DBConfigException;
+import org.openecomp.sdnc.sli.resource.dblib.config.BaseDBConfiguration;
+import org.openecomp.sdnc.sli.resource.dblib.config.JDBCConfiguration;
+import com.mysql.jdbc.Driver;
+
+
+/**
+ * @version $Revision: 1.7 $
+ * Change Log
+ * Author         Date     Comments
+ * ============== ======== ====================================================
+ * Rich Tabedzki
+ */
+
+public class JdbcDBCachedDataSource extends CachedDataSource
+{
+	private String dbUserId;
+	private String dbPasswd;
+	private String dbUrl;
+
+	private int minLimit;
+	private int maxLimit;
+	private int initialLimit;
+
+	private static final String AS_CONF_ERROR = "AS_CONF_ERROR: ";
+
+	private static Logger LOGGER = LoggerFactory.getLogger(JdbcDBCachedDataSource.class);
+
+	/**
+	 * @param jdbcElem
+	 * @param alarmLog
+	 * @param occManager
+	 * @throws Exception
+	 */
+	public JdbcDBCachedDataSource(BaseDBConfiguration jdbcElem)
+	{
+			super(jdbcElem);
+	}
+
+	@Override
+	protected void configure(BaseDBConfiguration xmlElem) throws DBConfigException
+	{
+		BaseDBConfiguration jdbcConfig = (BaseDBConfiguration)xmlElem;
+		if(jdbcConfig.getConnTimeout() > 0){
+			this.CONN_REQ_TIMEOUT = jdbcConfig.getConnTimeout();
+		}
+		if(jdbcConfig.getRequestTimeout() > 0){
+				this.DATA_REQ_TIMEOUT = jdbcConfig.getRequestTimeout();
+		}
+
+    	// set connection pool name
+		String dbConnectionName = jdbcConfig.getDbConnectionName();
+    	super.setDbConnectionName(dbConnectionName);
+    	// Configure the JDBC connection
+    	dbUserId = jdbcConfig.getDbUserId();
+        if (dbUserId == null)
+        {
+        	String errorMsg =  "Invalid XML contents: JDBCConnection missing dbUserId attribute";
+        	LOGGER.error(AS_CONF_ERROR + errorMsg);
+            throw new DBConfigException(errorMsg);
+        }
+
+        dbPasswd = jdbcConfig.getDbPasswd();
+        if (dbPasswd == null)
+        {
+        	String errorMsg =  "Invalid XML contents: JDBCConnection missing dbPasswd attribute";
+        	LOGGER.error(AS_CONF_ERROR + errorMsg);
+            throw new DBConfigException(errorMsg);
+        }
+        /*
+        dbDriver = jdbcConfig.getDbDriver();
+        if (dbDriver == null)
+        {
+        	String errorMsg =  "Invalid XML contents: JDBCConnection missing dbDriver attribute";
+        	LOGGER.error(AS_CONF_ERROR + errorMsg);
+        	throw new ScpTblUpdateError(errorMsg);
+        }
+        */
+
+        minLimit = jdbcConfig.getDbMinLimit();
+//        if (minLimit == null)
+//        {
+//        	String errorMsg =  "Invalid XML contents: JDBC Connection missing minLimit attribute";
+//        	LOGGER.error(AS_CONF_ERROR + errorMsg);
+//        	throw new DBConfigException(errorMsg);
+//        }
+        maxLimit =  jdbcConfig.getDbMaxLimit();
+//        if (maxLimit == null)
+//        {
+//        	String errorMsg =  "Invalid XML contents: JDBC Connection missing maxLimit attribute";
+//        	LOGGER.error(AS_CONF_ERROR + errorMsg);
+//        	throw new DBConfigException(errorMsg);
+//        }
+        initialLimit =  jdbcConfig.getDbInitialLimit();
+//        if (initialLimit == null)
+//        {
+//        	String errorMsg =  "Invalid XML contents: JDBC Connection missing initialLimit attribute";
+//        	LOGGER.error(AS_CONF_ERROR + errorMsg);
+//        	throw new DBConfigException(errorMsg);
+//        }
+
+        dbUrl = jdbcConfig.getDbUrl();
+        if(dbUrl == null){
+        	String errorMsg =  "Invalid XML contents: JDBCConnection missing dbUrl attribute";
+        	LOGGER.error(AS_CONF_ERROR + errorMsg);
+            throw new DBConfigException(errorMsg);
+        }
+
+		try {
+			Driver dr = new com.mysql.jdbc.Driver();
+			Class clazz = Class.forName("com.mysql.jdbc.Driver") ;
+
+			PoolProperties p = new PoolProperties();
+			p.setDriverClassName("com.mysql.jdbc.Driver");
+			p.setUrl(dbUrl);
+			p.setUsername(dbUserId);
+			p.setPassword(dbPasswd);
+			p.setJmxEnabled(true);
+			p.setTestWhileIdle(false);
+			p.setTestOnBorrow(true);
+			p.setValidationQuery("SELECT 1");
+			p.setTestOnReturn(false);
+			p.setValidationInterval(30000);
+			p.setTimeBetweenEvictionRunsMillis(30000);
+			p.setInitialSize(initialLimit);
+			p.setMaxActive(maxLimit);
+			p.setMaxIdle(maxLimit);
+			p.setMaxWait(10000);
+			p.setRemoveAbandonedTimeout(60);
+			p.setMinEvictableIdleTimeMillis(30000);
+			p.setMinIdle(minLimit);
+			p.setLogAbandoned(true);
+			p.setRemoveAbandoned(true);
+			p.setJdbcInterceptors("org.apache.tomcat.jdbc.pool.interceptor.ConnectionState;"
+					+ "org.apache.tomcat.jdbc.pool.interceptor.StatementFinalizer");
+
+			DataSource dataSource = new DataSource(p);
+
+			synchronized(this)
+			{
+				this.ds = dataSource;
+				Connection con = null;
+				PreparedStatement st = null;
+				ResultSet rs = null;
+
+				try {
+					con = dataSource.getConnection();
+					st = con.prepareStatement("Select 1 FROM DUAL");
+					rs = st.executeQuery();
+				} catch(Exception exc) {
+					LOGGER.error(exc.getMessage());
+				} finally {
+					if(rs != null) rs.close();
+					if(st != null) st.close();
+					if(con != null) con.close();
+				}
+
+				initialized = true;
+				LOGGER.info("MySQLDataSource <"+dbConnectionName+"> configured successfully. Using URL: "+dbUrl);
+			}
+
+//		} catch (SQLException exc) {
+//			initialized = false;
+//			StringBuffer sb = new StringBuffer();
+//			sb.append("Failed to initialize MySQLDataSource<");
+//			sb.append(dbConnectionName).append(">. Reason: ");
+//			sb.append(exc.getMessage());
+//			LOGGER.error("AS_CONF_ERROR: " + sb.toString());
+////			throw new DBConfigException(e.getMessage());
+		} catch (Exception exc) {
+    		initialized = false;
+			StringBuffer sb = new StringBuffer();
+			sb.append("Failed to initialize MySQLCachedDataSource <");
+			sb.append(dbConnectionName).append(">. Reason: ");
+			sb.append(exc.getMessage());
+			LOGGER.error("AS_CONF_ERROR: " + sb.toString());
+//    		throw new DBConfigException(e.getMessage());
+    	}
+    }
+
+	public final String getDbUrl()
+	{
+		return dbUrl;
+	}
+
+	public final String getDbUserId()
+	{
+		return dbUserId;
+	}
+
+	public final String getDbPasswd()
+	{
+		return dbPasswd;
+	}
+
+	public static JdbcDBCachedDataSource createInstance(BaseDBConfiguration config) /*throws Exception*/ {
+		return new JdbcDBCachedDataSource(config);
+	}
+
+	public String toString(){
+		return getDbConnectionName();
+	}
+
+	public java.util.logging.Logger getParentLogger()
+			throws SQLFeatureNotSupportedException {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	public void cleanUp(){
+		DataSource dataSource = (DataSource)ds;
+		dataSource.getPool().purge();
+		int active = dataSource.getActive();
+		int size = dataSource.getSize();
+		dataSource.close(true);
+		super.cleanUp();
+	}
+
+}
diff --git a/dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/jndi/JNDIDbResourceManagerFactory.java b/dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/jndi/JNDIDbResourceManagerFactory.java
deleted file mode 100644
index 2888bc5..0000000
--- a/dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/jndi/JNDIDbResourceManagerFactory.java
+++ /dev/null
@@ -1,167 +0,0 @@
-/*-
- * ============LICENSE_START=======================================================
- * openecomp
- * ================================================================================
- * Copyright (C) 2016 - 2017 AT&T
- * ================================================================================
- * Licensed 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.
- * ============LICENSE_END=========================================================
- */
-
-package org.openecomp.sdnc.sli.resource.dblib.jndi;
-
-import java.sql.SQLException;
-import java.util.HashSet;
-import java.util.Set;
-import java.util.concurrent.Callable;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-import java.util.concurrent.FutureTask;
-
-import org.openecomp.sdnc.sli.resource.dblib.CachedDataSource;
-import org.openecomp.sdnc.sli.resource.dblib.CachedDataSourceFactory;
-import org.openecomp.sdnc.sli.resource.dblib.DBResourceManager;
-import org.openecomp.sdnc.sli.resource.dblib.config.DbConfigPool;
-import org.openecomp.sdnc.sli.resource.dblib.config.JndiConfiguration;
-import org.openecomp.sdnc.sli.resource.dblib.factory.AbstractResourceManagerFactory;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * @version $Revision: 1.6 $
- * Change Log
- * Author         Date     Comments
- * ============== ======== ====================================================
- * Rich Tabedzki
- */
-public class JNDIDbResourceManagerFactory extends AbstractResourceManagerFactory {
-
-	private static Logger LOGGER = LoggerFactory.getLogger(JNDIDbResourceManagerFactory.class);
-
-	class MyFutureTask extends FutureTask<DBInitTask>
-	{
-
-		public MyFutureTask(Callable<CachedDataSource> result) {
-			super((Callable)result);
-		}
-		
-	}
-
-	public CachedDataSource[] initDBResourceManager(DbConfigPool dbConfig, DBResourceManager manager, String sourceName) throws SQLException 
-	{	
-		// here create the data sources objects
-		JndiConfiguration[] list = dbConfig.getJndiDbSourceArray();
-		CachedDataSource[] cachedDS = new CachedDataSource[1];
-
-		for(int i=0, max=list.length; i<max; i++){
-			if(!sourceName.equals(list[i].getJndiConnectionName()))
-				continue;
-
-			JndiConfiguration config = list[i];
-			CachedDataSource dataSource = CachedDataSourceFactory.createDataSource(config);
-			cachedDS[0] = dataSource;
-		}
-		return cachedDS;
-	}
-	
-	public CachedDataSource[] initDBResourceManager(DbConfigPool dbConfig, DBResourceManager manager) /* throws Exception */ {
-//		WSConfigManagement ws = WSConfigManagement.getInstance();
-		
-		ExecutorService threadExecutor = Executors.newFixedThreadPool(2);
-		// here create the data sources objects
-		JndiConfiguration[] list = dbConfig.getJndiDbSourceArray();
-		FutureTask<DBInitTask>[] futures = new MyFutureTask[list.length];
-		final Set<DBInitTask> tasks = new HashSet<DBInitTask>();
-		if(LOGGER.isDebugEnabled())
-			LOGGER.debug("Creating datasources.");
-		for(int i=0, max=list.length; i<max; i++){
-			JndiConfiguration config = list[i];
-//			if(manager.getJndiContextFactoryStr()!=null && manager.getJndiContextFactoryStr().trim().length()>0){
-//				config.setJndiContextFactory(manager.getJndiContextFactoryStr());
-//			}
-//			if(manager.getJndiURLStr()!=null && manager.getJndiURLStr().trim().length()>0){
-//				config.setJndiURL(manager.getJndiURLStr());
-//			}
-			DBInitTask task = new DBInitTask(config, tasks);
-			tasks.add(task);
-			futures[i] = new MyFutureTask(task);
-		}
-
-		try {
-			synchronized(tasks){
-				for(int i=0, max=list.length; i<max; i++){
-					threadExecutor.execute(futures[i]);
-				}
-				// the timeout param is set is seconds. 
-				long timeout = ((dbConfig.getTimeout() <= 0) ? 60L : dbConfig.getTimeout());
-				timeout *= 1000;
-				// the timeout param is set is seconds, hence it needs to be multiplied by 1000. 
-				tasks.wait(timeout);
-				if(LOGGER.isDebugEnabled())
-					LOGGER.debug("initDBResourceManager wait completed.");
-			}
-		} catch(Exception exc) {
-			LOGGER.error("Failed to initialize JndiCachedDataSource. Reason: ", exc);
-		}
-		
-		if(threadExecutor != null){
-			try {
-				threadExecutor.shutdown();
-			} catch(Exception exc){}
-		}
-
-		CachedDataSource[] cachedDS = new CachedDataSource[futures.length];
-		
-		boolean initialized = false;
-		for(int i=0; i<futures.length; i++){
-			Object obj = null;
-			if(futures[i].isDone()){
-				try {
-					obj = futures[i].get();
-					if(obj instanceof CachedDataSource){
-						cachedDS[i] = (CachedDataSource)obj;
-						initialized = true;
-						LOGGER.info("DataSource "+list[i].getJndiConnectionName()+" initialized successfully");
-					}
-				} catch (InterruptedException exc) {
-					LOGGER.error("DataSource "+list[i].getJndiConnectionName()+" initialization failed", exc);
-				} catch (ExecutionException exc) {
-					LOGGER.error("DataSource "+list[i].getJndiConnectionName()+" initialization failed", exc);
-				} catch (Exception exc) {
-					LOGGER.error("DataSource "+list[i].getJndiConnectionName()+" initialization failed", exc);
-				}
-			} else {
-				try {
-					obj = futures[i].get();
-					if(obj instanceof CachedDataSource){
-
-						LOGGER.error("DataSource "+((CachedDataSource)obj).getDbConnectionName()+" failed");
-					}
-				} catch (Exception exc) {
-					LOGGER.error("DataSource "+list[i].getJndiConnectionName()+" initialization failed", exc);
-				}
-			}
-		}
-
-		if(!initialized){
-			new Error("Failed to initialize DB Library.");
-		}
-		return cachedDS;
-	}
-	
-	public static AbstractResourceManagerFactory createIntstance() {
-		return new JNDIDbResourceManagerFactory();
-	}
-
-}
diff --git a/dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/jndi/JndiCachedDataSource.java b/dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/jndi/JndiCachedDataSource.java
deleted file mode 100644
index 19fa8e9..0000000
--- a/dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/jndi/JndiCachedDataSource.java
+++ /dev/null
@@ -1,131 +0,0 @@
-/*-
- * ============LICENSE_START=======================================================
- * openecomp
- * ================================================================================
- * Copyright (C) 2016 - 2017 AT&T
- * ================================================================================
- * Licensed 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.
- * ============LICENSE_END=========================================================
- */
-
-package org.openecomp.sdnc.sli.resource.dblib.jndi;
-
-import java.sql.SQLFeatureNotSupportedException;
-import java.util.Properties;
-
-import javax.naming.Context;
-import javax.naming.InitialContext;
-import javax.naming.NamingException;
-
-import org.openecomp.sdnc.sli.resource.dblib.CachedDataSource;
-import org.openecomp.sdnc.sli.resource.dblib.DBConfigException;
-import org.openecomp.sdnc.sli.resource.dblib.config.BaseDBConfiguration;
-import org.openecomp.sdnc.sli.resource.dblib.config.JndiConfiguration;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.xml.sax.SAXException;
-
-/**
- * @version $Revision: 1.2 $
- * Change Log
- * Author         Date     Comments
- * ============== ======== ====================================================
- * Rich Tabedzki
- */
-public class JndiCachedDataSource extends CachedDataSource
-{
-	private static Logger LOGGER = LoggerFactory.getLogger(JndiCachedDataSource.class);
-	/**
-	 * @param alarmLog 
-	 * @param jdbcElem
-	 * @throws SAXException 
-	 * @throws ScpTblUpdateError 
-	 */
-	public JndiCachedDataSource(BaseDBConfiguration xmlElem) throws DBConfigException
-	{
-		super(xmlElem);
-	}
-
-	protected void configure(BaseDBConfiguration xmlElem) throws DBConfigException {
-		JndiConfiguration jdbcConfig = (JndiConfiguration)xmlElem;
-    	String jndiContextFactoryStr = jdbcConfig.getJndiContextFactory(); 
-    	String jndiURLStr = jdbcConfig.getJndiURL();
-    	String jndiSourceStr = jdbcConfig.getJndiSource();
-    	
-    	if(jdbcConfig.getConnTimeout() > 0){
-    		this.CONN_REQ_TIMEOUT = jdbcConfig.getConnTimeout();
-    	}
-		if(jdbcConfig.getRequestTimeout() > 0){
-			this.DATA_REQ_TIMEOUT = jdbcConfig.getRequestTimeout();
-		}
-    	
-    	super.setDbConnectionName(jdbcConfig.getJndiConnectionName());
-    	
-    	if(jndiContextFactoryStr == null || jndiContextFactoryStr.length() == 0)
-    	{
-//    		throw new DBConfigException("The jndi configuration is incomplete: jndiContextFactory");
-    	}
-    	if(jndiURLStr == null || jndiContextFactoryStr.length() == 0)
-    	{
-//    		throw new ScpTblUpdateError("The jndi configuration is incomplete: jndiURL");
-    	}
-    	if(jndiSourceStr == null || jndiSourceStr.length() == 0)
-    	{
-    		throw new DBConfigException("The jndi configuration is incomplete: jndiSource");
-    	}
-
-    	Properties env = new Properties();
-    	Context ctx; 
-		try
-		{
-			if(jndiContextFactoryStr != null && jndiContextFactoryStr.length() != 0){
-				env.put(Context.INITIAL_CONTEXT_FACTORY, jndiContextFactoryStr);
-				ctx = new InitialContext(env);
-			} else {
-				ctx = new InitialContext();
-			}
-			ds = (javax.sql.DataSource) ctx.lookup (jndiSourceStr);
-			if(ds == null)
-			{
-				this.initialized = false;
-				LOGGER.error("AS_CONF_ERROR: Failed to initialize DataSource <"+getDbConnectionName()+"> using JNDI <"+jndiSourceStr+">");
-				return;
-			} else {
-				this.initialized = true;
-				LOGGER.info("JndiCachedDataSource <"+getDbConnectionName()+"> configured successfully.");
-				return;
-			}
-		} catch (NamingException exc) {
-			this.initialized = false;
-			LOGGER.error("AS_CONF_ERROR" + exc.getMessage());
-
-		} catch(Throwable exc) {
-			this.initialized = false;
-			LOGGER.error("AS_CONF_ERROR: " + exc.getMessage());
-		}
-    }
-
-	public static JndiCachedDataSource createInstance(BaseDBConfiguration config) {
-		return new JndiCachedDataSource(config);
-	}
-	
-	public String toString(){
-		return getDbConnectionName();
-	}
-
-	public java.util.logging.Logger getParentLogger()
-			throws SQLFeatureNotSupportedException {
-		// TODO Auto-generated method stub
-		return null;
-	}
-}
diff --git a/dblib/provider/src/main/resources/dblib.properties b/dblib/provider/src/main/resources/dblib.properties
index 3872288..0f28f1f 100755
--- a/dblib/provider/src/main/resources/dblib.properties
+++ b/dblib/provider/src/main/resources/dblib.properties
@@ -3,7 +3,7 @@
 org.openecomp.sdnc.sli.jdbc.url=jdbc:mysql://DBHOST:3306/sdnctl
 org.openecomp.sdnc.sli.jdbc.database=sdnctl
 org.openecomp.sdnc.sli.jdbc.user=sdnctl
-org.openecomp.sdnc.sli.jdbc.password=gamma
+org.openecomp.sdnc.sli.jdbc.password={password for sdnctl}
 org.openecomp.sdnc.sli.jdbc.connection.name=sdnctldb01
 
 org.openecomp.sdnc.sli.jdbc.connection.timeout=50
diff --git a/filters/provider/pom.xml b/filters/provider/pom.xml
index cf31a0c..6afa2d2 100755
--- a/filters/provider/pom.xml
+++ b/filters/provider/pom.xml
@@ -49,7 +49,11 @@
                         <artifactId>commons-codec</artifactId>
                         <version>${commons.codec.version}</version>
                 </dependency>
-
+                <dependency>
+                	<groupId>org.openecomp.sdnc.core</groupId>
+                	<artifactId>sli-common</artifactId>
+                	<version>${sdnctl.sli.version}</version>
+                </dependency>
 <!--
 		<dependency>
 			<groupId>mysql</groupId>
diff --git a/filters/provider/src/main/java/org/openecomp/sdnc/filters/LogFilter.java b/filters/provider/src/main/java/org/openecomp/sdnc/filters/LogFilter.java
index 40100c3..809cfb2 100644
--- a/filters/provider/src/main/java/org/openecomp/sdnc/filters/LogFilter.java
+++ b/filters/provider/src/main/java/org/openecomp/sdnc/filters/LogFilter.java
@@ -47,7 +47,7 @@
 
 
 /**
- * Logs IN request according ECOMP Logging Guidelines
+ * Logs IN request according ECOMP Logging Guidelines at https://tspace.web.att.com/viewer/app/lcfiles/ae5f7751-39da-4c6b-8a83-5836c8c815e1/content
  */
 public class LogFilter implements Filter {
 
diff --git a/filters/provider/src/main/java/org/openecomp/sdnc/filters/RequestResponseDbLoggingFilter.java b/filters/provider/src/main/java/org/openecomp/sdnc/filters/RequestResponseDbLoggingFilter.java
new file mode 100644
index 0000000..183301b
--- /dev/null
+++ b/filters/provider/src/main/java/org/openecomp/sdnc/filters/RequestResponseDbLoggingFilter.java
@@ -0,0 +1,297 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * openECOMP : SDN-C
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights
+ * 						reserved.
+ * ================================================================================
+ * Licensed 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.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.sdnc.filters;
+
+import java.io.BufferedReader;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.PrintWriter;
+import java.util.zip.GZIPInputStream;
+
+import javax.servlet.Filter;
+import javax.servlet.FilterChain;
+import javax.servlet.FilterConfig;
+import javax.servlet.ServletException;
+import javax.servlet.ServletInputStream;
+import javax.servlet.ServletOutputStream;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletRequestWrapper;
+import javax.servlet.http.HttpServletResponse;
+import javax.servlet.http.HttpServletResponseWrapper;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.openecomp.sdnc.sli.MessageWriter;
+
+public class RequestResponseDbLoggingFilter implements Filter {
+
+	private static Logger log = LoggerFactory.getLogger(RequestResponseDbLoggingFilter.class);
+
+	public static final String REQUEST_ID = "X-ECOMP-RequestID";
+
+	private static class ByteArrayServletStream extends ServletOutputStream {
+
+		ByteArrayOutputStream baos;
+
+		ByteArrayServletStream(ByteArrayOutputStream baos) {
+			this.baos = baos;
+		}
+
+		@Override
+		public void write(int param) throws IOException {
+			baos.write(param);
+		}
+	}
+
+	private static class ByteArrayPrintWriter {
+
+		private ByteArrayOutputStream baos = new ByteArrayOutputStream();
+
+		private PrintWriter pw = new PrintWriter(baos);
+
+		private ServletOutputStream sos = new ByteArrayServletStream(baos);
+
+		public PrintWriter getWriter() {
+			return pw;
+		}
+
+		public ServletOutputStream getStream() {
+			return sos;
+		}
+
+		byte[] toByteArray() {
+			return baos.toByteArray();
+		}
+	}
+
+	private class BufferedServletInputStream extends ServletInputStream {
+
+		ByteArrayInputStream bais;
+
+		public BufferedServletInputStream(ByteArrayInputStream bais) {
+			this.bais = bais;
+		}
+
+		@Override
+		public int available() {
+			return bais.available();
+		}
+
+		@Override
+		public int read() {
+			return bais.read();
+		}
+
+		@Override
+		public int read(byte[] buf, int off, int len) {
+			return bais.read(buf, off, len);
+		}
+
+	}
+
+	private class BufferedRequestWrapper extends HttpServletRequestWrapper {
+
+		ByteArrayInputStream bais;
+
+		ByteArrayOutputStream baos;
+
+		BufferedServletInputStream bsis;
+
+		byte[] buffer;
+
+		public BufferedRequestWrapper(HttpServletRequest req) throws IOException {
+			super(req);
+
+			InputStream is = req.getInputStream();
+			baos = new ByteArrayOutputStream();
+			byte buf[] = new byte[1024];
+			int letti;
+			while ((letti = is.read(buf)) > 0) {
+				baos.write(buf, 0, letti);
+			}
+			buffer = baos.toByteArray();
+
+		}
+
+		@Override
+		public ServletInputStream getInputStream() {
+			try {
+				bais = new ByteArrayInputStream(buffer);
+				bsis = new BufferedServletInputStream(bais);
+			} catch (Exception ex) {
+				ex.printStackTrace();
+			}
+
+			return bsis;
+		}
+
+		public byte[] getBuffer() {
+			return buffer;
+		}
+
+	}
+
+	@Override
+	public void init(FilterConfig filterConfig) throws ServletException {
+	}
+
+	@Override
+	public void doFilter(final ServletRequest request, final ServletResponse response, final FilterChain filterChain)
+	        throws IOException, ServletException {
+
+		if (request == null || !(request instanceof HttpServletRequest)) {
+			filterChain.doFilter(request, response);
+			return;
+		}
+
+		long t1 = System.currentTimeMillis();
+
+		final HttpServletRequest httpRequest = (HttpServletRequest) request;
+		BufferedRequestWrapper bufferedRequest = new BufferedRequestWrapper(httpRequest);
+
+		String requestId = httpRequest.getHeader(REQUEST_ID);
+		if (requestId == null || requestId.trim().length() == 0) {
+			log.warn("Could not write request in DB: " + REQUEST_ID + " is missing in the HTTP headers.");
+			return;
+		}
+
+		String requestHost = request.getRemoteHost();
+		if (requestHost == null)
+			requestHost = request.getRemoteAddr();
+
+		String requestStr = new String(bufferedRequest.getBuffer());
+
+		MessageWriter.saveIncomingRequest(requestId, null, requestHost, requestStr);
+
+		long t2 = System.currentTimeMillis();
+
+		log.info("Request saved in DB for request-id: " + requestId + ". TIme: " + (t2 - t1));
+
+		final HttpServletResponse httpResponse = (HttpServletResponse) response;
+
+		final ByteArrayPrintWriter pw = new ByteArrayPrintWriter();
+		HttpServletResponse wrappedResp = new HttpServletResponseWrapper(httpResponse) {
+
+			@Override
+			public PrintWriter getWriter() {
+				return pw.getWriter();
+			}
+
+			@Override
+			public ServletOutputStream getOutputStream() {
+				return pw.getStream();
+			}
+		};
+
+		try {
+
+			filterChain.doFilter(bufferedRequest, wrappedResp);
+
+		} finally {
+
+			if (request != null && request instanceof HttpServletRequest) {
+
+				t1 = System.currentTimeMillis();
+
+				byte[] bytes = pw.toByteArray();
+				response.getOutputStream().write(bytes);
+				response.getOutputStream().flush();
+
+				String responseStr = null;
+				if ("gzip".equals(httpResponse.getHeader("Content-Encoding"))) {
+					responseStr = decompressGZIPByteArray(bytes);
+				} else {
+					responseStr = new String(bytes);
+				}
+
+				MessageWriter.saveIncomingResponse(requestId, httpResponse.getStatus(), responseStr);
+
+				t2 = System.currentTimeMillis();
+
+				log.info("Response saved in DB for request-id: " + requestId + ". TIme: " + (t2 - t1));
+			}
+		}
+
+	}
+
+	@Override
+	public void destroy() {
+	}
+
+	private String decompressGZIPByteArray(byte[] bytes) {
+
+		BufferedReader in = null;
+		InputStreamReader inR = null;
+		ByteArrayInputStream byteS = null;
+		GZIPInputStream gzS = null;
+		StringBuilder str = new StringBuilder();
+		try {
+			byteS = new ByteArrayInputStream(bytes);
+			gzS = new GZIPInputStream(byteS);
+			inR = new InputStreamReader(gzS);
+			in = new BufferedReader(inR);
+
+			if (in != null) {
+
+				String content;
+
+				while ((content = in.readLine()) != null) {
+					str.append(content);
+				}
+			}
+
+		} catch (Exception e) {
+			log.error("Failed get read GZIPInputStream", e);
+		} finally {
+
+			if (byteS != null)
+				try {
+					byteS.close();
+				} catch (IOException e1) {
+					log.error("Failed to close ByteStream", e1);
+				}
+			if (gzS != null)
+				try {
+					gzS.close();
+				} catch (IOException e2) {
+					log.error("Failed to close GZStream", e2);
+				}
+			if (inR != null)
+				try {
+					inR.close();
+				} catch (IOException e3) {
+					log.error("Failed to close InputReader", e3);
+				}
+			if (in != null)
+				try {
+					in.close();
+				} catch (IOException e) {
+					log.error("Failed to close BufferedReader", e);
+				}
+		}
+		return str.toString();
+	}
+}
diff --git a/filters/provider/src/main/java/org/openecomp/sdnc/filters/RequestResponseLoggingFilter.java b/filters/provider/src/main/java/org/openecomp/sdnc/filters/RequestResponseLoggingFilter.java
index 48f0689..b15932f 100644
--- a/filters/provider/src/main/java/org/openecomp/sdnc/filters/RequestResponseLoggingFilter.java
+++ b/filters/provider/src/main/java/org/openecomp/sdnc/filters/RequestResponseLoggingFilter.java
@@ -30,7 +30,6 @@
 import java.io.PrintWriter;
 import java.util.Enumeration;
 import java.util.zip.GZIPInputStream;
-import java.util.zip.Inflater;
 
 import javax.servlet.Filter;
 import javax.servlet.FilterChain;
@@ -57,6 +56,7 @@
 			this.baos = baos;
 		}
 
+		@Override
 		public void write(int param) throws IOException {
 			baos.write(param);
 		}
@@ -91,14 +91,17 @@
 			this.bais = bais;
 		}
 
+		@Override
 		public int available() {
 			return bais.available();
 		}
 
+		@Override
 		public int read() {
 			return bais.read();
 		}
 
+		@Override
 		public int read(byte[] buf, int off, int len) {
 			return bais.read(buf, off, len);
 		}
@@ -129,6 +132,7 @@
 
 		}
 
+		@Override
 		public ServletInputStream getInputStream() {
 			try {
 				bais = new ByteArrayInputStream(buffer);
@@ -146,9 +150,11 @@
 
 	}
 
+	@Override
 	public void init(FilterConfig filterConfig) throws ServletException {
 	}
 
+	@Override
 	public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain)
 			throws IOException, ServletException {
 
@@ -177,10 +183,12 @@
 
 		final ByteArrayPrintWriter pw = new ByteArrayPrintWriter();
 		HttpServletResponse wrappedResp = new HttpServletResponseWrapper(response) {
+			@Override
 			public PrintWriter getWriter() {
 				return pw.getWriter();
 			}
 
+			@Override
 			public ServletOutputStream getOutputStream() {
 				return pw.getStream();
 			}
@@ -188,15 +196,16 @@
 		};
 
 		try {
-			
+
 		filterChain.doFilter(bufferedRequest, wrappedResp);
-		
+
 		}catch (Exception e){
 			log.error("Chain Exception",e);
 			throw e;
 		} finally {
 		byte[] bytes = pw.toByteArray();
 		response.getOutputStream().write(bytes);
+		response.getOutputStream().flush();
 
 		StringBuilder responseHeaders = new StringBuilder("RESPONSE HEADERS|");
 
@@ -220,6 +229,7 @@
 		}
 	}
 
+	@Override
 	public void destroy() {
 	}
 
diff --git a/pom.xml b/pom.xml
index 4469f9a..a305621 100755
--- a/pom.xml
+++ b/pom.xml
@@ -7,8 +7,9 @@
 	<groupId>org.openecomp.sdnc.core</groupId>
 	<artifactId>sdnc-core</artifactId>
 
+
 	<name>SDN-C Core Components</name>
-	<url>https://wiki.onap.org</url>
+	<url>https://wiki.openecomp.org</url>
 	<description>The SDN-C core components contains the SLI, dblib and root pom</description>
 
 	<parent>
@@ -21,7 +22,7 @@
 
 	<issueManagement>
 		<system>JIRA</system>
-		<url>http://jira.onap.org/</url>
+		<url>http://jira.openecomp.org/</url>
 	</issueManagement>
 
 
@@ -34,7 +35,7 @@
 
 	<ciManagement>
 		<system>Jenkins</system>
-		<url>https://jenkins.onap.org/</url>
+		<url>https://jenkins.openecomp.org/</url>
 	</ciManagement>
 
 
@@ -55,7 +56,6 @@
 				</property>
 			</activation>
 			<build>
-				<pluginManagement>
 					<plugins>
 						<plugin>
 							<groupId>com.blackducksoftware.integration</groupId>
@@ -78,7 +78,7 @@
 						</plugin>
 					</plugins>
 
-				</pluginManagement>
+
 
 			</build>
 
@@ -172,7 +172,6 @@
 
 	</build>
 	<modules>
-		<module>rootpom</module>
 		<module>dblib</module>
 		<module>filters</module>
 		<module>sli</module>
diff --git a/rootpom/pom.xml b/rootpom/pom.xml
index 7a59501..4938811 100755
--- a/rootpom/pom.xml
+++ b/rootpom/pom.xml
@@ -5,7 +5,7 @@
 	<parent>
 		<groupId>org.opendaylight.odlparent</groupId>
 		<artifactId>odlparent</artifactId>
-		<version>1.6.2-Beryllium-SR2</version>
+		<version>1.7.1-Boron-SR1</version>
 		<relativePath>../../../../../opendaylight/odlparent</relativePath>
 	</parent>
 
@@ -28,37 +28,13 @@
 		<opendaylight.nexus.public-url>https://nexus.opendaylight.org/content/repositories/public/</opendaylight.nexus.public-url>
 		<opendaylight.nexus.snapshot-url>https://nexus.opendaylight.org/content/repositories/opendaylight.snapshot/</opendaylight.nexus.snapshot-url>
 
-		<release-tag>R17.01</release-tag>
+		<release-tag>R17.07</release-tag>
 		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+		<java.version.source>1.8</java.version.source>
+		<java.version.target>1.8</java.version.target>
 		<bundle.plugin.version>2.5.0</bundle.plugin.version>
-		<java.version.source>1.7</java.version.source>
-		<java.version.target>1.7</java.version.target>
 		<maven.compile.plugin.version>2.5.1</maven.compile.plugin.version>
-		<equinox.osgi.version>3.8.1.v20120830-144521</equinox.osgi.version>
-		<jackson-annotations-version>${jackson.version}</jackson-annotations-version>
-		<jettison.version>1.3.7</jettison.version>
-		<jvnet.jaxb2.version>0.6.4</jvnet.jaxb2.version>
-		<apache.httpcomponents.version>4.4</apache.httpcomponents.version>
-		<antlr.version>4.5.1</antlr.version>
-		<mysql.connector.version>5.1.39</mysql.connector.version>
-		<odl.version>1.6.2-Beryllium-SR2</odl.version>
-		<odl.dlux.version>0.3.2-Beryllium-SR2</odl.dlux.version>
-		<odl.yangtools.version>0.8.2-Beryllium-SR2</odl.yangtools.version>
-		<odl.mdsal.version>1.3.2-Beryllium-SR2</odl.mdsal.version>
-		<odl.mdsal.features.version>2.0.2-Beryllium-SR2</odl.mdsal.features.version>
-		<odl.mdsal.model.version>0.8.2-Beryllium-SR2</odl.mdsal.model.version>
-		<odl.restconf.version>1.3.2-Beryllium-SR2</odl.restconf.version>
-		<odl.yangtools.version>0.8.2-Beryllium-SR2</odl.yangtools.version>
-		<odl.controller.model.version>${odl.mdsal.model.version}</odl.controller.model.version>
-		<odl.controller.config.api.version>0.4.2-Beryllium-SR2</odl.controller.config.api.version>
-		<odl.karaf.empty.distro.version>${odl.version}</odl.karaf.empty.distro.version>
-		<odl.commons.opendaylight.version>${odl.version}</odl.commons.opendaylight.version>
-		<odl.ietf-inet-types.version>2010.09.24.8.2-Beryllium-SR2</odl.ietf-inet-types.version>
-		<odl.ietf-yang-types.version>2010.09.24.8.2-Beryllium-SR2</odl.ietf-yang-types.version>
-		<odl.yang.jmx.generator.version>0.4.2-Beryllium-SR2</odl.yang.jmx.generator.version>
-		<odl.yangtools.yang.maven.plugin.version>${odl.yangtools.version}</odl.yangtools.yang.maven.plugin.version>
 		<features.file>features.xml</features.file>
-		<h2database.version>1.4.186</h2database.version>
 		<jmxGeneratorPath>src/main/yang-gen-config</jmxGeneratorPath>
 		<salGeneratorPath>src/main/yang-gen-sal</salGeneratorPath>
 		<checkstyle.skip>true</checkstyle.skip>
@@ -70,13 +46,110 @@
 		<sonar.jacoco.reportMissing.force.zero>true</sonar.jacoco.reportMissing.force.zero>
 		<sonar.projectVersion>${project.version}</sonar.projectVersion>
 
+		<!-- OpenDaylight component versions -->
+		<odl.version>1.7.1-Boron-SR1</odl.version>
+		<odl.dlux.version>0.4.1-Boron-SR1</odl.dlux.version>
+		<odl.yangtools.version>1.0.1-Boron-SR1</odl.yangtools.version>
+		<odl.mdsal.version>1.4.1-Boron-SR1</odl.mdsal.version>
+		<odl.mdsal.features.version>2.1.1-Boron-SR1</odl.mdsal.features.version>
+		<odl.mdsal.model.version>0.9.1-Boron-SR1</odl.mdsal.model.version>
+		<odl.mdsal.yang.binding.version>0.9.1-Boron-SR1</odl.mdsal.yang.binding.version>
+		<odl.restconf.version>1.4.1-Boron-SR1</odl.restconf.version>
+		<odl.controller.model.version>${odl.mdsal.model.version}</odl.controller.model.version>
+		<odl.controller.config.api.version>0.5.1-Boron-SR1</odl.controller.config.api.version>
+		<odl.karaf.empty.distro.version>${odl.version}</odl.karaf.empty.distro.version>
+		<odl.commons.opendaylight.version>${odl.version}</odl.commons.opendaylight.version>
+		<odl.ietf-inet-types.version>2010.09.24.9.1-Boron-SR1</odl.ietf-inet-types.version>
+		<odl.ietf-yang-types.version>2010.09.24.9.1-Boron-SR1</odl.ietf-yang-types.version>
+		<odl.yang.jmx.generator.version>0.5.1-Boron-SR1</odl.yang.jmx.generator.version>
+		<odl.yangtools.yang.maven.plugin.version>${odl.yangtools.version}</odl.yangtools.yang.maven.plugin.version>
+		<odl.sal.api.gen.plugin.version>0.9.1-Boron-SR1</odl.sal.api.gen.plugin.version>
+
+
+
+		<!--  SDN-C component versions  -->
 		<sdnc.core.version>1.1.0-SNAPSHOT</sdnc.core.version>
 		<sdnc.adaptors.version>1.1.0-SNAPSHOT</sdnc.adaptors.version>
+		<sdnc.northbound.version>1.1.0-SNAPSHOT</sdnc.northbound.version>
+		<sdnc.oam.version>1.1.0-SNAPSHOT</sdnc.oam.version>
+		<sdnc.plugins.version>1.1.0-SNAPSHOT</sdnc.plugins.version>
 		<sdnctl.sli.version>${sdnc.core.version}</sdnctl.sli.version>
 		<sdnctl.aai.service.version>${sdnc.adaptors.version}</sdnctl.aai.service.version>
 		<sdnctl.dblib.version>${sdnc.core.version}</sdnctl.dblib.version>
 		<sdnctl.mdsal.resource.version>${sdnc.adaptors.version}</sdnctl.mdsal.resource.version>
 		<sdnctl.slipluginutils.version>${sdnc.core.version}</sdnctl.slipluginutils.version>
+
+		<!-- Support libraries used by OpenDaylight -->
+		<!-- Used by aaa, vtn -->
+		<commons.codec.version>1.10</commons.codec.version>
+		<!-- Used by netconf, ovsdb -->
+		<commons.lang3.version>3.4</commons.lang3.version>
+		<!-- Used by sfc, snmp4sdn; see also affinity, toolkit -->
+		<commons.lang.version>2.6</commons.lang.version>
+		<!-- Used by neutron; see also controller, vtn -->
+		<commons.net.version>3.5</commons.net.version>
+		<!-- Used by neutron -->
+		<eclipse.persistence.version>2.6.2</eclipse.persistence.version>
+		<!-- Used by aaa -->
+		<felix.dependencymanager.version>4.3.0</felix.dependencymanager.version>
+		<!-- Used by lacp, netconf, ovsdb, sfc, toolkit; see also vtn -->
+		<gson.version>2.3.1</gson.version>
+		<!-- Used by aaa, dlux, persistence, snmp4sdn, sxp -->
+		<guava.version>18.0</guava.version>
+		<!-- Used by lispflowmapping, sxp, vtn/manager -->
+		<hamcrest.version>1.3</hamcrest.version>
+		<!-- Used by aaa, alto, netconf, ovsdb, sfc; see also affinity, defense4all,
+			integration/distribution, snmp4sdn, toolkit, ttp -->
+		<jackson.version>2.3.2</jackson.version>
+		<!-- Used by snmp4sdn, yangtools -->
+		<javassist.version>3.20.0-GA</javassist.version>
+
+		<!-- FIXME remove all dependencies for jersey 1.17 after migration all
+			projects -->
+		<!-- Used by aaa, alto, netconf, neutron, sfc; see also affinity, defense4all,
+			snmp4sdn, toolkit -->
+		<jersey.version>1.17</jersey.version>
+		<!-- Used by sfc -->
+		<jersey.client.version>1.17</jersey.client.version>
+
+		<!-- New packages for jersey migration 1.17 to 2.8 -->
+		<!-- appache.geronimo.bundle for DocGen -->
+		<!-- Used by aaa, iotdm, netconf, ovsdb, sfc -->
+		<org.json.version>20131018</org.json.version>
+
+		<!-- Used by sfc -->
+		<jettison.version>1.3.7</jettison.version>
+		<!-- Used by persistence -->
+		<jsr305.api.version>3.0.0</jsr305.api.version>
+		<!-- Need to stick to JUnit 4.11 until https://github.com/jayway/powermock/issues/560
+			is fixed (either in PowerMock or with a new JUnit release) -->
+		<!-- Used everywhere -->
+		<junit.version>4.11</junit.version>
+		<!-- Used by coretutorials, sfc, snmp4sdn, sxp; see also affinity, toolkit -->
+		<logback.version>1.1.7</logback.version>
+		<!-- Used by nic, sfc, sxp, tsdr -->
+		<mockito.version>1.10.19</mockito.version>
+		<!-- Used by bgpcep, netconf, ovsdb, sxp; see also opendove, toolkit -->
+		<netty.version>4.0.37.Final</netty.version>
+		<!-- Used by openflowjava, persistence, sfc, snmp4sdn, sxp; see also affinity,
+			toolkit -->
+		<slf4j.version>1.7.21</slf4j.version>
+		<!-- Used in integration/distribution; see also affinity, snmp4sdn, toolkit,
+			tsdr, ttp -->
+		<spring.version>3.2.14.RELEASE</spring.version>
+
+
+
+		<!-- Extra support libraries used by SDN-C -->
+		<equinox.osgi.version>3.8.1.v20120830-144521</equinox.osgi.version>
+		<jackson-annotations-version>${jackson.version}</jackson-annotations-version>
+		<jettison.version>1.3.7</jettison.version>
+		<jvnet.jaxb2.version>0.6.4</jvnet.jaxb2.version>
+		<apache.httpcomponents.version>4.4</apache.httpcomponents.version>
+		<antlr.version>4.5.1</antlr.version>
+		<mysql.connector.version>5.1.39</mysql.connector.version>
+		<h2database.version>1.4.186</h2database.version>
+
 	</properties>
 
 	<modelVersion>4.0.0</modelVersion>
@@ -154,7 +227,7 @@
 						<additionalDependency>
 							<groupId>org.opendaylight.odlparent</groupId>
 							<artifactId>odlparent</artifactId>
-							<version>1.6.2-Beryllium-SR2</version>
+							<version>1.7.1-Boron-SR1</version>
 						</additionalDependency>
 						<additionalDependency>
 							<groupId>org.slf4j</groupId>
@@ -215,7 +288,7 @@
 						<additionalDependency>
 							<groupId>org.opendaylight.mdsal</groupId>
 							<artifactId>yang-binding</artifactId>
-							<version>${odl.yangtools.version}</version>
+							<version>${odl.mdsal.yang.binding.version}</version>
 						</additionalDependency>
 						<additionalDependency>
 							<groupId>org.opendaylight.yangtools</groupId>
@@ -535,7 +608,7 @@
 							<additionalDependency>
 								<groupId>org.opendaylight.mdsal</groupId>
 								<artifactId>yang-binding</artifactId>
-								<version>${odl.yangtools.version}</version>
+								<version>${odl.mdsal.yang.binding.version}</version>
 							</additionalDependency>
 							<additionalDependency>
 								<groupId>org.opendaylight.yangtools</groupId>
diff --git a/sli/common/pom.xml b/sli/common/pom.xml
index 7a08c34..eb06e6b 100755
--- a/sli/common/pom.xml
+++ b/sli/common/pom.xml
@@ -44,7 +44,7 @@
 		<dependency>
 			<groupId>org.opendaylight.mdsal</groupId>
 			<artifactId>yang-binding</artifactId>
-			<version>${odl.yangtools.version}</version>
+			<version>${odl.mdsal.yang.binding.version}</version>
 		</dependency>
 		<dependency>
 			<groupId>org.opendaylight.yangtools</groupId>
diff --git a/sli/common/src/main/java/org/openecomp/sdnc/sli/BreakNodeException.java b/sli/common/src/main/java/org/openecomp/sdnc/sli/BreakNodeException.java
new file mode 100644
index 0000000..3e355ba
--- /dev/null
+++ b/sli/common/src/main/java/org/openecomp/sdnc/sli/BreakNodeException.java
@@ -0,0 +1,46 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * openECOMP : SDN-C
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights
+ * 						reserved.
+ * ================================================================================
+ * Licensed 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.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.sdnc.sli;
+
+public class BreakNodeException extends SvcLogicException {
+	
+	/**
+	 * 
+	 */
+	private static final long serialVersionUID = 1L;
+
+	public BreakNodeException()
+	{
+		super();
+	}
+	
+	public BreakNodeException(String message)
+	{
+		super(message);
+	}
+	
+	public BreakNodeException(String message, Throwable t)
+	{
+		super(message, t);
+	}
+
+}
diff --git a/sli/common/src/main/java/org/openecomp/sdnc/sli/MessageWriter.java b/sli/common/src/main/java/org/openecomp/sdnc/sli/MessageWriter.java
new file mode 100644
index 0000000..5e5b621
--- /dev/null
+++ b/sli/common/src/main/java/org/openecomp/sdnc/sli/MessageWriter.java
@@ -0,0 +1,302 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * openECOMP : SDN-C
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights
+ * 						reserved.
+ * ================================================================================
+ * Licensed 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.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.sdnc.sli;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.sql.SQLException;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.Properties;
+
+import javax.sql.rowset.CachedRowSet;
+
+import org.openecomp.sdnc.sli.resource.dblib.DbLibService;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.FrameworkUtil;
+import org.osgi.framework.ServiceReference;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+
+public class MessageWriter {
+
+	private static final Logger LOG = LoggerFactory.getLogger(MessageWriter.class);
+
+	private static final String DBLIB_SERVICE = "org.openecomp.sdnc.sli.resource.dblib.DBResourceManager";
+	private static final String SVCLOGIC_PROP_VAR = "SDNC_SLI_PROPERTIES";
+	private static final String SDNC_CONFIG_DIR = "SDNC_CONFIG_DIR";
+
+	private static final String INCOMING_PROPERTY_NAME = "org.openecomp.sdnc.sli.MessageWriter.writeIncomingRequests";
+	private static final String OUTGOING_PROPERTY_NAME = "org.openecomp.sdnc.sli.MessageWriter.writeOutgoingRequests";
+
+	private static final SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
+
+	private static DbLibService dbLibService = null;
+
+	private static boolean incomingEnabled = false;
+	private static boolean outgoingEnabled = false;
+
+	private static boolean initialized = false;
+
+	@SuppressWarnings({ "rawtypes", "unchecked" })
+	private static void init() {
+		if (initialized)
+			return;
+
+		initialized = true;
+
+		// Read properties
+		Properties props = new Properties();
+		String propPath = System.getenv(SVCLOGIC_PROP_VAR);
+
+		if (propPath == null) {
+			String propDir = System.getenv(SDNC_CONFIG_DIR);
+			if (propDir == null) {
+				propDir = "/opt/sdnc/data/properties";
+			}
+			propPath = propDir + "/svclogic.properties";
+			LOG.warn("Environment variable " + SVCLOGIC_PROP_VAR + " unset - defaulting to " + propPath);
+		}
+
+		File propFile = new File(propPath);
+
+		if (!propFile.exists()) {
+			LOG.warn("Property file does not exist: " + propPath);
+		}
+
+		try {
+			props.load(new FileInputStream(propFile));
+		} catch (Exception e) {
+			LOG.warn("Error loading property file: " + propPath, e);
+		}
+
+		incomingEnabled = Boolean.valueOf(props.getProperty(INCOMING_PROPERTY_NAME, "false"));
+		outgoingEnabled = Boolean.valueOf(props.getProperty(OUTGOING_PROPERTY_NAME, "false"));
+
+		LOG.info(INCOMING_PROPERTY_NAME + ": " + incomingEnabled);
+		LOG.info(OUTGOING_PROPERTY_NAME + ": " + outgoingEnabled);
+
+		if (dbLibService != null)
+			return;
+
+		BundleContext bctx = FrameworkUtil.getBundle(MessageWriter.class).getBundleContext();
+
+		ServiceReference sref = bctx.getServiceReference(DBLIB_SERVICE);
+
+		if (sref == null) {
+			LOG.warn("Could not find service reference for DBLIB service (" + DBLIB_SERVICE + ")");
+		} else {
+			dbLibService = (DbLibService) bctx.getService(sref);
+			if (dbLibService == null) {
+				LOG.warn("Could not find service reference for DBLIB service (" + DBLIB_SERVICE + ")");
+			}
+		}
+	}
+
+	public static void saveOutgoingRequest(
+	        String requestId,
+	        String serviceInstanceId,
+	        String targetUrl,
+	        String request) {
+		try {
+			init();
+
+			if (!outgoingEnabled)
+				return;
+
+			if (serviceInstanceId == null || serviceInstanceId.trim().length() == 0)
+				serviceInstanceId = "NA";
+
+			int seqnum = getLastSequenceNumber("OUTGOING_MESSAGE", requestId) + 1;
+			String now = df.format(new Date());
+
+			String sql = "INSERT INTO OUTGOING_MESSAGE (\n" +
+			        "	request_id, sequence_number, service_instance_id, target_url, request, start_time)\n" +
+			        "VALUES (?, ?, ?, ?, ?, ?)";
+
+			ArrayList<String> data = new ArrayList<>();
+			data.add(requestId);
+			data.add(String.valueOf(seqnum));
+			data.add(serviceInstanceId);
+			data.add(targetUrl);
+			data.add(request);
+			data.add(now);
+
+			dbLibService.writeData(sql, data, null);
+
+		} catch (Exception e) {
+			LOG.warn("Failed to save outgoing request for request-id: " + requestId, e);
+		}
+	}
+
+	public static void saveOutgoingResponse(String requestId, int httpResponseCode, String response) {
+		try {
+			init();
+
+			if (!outgoingEnabled)
+				return;
+
+			int seqnum = getLastSequenceNumber("OUTGOING_MESSAGE", requestId);
+			if (seqnum == 0) {
+				LOG.warn("Failed to save outgoing response for request-id: " + requestId +
+				        ": Request record not found in OUTGOING_MESSAGE");
+				return;
+			}
+
+			String now = df.format(new Date());
+
+			String sql = "UPDATE OUTGOING_MESSAGE SET http_response_code = ?, response = ?,\n" +
+			        "	duration = timestampdiff(MICROSECOND, start_time, ?) / 1000\n" +
+			        "WHERE request_id = ? AND sequence_number = ?";
+
+			ArrayList<String> data = new ArrayList<>();
+			data.add(String.valueOf(httpResponseCode));
+			data.add(response);
+			data.add(now);
+			data.add(requestId);
+			data.add(String.valueOf(seqnum));
+
+			dbLibService.writeData(sql, data, null);
+
+		} catch (Exception e) {
+			LOG.warn("Failed to save outgoing response for request-id: " + requestId, e);
+		}
+	}
+
+	public static void saveIncomingRequest(
+	        String requestId,
+	        String serviceInstanceId,
+	        String requestHost,
+	        String request) {
+		try {
+			init();
+
+			if (!incomingEnabled)
+				return;
+
+			if (serviceInstanceId == null || serviceInstanceId.trim().length() == 0)
+				serviceInstanceId = "NA";
+
+			int seqnum = getLastSequenceNumber("INCOMING_MESSAGE", requestId) + 1;
+			String now = df.format(new Date());
+
+			String sql = "INSERT INTO INCOMING_MESSAGE (\n" +
+			        "	request_id, sequence_number, service_instance_id, request_host, request, start_time)\n" +
+			        "VALUES (?, ?, ?, ?, ?, ?)";
+
+			ArrayList<String> data = new ArrayList<>();
+			data.add(requestId);
+			data.add(String.valueOf(seqnum));
+			data.add(serviceInstanceId);
+			data.add(requestHost);
+			data.add(request);
+			data.add(now);
+
+			dbLibService.writeData(sql, data, null);
+
+		} catch (Exception e) {
+			LOG.warn("Failed to save incoming request for request-id: " + requestId, e);
+		}
+	}
+
+	public static void saveIncomingResponse(String requestId, int httpResponseCode, String response) {
+		try {
+			init();
+
+			if (!incomingEnabled)
+				return;
+
+			int seqnum = getLastSequenceNumber("INCOMING_MESSAGE", requestId);
+			if (seqnum == 0) {
+				LOG.warn("Failed to save response for request-id: " + requestId +
+				        ": Request record not found in INCOMING_MESSAGE");
+				return;
+			}
+
+			String now = df.format(new Date());
+
+			String sql = "UPDATE INCOMING_MESSAGE SET http_response_code = ?, response = ?,\n" +
+			        "	duration = timestampdiff(MICROSECOND, start_time, ?) / 1000\n" +
+			        "WHERE request_id = ? AND sequence_number = ?";
+
+			ArrayList<String> data = new ArrayList<>();
+			data.add(String.valueOf(httpResponseCode));
+			data.add(response);
+			data.add(now);
+			data.add(requestId);
+			data.add(String.valueOf(seqnum));
+
+			dbLibService.writeData(sql, data, null);
+
+		} catch (Exception e) {
+			LOG.warn("Failed to save response for request-id: " + requestId, e);
+		}
+	}
+
+	public static String getServiceInstanceId(String requestId) throws SQLException {
+		init();
+
+		String sql = "SELECT service_instance_id FROM OUTGOING_MESSAGE WHERE request_id = '" + requestId +
+		        "' ORDER BY sequence_number DESC";
+
+		CachedRowSet rs = null;
+		try {
+			rs = dbLibService.getData(sql, null, null);
+			if (rs.next()) {
+				return rs.getString("service_instance_id");
+			}
+		} finally {
+			if (rs != null) {
+				try {
+					rs.close();
+				} catch (Exception e) {
+					LOG.warn("Failed to close CachedRowSet", e);
+				}
+			}
+		}
+		return null;
+	}
+
+	private static int getLastSequenceNumber(String tableName, String requestId) throws SQLException {
+		String sql = "SELECT sequence_number FROM " + tableName + " WHERE request_id = '" + requestId +
+		        "' ORDER BY sequence_number DESC";
+
+		CachedRowSet rs = null;
+		try {
+			rs = dbLibService.getData(sql, null, null);
+			if (rs.next()) {
+				return rs.getInt("sequence_number");
+			}
+		} finally {
+			if (rs != null) {
+				try {
+					rs.close();
+				} catch (Exception e) {
+					LOG.warn("Failed to close CachedRowSet", e);
+				}
+			}
+		}
+		return 0;
+	}
+}
diff --git a/sli/common/src/main/java/org/openecomp/sdnc/sli/SvcLogicExprListener.java b/sli/common/src/main/java/org/openecomp/sdnc/sli/SvcLogicExprListener.java
index d8d3384..4fef12f 100644
--- a/sli/common/src/main/java/org/openecomp/sdnc/sli/SvcLogicExprListener.java
+++ b/sli/common/src/main/java/org/openecomp/sdnc/sli/SvcLogicExprListener.java
@@ -77,7 +77,7 @@
 	
 	private void pushExpr(SvcLogicExpression expr)
 	{
-		LOG.debug("Pushing expression ["+expr.getClass().getName()+"]");
+		LOG.trace("Pushing expression ["+expr.getClass().getName()+"]");
 		if (curExpr != null)
 		{
 			exprStack.push(curExpr);
@@ -89,7 +89,7 @@
 	{
 		if (exprStack.isEmpty())
 		{
-			LOG.debug("Popping last expression");
+			LOG.trace("Popping last expression");
 			topExpr = curExpr;
 		}
 		else
@@ -97,7 +97,7 @@
 			SvcLogicExpression lastExpr = curExpr;
 			curExpr = exprStack.pop();
 			curExpr.addOperand(lastExpr);
-			LOG.debug("New curExpr is ["+curExpr.getClass().getName()+"]");
+			LOG.trace("New curExpr is ["+curExpr.getClass().getName()+"]");
 		}
 		
 	}
@@ -107,7 +107,7 @@
 		
 		String atomText = ctx.getText();
 		
-		LOG.debug("enterAtom: text = "+atomText);
+		LOG.trace("enterAtom: text = "+atomText);
 
 		
 		SvcLogicAtom newAtom = new SvcLogicAtom(atomText);
@@ -118,7 +118,7 @@
 
 	@Override
 	public void enterMultExpr(MultExprContext ctx) {
-		LOG.debug("enterMultExpr: text = "+ctx.getText());
+		LOG.trace("enterMultExpr: text = "+ctx.getText());
 		
 		SvcLogicBinaryExpression curBinExpr = new SvcLogicBinaryExpression();
 		pushExpr(curBinExpr);
@@ -127,7 +127,7 @@
 		
 		for (TerminalNode nd : opList)
 		{
-			LOG.debug("enterMultExpr: operator - "+nd.getText());
+			LOG.trace("enterMultExpr: operator - "+nd.getText());
 			curBinExpr.addOperator(nd.getText());
 		}
 
@@ -136,7 +136,7 @@
 	@Override
 	public void exitMultExpr(MultExprContext ctx) {
 
-		LOG.debug("exitMultExpr: text = "+ctx.getText());
+		LOG.trace("exitMultExpr: text = "+ctx.getText());
 
 		popExpr();
 		
@@ -144,13 +144,13 @@
 
 	@Override
 	public void exitAtom(AtomContext ctx) {
-		LOG.debug("exitAtom: text = "+ctx.getText());
+		LOG.trace("exitAtom: text = "+ctx.getText());
 		popExpr();
 	}
 
 	@Override
 	public void enterAddExpr(AddExprContext ctx) {
-		LOG.debug("enterAddExpr: text = "+ctx.getText());
+		LOG.trace("enterAddExpr: text = "+ctx.getText());
 		List<TerminalNode> opList = ctx.ADDOP();
 		
 
@@ -160,7 +160,7 @@
 		
 		for (TerminalNode nd : opList)
 		{
-			LOG.debug("enterAddExpr: operator - "+nd.getText());
+			LOG.trace("enterAddExpr: operator - "+nd.getText());
 			curBinExpr.addOperator(nd.getText());
 		}
 		
@@ -168,19 +168,19 @@
 
 	@Override
 	public void exitAddExpr(AddExprContext ctx) {
-		LOG.debug("exitAddExpr: text = "+ctx.getText());
+		LOG.trace("exitAddExpr: text = "+ctx.getText());
 		
 		popExpr();
 	}
 
 	@Override
 	public void enterFuncExpr(FuncExprContext ctx) {
-		LOG.debug("enterFuncExpr: text = "+ctx.getText());
-		LOG.debug("enterFuncExpr - IDENTIFIER : "+ctx.IDENTIFIER().getText());
+		LOG.trace("enterFuncExpr: text = "+ctx.getText());
+		LOG.trace("enterFuncExpr - IDENTIFIER : "+ctx.IDENTIFIER().getText());
 		
 		for (ExprContext expr: ctx.expr())
 		{
-			LOG.debug("enterFuncExpr - expr = "+expr.getText());
+			LOG.trace("enterFuncExpr - expr = "+expr.getText());
 		}
 		
 
@@ -189,25 +189,25 @@
 
 	@Override
 	public void exitFuncExpr(FuncExprContext ctx) {
-		LOG.debug("exitFuncExpr: text = "+ctx.getText());
+		LOG.trace("exitFuncExpr: text = "+ctx.getText());
 		
 		popExpr();
 	}
 
 	@Override
 	public void enterParenExpr(ParenExprContext ctx) {
-		LOG.debug("enterParenExpr: text = "+ctx.getText());
-		LOG.debug("enterParenExpr: expr = "+ctx.expr().getText());
+		LOG.trace("enterParenExpr: text = "+ctx.getText());
+		LOG.trace("enterParenExpr: expr = "+ctx.expr().getText());
 	}
 
 	@Override
 	public void exitParenExpr(ParenExprContext ctx) {
-		LOG.debug("exitParenExpr: text = "+ctx.getText());
+		LOG.trace("exitParenExpr: text = "+ctx.getText());
 	}
 
 	@Override
 	public void enterRelExpr(RelExprContext ctx) {
-		LOG.debug("enterRelExpr: text = "+ctx.getText());
+		LOG.trace("enterRelExpr: text = "+ctx.getText());
 		
 		List<TerminalNode> opList = ctx.RELOP();
 		
@@ -218,7 +218,7 @@
 		
 		for (TerminalNode nd : opList)
 		{
-			LOG.debug("enterRelExpr: operator - "+nd.getText());
+			LOG.trace("enterRelExpr: operator - "+nd.getText());
 			curBinExpr.addOperator(nd.getText());
 		}
 		
@@ -226,28 +226,28 @@
 
 	@Override
 	public void exitRelExpr(RelExprContext ctx) {
-		LOG.debug("exitRelExpr: text = "+ctx.getText());
+		LOG.trace("exitRelExpr: text = "+ctx.getText());
 		
 		popExpr();
 	}
 
 	@Override
 	public void enterCompareExpr(CompareExprContext ctx) {
-		LOG.debug("enterCompareExpr: text = "+ctx.getText());
+		LOG.trace("enterCompareExpr: text = "+ctx.getText());
 		
 		TerminalNode nd = ctx.COMPAREOP();
 
 		SvcLogicBinaryExpression curBinExpr = new SvcLogicBinaryExpression();
 		pushExpr(curBinExpr);
 
-		LOG.debug("enterCompareExpr: operator - "+nd.getText());
+		LOG.trace("enterCompareExpr: operator - "+nd.getText());
 		curBinExpr.addOperator(nd.getText());
 
 	}
 
 	@Override
 	public void exitCompareExpr(CompareExprContext ctx) {
-		LOG.debug("exitCompareExpr : text = "+ctx.getText());
+		LOG.trace("exitCompareExpr : text = "+ctx.getText());
 		
 		popExpr();
 	}
@@ -256,18 +256,18 @@
 	
 	@Override 
 	public void enterConstant(ConstantContext ctx) {
-		LOG.debug("enterConstant: text = "+ctx.getText());
+		LOG.trace("enterConstant: text = "+ctx.getText());
 	}
 
 	@Override
 	public void exitConstant(ConstantContext ctx) {
-		LOG.debug("exitConstant: text = "+ctx.getText());
+		LOG.trace("exitConstant: text = "+ctx.getText());
 	}
 
 
 	@Override
 	public void enterVariable(VariableContext ctx) {
-		LOG.debug("enterVariable: text = "+ctx.getText());
+		LOG.trace("enterVariable: text = "+ctx.getText());
 		
 		
 	}
@@ -290,12 +290,12 @@
 	@Override
 	public void exitVariableLead(VariableLeadContext ctx) {
 
-		LOG.debug("exitVariableLead: text ="+ctx.getText());
+		LOG.trace("exitVariableLead: text ="+ctx.getText());
 	}
 
 	@Override
 	public void enterVariableTerm(VariableTermContext ctx) {
-		LOG.debug("enterVariableTerm: text ="+ctx.getText());
+		LOG.trace("enterVariableTerm: text ="+ctx.getText());
 		
 		String name = ctx.getText();
 		
@@ -310,7 +310,7 @@
 
 	@Override
 	public void exitVariableTerm(VariableTermContext ctx) {
-		LOG.debug("exitVariableTerm: text="+ctx.getText());
+		LOG.trace("exitVariableTerm: text="+ctx.getText());
 		popExpr();
 	}
 }
diff --git a/sli/common/src/main/java/org/openecomp/sdnc/sli/SvcLogicExpressionFactory.java b/sli/common/src/main/java/org/openecomp/sdnc/sli/SvcLogicExpressionFactory.java
index 751564b..cce8e04 100644
--- a/sli/common/src/main/java/org/openecomp/sdnc/sli/SvcLogicExpressionFactory.java
+++ b/sli/common/src/main/java/org/openecomp/sdnc/sli/SvcLogicExpressionFactory.java
@@ -42,7 +42,7 @@
 	
 	public static SvcLogicExpression parse(String exprStr) throws IOException
 	{
-		LOG.debug("parse("+exprStr+")");
+		LOG.trace("parse("+exprStr+")");
 		InputStream exprStream = new ByteArrayInputStream(exprStr.getBytes());
 		CharStream input = new ANTLRInputStream(exprStream);
 		ExprGrammarLexer lexer = new ExprGrammarLexer(input);
diff --git a/sli/provider/src/main/java/org/openecomp/sdnc/sli/provider/BreakNodeExecutor.java b/sli/provider/src/main/java/org/openecomp/sdnc/sli/provider/BreakNodeExecutor.java
new file mode 100644
index 0000000..0f8719c
--- /dev/null
+++ b/sli/provider/src/main/java/org/openecomp/sdnc/sli/provider/BreakNodeExecutor.java
@@ -0,0 +1,42 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * openECOMP : SDN-C
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights
+ * 						reserved.
+ * ================================================================================
+ * Licensed 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.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.sdnc.sli.provider;
+
+import org.openecomp.sdnc.sli.BreakNodeException;
+import org.openecomp.sdnc.sli.SvcLogicContext;
+import org.openecomp.sdnc.sli.SvcLogicException;
+import org.openecomp.sdnc.sli.SvcLogicNode;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class BreakNodeExecutor extends SvcLogicNodeExecutor {
+
+    private static final Logger LOG = LoggerFactory.getLogger(BreakNodeExecutor.class);
+
+    @Override
+    public SvcLogicNode execute(SvcLogicServiceImpl svc, SvcLogicNode node, SvcLogicContext ctx) throws SvcLogicException {
+        String message = "BreakNodeExecutor encountered break with nodeId " + node.getNodeId();
+        LOG.debug(message);
+        throw new BreakNodeException(message);
+    }
+
+}
diff --git a/sli/provider/src/main/java/org/openecomp/sdnc/sli/provider/CallNodeExecutor.java b/sli/provider/src/main/java/org/openecomp/sdnc/sli/provider/CallNodeExecutor.java
index 2ce4f0a..da0bc56 100644
--- a/sli/provider/src/main/java/org/openecomp/sdnc/sli/provider/CallNodeExecutor.java
+++ b/sli/provider/src/main/java/org/openecomp/sdnc/sli/provider/CallNodeExecutor.java
@@ -114,24 +114,21 @@
 			version  = SvcLogicExpressionResolver.evaluate(moduleExpr, node, ctx);
 		}
 
+		String parentGraph = ctx.getAttribute("currentGraph");
+        ctx.setAttribute("parentGraph", parentGraph);
 		
 		SvcLogicStore store = SvcLogicActivator.getStore();
 		
-		LOG.debug("Calling ["+module+","+rpc+","+version+","+mode+"]");
-		
-		if (store != null)
-		{
+        if (store != null) {
 			SvcLogicGraph calledGraph = store.fetch(module, rpc, version, mode);
-			
-			if (calledGraph != null)
-			{
+            LOG.debug("Parent " + parentGraph + " is calling child " + calledGraph.toString());
+            ctx.setAttribute("currentGraph", calledGraph.toString());
+            if (calledGraph != null) {
 				svc.execute(calledGraph, ctx);
 				
 				outValue = ctx.getStatus();
-			}
-			else
-			{
-				LOG.debug("Could not find service logic for ["+module+","+rpc+","+version+","+mode+"]");
+            } else {
+                LOG.error("Could not find service logic for [" + module + "," + rpc + "," + version + "," + mode + "]");
 			}
 		}
 		else
@@ -144,6 +141,7 @@
 			if (LOG.isDebugEnabled()) {
 				LOG.debug("about to execute " + outValue + " branch");
 			}
+            ctx.setAttribute("currentGraph", parentGraph);
 			return (nextNode);
 		}
 
@@ -157,6 +155,9 @@
 				LOG.debug("no " + outValue + " or Other branch found");
 			}
 		}
+        ctx.setAttribute("currentGraph", parentGraph);
+        ctx.setAttribute("parentGraph", null);
+
 		return (nextNode);
 
 	}
diff --git a/sli/provider/src/main/java/org/openecomp/sdnc/sli/provider/DeleteNodeExecutor.java b/sli/provider/src/main/java/org/openecomp/sdnc/sli/provider/DeleteNodeExecutor.java
index 97da2a6..375c631 100644
--- a/sli/provider/src/main/java/org/openecomp/sdnc/sli/provider/DeleteNodeExecutor.java
+++ b/sli/provider/src/main/java/org/openecomp/sdnc/sli/provider/DeleteNodeExecutor.java
@@ -53,15 +53,8 @@
 					+ plugin);
 		}
 
-		BundleContext bctx = FrameworkUtil.getBundle(this.getClass())
-				.getBundleContext();
 
-		ServiceReference sref = bctx.getServiceReference(plugin);
-
-		if (sref != null) {
-			SvcLogicResource resourcePlugin = (SvcLogicResource) bctx
-					.getService(sref);
-
+		SvcLogicResource resourcePlugin = getSvcLogicResource(plugin);
 			if (resourcePlugin != null) {
 
 				try {
@@ -85,10 +78,7 @@
 				LOG.warn("Could not find SvcLogicResource object for plugin "
 						+ plugin);
 			}
-		} else {
-			LOG.warn("Could not find service reference object for plugin "
-					+ plugin);
-		}
+
 
 		SvcLogicNode nextNode = node.getOutcomeValue(outValue);
 		if (nextNode != null) {
@@ -110,6 +100,22 @@
 		}
 		return (nextNode);
 	}
+	
+    protected SvcLogicResource getSvcLogicResource(String plugin) {
+        BundleContext bctx = FrameworkUtil.getBundle(this.getClass())
+                .getBundleContext();
+
+        ServiceReference sref = bctx.getServiceReference(plugin);
+        if (sref != null) {
+            SvcLogicResource resourcePlugin = (SvcLogicResource) bctx
+                    .getService(sref);
+            return resourcePlugin;
+        }
+        else {
+            LOG.warn("Could not find service reference object for plugin " + plugin);
+            return null;
+        }
+    }
 
 
 }
diff --git a/sli/provider/src/main/java/org/openecomp/sdnc/sli/provider/ExecuteNodeExecutor.java b/sli/provider/src/main/java/org/openecomp/sdnc/sli/provider/ExecuteNodeExecutor.java
index 158c843..85aede7 100644
--- a/sli/provider/src/main/java/org/openecomp/sdnc/sli/provider/ExecuteNodeExecutor.java
+++ b/sli/provider/src/main/java/org/openecomp/sdnc/sli/provider/ExecuteNodeExecutor.java
@@ -21,6 +21,7 @@
 
 package org.openecomp.sdnc.sli.provider;
 
+import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
 import java.util.HashMap;
 import java.util.Iterator;
@@ -44,6 +45,7 @@
 	private static final Logger LOG = LoggerFactory
 			.getLogger(ExecuteNodeExecutor.class);
 
+	private static final String pluginErrorMessage = "Could not execute plugin. SvcLogic status will be set to failure.";
 	public SvcLogicNode execute(SvcLogicServiceImpl svc, SvcLogicNode node,
 			SvcLogicContext ctx) throws SvcLogicException {
 
@@ -55,35 +57,30 @@
 			LOG.debug("execute node encountered - looking for plugin "
 					+ pluginName);
 		}
-		
-		BundleContext bctx = FrameworkUtil.getBundle(this.getClass())
-				.getBundleContext();
 
-		ServiceReference sref = bctx.getServiceReference(pluginName);
+        SvcLogicJavaPlugin plugin  = getSvcLogicJavaPlugin(pluginName);
 
-		if (sref == null) {
+		if (plugin == null) {
 			outValue = "not-found";
 		} else {
-			SvcLogicJavaPlugin plugin  = (SvcLogicJavaPlugin) bctx
-					.getService(sref);
-			
-			String methodName = SvcLogicExpressionResolver.evaluate(node.getAttribute("method"),  node, ctx);
-			
+
+			String methodName = evaluate(node.getAttribute("method"),  node, ctx);
+
 			Class pluginClass = plugin.getClass();
-			
+
 			Method pluginMethod = null;
-			
+
 			try {
 				pluginMethod = pluginClass.getMethod(methodName, Map.class, SvcLogicContext.class);
-			} catch (Exception e) {
-				LOG.error("Caught exception looking for method "+pluginName+"."+methodName+"(Map, SvcLogicContext)");
+			} catch (NoSuchMethodException e) {
+				LOG.error(pluginErrorMessage, e);
 			}
-			
+
 			if (pluginMethod == null) {
 				outValue = "unsupported-method";
 			} else {
 				try {
-					
+
 					Map<String, String> parmMap = new HashMap<String, String>();
 
 					Set<Map.Entry<String, SvcLogicExpression>> parmSet = node
@@ -95,21 +92,34 @@
 						String curName = curEnt.getKey();
 						SvcLogicExpression curExpr = curEnt.getValue();
 						String curExprValue = SvcLogicExpressionResolver.evaluate(curExpr, node, ctx);
-						
+
 						LOG.debug("Parameter "+curName+" = "+curExpr.asParsedExpr()+" resolves to "+curExprValue);
 
 						parmMap.put(curName,curExprValue);
 					}
-					
-					pluginMethod.invoke(plugin, parmMap, ctx);
-					
-					outValue = "success";
-				} catch (Exception e) {
-					LOG.error("Caught exception executing "+pluginName+"."+methodName, e);
-					
+
+					Object o = pluginMethod.invoke(plugin, parmMap, ctx);
+			        String emitsOutcome = SvcLogicExpressionResolver.evaluate(node.getAttribute("emitsOutcome"),  node, ctx);
+
+					outValue = mapOutcome(o, emitsOutcome);
+
+				} catch (InvocationTargetException e) {
+				    if(e.getCause() != null){
+	                    LOG.error(pluginErrorMessage, e.getCause());
+				    }else{
+					LOG.error(pluginErrorMessage, e);
+				    }
 					outValue = "failure";
 					ctx.setStatus("failure");
-				}
+				} catch (IllegalAccessException e) {
+                    LOG.error(pluginErrorMessage, e);
+                    outValue = "failure";
+                    ctx.setStatus("failure");
+                } catch (IllegalArgumentException e) {
+                    LOG.error(pluginErrorMessage, e);
+                    outValue = "failure";
+                    ctx.setStatus("failure");
+                }
 			}
 
 		}
@@ -135,4 +145,37 @@
 		return (nextNode);
 	}
 
+	protected SvcLogicJavaPlugin getSvcLogicJavaPlugin(String pluginName){
+	       BundleContext bctx = FrameworkUtil.getBundle(this.getClass())
+	                .getBundleContext();
+
+	        ServiceReference sref = bctx.getServiceReference(pluginName);
+
+	        if (sref == null) {
+	            LOG.warn("Could not find service reference object for plugin " + pluginName);
+	            return null;
+	        } else {
+	            SvcLogicJavaPlugin plugin  = (SvcLogicJavaPlugin) bctx
+	                    .getService(sref);
+	            return plugin;
+	        }
+	}
+	protected String evaluate(SvcLogicExpression expr, SvcLogicNode node, SvcLogicContext ctx) throws SvcLogicException {
+        return SvcLogicExpressionResolver.evaluate(node.getAttribute("method"), node, ctx);
+    }
+
+    public String mapOutcome(Object o, String emitsOutcome) {
+        if (emitsOutcome != null) {
+            Boolean nodeEmitsOutcome = Boolean.valueOf(emitsOutcome);
+            if (nodeEmitsOutcome) {
+                return (String) o;
+            } else {
+                return "success";
+            }
+
+        } else {
+            return "success";
+        }
+    }
+
 }
diff --git a/sli/provider/src/main/java/org/openecomp/sdnc/sli/provider/ExistsNodeExecutor.java b/sli/provider/src/main/java/org/openecomp/sdnc/sli/provider/ExistsNodeExecutor.java
index 48b511e..464c676 100644
--- a/sli/provider/src/main/java/org/openecomp/sdnc/sli/provider/ExistsNodeExecutor.java
+++ b/sli/provider/src/main/java/org/openecomp/sdnc/sli/provider/ExistsNodeExecutor.java
@@ -55,14 +55,9 @@
 					+ plugin);
 		}
 
-		BundleContext bctx = FrameworkUtil.getBundle(this.getClass())
-				.getBundleContext();
 
-		ServiceReference sref = bctx.getServiceReference(plugin);
 
-		if (sref != null) {
-			SvcLogicResource resourcePlugin = (SvcLogicResource) bctx
-					.getService(sref);
+			SvcLogicResource resourcePlugin = getSvcLogicResource(plugin);
 
 			if (resourcePlugin != null) {
 
@@ -87,10 +82,6 @@
 				LOG.warn("Could not find SvcLogicResource object for plugin "
 						+ plugin);
 			}
-		} else {
-			LOG.warn("Could not find service reference object for plugin "
-					+ plugin);
-		}
 
 		SvcLogicNode nextNode = node.getOutcomeValue(outValue);
 		if (nextNode != null) {
@@ -114,5 +105,21 @@
 		return (nextNode);
 	}
 
+    protected SvcLogicResource getSvcLogicResource(String plugin) {
+        BundleContext bctx = FrameworkUtil.getBundle(this.getClass())
+                .getBundleContext();
+
+        ServiceReference sref = bctx.getServiceReference(plugin);
+        if (sref != null) {
+            SvcLogicResource resourcePlugin = (SvcLogicResource) bctx
+                    .getService(sref);
+            return resourcePlugin;
+        }
+        else {
+            LOG.warn("Could not find service reference object for plugin " + plugin);
+            return null;
+        }
+    }
+
 
 }
diff --git a/sli/provider/src/main/java/org/openecomp/sdnc/sli/provider/ForNodeExecutor.java b/sli/provider/src/main/java/org/openecomp/sdnc/sli/provider/ForNodeExecutor.java
index a669712..e9fdc55 100644
--- a/sli/provider/src/main/java/org/openecomp/sdnc/sli/provider/ForNodeExecutor.java
+++ b/sli/provider/src/main/java/org/openecomp/sdnc/sli/provider/ForNodeExecutor.java
@@ -21,6 +21,7 @@
 
 package org.openecomp.sdnc.sli.provider;
 
+import org.openecomp.sdnc.sli.BreakNodeException;
 import org.openecomp.sdnc.sli.SvcLogicContext;
 import org.openecomp.sdnc.sli.SvcLogicException;
 import org.openecomp.sdnc.sli.SvcLogicExpression;
@@ -40,7 +41,7 @@
 		SvcLogicExpression atomicExpr = node.getAttribute("atomic");
 		String atomicStr = SvcLogicExpressionResolver.evaluate(atomicExpr, node, ctx);
 		boolean isAtomic = !("false".equalsIgnoreCase(atomicStr));
-		
+
 		int numOutcomes = node.getNumOutcomes();
 		String idxVar = SvcLogicExpressionResolver.evaluate(
 				node.getAttribute("index"), node, ctx);
@@ -59,21 +60,30 @@
 			startIdx = Integer.parseInt(startVal);
 			endIdx = Integer.parseInt(endVal);
 		} catch (NumberFormatException e) {
-			throw new SvcLogicException("Invalid index values [" + startVal
-					+ "," + endVal + "]");
+			SvcLogicExpression silentFailureExpr = node.getAttribute("silentFailure");
+			String silentFailure = SvcLogicExpressionResolver.evaluate(silentFailureExpr, node, ctx);
+			boolean isSilentFailure = Boolean.parseBoolean(silentFailure);
+			String message = "Invalid index values [" + startVal + "," + endVal + "]";
+			if(!isSilentFailure){
+			throw new SvcLogicException(message);
+			}else{
+			    LOG.debug(message + ". Not exiting because silentFailure was set to true.");
+			    return(null);
+			}
 		}
 
+        try {
 		for (int ctr = startIdx; ctr < endIdx; ctr++) {
 
 			ctx.setAttribute(idxVar, "" + ctr);
 
 			for (int i = 0; i < numOutcomes; i++) {
-				
+
 				if ("failure".equals(ctx.getStatus()) && isAtomic) {
 					LOG.info("For - stopped executing nodes due to failure status");
 					return(null);
 				}
-				
+
 				SvcLogicNode nextNode = node.getOutcomeValue("" + (i + 1));
 				if (nextNode != null) {
 					if (LOG.isDebugEnabled()) {
@@ -83,7 +93,6 @@
 					while (innerNextNode != null) {
 						innerNextNode = svc.executeNode(innerNextNode, ctx);
 					}
-
 				} else {
 					if (LOG.isDebugEnabled()) {
 						LOG.debug("For - done: no outcome " + (i + 1));
@@ -91,6 +100,9 @@
 				}
 			}
 		}
+        } catch (BreakNodeException br) {
+            LOG.debug("ForNodeExecutor caught break");
+        }
 		return (null);
 	}
 
diff --git a/sli/provider/src/main/java/org/openecomp/sdnc/sli/provider/GetResourceNodeExecutor.java b/sli/provider/src/main/java/org/openecomp/sdnc/sli/provider/GetResourceNodeExecutor.java
index ce0fe68..c260db2 100644
--- a/sli/provider/src/main/java/org/openecomp/sdnc/sli/provider/GetResourceNodeExecutor.java
+++ b/sli/provider/src/main/java/org/openecomp/sdnc/sli/provider/GetResourceNodeExecutor.java
@@ -84,14 +84,8 @@
 					+ plugin);
 		}
 
-		BundleContext bctx = FrameworkUtil.getBundle(this.getClass())
-				.getBundleContext();
 
-		ServiceReference sref = bctx.getServiceReference(plugin);
-
-		if (sref != null) {
-			SvcLogicResource resourcePlugin = (SvcLogicResource) bctx
-					.getService(sref);
+			SvcLogicResource resourcePlugin = getSvcLogicResource(plugin);
 
 			if (resourcePlugin != null) {
 
@@ -116,9 +110,7 @@
 				LOG.warn("Could not find SvcLogicResource object for plugin "
 						+ plugin);
 			}
-		} else {
-			LOG.warn("Cound not find service reference for plugin " + plugin);
-		}
+
 
 		SvcLogicNode nextNode = node.getOutcomeValue(outValue);
 		if (nextNode != null) {
@@ -141,6 +133,22 @@
 		}
 		return (nextNode);
 	}
+	
+    protected SvcLogicResource getSvcLogicResource(String plugin) {
+        BundleContext bctx = FrameworkUtil.getBundle(this.getClass())
+                .getBundleContext();
+
+        ServiceReference sref = bctx.getServiceReference(plugin);
+        if (sref != null) {
+            SvcLogicResource resourcePlugin = (SvcLogicResource) bctx
+                    .getService(sref);
+            return resourcePlugin;
+        }
+        else {
+            LOG.warn("Could not find service reference object for plugin " + plugin);
+            return null;
+        }
+    }
 
 
 }
diff --git a/sli/provider/src/main/java/org/openecomp/sdnc/sli/provider/IsAvailableNodeExecutor.java b/sli/provider/src/main/java/org/openecomp/sdnc/sli/provider/IsAvailableNodeExecutor.java
index 47eebe4..00c7e66 100644
--- a/sli/provider/src/main/java/org/openecomp/sdnc/sli/provider/IsAvailableNodeExecutor.java
+++ b/sli/provider/src/main/java/org/openecomp/sdnc/sli/provider/IsAvailableNodeExecutor.java
@@ -56,14 +56,8 @@
 					+ plugin);
 		}
 
-		BundleContext bctx = FrameworkUtil.getBundle(this.getClass())
-				.getBundleContext();
+            SvcLogicResource resourcePlugin = getSvcLogicResource(plugin);
 
-		ServiceReference sref = bctx.getServiceReference(plugin);
-
-		if (sref != null) {
-			SvcLogicResource resourcePlugin = (SvcLogicResource) bctx
-					.getService(sref);
 
 			if (resourcePlugin != null) {
 				try {
@@ -86,10 +80,6 @@
 				LOG.warn("Could not find SvcLogicResource object for plugin "
 						+ plugin);
 			}
-		} else {
-			LOG.warn("Could not find service reference object for plugin "
-					+ plugin);
-		}
 
 		SvcLogicNode nextNode = node.getOutcomeValue(outValue);
 		if (nextNode != null) {
@@ -113,5 +103,20 @@
 		return (nextNode);
 	}
 
+    protected SvcLogicResource getSvcLogicResource(String plugin) {
+        BundleContext bctx = FrameworkUtil.getBundle(this.getClass())
+                .getBundleContext();
+
+        ServiceReference sref = bctx.getServiceReference(plugin);
+        if (sref != null) {
+            SvcLogicResource resourcePlugin = (SvcLogicResource) bctx
+                    .getService(sref);
+            return resourcePlugin;
+        }
+        else {
+            LOG.warn("Could not find service reference object for plugin " + plugin);
+            return null;
+        }
+    }
 
 }
diff --git a/sli/provider/src/main/java/org/openecomp/sdnc/sli/provider/MdsalHelper.java b/sli/provider/src/main/java/org/openecomp/sdnc/sli/provider/MdsalHelper.java
index 9847416..4c5ee06 100644
--- a/sli/provider/src/main/java/org/openecomp/sdnc/sli/provider/MdsalHelper.java
+++ b/sli/provider/src/main/java/org/openecomp/sdnc/sli/provider/MdsalHelper.java
@@ -47,1359 +47,1140 @@
 
 public class MdsalHelper {
 
-	private static final Logger LOG = LoggerFactory.getLogger(MdsalHelper.class);
-	public static final String PROPERTIES_FILE="/opt/bvc/controller/configuration/l3sdn.properties";
-	private static Properties properties = new Properties();
-	
-	
-	public static void setProperties(Properties properties) {
-		
-		for (Object propNameObj: properties.keySet()) {
-			String propName = (String) propNameObj;
-			MdsalHelper.properties.setProperty(propName, properties.getProperty(propName));
+    private static final Logger LOG = LoggerFactory.getLogger(MdsalHelper.class);
+    private static Properties yangMappingProperties = new Properties();
+
+    @Deprecated
+    public static void setProperties(Properties input) {
+        setYangMappingProperties(input);
+    }
+    
+    public static void setYangMappingProperties(Properties properties) {
+        for (Object propNameObj : properties.keySet()) {
+            String propName = (String) propNameObj;
+            MdsalHelper.yangMappingProperties.setProperty(propName, properties.getProperty(propName));
+        }
+    }
+
+    public static void loadProperties(String propertiesFile) {
+	File file = new File(propertiesFile);
+	Properties properties = new Properties();
+	InputStream input = null;
+	if (file.isFile() && file.canRead()) {
+	    try {
+		input = new FileInputStream(file);
+		properties.load(input);
+		MdsalHelper.setYangMappingProperties(properties);
+		LOG.info("Loaded properties from " + propertiesFile);
+	    } catch (Exception e) {
+		LOG.error("Failed to load properties " + propertiesFile + "\n", e);
+	    } finally {
+		if (input != null) {
+		    try {
+			input.close();
+		    } catch (IOException e) {
+			LOG.error("Failed to close properties file " + propertiesFile + "\n", e);
+		    }
 		}
+	    }
+	}else{
+	    LOG.error("Failed to load the properties file " + propertiesFile + "\n");
+	    LOG.error("Either isFile or canRead returned false for " + propertiesFile + "\n");
+	}
+    }
+
+    public static Properties toProperties(Properties props, Object fromObj) {
+	Class fromClass = null;
+
+	if (fromObj != null) {
+	    fromClass = fromObj.getClass();
+	}
+	return (toProperties(props, "", fromObj, fromClass));
+    }
+
+    public static Properties toProperties(Properties props, String pfx, Object fromObj) {
+	Class fromClass = null;
+
+	if (fromObj != null) {
+	    fromClass = fromObj.getClass();
 	}
 
-	public static void loadProperties() {
+	return (toProperties(props, pfx, fromObj, fromClass));
+    }
 
-		File file = new File(PROPERTIES_FILE); 
-		Properties properties = new Properties();
-		InputStream input = null;
-		if (file.isFile() && file.canRead()) {
-			try	{
-				input = new FileInputStream(file);
-				properties.load(input);
-				MdsalHelper.setProperties(properties);
-				LOG.info("Loaded properties from " + PROPERTIES_FILE );
-			} catch (Exception e) {
-				LOG.error("Failed to load properties " + PROPERTIES_FILE +"\n",e);
-			} finally {
-				if (input != null) {
-					try {
-						input.close();
-					} catch (IOException e) {
-						LOG.error("Failed to close properties file " + PROPERTIES_FILE +"\n",e);
-					}
-				}
-			}
-		}
-	}
-	
-	public static Properties toProperties(Properties props, Object fromObj) {
-		Class fromClass = null;
-		
-		if (fromObj != null)
-		{
-			fromClass = fromObj.getClass();
-		}
-		return (toProperties(props, "", fromObj, fromClass));
-	}
-	
-	public static Properties toProperties(Properties props, String pfx, Object fromObj)
-	{
-		Class fromClass = null;
-		
-		if (fromObj != null)
-		{
-			fromClass = fromObj.getClass();
-		}
-		
-		return(toProperties(props, pfx, fromObj, fromClass));
+    public static Properties toProperties(Properties props, String pfx, Object fromObj, Class fromClass) {
+
+	if (fromObj == null) {
+	    return (props);
 	}
 
-	public static Properties toProperties(Properties props, String pfx,
-			Object fromObj, Class fromClass) {
+	String simpleName = fromClass.getSimpleName();
 
-		if (fromObj == null) {
-			return (props);
-		}
-	
-		
-		String simpleName = fromClass.getSimpleName();
+	LOG.trace("Extracting properties from " + fromClass.getName() + " class");
+	if (fromObj instanceof List) {
 
-		LOG.trace("Extracting properties from " + fromClass.getName()
-				+ " class");
-		if (fromObj instanceof List) {
+	    // Class is a List. List should contain yang-generated classes.
+	    LOG.trace(fromClass.getName() + " is a List");
 
-			// Class is a List. List should contain yang-generated classes.
-			LOG.trace(fromClass.getName() + " is a List");
+	    List fromList = (List) fromObj;
 
-			List fromList = (List) fromObj;
+	    for (int i = 0; i < fromList.size(); i++) {
+		toProperties(props, pfx + "[" + i + "]", fromList.get(i), fromClass);
+	    }
+	    props.setProperty(pfx + "_length", "" + fromList.size());
 
-			for (int i = 0; i < fromList.size(); i++) {
-				toProperties(props, pfx + "[" + i + "]", fromList.get(i), fromClass);
-			}
-			props.setProperty(pfx + "_length", "" + fromList.size());
+	} else if (isYangGenerated(fromClass)) {
+	    // Class is yang generated.
+	    LOG.trace(fromClass.getName() + " is a Yang-generated class");
 
-		} else if (isYangGenerated(fromClass)) {
-			// Class is yang generated.
-			LOG.trace(fromClass.getName() + " is a Yang-generated class");
+	    String propNamePfx = null;
 
-			String propNamePfx = null;
-
-			// If called from a list (so prefix ends in ']'), don't
-			// add class name again
-			if (pfx.endsWith("]")) {
-				propNamePfx = pfx;
-			} else {
-				if ((pfx != null) && (pfx.length() > 0)) {
-					propNamePfx = pfx ;
-				} else {
-					propNamePfx = toLowerHyphen(fromClass.getSimpleName());
-				}
-
-				if (propNamePfx.endsWith("-builder")) {
-					propNamePfx = propNamePfx.substring(0, propNamePfx.length()
-							- "-builder".length());
-				}
-
-				if (propNamePfx.endsWith("-impl")) {
-					propNamePfx = propNamePfx.substring(0, propNamePfx.length()
-							- "-impl".length());
-				}
-			}
-			
-			// Iterate through getter methods to figure out values we need to
-			// save from
-
-			int numGetters = 0;
-			String lastGetterName = null;
-			String propVal = null;
-			
-			for (Method m : fromClass.getMethods()) {
-				if (isGetter(m)) {
-					
-					numGetters++;
-					lastGetterName = m.getName();
-					
-					Class returnType = m.getReturnType();
-					String fieldName;
-					if (m.getName().startsWith("get")) {
-						fieldName = toLowerHyphen(m.getName().substring(3));
-					} else {
-
-						fieldName = toLowerHyphen(m.getName().substring(2));
-					}
-					
-					fieldName = fieldName.substring(0, 1).toLowerCase()
-							+ fieldName.substring(1);
-
-					// Is the return type a yang generated class?
-					if (isYangGenerated(returnType)) {
-						// Is it an enum?
-						if (returnType.isEnum()) {
-							// Return type is a typedef. Save its value.
-							try {
-								boolean isAccessible = m.isAccessible();
-								if (!isAccessible) {
-									m.setAccessible(true);
-								}
-
-								Object retValue = m.invoke(fromObj);
-
-								if (!isAccessible) {
-									m.setAccessible(isAccessible);
-								}
-								if (retValue != null) {
-									String propName = propNamePfx + "."
-											+ fieldName;
-									propVal = retValue.toString();
-									String yangProp = "yang." + fieldName + "." + propVal;
-									if ( properties.containsKey(yangProp)) {
-										propVal = properties.getProperty(yangProp);
-										LOG.trace("Adjusting property " + yangProp + " " + propVal);
-									}
-									LOG.debug("Setting property " + propName
-											+ " to " + propVal);
-									props.setProperty(propName, propVal);
-								}
-							} catch (Exception e) {
-								LOG.error(
-										"Caught exception trying to convert Yang-generated enum returned by "
-												+ fromClass.getName() + "."
-												+ m.getName()
-												+ "() to Properties entry", e);
-							}
-						} else if (isIpv4Address(returnType)) {
-							// Save its value
-							try {
-								String propName = propNamePfx + "." + fieldName;
-								boolean isAccessible = m.isAccessible();
-								if (!isAccessible) {
-									m.setAccessible(true);
-								}
-								Ipv4Address retValue = (Ipv4Address) m.invoke(fromObj);
-								if (!isAccessible) {
-									m.setAccessible(isAccessible);
-								}
-
-								if (retValue != null) {
-									propVal = retValue.getValue().toString();
-									LOG.debug("Setting property " + propName
-											+ " to " + propVal);
-									props.setProperty(propName, propVal);
-
-								}
-							} catch (Exception e) {
-								LOG.error(
-										"Caught exception trying to convert value returned by "
-												+ fromClass.getName() + "."
-												+ m.getName()
-												+ "() to Properties entry", e);
-							}
-						} else if (isIpv6Address(returnType)) {
-							// Save its value
-							try {
-								String propName = propNamePfx + "." + fieldName;
-								boolean isAccessible = m.isAccessible();
-								if (!isAccessible) {
-									m.setAccessible(true);
-								}
-								Ipv6Address retValue = (Ipv6Address) m.invoke(fromObj);
-								if (!isAccessible) {
-									m.setAccessible(isAccessible);
-								}
-
-								if (retValue != null) {
-									propVal = retValue.getValue().toString();
-									LOG.debug("Setting property " + propName
-											+ " to " + propVal);
-									props.setProperty(propName, propVal);
-
-								}
-							} catch (Exception e) {
-								LOG.error(
-										"Caught exception trying to convert value returned by "
-												+ fromClass.getName() + "."
-												+ m.getName()
-												+ "() to Properties entry", e);
-							}
-						} else if (isIpAddress(returnType)) {
-							// Save its value
-							try {
-								String propName = propNamePfx + "." + fieldName;
-								boolean isAccessible = m.isAccessible();
-								if (!isAccessible) {
-									m.setAccessible(true);
-								}
-								IpAddress retValue = (IpAddress) m.invoke(fromObj);
-								if (!isAccessible) {
-									m.setAccessible(isAccessible);
-								}
-
-								if (retValue != null) {
-									propVal = new String(retValue.getValue());
-									LOG.debug("Setting property " + propName
-											+ " to " + propVal);
-									props.setProperty(propName, propVal);
-
-								}
-							} catch (Exception e) {
-								LOG.error(
-										"Caught exception trying to convert value returned by "
-												+ fromClass.getName() + "."
-												+ m.getName()
-												+ "() to Properties entry", e);
-							}
-						} else if (isIpPrefix(returnType)) {
-							// Save its value
-							try {
-								String propName = propNamePfx + "." + fieldName;
-								boolean isAccessible = m.isAccessible();
-								if (!isAccessible) {
-									m.setAccessible(true);
-								}
-								IpPrefix retValue = (IpPrefix) m.invoke(fromObj);
-								if (!isAccessible) {
-									m.setAccessible(isAccessible);
-								}
-
-								if (retValue != null) {
-									propVal = new String(retValue.getValue());
-									LOG.debug("Setting property " + propName
-											+ " to " + propVal);
-									props.setProperty(propName, propVal);
-
-								}
-							} catch (Exception e) {
-								LOG.error(
-										"Caught exception trying to convert value returned by "
-												+ fromClass.getName() + "."
-												+ m.getName()
-												+ "() to Properties entry", e);
-							}
-						} else {
-							try {
-								boolean isAccessible = m.isAccessible();
-								if (!isAccessible) {
-									m.setAccessible(true);
-								}
-								Object retValue = m.invoke(fromObj);
-								
-								if (retValue instanceof byte[]) {
-									LOG.trace(m.getName()+" returns a byte[]");
-									retValue = new String((byte[]) retValue, "UTF-8");
-									LOG.trace("Converted byte array "+propNamePfx+"."+fieldName+"to string "+ retValue );
-								}
-								if (!isAccessible) {
-									m.setAccessible(isAccessible);
-								}
-								if (retValue != null) {
-									toProperties(props, propNamePfx + "." + fieldName, retValue, returnType);
-								}
-							} catch (Exception e) {
-								
-								if (m.getName().equals("getKey")) {
-									LOG.trace("Caught "+e.getClass().getName()+" exception trying to convert results from getKey() - ignoring");
-								} else {
-									LOG.error(
-											"Caught exception trying to convert Yang-generated class returned by"
-													+ fromClass.getName() + "."
-													+ m.getName()
-													+ "() to Properties entry", e);
-								}
-							}
-						}
-					} else if (returnType.equals(Class.class)) {
-
-						LOG.trace(m.getName()
-								+ " returns a Class object - not interested");
-
-					} else if (List.class.isAssignableFrom(returnType)) {
-
-						// This getter method returns a list.
-						try {
-							boolean isAccessible = m.isAccessible();
-							if (!isAccessible) {
-								m.setAccessible(true);
-							}
-							Object retList = m.invoke(fromObj);
-							if (!isAccessible) {
-								m.setAccessible(isAccessible);
-							}
-							// Figure out what type of elements are stored in this array.
-							Type paramType = m.getGenericReturnType();
-							Type elementType = ((ParameterizedType) paramType)
-									.getActualTypeArguments()[0];
-							toProperties(props, propNamePfx + "." + fieldName,
-									retList, (Class)elementType);
-						} catch (Exception e) {
-							LOG.error(
-									"Caught exception trying to convert List returned by "
-											+ fromClass.getName() + "."
-											+ m.getName()
-											+ "() to Properties entry", e);
-						}
-
-					} else {
-
-						// Method returns something that is not a List and not
-						// yang-generated.
-						// Save its value
-						try {
-							String propName = propNamePfx + "." + fieldName;
-							boolean isAccessible = m.isAccessible();
-							if (!isAccessible) {
-								m.setAccessible(true);
-							}
-							Object propValObj = m.invoke(fromObj);
-							if (!isAccessible) {
-								m.setAccessible(isAccessible);
-							}
-
-							if (propValObj != null) {
-								if (propValObj instanceof byte[]) {
-									LOG.trace(m.getName()+" returns a byte[]");
-									propVal = new String((byte[]) propValObj, "UTF-8");
-									LOG.trace("Converted byte array "+propNamePfx+"."+fieldName+"to string "+ propVal );
-
-								} else {
-									propVal = propValObj.toString();
-								}
-								LOG.debug("Setting property " + propName
-										+ " to " + propVal);
-								props.setProperty(propName, propVal);
-
-							}
-						} catch (Exception e) {
-							if (m.getName().equals("getKey")) {
-								LOG.trace("Caught "+e.getClass().getName()+" exception trying to convert results from getKey() - ignoring");
-							} else {
-								LOG.error(
-										"Caught exception trying to convert value returned by"
-												+ fromClass.getName() + "."
-												+ m.getName()
-												+ "() to Properties entry", e);
-							}
-						}
-					}
-
-				}
-			}
-			
-			// End of method loop.  If there was only one getter, named "getValue", then
-			// set value identified by "prefix" to that one value.
-			if ((numGetters == 1) && ("getValue".equals(lastGetterName))) {
-				LOG.trace("getValueFIX : "+ propNamePfx+" only has getValue() getter - setting "+propNamePfx+" = "+propVal);
-				props.setProperty(propNamePfx, propVal);
-			} else {
-				LOG.trace("getValueFIX : " + propNamePfx+" has "+numGetters+" getter(s), last one found was "+lastGetterName);
-				
-			}
-
+	    // If called from a list (so prefix ends in ']'), don't
+	    // add class name again
+	    if (pfx.endsWith("]")) {
+		propNamePfx = pfx;
+	    } else {
+		if ((pfx != null) && (pfx.length() > 0)) {
+		    propNamePfx = pfx;
 		} else {
-			// Class is not yang generated and not a list
-			// It must be an element of a leaf list - set "prefix" to value
-			String fromVal = null;
-			if (fromObj instanceof byte[]) {
-				try {
-				fromVal = new String((byte[]) fromObj, "UTF-8");
-				LOG.trace("Converted byte array "+pfx+"to string "+ fromVal );
-				} catch (Exception e) {
-					LOG.warn("Caught exception trying to convert "+pfx+" from byte[] to String", e);
-					fromVal = fromObj.toString();
-				}
-
-			} else {
-				fromVal = fromObj.toString();
-			}
-			LOG.debug("Setting property " + pfx
-					+ " to " + fromVal);
-			props.setProperty(pfx, fromVal);
+		    propNamePfx = toLowerHyphen(fromClass.getSimpleName());
 		}
 
-		return (props);
-	}
+		if (propNamePfx.endsWith("-builder")) {
+		    propNamePfx = propNamePfx.substring(0, propNamePfx.length() - "-builder".length());
+		}
 
-	public static Object toBuilder(Properties props, Object toObj) {
+		if (propNamePfx.endsWith("-impl")) {
+		    propNamePfx = propNamePfx.substring(0, propNamePfx.length() - "-impl".length());
+		}
+	    }
 
-		return (toBuilder(props, "", toObj));
-	}
+	    // Iterate through getter methods to figure out values we need to
+	    // save from
 
-	public static List toList(Properties props, String pfx, List toObj,
-			Class elemType) {
+	    int numGetters = 0;
+	    String lastGetterName = null;
+	    String propVal = null;
 
-		int maxIdx = -1;
-		boolean foundValue = false;
+	    for (Method m : fromClass.getMethods()) {
+		if (isGetter(m)) {
 
-		LOG.trace("Saving properties to List<" + elemType.getName()
-				+ ">  from " + pfx);
+		    numGetters++;
+		    lastGetterName = m.getName();
 
-		if (props.contains(pfx+"_length")) {
+		    Class returnType = m.getReturnType();
+		    String fieldName;
+		    if (m.getName().startsWith("get")) {
+			fieldName = toLowerHyphen(m.getName().substring(3));
+		    } else {
+
+			fieldName = toLowerHyphen(m.getName().substring(2));
+		    }
+
+		    fieldName = fieldName.substring(0, 1).toLowerCase() + fieldName.substring(1);
+
+		    // Is the return type a yang generated class?
+		    if (isYangGenerated(returnType)) {
+			// Is it an enum?
+			if (returnType.isEnum()) {
+			    // Return type is a typedef. Save its value.
+			    try {
+				boolean isAccessible = m.isAccessible();
+				if (!isAccessible) {
+				    m.setAccessible(true);
+				}
+
+				Object retValue = m.invoke(fromObj);
+
+				if (!isAccessible) {
+				    m.setAccessible(isAccessible);
+				}
+				if (retValue != null) {
+				    String propName = propNamePfx + "." + fieldName;
+				    propVal = retValue.toString();
+				    props.setProperty(propName, mapEnumeratedValue(fieldName, propVal));
+				}
+			    } catch (Exception e) {
+				LOG.error("Caught exception trying to convert Yang-generated enum returned by " + fromClass.getName() + "." + m.getName() + "() to Properties entry", e);
+			    }
+			} else if (isIpv4Address(returnType)) {
+			    // Save its value
+			    try {
+				String propName = propNamePfx + "." + fieldName;
+				boolean isAccessible = m.isAccessible();
+				if (!isAccessible) {
+				    m.setAccessible(true);
+				}
+				Ipv4Address retValue = (Ipv4Address) m.invoke(fromObj);
+				if (!isAccessible) {
+				    m.setAccessible(isAccessible);
+				}
+
+				if (retValue != null) {
+				    propVal = retValue.getValue().toString();
+				    LOG.debug("Setting property " + propName + " to " + propVal);
+				    props.setProperty(propName, propVal);
+
+				}
+			    } catch (Exception e) {
+				LOG.error("Caught exception trying to convert value returned by " + fromClass.getName() + "." + m.getName() + "() to Properties entry", e);
+			    }
+			} else if (isIpv6Address(returnType)) {
+			    // Save its value
+			    try {
+				String propName = propNamePfx + "." + fieldName;
+				boolean isAccessible = m.isAccessible();
+				if (!isAccessible) {
+				    m.setAccessible(true);
+				}
+				Ipv6Address retValue = (Ipv6Address) m.invoke(fromObj);
+				if (!isAccessible) {
+				    m.setAccessible(isAccessible);
+				}
+
+				if (retValue != null) {
+				    propVal = retValue.getValue().toString();
+				    LOG.debug("Setting property " + propName + " to " + propVal);
+				    props.setProperty(propName, propVal);
+
+				}
+			    } catch (Exception e) {
+				LOG.error("Caught exception trying to convert value returned by " + fromClass.getName() + "." + m.getName() + "() to Properties entry", e);
+			    }
+			} else if (isIpAddress(returnType)) {
+			    // Save its value
+			    try {
+				String propName = propNamePfx + "." + fieldName;
+				boolean isAccessible = m.isAccessible();
+				if (!isAccessible) {
+				    m.setAccessible(true);
+				}
+				IpAddress retValue = (IpAddress) m.invoke(fromObj);
+				if (!isAccessible) {
+				    m.setAccessible(isAccessible);
+				}
+
+				if (retValue != null) {
+				    propVal = new String(retValue.getValue());
+				    LOG.debug("Setting property " + propName + " to " + propVal);
+				    props.setProperty(propName, propVal);
+
+				}
+			    } catch (Exception e) {
+				LOG.error("Caught exception trying to convert value returned by " + fromClass.getName() + "." + m.getName() + "() to Properties entry", e);
+			    }
+			} else if (isIpPrefix(returnType)) {
+			    // Save its value
+			    try {
+				String propName = propNamePfx + "." + fieldName;
+				boolean isAccessible = m.isAccessible();
+				if (!isAccessible) {
+				    m.setAccessible(true);
+				}
+				IpPrefix retValue = (IpPrefix) m.invoke(fromObj);
+				if (!isAccessible) {
+				    m.setAccessible(isAccessible);
+				}
+
+				if (retValue != null) {
+				    propVal = new String(retValue.getValue());
+				    LOG.debug("Setting property " + propName + " to " + propVal);
+				    props.setProperty(propName, propVal);
+
+				}
+			    } catch (Exception e) {
+				LOG.error("Caught exception trying to convert value returned by " + fromClass.getName() + "." + m.getName() + "() to Properties entry", e);
+			    }
+			} else {
+			    try {
+				boolean isAccessible = m.isAccessible();
+				if (!isAccessible) {
+				    m.setAccessible(true);
+				}
+				Object retValue = m.invoke(fromObj);
+
+				if (retValue instanceof byte[]) {
+				    LOG.trace(m.getName() + " returns a byte[]");
+				    retValue = new String((byte[]) retValue, "UTF-8");
+				    LOG.trace("Converted byte array " + propNamePfx + "." + fieldName + "to string " + retValue);
+				}
+				if (!isAccessible) {
+				    m.setAccessible(isAccessible);
+				}
+				if (retValue != null) {
+				    toProperties(props, propNamePfx + "." + fieldName, retValue, returnType);
+				}
+			    } catch (Exception e) {
+
+				if (m.getName().equals("getKey")) {
+				    LOG.trace("Caught " + e.getClass().getName() + " exception trying to convert results from getKey() - ignoring");
+				} else {
+				    LOG.error("Caught exception trying to convert Yang-generated class returned by" + fromClass.getName() + "." + m.getName() + "() to Properties entry", e);
+				}
+			    }
+			}
+		    } else if (returnType.equals(Class.class)) {
+
+			LOG.trace(m.getName() + " returns a Class object - not interested");
+
+		    } else if (List.class.isAssignableFrom(returnType)) {
+
+			// This getter method returns a list.
 			try {
-				int listLength = Integer.parseInt(props.getProperty(pfx+"_length"));
-				
-				if (listLength > 0) {
-					maxIdx = listLength - 1;
-				}
+			    boolean isAccessible = m.isAccessible();
+			    if (!isAccessible) {
+				m.setAccessible(true);
+			    }
+			    Object retList = m.invoke(fromObj);
+			    if (!isAccessible) {
+				m.setAccessible(isAccessible);
+			    }
+			    // Figure out what type of elements are stored in
+			    // this array.
+			    Type paramType = m.getGenericReturnType();
+			    Type elementType = ((ParameterizedType) paramType).getActualTypeArguments()[0];
+			    toProperties(props, propNamePfx + "." + fieldName, retList, (Class) elementType);
 			} catch (Exception e) {
-				// Ignore exception
+			    LOG.error("Caught exception trying to convert List returned by " + fromClass.getName() + "." + m.getName() + "() to Properties entry", e);
 			}
-		}
-		
-		if (maxIdx == -1) {
-			// Figure out array size
-			for (Object pNameObj : props.keySet()) {
-				String key = (String) pNameObj;
 
-				if (key.startsWith(pfx + "[")) {
-					String idxStr = key.substring(pfx.length() + 1);
-					int endloc = idxStr.indexOf("]");
-					if (endloc != -1) {
-						idxStr = idxStr.substring(0, endloc);
-					}
+		    } else {
 
-					try {
-						int curIdx = Integer.parseInt(idxStr);
-						if (curIdx > maxIdx) {
-							maxIdx = curIdx;
-						}
-					} catch (Exception e) {
-						LOG.error("Illegal subscript in property " + key);
-					}
+			// Method returns something that is not a List and not
+			// yang-generated.
+			// Save its value
+			try {
+			    String propName = propNamePfx + "." + fieldName;
+			    boolean isAccessible = m.isAccessible();
+			    if (!isAccessible) {
+				m.setAccessible(true);
+			    }
+			    Object propValObj = m.invoke(fromObj);
+			    if (!isAccessible) {
+				m.setAccessible(isAccessible);
+			    }
 
+			    if (propValObj != null) {
+				if (propValObj instanceof byte[]) {
+				    LOG.trace(m.getName() + " returns a byte[]");
+				    propVal = new String((byte[]) propValObj, "UTF-8");
+				    LOG.trace("Converted byte array " + propNamePfx + "." + fieldName + "to string " + propVal);
+
+				} else {
+				    propVal = propValObj.toString();
 				}
+				LOG.debug("Setting property " + propName + " to " + propVal);
+				props.setProperty(propName, propVal);
+
+			    }
+			} catch (Exception e) {
+			    if (m.getName().equals("getKey")) {
+				LOG.trace("Caught " + e.getClass().getName() + " exception trying to convert results from getKey() - ignoring");
+			    } else {
+				LOG.error("Caught exception trying to convert value returned by" + fromClass.getName() + "." + m.getName() + "() to Properties entry", e);
+			    }
 			}
+		    }
+
 		}
-		
+	    }
 
-		LOG.trace(pfx + " has max index of " + maxIdx);
-		for (int i = 0; i <= maxIdx; i++) {
+	    // End of method loop. If there was only one getter, named
+	    // "getValue", then
+	    // set value identified by "prefix" to that one value.
+	    if ((numGetters == 1) && ("getValue".equals(lastGetterName))) {
+		LOG.trace("getValueFIX : " + propNamePfx + " only has getValue() getter - setting " + propNamePfx + " = " + propVal);
+		props.setProperty(propNamePfx, propVal);
+	    } else {
+		LOG.trace("getValueFIX : " + propNamePfx + " has " + numGetters + " getter(s), last one found was " + lastGetterName);
 
-			String curBase = pfx + "[" + i + "]";
+	    }
 
-			if (isYangGenerated(elemType)) {
-				String builderName = elemType.getName() + "Builder";
+	} else {
+	    // Class is not yang generated and not a list
+	    // It must be an element of a leaf list - set "prefix" to value
+	    String fromVal = null;
+	    if (fromObj instanceof byte[]) {
+		try {
+		    fromVal = new String((byte[]) fromObj, "UTF-8");
+		    LOG.trace("Converted byte array " + pfx + "to string " + fromVal);
+		} catch (Exception e) {
+		    LOG.warn("Caught exception trying to convert " + pfx + " from byte[] to String", e);
+		    fromVal = fromObj.toString();
+		}
+
+	    } else {
+		fromVal = fromObj.toString();
+	    }
+	    LOG.debug("Setting property " + pfx + " to " + fromVal);
+	    props.setProperty(pfx, fromVal);
+	}
+
+	return (props);
+    }
+
+    public static Object toBuilder(Properties props, Object toObj) {
+
+	return (toBuilder(props, "", toObj));
+    }
+
+    public static List toList(Properties props, String pfx, List toObj, Class elemType) {
+
+	int maxIdx = -1;
+	boolean foundValue = false;
+
+	LOG.trace("Saving properties to List<" + elemType.getName() + ">  from " + pfx);
+
+	if (props.contains(pfx + "_length")) {
+	    try {
+		int listLength = Integer.parseInt(props.getProperty(pfx + "_length"));
+
+		if (listLength > 0) {
+		    maxIdx = listLength - 1;
+		}
+	    } catch (Exception e) {
+		// Ignore exception
+	    }
+	}
+
+	if (maxIdx == -1) {
+	    // Figure out array size
+	    for (Object pNameObj : props.keySet()) {
+		String key = (String) pNameObj;
+
+		if (key.startsWith(pfx + "[")) {
+		    String idxStr = key.substring(pfx.length() + 1);
+		    int endloc = idxStr.indexOf("]");
+		    if (endloc != -1) {
+			idxStr = idxStr.substring(0, endloc);
+		    }
+
+		    try {
+			int curIdx = Integer.parseInt(idxStr);
+			if (curIdx > maxIdx) {
+			    maxIdx = curIdx;
+			}
+		    } catch (Exception e) {
+			LOG.error("Illegal subscript in property " + key);
+		    }
+
+		}
+	    }
+	}
+
+	LOG.trace(pfx + " has max index of " + maxIdx);
+	for (int i = 0; i <= maxIdx; i++) {
+
+	    String curBase = pfx + "[" + i + "]";
+
+	    if (isYangGenerated(elemType)) {
+		String builderName = elemType.getName() + "Builder";
+		try {
+		    Class builderClass = Class.forName(builderName);
+		    Object builderObj = builderClass.newInstance();
+		    Method buildMethod = builderClass.getMethod("build");
+		    builderObj = toBuilder(props, curBase, builderObj, true);
+		    if (builderObj != null) {
+			LOG.trace("Calling " + builderObj.getClass().getName() + "." + buildMethod.getName() + "()");
+			Object builtObj = buildMethod.invoke(builderObj);
+			toObj.add(builtObj);
+			foundValue = true;
+		    }
+
+		} catch (ClassNotFoundException e) {
+		    LOG.warn("Could not find builder class " + builderName, e);
+		} catch (Exception e) {
+		    LOG.error("Caught exception trying to populate list from " + pfx);
+		}
+	    } else {
+		// Must be a leaf list
+		String curValue = props.getProperty(curBase, "");
+
+		toObj.add(curValue);
+
+		if ((curValue != null) && (curValue.length() > 0)) {
+		    foundValue = true;
+		}
+	    }
+
+	}
+
+	if (foundValue) {
+	    return (toObj);
+	} else {
+	    return (null);
+	}
+
+    }
+
+    public static Object toBuilder(Properties props, String pfx, Object toObj) {
+	return (toBuilder(props, pfx, toObj, false));
+    }
+
+    public static Object toBuilder(Properties props, String pfx, Object toObj, boolean preservePfx) {
+	Class toClass = toObj.getClass();
+	boolean foundValue = false;
+
+	LOG.trace("Saving properties to " + toClass.getName() + " class from " + pfx);
+
+	Ipv4Address addr;
+
+	if (isYangGenerated(toClass)) {
+	    // Class is yang generated.
+	    LOG.trace(toClass.getName() + " is a Yang-generated class");
+
+	    String propNamePfx = null;
+	    if (preservePfx) {
+		propNamePfx = pfx;
+	    } else {
+
+		if ((pfx != null) && (pfx.length() > 0)) {
+		    propNamePfx = pfx + "." + toLowerHyphen(toClass.getSimpleName());
+		} else {
+		    propNamePfx = toLowerHyphen(toClass.getSimpleName());
+		}
+
+		if (propNamePfx.endsWith("-builder")) {
+		    propNamePfx = propNamePfx.substring(0, propNamePfx.length() - "-builder".length());
+		}
+
+		if (propNamePfx.endsWith("-impl")) {
+		    propNamePfx = propNamePfx.substring(0, propNamePfx.length() - "-impl".length());
+		}
+	    }
+
+	    if (toObj instanceof Identifier) {
+		LOG.trace(toClass.getName() + " is a Key - skipping");
+		return (toObj);
+	    }
+
+	    // Iterate through getter methods to figure out values we need to
+	    // set
+
+	    for (Method m : toClass.getMethods()) {
+		if (isSetter(m)) {
+		    Class paramTypes[] = m.getParameterTypes();
+		    Class paramClass = paramTypes[0];
+
+		    String fieldName = toLowerHyphen(m.getName().substring(3));
+		    fieldName = fieldName.substring(0, 1).toLowerCase() + fieldName.substring(1);
+
+		    String propName = propNamePfx + "." + fieldName;
+
+		    String paramValue = props.getProperty(propName);
+		    if (paramValue == null) {
+			LOG.trace(propName + " is unset");
+		    } else {
+			LOG.trace(propName + " = " + paramValue);
+		    }
+
+		    // Is the return type a yang generated class?
+		    if (isYangGenerated(paramClass)) {
+			// Is it an enum?
+			if (paramClass.isEnum()) {
+
+			    LOG.trace(m.getName() + " expects an Enum");
+			    // Param type is a typedef.
+			    if ((paramValue != null) && (paramValue.length() > 0)) {
+				Object paramObj = null;
+
 				try {
-					Class builderClass = Class.forName(builderName);
-					Object builderObj = builderClass.newInstance();
-					Method buildMethod = builderClass.getMethod("build");
-					builderObj = toBuilder(props, curBase, builderObj, true);
-					if (builderObj != null) {
-						LOG.trace("Calling " + builderObj.getClass().getName()
-								+ "." + buildMethod.getName() + "()");
-						Object builtObj = buildMethod.invoke(builderObj);
-						toObj.add(builtObj);
-						foundValue = true;
-					}
-
-				} catch (ClassNotFoundException e) {
-					LOG.warn("Could not find builder class " + builderName, e);
+				    paramObj = Enum.valueOf(paramClass, toJavaEnum(paramValue));
 				} catch (Exception e) {
-					LOG.error("Caught exception trying to populate list from "
-							+ pfx);
+				    LOG.error("Caught exception trying to convert field " + propName + " to enum " + paramClass.getName(), e);
 				}
+
+				try {
+				    boolean isAccessible = m.isAccessible();
+				    if (!isAccessible) {
+					m.setAccessible(true);
+				    }
+
+				    LOG.trace("Calling " + toObj.getClass().getName() + "." + m.getName() + "(" + paramValue + ")");
+				    m.invoke(toObj, paramObj);
+
+				    if (!isAccessible) {
+					m.setAccessible(isAccessible);
+				    }
+				    foundValue = true;
+
+				} catch (Exception e) {
+				    LOG.error("Caught exception trying to create Yang-generated enum expected by" + toClass.getName() + "." + m.getName() + "() from Properties entry", e);
+				}
+			    }
 			} else {
-				// Must be a leaf list
-				String curValue = props.getProperty(curBase, "");
-				
-				toObj.add(curValue);
-				
-				if ((curValue != null) && (curValue.length() > 0)) {
+
+			    String simpleName = paramClass.getSimpleName();
+
+			    if ("Ipv4Address".equals(simpleName) || "Ipv6Address".equals(simpleName) || "IpAddress".equals(simpleName)) {
+
+				if ((paramValue != null) && (paramValue.length() > 0)) {
+				    try {
+					IpAddress ipAddr = IpAddressBuilder.getDefaultInstance(paramValue);
+
+					if ("Ipv4Address".equals(simpleName)) {
+					    m.invoke(toObj, ipAddr.getIpv4Address());
+					} else if ("Ipv6Address".equals(simpleName)) {
+					    m.invoke(toObj, ipAddr.getIpv6Address());
+
+					} else {
+					    m.invoke(toObj, ipAddr);
+					}
 					foundValue = true;
+				    } catch (Exception e) {
+					LOG.error("Caught exception calling " + toClass.getName() + "." + m.getName() + "(" + paramValue + ")", e);
+
+				    }
+				} else {
+				    try {
+					boolean isAccessible = m.isAccessible();
+					if (!isAccessible) {
+					    m.setAccessible(true);
+					}
+					LOG.trace("Calling " + toObj.getClass().getName() + "." + m.getName() + "(" + paramValue + ")");
+					m.invoke(toObj, paramValue);
+					if (!isAccessible) {
+					    m.setAccessible(isAccessible);
+					}
+					foundValue = true;
+
+				    } catch (Exception e) {
+					LOG.error("Caught exception trying to call " + toClass.getName() + "." + m.getName() + "() with Properties entry", e);
+				    }
 				}
+			    } else if ("IpPrefix".equals(simpleName)) {
+				if ((paramValue != null) && (paramValue.length() > 0)) {
+				    try {
+					IpPrefix ipPrefix = IpPrefixBuilder.getDefaultInstance(paramValue);
+					m.invoke(toObj, ipPrefix);
+					foundValue = true;
+				    } catch (Exception e) {
+					LOG.error("Caught exception calling " + toClass.getName() + "." + m.getName() + "(" + paramValue + ")", e);
+				    }
+				}
+			    } else {
+				// setter expects a yang-generated class. Need
+				// to
+				// create a builder to set it.
+
+				String builderName = paramClass.getName() + "Builder";
+				Class builderClass = null;
+				Object builderObj = null;
+				Object paramObj = null;
+
+				Object constObj = null;
+
+				LOG.trace(m.getName() + " expects a yang-generated class - looking for builder " + builderName);
+				try {
+				    builderClass = Class.forName(builderName);
+				    builderObj = builderClass.newInstance();
+				    paramObj = toBuilder(props, propNamePfx, builderObj);
+				} catch (ClassNotFoundException e) {
+
+				    if (paramValue == null) {
+					try {
+					    boolean isAccessible = m.isAccessible();
+					    if (!isAccessible) {
+						m.setAccessible(true);
+					    }
+					    LOG.trace("Calling " + toObj.getClass().getName() + "." + m.getName() + "(null)");
+					    m.invoke(toObj, new Object[] { null });
+					    if (!isAccessible) {
+						m.setAccessible(isAccessible);
+					    }
+					    foundValue = true;
+
+					} catch (Exception e1) {
+					    LOG.error("Caught exception trying to cally" + toClass.getName() + "." + m.getName() + "() with Properties entry", e1);
+					}
+				    } else {
+					try {
+					    // See if I can find a constructor I
+					    // can
+					    // use
+					    Constructor[] constructors = paramClass.getConstructors();
+					    // Is there a String constructor?
+					    for (Constructor c : constructors) {
+						Class[] cParms = c.getParameterTypes();
+						if ((cParms != null) && (cParms.length == 1)) {
+						    if (String.class.isAssignableFrom(cParms[0])) {
+							constObj = c.newInstance(paramValue);
+						    }
+						}
+					    }
+
+					    if (constObj == null) {
+						// Is there a Long constructor?
+						for (Constructor c : constructors) {
+						    Class[] cParms = c.getParameterTypes();
+						    if ((cParms != null) && (cParms.length == 1)) {
+							if (Long.class.isAssignableFrom(cParms[0])) {
+							    constObj = c.newInstance(Long.parseLong(paramValue));
+							}
+						    }
+						}
+
+					    }
+
+					    if (constObj == null) {
+
+						// Last chance - see if
+						// parameter class has a static
+						// method
+						// getDefaultInstance(String)
+						try {
+						    Method gm = paramClass.getMethod("getDefaultInstance", String.class);
+
+						    int gmodifier = gm.getModifiers();
+						    if (Modifier.isStatic(gmodifier)) {
+							// Invoke static
+							// getDefaultInstance(String)
+							paramObj = gm.invoke(null, paramValue);
+						    }
+
+						} catch (Exception gme) {
+						    // Ignore exceptions
+						}
+					    }
+
+					} catch (Exception e1) {
+					    LOG.warn("Could not find a suitable constructor for " + paramClass.getName(), e1);
+					}
+
+					if (constObj == null) {
+					    LOG.warn("Could not find builder class " + builderName + " and could not find a String or Long constructor or static getDefaultInstance(String) - trying just to set passing paramValue");
+
+					}
+				    }
+				} catch (Exception e) {
+				    LOG.error("Caught exception trying to create builder " + builderName, e);
+				}
+
+				if (paramObj != null) {
+
+				    try {
+
+					Method buildMethod = builderClass.getMethod("build");
+					LOG.trace("Calling " + paramObj.getClass().getName() + "." + buildMethod.getName() + "()");
+					Object builtObj = buildMethod.invoke(paramObj);
+
+					boolean isAccessible = m.isAccessible();
+					if (!isAccessible) {
+					    m.setAccessible(true);
+					}
+
+					LOG.trace("Calling " + toObj.getClass().getName() + "." + m.getName() + "()");
+					m.invoke(toObj, builtObj);
+					if (!isAccessible) {
+					    m.setAccessible(isAccessible);
+					}
+					foundValue = true;
+
+				    } catch (Exception e) {
+					LOG.error("Caught exception trying to set Yang-generated class expected by" + toClass.getName() + "." + m.getName() + "() from Properties entry", e);
+				    }
+				} else {
+				    try {
+					boolean isAccessible = m.isAccessible();
+					if (!isAccessible) {
+					    m.setAccessible(true);
+					}
+
+					if (constObj != null) {
+
+					    LOG.trace("Calling " + toObj.getClass().getName() + "." + m.getName() + "(" + constObj.toString() + ")");
+					    m.invoke(toObj, constObj);
+					} else {
+					    LOG.trace("Calling " + toObj.getClass().getName() + "." + m.getName() + "(" + paramValue + ")");
+					    m.invoke(toObj, paramValue);
+
+					}
+					if (!isAccessible) {
+					    m.setAccessible(isAccessible);
+					}
+					foundValue = true;
+
+				    } catch (Exception e) {
+					LOG.error("Caught exception trying to convert value returned by" + toClass.getName() + "." + m.getName() + "() to Properties entry", e);
+				    }
+				}
+			    }
 			}
+		    } else {
 
-		}
+			// Setter's argument is not a yang-generated class. See
+			// if it is a List.
 
-		if (foundValue) {
-			return (toObj);
-		} else {
-			return (null);
-		}
+			if (List.class.isAssignableFrom(paramClass)) {
 
-	}
-	
-	public static Object toBuilder(Properties props, String pfx, Object toObj) {
-		return(toBuilder(props, pfx, toObj, false));
-	}
+			    LOG.trace("Parameter class " + paramClass.getName() + " is a List");
 
-	public static Object toBuilder(Properties props, String pfx, Object toObj, boolean preservePfx) {
-		Class toClass = toObj.getClass();
-		boolean foundValue = false;
+			    // Figure out what type of args are in List and pass
+			    // that to toList().
 
-		LOG.trace("Saving properties to " + toClass.getName() + " class from "
-				+ pfx);
+			    Type paramType = m.getGenericParameterTypes()[0];
+			    Type elementType = ((ParameterizedType) paramType).getActualTypeArguments()[0];
+			    Object paramObj = new LinkedList();
+			    try {
+				paramObj = toList(props, propName, (List) paramObj, (Class) elementType);
+			    } catch (Exception e) {
+				LOG.error("Caught exception trying to create list expected as argument to " + toClass.getName() + "." + m.getName());
+			    }
 
-		Ipv4Address addr;
+			    if (paramObj != null) {
+				try {
+				    boolean isAccessible = m.isAccessible();
+				    if (!isAccessible) {
+					m.setAccessible(true);
+				    }
+				    LOG.trace("Calling " + toObj.getClass().getName() + "." + m.getName() + "(" + paramValue + ")");
+				    m.invoke(toObj, paramObj);
+				    if (!isAccessible) {
+					m.setAccessible(isAccessible);
+				    }
+				    foundValue = true;
 
-		if (isYangGenerated(toClass)) {
-			// Class is yang generated.
-			LOG.trace(toClass.getName() + " is a Yang-generated class");
-
-			String propNamePfx = null;
-			if (preservePfx) {
-				propNamePfx = pfx;
+				} catch (Exception e) {
+				    LOG.error("Caught exception trying to convert List returned by" + toClass.getName() + "." + m.getName() + "() to Properties entry", e);
+				}
+			    }
 			} else {
 
-				if ((pfx != null) && (pfx.length() > 0)) {
-					propNamePfx = pfx + "."
-							+ toLowerHyphen(toClass.getSimpleName());
-				} else {
-					propNamePfx = toLowerHyphen(toClass.getSimpleName());
-				}
+			    // Setter expects something that is not a List and
+			    // not yang-generated. Just pass the parameter value
 
-				if (propNamePfx.endsWith("-builder")) {
-					propNamePfx = propNamePfx.substring(0, propNamePfx.length()
-							- "-builder".length());
-				}
+			    LOG.trace("Parameter class " + paramClass.getName() + " is not a yang-generated class or a List");
 
-				if (propNamePfx.endsWith("-impl")) {
-					propNamePfx = propNamePfx.substring(0, propNamePfx.length()
-							- "-impl".length());
-				}
-			}
+			    if ((paramValue != null) && (paramValue.length() > 0)) {
 
-			if (toObj instanceof Identifier) {
-				LOG.trace(toClass.getName() + " is a Key - skipping");
-				return (toObj);
-			}
+				Object constObj = null;
 
-			// Iterate through getter methods to figure out values we need to
-			// set
+				try {
+				    // See if I can find a constructor I can use
+				    Constructor[] constructors = paramClass.getConstructors();
+				    // Is there a String constructor?
+				    for (Constructor c : constructors) {
+					Class[] cParms = c.getParameterTypes();
+					if ((cParms != null) && (cParms.length == 1)) {
+					    if (String.class.isAssignableFrom(cParms[0])) {
+						constObj = c.newInstance(paramValue);
+					    }
+					}
+				    }
 
-			for (Method m : toClass.getMethods()) {
-				if (isSetter(m)) {
-					Class paramTypes[] = m.getParameterTypes();
-					Class paramClass = paramTypes[0];
-
-					String fieldName = toLowerHyphen(m.getName().substring(3));
-					fieldName = fieldName.substring(0, 1).toLowerCase()
-							+ fieldName.substring(1);
-
-					String propName = propNamePfx + "." + fieldName;
-
-					String paramValue = props.getProperty(propName);
-					if (paramValue == null) {
-						LOG.trace(propName + " is unset");
-					} else {
-						LOG.trace(propName + " = " + paramValue);
+				    if (constObj == null) {
+					// Is there a Long constructor?
+					for (Constructor c : constructors) {
+					    Class[] cParms = c.getParameterTypes();
+					    if ((cParms != null) && (cParms.length == 1)) {
+						if (Long.class.isAssignableFrom(cParms[0])) {
+						    constObj = c.newInstance(Long.parseLong(paramValue));
+						}
+					    }
 					}
 
-					// Is the return type a yang generated class?
-					if (isYangGenerated(paramClass)) {
-						// Is it an enum?
-						if (paramClass.isEnum()) {
+				    }
 
-							LOG.trace(m.getName() + " expects an Enum");
-							// Param type is a typedef.
-							if ((paramValue != null)  && (paramValue.length() > 0)) {
-								Object paramObj = null;
-
-								try {
-									paramObj = Enum.valueOf(paramClass,
-											toUpperCamelCase(paramValue));
-								} catch (Exception e) {
-									LOG.error(
-											"Caught exception trying to convert field "
-													+ propName + " to enum "
-													+ paramClass.getName(), e);
-								}
-
-								try {
-									boolean isAccessible = m.isAccessible();
-									if (!isAccessible) {
-										m.setAccessible(true);
-									}
-
-									LOG.trace("Calling "
-											+ toObj.getClass().getName() + "."
-											+ m.getName() + "(" + paramValue
-											+ ")");
-									m.invoke(toObj, paramObj);
-
-									if (!isAccessible) {
-										m.setAccessible(isAccessible);
-									}
-									foundValue = true;
-
-								} catch (Exception e) {
-									LOG.error(
-											"Caught exception trying to create Yang-generated enum expected by"
-													+ toClass.getName()
-													+ "."
-													+ m.getName()
-													+ "() from Properties entry",
-											e);
-								}
-							}
-						} else {
-
-							String simpleName = paramClass.getSimpleName();
-
-							if ("Ipv4Address".equals(simpleName)
-									|| "Ipv6Address".equals(simpleName) || "IpAddress".equals(simpleName)) {
-								
-								if ((paramValue != null) && (paramValue.length() > 0)) {
-									try {
-										IpAddress ipAddr = IpAddressBuilder
-												.getDefaultInstance(paramValue);
-
-
-										if ("Ipv4Address".equals(simpleName))
-										{
-											m.invoke(toObj, ipAddr.getIpv4Address());
-										}
-										else if ("Ipv6Address".equals(simpleName))
-										{
-											m.invoke(toObj, ipAddr.getIpv6Address());
-
-										}
-										else
-										{
-											m.invoke(toObj, ipAddr);
-										}
-										foundValue = true;
-									} catch (Exception e) {
-										LOG.error(
-												"Caught exception calling "
-														+ toClass.getName() + "."
-														+ m.getName() + "("
-														+ paramValue + ")", e);
-
-									}
-								} else {
-									try {
-										boolean isAccessible = m.isAccessible();
-										if (!isAccessible) {
-											m.setAccessible(true);
-										}
-										LOG.trace("Calling "
-												+ toObj.getClass().getName()
-												+ "." + m.getName() + "("
-												+ paramValue + ")");
-										m.invoke(toObj, paramValue);
-										if (!isAccessible) {
-											m.setAccessible(isAccessible);
-										}
-										foundValue = true;
-
-									} catch (Exception e) {
-										LOG.error(
-												"Caught exception trying to call "
-														+ toClass.getName()
-														+ "."
-														+ m.getName()
-														+ "() with Properties entry",
-												e);
-									}
-								}
-							} else if ("IpPrefix".equals(simpleName)) {
-									if ((paramValue != null) && (paramValue.length() > 0)) {
-										try {
-											IpPrefix ipPrefix = IpPrefixBuilder.getDefaultInstance(paramValue);
-											m.invoke(toObj, ipPrefix);
-											foundValue = true;
-										} catch (Exception e) {
-											LOG.error(
-													"Caught exception calling "
-															+ toClass.getName() + "."
-															+ m.getName() + "("
-															+ paramValue + ")", e);
-										}
-									}
-							} else {
-								// setter expects a yang-generated class. Need
-								// to
-								// create a builder to set it.
-
-								String builderName = paramClass.getName()
-										+ "Builder";
-								Class builderClass = null;
-								Object builderObj = null;
-								Object paramObj = null;
-
-								Object constObj = null;
-								
-								LOG.trace(m.getName()
-										+ " expects a yang-generated class - looking for builder "
-										+ builderName);
-								try {
-									builderClass = Class.forName(builderName);
-									builderObj = builderClass.newInstance();
-									paramObj = toBuilder(props, propNamePfx,
-											builderObj);
-								} catch (ClassNotFoundException e) {
-									
-									if (paramValue == null) {
-										try {
-											boolean isAccessible = m
-													.isAccessible();
-											if (!isAccessible) {
-												m.setAccessible(true);
-											}
-											LOG.trace("Calling "
-													+ toObj.getClass()
-															.getName() + "."
-													+ m.getName() + "(null)");
-											m.invoke(toObj, new Object[]{null});
-											if (!isAccessible) {
-												m.setAccessible(isAccessible);
-											}
-											foundValue = true;
-
-										} catch (Exception e1) {
-											LOG.error(
-													"Caught exception trying to cally"
-															+ toClass.getName()
-															+ "."
-															+ m.getName()
-															+ "() with Properties entry",
-													e1);
-										}
-									} else {
-										try {
-											// See if I can find a constructor I
-											// can
-											// use
-											Constructor[] constructors = paramClass
-													.getConstructors();
-											// Is there a String constructor?
-											for (Constructor c : constructors) {
-												Class[] cParms = c
-														.getParameterTypes();
-												if ((cParms != null)
-														&& (cParms.length == 1)) {
-													if (String.class
-															.isAssignableFrom(cParms[0])) {
-														constObj = c
-																.newInstance(paramValue);
-													}
-												}
-											}
-
-											if (constObj == null) {
-												// Is there a Long constructor?
-												for (Constructor c : constructors) {
-													Class[] cParms = c
-															.getParameterTypes();
-													if ((cParms != null)
-															&& (cParms.length == 1)) {
-														if (Long.class
-																.isAssignableFrom(cParms[0])) {
-															constObj = c
-																	.newInstance(Long
-																			.parseLong(paramValue));
-														}
-													}
-												}
-
-											}
-
-											if (constObj == null) {
-
-												// Last chance - see if
-												// parameter class has a static
-												// method
-												// getDefaultInstance(String)
-												try {
-													Method gm = paramClass
-															.getMethod(
-																	"getDefaultInstance",
-																	String.class);
-
-													int gmodifier = gm
-															.getModifiers();
-													if (Modifier
-															.isStatic(gmodifier)) {
-														// Invoke static
-														// getDefaultInstance(String)
-														paramObj = gm.invoke(
-																null,
-																paramValue);
-													}
-
-												} catch (Exception gme) {
-													// Ignore exceptions
-												}
-											}
-											
-											
-										} catch (Exception e1) {
-											LOG.warn(
-													"Could not find a suitable constructor for "
-															+ paramClass
-																	.getName(),
-													e1);
-										}
-
-										if (constObj == null) {
-											LOG.warn("Could not find builder class "
-													+ builderName
-													+ " and could not find a String or Long constructor or static getDefaultInstance(String) - trying just to set passing paramValue");
-
-										}
-									}
-								} catch (Exception e) {
-									LOG.error(
-											"Caught exception trying to create builder "
-													+ builderName, e);
-								}
-
-								if (paramObj != null) {
-
-									try {
-
-										Method buildMethod = builderClass
-												.getMethod("build");
-										LOG.trace("Calling "
-												+ paramObj.getClass().getName()
-												+ "." + buildMethod.getName()
-												+ "()");
-										Object builtObj = buildMethod
-												.invoke(paramObj);
-
-										boolean isAccessible = m.isAccessible();
-										if (!isAccessible) {
-											m.setAccessible(true);
-										}
-
-										LOG.trace("Calling "
-												+ toObj.getClass().getName()
-												+ "." + m.getName() + "()");
-										m.invoke(toObj, builtObj);
-										if (!isAccessible) {
-											m.setAccessible(isAccessible);
-										}
-										foundValue = true;
-
-									} catch (Exception e) {
-										LOG.error(
-												"Caught exception trying to set Yang-generated class expected by"
-														+ toClass.getName()
-														+ "."
-														+ m.getName()
-														+ "() from Properties entry",
-												e);
-									}
-								} else {
-									try {
-										boolean isAccessible = m.isAccessible();
-										if (!isAccessible) {
-											m.setAccessible(true);
-										}
-										
-										if (constObj != null) {
-
-											LOG.trace("Calling "
-													+ toObj.getClass()
-															.getName() + "."
-													+ m.getName() + "("
-													+ constObj.toString() + ")");
-											m.invoke(toObj, constObj);
-										} else {
-											LOG.trace("Calling "
-													+ toObj.getClass()
-															.getName() + "."
-													+ m.getName() + "("
-													+ paramValue + ")");
-											m.invoke(toObj, paramValue);
-
-										}
-										if (!isAccessible) {
-											m.setAccessible(isAccessible);
-										}
-										foundValue = true;
-
-									} catch (Exception e) {
-										LOG.error(
-												"Caught exception trying to convert value returned by"
-														+ toClass.getName()
-														+ "."
-														+ m.getName()
-														+ "() to Properties entry",
-												e);
-									}
-								}
-							}
-						}
-					} else {
-
-						// Setter's argument is not a yang-generated class. See
-						// if it is a List.
-
-						if (List.class.isAssignableFrom(paramClass)) {
-
-							LOG.trace("Parameter class " + paramClass.getName()
-									+ " is a List");
-
-							// Figure out what type of args are in List and pass
-							// that to toList().
-
-							Type paramType = m.getGenericParameterTypes()[0];
-							Type elementType = ((ParameterizedType) paramType)
-									.getActualTypeArguments()[0];
-							Object paramObj = new LinkedList();
-							try {
-								paramObj = toList(props, propName,
-										(List) paramObj, (Class) elementType);
-							} catch (Exception e) {
-								LOG.error("Caught exception trying to create list expected as argument to "
-										+ toClass.getName() + "." + m.getName());
-							}
-
-							if (paramObj != null) {
-								try {
-									boolean isAccessible = m.isAccessible();
-									if (!isAccessible) {
-										m.setAccessible(true);
-									}
-									LOG.trace("Calling "
-											+ toObj.getClass().getName() + "."
-											+ m.getName() + "(" + paramValue
-											+ ")");
-									m.invoke(toObj, paramObj);
-									if (!isAccessible) {
-										m.setAccessible(isAccessible);
-									}
-									foundValue = true;
-
-								} catch (Exception e) {
-									LOG.error(
-											"Caught exception trying to convert List returned by"
-													+ toClass.getName() + "."
-													+ m.getName()
-													+ "() to Properties entry",
-											e);
-								}
-							}
-						} else {
-
-							// Setter expects something that is not a List and
-							// not yang-generated. Just pass the parameter value
-
-							LOG.trace("Parameter class "
-									+ paramClass.getName()
-									+ " is not a yang-generated class or a List");
-
-							if ((paramValue != null) && (paramValue.length() > 0)) {
-
-								Object constObj = null;
-
-								try {
-									// See if I can find a constructor I can use
-									Constructor[] constructors = paramClass
-											.getConstructors();
-									// Is there a String constructor?
-									for (Constructor c : constructors) {
-										Class[] cParms = c.getParameterTypes();
-										if ((cParms != null)
-												&& (cParms.length == 1)) {
-											if (String.class
-													.isAssignableFrom(cParms[0])) {
-												constObj = c
-														.newInstance(paramValue);
-											}
-										}
-									}
-
-									if (constObj == null) {
-										// Is there a Long constructor?
-										for (Constructor c : constructors) {
-											Class[] cParms = c
-													.getParameterTypes();
-											if ((cParms != null)
-													&& (cParms.length == 1)) {
-												if (Long.class
-														.isAssignableFrom(cParms[0])) {
-													constObj = c
-															.newInstance(Long
-																	.parseLong(paramValue));
-												}
-											}
-										}
-
-									}
-
-									if (constObj != null) {
-										try {
-											LOG.trace("Calling "
-													+ toObj.getClass()
-															.getName() + "."
-													+ m.getName() + "("
-													+ constObj + ")");
-											m.invoke(toObj, constObj);
-											foundValue = true;
-										} catch (Exception e2) {
-											LOG.error(
-													"Caught exception trying to call "
-															+ m.getName(), e2);
-										}
-									} else {
-										try {
-											boolean isAccessible = m
-													.isAccessible();
-											if (!isAccessible) {
-												m.setAccessible(true);
-											}
-											LOG.trace("Calling "
-													+ toObj.getClass()
-															.getName() + "."
-													+ m.getName() + "("
-													+ paramValue + ")");
-											m.invoke(toObj, paramValue);
-											if (!isAccessible) {
-												m.setAccessible(isAccessible);
-											}
-											foundValue = true;
-
-										} catch (Exception e) {
-											LOG.error(
-													"Caught exception trying to convert value returned by"
-															+ toClass.getName()
-															+ "."
-															+ m.getName()
-															+ "() to Properties entry",
-													e);
-										}
-									}
-								} catch (Exception e1) {
-									LOG.warn(
-											"Could not find a suitable constructor for "
-													+ paramClass.getName(), e1);
-								}
-
-
-							}
-						}
+				    if (constObj != null) {
+					try {
+					    LOG.trace("Calling " + toObj.getClass().getName() + "." + m.getName() + "(" + constObj + ")");
+					    m.invoke(toObj, constObj);
+					    foundValue = true;
+					} catch (Exception e2) {
+					    LOG.error("Caught exception trying to call " + m.getName(), e2);
 					}
-				} // End of section handling "setter" method
-			} // End of loop through Methods
-		} // End of section handling yang-generated class
+				    } else {
+					try {
+					    boolean isAccessible = m.isAccessible();
+					    if (!isAccessible) {
+						m.setAccessible(true);
+					    }
+					    LOG.trace("Calling " + toObj.getClass().getName() + "." + m.getName() + "(" + paramValue + ")");
+					    m.invoke(toObj, paramValue);
+					    if (!isAccessible) {
+						m.setAccessible(isAccessible);
+					    }
+					    foundValue = true;
 
-		if (foundValue) {
-			return (toObj);
-		} else {
-			return (null);
-		}
+					} catch (Exception e) {
+					    LOG.error("Caught exception trying to convert value returned by" + toClass.getName() + "." + m.getName() + "() to Properties entry", e);
+					}
+				    }
+				} catch (Exception e1) {
+				    LOG.warn("Could not find a suitable constructor for " + paramClass.getName(), e1);
+				}
+
+			    }
+			}
+		    }
+		} // End of section handling "setter" method
+	    } // End of loop through Methods
+	} // End of section handling yang-generated class
+
+	if (foundValue) {
+	    return (toObj);
+	} else {
+	    return (null);
 	}
+    }
 
-	public static void printPropertyList(PrintStream pstr, String pfx,
-			Class toClass) {
-		boolean foundValue = false;
+    public static void printPropertyList(PrintStream pstr, String pfx, Class toClass) {
+	boolean foundValue = false;
 
-		LOG.trace("Analyzing " + toClass.getName() + " class : pfx " + pfx);
+	LOG.trace("Analyzing " + toClass.getName() + " class : pfx " + pfx);
 
-		if (isYangGenerated(toClass)
-				&& (!Identifier.class.isAssignableFrom(toClass))) {
-			// Class is yang generated.
-			LOG.trace(toClass.getName() + " is a Yang-generated class");
+	if (isYangGenerated(toClass) && (!Identifier.class.isAssignableFrom(toClass))) {
+	    // Class is yang generated.
+	    LOG.trace(toClass.getName() + " is a Yang-generated class");
 
-			if (toClass.getName().endsWith("Key")) {
-				if (Identifier.class.isAssignableFrom(toClass)) {
-					LOG.trace(Identifier.class.getName()
-							+ " is assignable from " + toClass.getName());
-				} else {
+	    if (toClass.getName().endsWith("Key")) {
+		if (Identifier.class.isAssignableFrom(toClass)) {
+		    LOG.trace(Identifier.class.getName() + " is assignable from " + toClass.getName());
+		} else {
 
-					LOG.trace(Identifier.class.getName()
-							+ " is NOT assignable from " + toClass.getName());
-				}
-			}
+		    LOG.trace(Identifier.class.getName() + " is NOT assignable from " + toClass.getName());
+		}
+	    }
 
-			String propNamePfx = null;
-			if (pfx.endsWith("]")) {
-				propNamePfx = pfx;
+	    String propNamePfx = null;
+	    if (pfx.endsWith("]")) {
+		propNamePfx = pfx;
+	    } else {
+
+		if ((pfx != null) && (pfx.length() > 0)) {
+		    propNamePfx = pfx + "." + toLowerHyphen(toClass.getSimpleName());
+		} else {
+		    propNamePfx = toLowerHyphen(toClass.getSimpleName());
+		}
+
+		if (propNamePfx.endsWith("-builder")) {
+		    propNamePfx = propNamePfx.substring(0, propNamePfx.length() - "-builder".length());
+		}
+
+		if (propNamePfx.endsWith("-impl")) {
+		    propNamePfx = propNamePfx.substring(0, propNamePfx.length() - "-impl".length());
+		}
+	    }
+
+	    // Iterate through getter methods to figure out values we need to
+	    // set
+
+	    for (Method m : toClass.getMethods()) {
+		LOG.trace("Is " + m.getName() + " method a getter?");
+		if (isGetter(m)) {
+		    LOG.trace(m.getName() + " is a getter");
+		    Class returnClass = m.getReturnType();
+
+		    String fieldName = toLowerHyphen(m.getName().substring(3));
+		    fieldName = fieldName.substring(0, 1).toLowerCase() + fieldName.substring(1);
+
+		    String propName = propNamePfx + "." + fieldName;
+
+		    // Is the return type a yang generated class?
+		    if (isYangGenerated(returnClass)) {
+			// Is it an enum?
+			if (returnClass.isEnum()) {
+
+			    LOG.trace(m.getName() + " is an Enum");
+			    pstr.print("\n\n     * " + propName);
+
 			} else {
 
-				if ((pfx != null) && (pfx.length() > 0)) {
-					propNamePfx = pfx + "."
-							+ toLowerHyphen(toClass.getSimpleName());
-				} else {
-					propNamePfx = toLowerHyphen(toClass.getSimpleName());
-				}
+			    String simpleName = returnClass.getSimpleName();
 
-				if (propNamePfx.endsWith("-builder")) {
-					propNamePfx = propNamePfx.substring(0, propNamePfx.length()
-							- "-builder".length());
-				}
+			    if ("Ipv4Address".equals(simpleName) || "Ipv6Address".equals(simpleName) || "IpAddress".equals(simpleName) || "IpPrefix".equals(simpleName)) {
+				LOG.trace(m.getName() + " is an " + simpleName);
+				pstr.print("\n\n     * " + propName);
+			    } else {
+				printPropertyList(pstr, propNamePfx, returnClass);
+			    }
 
-				if (propNamePfx.endsWith("-impl")) {
-					propNamePfx = propNamePfx.substring(0, propNamePfx.length()
-							- "-impl".length());
-				}
 			}
+		    } else {
 
-			// Iterate through getter methods to figure out values we need to
-			// set
+			// Setter's argument is not a yang-generated class. See
+			// if it is a List.
 
-			for (Method m : toClass.getMethods()) {
-				LOG.trace("Is " + m.getName() + " method a getter?");
-				if (isGetter(m)) {
-					LOG.trace(m.getName() + " is a getter");
-					Class returnClass = m.getReturnType();
+			if (List.class.isAssignableFrom(returnClass)) {
 
-					String fieldName = toLowerHyphen(m.getName().substring(3));
-					fieldName = fieldName.substring(0, 1).toLowerCase()
-							+ fieldName.substring(1);
+			    LOG.trace("Parameter class " + returnClass.getName() + " is a List");
 
-					String propName = propNamePfx + "." + fieldName;
+			    // Figure out what type of args are in List and pass
+			    // that to toList().
 
-					// Is the return type a yang generated class?
-					if (isYangGenerated(returnClass)) {
-						// Is it an enum?
-						if (returnClass.isEnum()) {
+			    Type returnType = m.getGenericReturnType();
+			    Type elementType = ((ParameterizedType) returnType).getActualTypeArguments()[0];
+			    Class elementClass = (Class) elementType;
+			    LOG.trace("Calling printPropertyList on list type (" + elementClass.getName() + "), pfx is (" + pfx + "), toClass is (" + toClass.getName() + ")");
+			    printPropertyList(pstr, propNamePfx + "." + toLowerHyphen(elementClass.getSimpleName()) + "[]", elementClass);
 
-							LOG.trace(m.getName() + " is an Enum");
-							pstr.print("\n\n     * " + propName);
+			} else if (!returnClass.equals(Class.class)) {
 
-						} else {
-							
-							String simpleName = returnClass.getSimpleName();
-							
-							if ("Ipv4Address".equals(simpleName) || "Ipv6Address".equals(simpleName) || "IpAddress".equals(simpleName) || "IpPrefix".equals(simpleName)) {
-								LOG.trace(m.getName()+" is an "+simpleName);
-								pstr.print("\n\n     * " + propName);
-							} else {
-								printPropertyList(pstr, propNamePfx, returnClass);
-							}
+			    // Setter expects something that is not a List and
+			    // not yang-generated. Just pass the parameter value
 
-						}
-					} else {
+			    LOG.trace("Parameter class " + returnClass.getName() + " is not a yang-generated class or a List");
 
-						// Setter's argument is not a yang-generated class. See
-						// if it is a List.
+			    pstr.print("\n\n     * " + propName);
 
-						if (List.class.isAssignableFrom(returnClass)) {
+			}
+		    }
+		} // End of section handling "setter" method
+	    } // End of loop through Methods
+	} // End of section handling yang-generated class
 
-							LOG.trace("Parameter class "
-									+ returnClass.getName() + " is a List");
+    }
 
-							// Figure out what type of args are in List and pass
-							// that to toList().
+    public static boolean isYangGenerated(Class c) {
+	if (c == null) {
+	    return (false);
+	} else {
+	    return (c.getName().startsWith("org.opendaylight.yang.gen."));
+	}
+    }
 
-							Type returnType = m.getGenericReturnType();
-							Type elementType = ((ParameterizedType) returnType)
-									.getActualTypeArguments()[0];
-							Class elementClass = (Class) elementType;
-							LOG.trace("Calling printPropertyList on list type ("
-									+ elementClass.getName()
-									+ "), pfx is ("
-									+ pfx
-									+ "), toClass is ("
-									+ toClass.getName() + ")");
-							printPropertyList(
-									pstr,
-									propNamePfx
-											+ "."
-											+ toLowerHyphen(elementClass
-													.getSimpleName()) + "[]",
-									elementClass);
+    public static boolean isIpPrefix(Class c) {
 
-						} else if (!returnClass.equals(Class.class)) {
+	if (c == null) {
+	    return (false);
+	}
+	String simpleName = c.getSimpleName();
+	return ("IpPrefix".equals(simpleName));
+    }
 
-							// Setter expects something that is not a List and
-							// not yang-generated. Just pass the parameter value
+    public static boolean isIpv4Address(Class c) {
 
-							LOG.trace("Parameter class "
-									+ returnClass.getName()
-									+ " is not a yang-generated class or a List");
+	if (c == null) {
+	    return (false);
+	}
+	String simpleName = c.getSimpleName();
+	return ("Ipv4Address".equals(simpleName));
+    }
 
-							pstr.print("\n\n     * " + propName);
+    public static boolean isIpv6Address(Class c) {
 
-						}
-					}
-				} // End of section handling "setter" method
-			} // End of loop through Methods
-		} // End of section handling yang-generated class
+	if (c == null) {
+	    return (false);
+	}
+	String simpleName = c.getSimpleName();
+	return ("Ipv6Address".equals(simpleName));
+    }
 
+    public static boolean isIpAddress(Class c) {
+
+	if (c == null) {
+	    return (false);
+	}
+	String simpleName = c.getSimpleName();
+	return ("IpAddress".equals(simpleName));
+    }
+
+    public static String toLowerHyphen(String inStr) {
+	if (inStr == null) {
+	    return (null);
 	}
 
-	public static boolean isYangGenerated(Class c) {
-		if (c == null) {
-			return (false);
+	String str = inStr.substring(0, 1).toLowerCase();
+	if (inStr.length() > 1) {
+	    str = str + inStr.substring(1);
+	}
+
+	String regex = "(([a-z0-9])([A-Z]))";
+	String replacement = "$2-$3";
+
+	String retval = str.replaceAll(regex, replacement).toLowerCase();
+
+	LOG.trace("Converting " + inStr + " => " + str + " => " + retval);
+	return (retval);
+    }
+
+    //This is called when mapping the yang value back to a valid java enumeration
+    public static String toJavaEnum(String inStr) {
+	if (inStr == null) {
+	    return (null);
+	} else if (inStr.length() == 0) {
+	    return (inStr);
+	}
+
+	//This will strip out all periods, which cannot be in a java enum
+    inStr = inStr.replaceAll("\\.", "");
+
+	String[] terms = inStr.split("-");
+	StringBuffer sbuff = new StringBuffer();
+
+	//appends an _ if the string starts with a digit to make it a valid java enum
+	if (Character.isDigit(inStr.charAt(0))) {
+	    sbuff.append('_');
+	}
+	//If the string contains hyphens it will convert the string to upperCamelCase without hyphens
+	for (String term : terms) {
+	    sbuff.append(term.substring(0, 1).toUpperCase());
+	    if (term.length() > 1) {
+		sbuff.append(term.substring(1));
+	    }
+	}
+	return (sbuff.toString());
+
+    }
+
+    public static boolean isGetter(Method m) {
+	if (m == null) {
+	    return (false);
+	}
+
+	if (Modifier.isPublic(m.getModifiers()) && (m.getParameterTypes().length == 0)) {
+	    if (m.getName().matches("^get[A-Z].*") && !m.getReturnType().equals(void.class)) {
+		if (!"getClass".equals(m.getName())) {
+		    return (true);
+		}
+	    }
+
+	    if (m.getName().matches("^get[A-Z].*") && m.getReturnType().equals(boolean.class)) {
+		return (true);
+	    }
+
+	    if (m.getName().matches("^is[A-Z].*") && m.getReturnType().equals(Boolean.class)) {
+		return (true);
+	    }
+	}
+
+	return (false);
+    }
+
+    public static boolean isSetter(Method m) {
+	if (m == null) {
+	    return (false);
+	}
+
+	if (Modifier.isPublic(m.getModifiers()) && (m.getParameterTypes().length == 1)) {
+	    if (m.getName().matches("^set[A-Z].*")) {
+		Class[] paramTypes = m.getParameterTypes();
+		if (paramTypes[0].isAssignableFrom(Identifier.class) || Identifier.class.isAssignableFrom(paramTypes[0])) {
+		    return (false);
 		} else {
-			return (c.getName().startsWith("org.opendaylight.yang.gen."));
+		    return (true);
 		}
-	}
-	
-	public static boolean isIpPrefix(Class c) {
-		
-		if (c == null ) {
-			return (false);
-		}
-		String simpleName = c.getSimpleName();
-		return ("IpPrefix".equals(simpleName)) ;
-	}
-	
-	
-	
-	public static boolean isIpv4Address(Class c) {
-		
-		if (c == null ) {
-			return (false);
-		}
-		String simpleName = c.getSimpleName();
-		return ("Ipv4Address".equals(simpleName)) ;
-	}
-	
-	public static boolean isIpv6Address(Class c) {
-		
-		if (c == null ) {
-			return (false);
-		} 
-		String simpleName = c.getSimpleName();
-		return ("Ipv6Address".equals(simpleName)) ;
-	}
-	
-	public static boolean isIpAddress(Class c) {
-		
-		if (c == null ) {
-			return (false);
-		} 
-		String simpleName = c.getSimpleName();
-		return ("IpAddress".equals(simpleName)) ;
-	}
-
-	public static String toLowerHyphen(String inStr) {
-		if (inStr == null) {
-			return (null);
-		}
-
-		String str = inStr.substring(0, 1).toLowerCase();
-		if (inStr.length() > 1) {
-			str = str + inStr.substring(1);
-		}
-
-		String regex = "(([a-z0-9])([A-Z]))";
-		String replacement = "$2-$3";
-
-		String retval = str.replaceAll(regex, replacement).toLowerCase();
-
-		LOG.trace("Converting " + inStr + " => " + str + " => " + retval);
-		return (retval);
-	}
-
-	public static String toUpperCamelCase(String inStr) {
-		if (inStr == null) {
-			return (null);
-		} else if (inStr.length() == 0) {
-			return(inStr);
-		}
-
-		String[] terms = inStr.split("-");
-		StringBuffer sbuff = new StringBuffer();
-		// Check if string begins with a digit
-		if (Character.isDigit(inStr.charAt(0))) {
-			sbuff.append('_');
-		}
-		for (String term : terms) {
-			sbuff.append(term.substring(0, 1).toUpperCase());
-			if (term.length() > 1) {
-				sbuff.append(term.substring(1));
-			}
-		}
-		return (sbuff.toString());
+	    }
 
 	}
 
-	public static boolean isGetter(Method m) {
-		if (m == null) {
-			return (false);
-		}
+	return (false);
+    }
 
-		if (Modifier.isPublic(m.getModifiers())
-				&& (m.getParameterTypes().length == 0)) {
-			if (m.getName().matches("^get[A-Z].*")
-					&& !m.getReturnType().equals(void.class)) {
-				if (!"getClass".equals(m.getName())) {
-					return (true);
-				}
-			}
-
-			if (m.getName().matches("^get[A-Z].*")
-					&& m.getReturnType().equals(boolean.class)) {
-				return (true);
-			}
-			
-			if (m.getName().matches("^is[A-Z].*")
-					&& m.getReturnType().equals(Boolean.class)) {
-				return(true);
-			}
-		}
-
-		return (false);
-	}
-
-	public static boolean isSetter(Method m) {
-		if (m == null) {
-			return (false);
-		}
-
-		if (Modifier.isPublic(m.getModifiers())
-				&& (m.getParameterTypes().length == 1)) {
-			if (m.getName().matches("^set[A-Z].*")) {
-				Class[] paramTypes = m.getParameterTypes();
-				if (paramTypes[0].isAssignableFrom(Identifier.class)
-						|| Identifier.class.isAssignableFrom(paramTypes[0])) {
-					return (false);
-				} else {
-					return (true);
-				}
-			}
-
-		}
-
-		return (false);
-	}
+    public static String getFullPropertiesPath(String propertiesFileName) {
+	return "/opt/bvc/controller/configuration/" + propertiesFileName;
+    }
+    
+    //This is called when mapping a valid java enumeration back to the yang model value
+    public static String mapEnumeratedValue(String propertyName, String propertyValue) {
+        LOG.info("mapEnumeratedValue called with propertyName=" + propertyName + " and value=" + propertyValue);
+        String mappingKey = "yang." + propertyName + "." + propertyValue;
+        if (yangMappingProperties.containsKey(mappingKey)) {
+            return (yangMappingProperties.getProperty(mappingKey));
+        } else {
+            LOG.info("yangMappingProperties did not contain the key " + mappingKey + " returning the original value.");
+            return propertyValue;
+        }
+    }
 
 }
diff --git a/sli/provider/src/main/java/org/openecomp/sdnc/sli/provider/NotifyNodeExecutor.java b/sli/provider/src/main/java/org/openecomp/sdnc/sli/provider/NotifyNodeExecutor.java
index 5002604..4dc4a93 100644
--- a/sli/provider/src/main/java/org/openecomp/sdnc/sli/provider/NotifyNodeExecutor.java
+++ b/sli/provider/src/main/java/org/openecomp/sdnc/sli/provider/NotifyNodeExecutor.java
@@ -56,15 +56,7 @@
 					+ plugin);
 		}
 
-		BundleContext bctx = FrameworkUtil.getBundle(this.getClass())
-				.getBundleContext();
-
-		ServiceReference sref = bctx.getServiceReference(plugin);
-
-		if (sref != null) {
-			SvcLogicResource resourcePlugin = (SvcLogicResource) bctx
-					.getService(sref);
-
+        SvcLogicResource resourcePlugin = getSvcLogicResource(plugin);
 			if (resourcePlugin != null) {
 
 				try {
@@ -88,10 +80,6 @@
 				LOG.warn("Could not find SvcLogicResource object for plugin "
 						+ plugin);
 			}
-		} else {
-			LOG.warn("Could not find service reference object for plugin "
-					+ plugin);
-		}
 
 		SvcLogicNode nextNode = node.getOutcomeValue(outValue);
 		if (nextNode != null) {
@@ -114,5 +102,21 @@
 		return (nextNode);
 	}
 
+    protected SvcLogicResource getSvcLogicResource(String plugin) {
+        BundleContext bctx = FrameworkUtil.getBundle(this.getClass())
+                .getBundleContext();
+
+        ServiceReference sref = bctx.getServiceReference(plugin);
+        if (sref != null) {
+            SvcLogicResource resourcePlugin = (SvcLogicResource) bctx
+                    .getService(sref);
+            return resourcePlugin;
+        }
+        else {
+            LOG.warn("Could not find service reference object for plugin " + plugin);
+            return null;
+        }
+    }
+
 
 }
diff --git a/sli/provider/src/main/java/org/openecomp/sdnc/sli/provider/RecordNodeExecutor.java b/sli/provider/src/main/java/org/openecomp/sdnc/sli/provider/RecordNodeExecutor.java
index d07a4d6..f75752b 100644
--- a/sli/provider/src/main/java/org/openecomp/sdnc/sli/provider/RecordNodeExecutor.java
+++ b/sli/provider/src/main/java/org/openecomp/sdnc/sli/provider/RecordNodeExecutor.java
@@ -50,8 +50,8 @@
 				node.getAttribute("plugin"), node, ctx);
 		String outValue = "failure";
 
-		if (LOG.isDebugEnabled()) {
-			LOG.debug(node.getNodeType()
+		if (LOG.isTraceEnabled()) {
+			LOG.trace(node.getNodeType()
 					+ " node encountered - looking for recorder class "
 					+ plugin);
 		}
@@ -71,21 +71,15 @@
 			String curExprValue = SvcLogicExpressionResolver.evaluate(curExpr,
 					node, ctx);
 
-			if (LOG.isDebugEnabled()) {
-				LOG.debug("executeRecordNode : parameter " + curName + " = "
+			if (LOG.isTraceEnabled()) {
+				LOG.trace("executeRecordNode : parameter " + curName + " = "
 						+ curExpr + " => " + curExprValue);
 			}
 			parmMap.put(curName, curExprValue);
 		}
 
-		BundleContext bctx = FrameworkUtil.getBundle(this.getClass())
-				.getBundleContext();
 
-		ServiceReference sref = bctx.getServiceReference(plugin);
-
-		if (sref != null) {
-			SvcLogicRecorder recorder = (SvcLogicRecorder) bctx
-					.getService(sref);
+			SvcLogicRecorder recorder = getSvcLogicResource(plugin);
 
 			if (recorder != null) {
 
@@ -99,9 +93,6 @@
 				LOG.warn("Could not find SvcLogicRecorder object for plugin "
 						+ plugin);
 			}
-		} else {
-			LOG.warn("Cound not find service reference for plugin " + plugin);
-		}
 
 		SvcLogicNode nextNode = node.getOutcomeValue(outValue);
 		if (nextNode != null) {
@@ -117,13 +108,28 @@
 				LOG.debug("about to execute Other branch");
 			}
 		} else {
-			if (LOG.isDebugEnabled()) {
-				LOG.debug("no failure or Other branch found");
+			if (LOG.isTraceEnabled()) {
+				LOG.trace("no failure or Other branch found");
 			}
 		}
 		return (nextNode);
 	}
 
+    protected SvcLogicRecorder getSvcLogicResource(String plugin) {
+        BundleContext bctx = FrameworkUtil.getBundle(this.getClass())
+                .getBundleContext();
+
+        ServiceReference sref = bctx.getServiceReference(plugin);
+        if (sref != null) {
+            SvcLogicRecorder resourcePlugin = (SvcLogicRecorder) bctx
+                    .getService(sref);
+            return resourcePlugin;
+        }
+        else {
+            return null;
+        }
+    }
+
 
 
 }
diff --git a/sli/provider/src/main/java/org/openecomp/sdnc/sli/provider/ReleaseNodeExecutor.java b/sli/provider/src/main/java/org/openecomp/sdnc/sli/provider/ReleaseNodeExecutor.java
index 12e85db..b51cf9f 100644
--- a/sli/provider/src/main/java/org/openecomp/sdnc/sli/provider/ReleaseNodeExecutor.java
+++ b/sli/provider/src/main/java/org/openecomp/sdnc/sli/provider/ReleaseNodeExecutor.java
@@ -53,15 +53,7 @@
 					+ plugin);
 		}
 
-		BundleContext bctx = FrameworkUtil.getBundle(this.getClass())
-				.getBundleContext();
-
-		ServiceReference sref = bctx.getServiceReference(plugin);
-
-		if (sref != null) {
-			SvcLogicResource resourcePlugin = (SvcLogicResource) bctx
-					.getService(sref);
-
+        SvcLogicResource resourcePlugin = getSvcLogicResource(plugin);
 			if (resourcePlugin != null) {
 
 				try {
@@ -85,10 +77,6 @@
 				LOG.warn("Could not find SvcLogicResource object for plugin "
 						+ plugin);
 			}
-		} else {
-			LOG.warn("Could not find service reference object for plugin "
-					+ plugin);
-		}
 
 		SvcLogicNode nextNode = node.getOutcomeValue(outValue);
 		if (nextNode != null) {
@@ -112,5 +100,21 @@
 		return (nextNode);
 	}
 
+    protected SvcLogicResource getSvcLogicResource(String plugin) {
+        BundleContext bctx = FrameworkUtil.getBundle(this.getClass())
+                .getBundleContext();
+
+        ServiceReference sref = bctx.getServiceReference(plugin);
+        if (sref != null) {
+            SvcLogicResource resourcePlugin = (SvcLogicResource) bctx
+                    .getService(sref);
+            return resourcePlugin;
+        }
+        else {
+            LOG.warn("Could not find service reference object for plugin " + plugin);
+            return null;
+        }
+    }
+
 
 }
diff --git a/sli/provider/src/main/java/org/openecomp/sdnc/sli/provider/ReserveNodeExecutor.java b/sli/provider/src/main/java/org/openecomp/sdnc/sli/provider/ReserveNodeExecutor.java
index aa5d5ef..7db233f 100644
--- a/sli/provider/src/main/java/org/openecomp/sdnc/sli/provider/ReserveNodeExecutor.java
+++ b/sli/provider/src/main/java/org/openecomp/sdnc/sli/provider/ReserveNodeExecutor.java
@@ -65,14 +65,9 @@
 					+ plugin);
 		}
 
-		BundleContext bctx = FrameworkUtil.getBundle(this.getClass())
-				.getBundleContext();
 
-		ServiceReference sref = bctx.getServiceReference(plugin);
 
-		if (sref != null) {
-			SvcLogicResource resourcePlugin = (SvcLogicResource) bctx
-					.getService(sref);
+        SvcLogicResource resourcePlugin = getSvcLogicResource(plugin);
 
 			if (resourcePlugin != null) {
 
@@ -96,10 +91,6 @@
 				LOG.warn("Could not find SvcLogicResource object for plugin "
 						+ plugin);
 			}
-		} else {
-			LOG.warn("Could not find service reference object for plugin "
-					+ plugin);
-		}
 
 		SvcLogicNode nextNode = node.getOutcomeValue(outValue);
 		if (nextNode != null) {
@@ -123,5 +114,21 @@
 		return (nextNode);
 	}
 
+    protected SvcLogicResource getSvcLogicResource(String plugin) {
+        BundleContext bctx = FrameworkUtil.getBundle(this.getClass())
+                .getBundleContext();
+
+        ServiceReference sref = bctx.getServiceReference(plugin);
+        if (sref != null) {
+            SvcLogicResource resourcePlugin = (SvcLogicResource) bctx
+                    .getService(sref);
+            return resourcePlugin;
+        }
+        else {
+            LOG.warn("Could not find service reference object for plugin " + plugin);
+            return null;
+        }
+    }
+
 
 }
diff --git a/sli/provider/src/main/java/org/openecomp/sdnc/sli/provider/SaveNodeExecutor.java b/sli/provider/src/main/java/org/openecomp/sdnc/sli/provider/SaveNodeExecutor.java
index fc3adcc..f57eac8 100644
--- a/sli/provider/src/main/java/org/openecomp/sdnc/sli/provider/SaveNodeExecutor.java
+++ b/sli/provider/src/main/java/org/openecomp/sdnc/sli/provider/SaveNodeExecutor.java
@@ -93,14 +93,9 @@
 					+ plugin);
 		}
 
-		BundleContext bctx = FrameworkUtil.getBundle(this.getClass())
-				.getBundleContext();
 
-		ServiceReference sref = bctx.getServiceReference(plugin);
 
-		if (sref != null) {
-			SvcLogicResource resourcePlugin = (SvcLogicResource) bctx
-					.getService(sref);
+        SvcLogicResource resourcePlugin = getSvcLogicResource(plugin);
 
 			if (resourcePlugin != null) {
 
@@ -125,10 +120,6 @@
 				LOG.warn("Could not find SvcLogicResource object for plugin "
 						+ plugin);
 			}
-		} else {
-			LOG.warn("Could not find service reference object for plugin "
-					+ plugin);
-		}
 
 		SvcLogicNode nextNode = node.getOutcomeValue(outValue);
 		if (nextNode != null) {
@@ -151,4 +142,20 @@
 		return (nextNode);
 	}
 
+    protected SvcLogicResource getSvcLogicResource(String plugin) {
+        BundleContext bctx = FrameworkUtil.getBundle(this.getClass())
+                .getBundleContext();
+
+        ServiceReference sref = bctx.getServiceReference(plugin);
+        if (sref != null) {
+            SvcLogicResource resourcePlugin = (SvcLogicResource) bctx
+                    .getService(sref);
+            return resourcePlugin;
+        }
+        else {
+            LOG.warn("Could not find service reference object for plugin " + plugin);
+            return null;
+        }
+    }
+
 }
diff --git a/sli/provider/src/main/java/org/openecomp/sdnc/sli/provider/SetNodeExecutor.java b/sli/provider/src/main/java/org/openecomp/sdnc/sli/provider/SetNodeExecutor.java
index 0de109b..55ad737 100644
--- a/sli/provider/src/main/java/org/openecomp/sdnc/sli/provider/SetNodeExecutor.java
+++ b/sli/provider/src/main/java/org/openecomp/sdnc/sli/provider/SetNodeExecutor.java
@@ -173,7 +173,7 @@
 							curEnt.getValue(), node, ctx);
 
 					if (LOG.isDebugEnabled()) {
-						LOG.debug("Parameter value "
+						LOG.trace("Parameter value "
 								+ curEnt.getValue().asParsedExpr()
 								+ " resolves to " + curValue);
 						LOG.debug("Setting context attribute " + lhsVarName
diff --git a/sli/provider/src/main/java/org/openecomp/sdnc/sli/provider/SvcLogicActivator.java b/sli/provider/src/main/java/org/openecomp/sdnc/sli/provider/SvcLogicActivator.java
index 33de964..691ad40 100644
--- a/sli/provider/src/main/java/org/openecomp/sdnc/sli/provider/SvcLogicActivator.java
+++ b/sli/provider/src/main/java/org/openecomp/sdnc/sli/provider/SvcLogicActivator.java
@@ -69,6 +69,7 @@
 			put("set", new SetNodeExecutor());
 			put("switch", new SwitchNodeExecutor());
 			put("update", new UpdateNodeExecutor());
+            put("break", new BreakNodeExecutor());
 
 		}
 	};
diff --git a/sli/provider/src/main/java/org/openecomp/sdnc/sli/provider/SvcLogicExpressionResolver.java b/sli/provider/src/main/java/org/openecomp/sdnc/sli/provider/SvcLogicExpressionResolver.java
index f248a59..29bd9b4 100644
--- a/sli/provider/src/main/java/org/openecomp/sdnc/sli/provider/SvcLogicExpressionResolver.java
+++ b/sli/provider/src/main/java/org/openecomp/sdnc/sli/provider/SvcLogicExpressionResolver.java
@@ -65,12 +65,12 @@
 				
 				if (atomType == AtomType.CONTEXT_VAR)
 				{
-					LOG.debug("Evaluating context variable $"+varName);
+					LOG.trace("Evaluating context variable $"+varName);
 					
 					String varValue = ctx.getAttribute(varName);
 					
 					if (varValue == null) {
-						LOG.debug("Context variable $"+varName+" unset - treating as empty string");
+						LOG.trace("Context variable $"+varName+" unset - treating as empty string");
 						varValue = "";
 					}
 						
@@ -78,7 +78,7 @@
 				}
 				SvcLogicExpression parm = node.getParameter(varName);
 				if (parm != null) {
-					LOG.debug("Evaluating value of parameter "+varName+": "+parm.asParsedExpr());
+					LOG.trace("Evaluating value of parameter "+varName+": "+parm.asParsedExpr());
 					
 					return (evaluate(parm, node, ctx));
 				}
@@ -98,7 +98,7 @@
 				List<SvcLogicExpression> operands = binExpr.getOperands();
 				if (operands.size() == 1)
 				{
-					LOG.debug("SvcLogicBinaryExpression as no operator and one operand - evaluating its operand");
+					LOG.trace("SvcLogicBinaryExpression as no operator and one operand - evaluating its operand");
 					return(evaluate(operands.get(0), node, ctx));
 				}
 				else
diff --git a/sli/provider/src/main/java/org/openecomp/sdnc/sli/provider/SvcLogicServiceImpl.java b/sli/provider/src/main/java/org/openecomp/sdnc/sli/provider/SvcLogicServiceImpl.java
index 14366a9..6ee264e 100644
--- a/sli/provider/src/main/java/org/openecomp/sdnc/sli/provider/SvcLogicServiceImpl.java
+++ b/sli/provider/src/main/java/org/openecomp/sdnc/sli/provider/SvcLogicServiceImpl.java
@@ -268,6 +268,8 @@
 
 		LOG.info("Executing root node");
 		SvcLogicContext ctx = new SvcLogicContext(props);
+        ctx.setAttribute("currentGraph", graph.toString());
+        ctx.setAttribute("X-ECOMP-RequestID", MDC.get("X-ECOMP-RequestID"));
 		ctx.setDomDataBroker(domDataBroker);
 		SvcLogicNode curNode = graph.getRootNode();
 
diff --git a/sli/provider/src/main/java/org/openecomp/sdnc/sli/provider/SwitchNodeExecutor.java b/sli/provider/src/main/java/org/openecomp/sdnc/sli/provider/SwitchNodeExecutor.java
index 4ea851f..2e32a58 100644
--- a/sli/provider/src/main/java/org/openecomp/sdnc/sli/provider/SwitchNodeExecutor.java
+++ b/sli/provider/src/main/java/org/openecomp/sdnc/sli/provider/SwitchNodeExecutor.java
@@ -55,8 +55,7 @@
 
 		if (LOG.isDebugEnabled()) {
 			if (nextNode != null) {
-				LOG.debug("Next node to execute is node "
-						+ nextNode.getNodeId());
+                LOG.debug("Next node to execute is node " + nextNode.getNodeId());
 			} else {
 				LOG.debug("No next node found");
 			}
diff --git a/sli/provider/src/main/java/org/openecomp/sdnc/sli/provider/UpdateNodeExecutor.java b/sli/provider/src/main/java/org/openecomp/sdnc/sli/provider/UpdateNodeExecutor.java
index ac1144c..e7a6621 100644
--- a/sli/provider/src/main/java/org/openecomp/sdnc/sli/provider/UpdateNodeExecutor.java
+++ b/sli/provider/src/main/java/org/openecomp/sdnc/sli/provider/UpdateNodeExecutor.java
@@ -87,14 +87,9 @@
 					+ plugin);
 		}
 
-		BundleContext bctx = FrameworkUtil.getBundle(this.getClass())
-				.getBundleContext();
 
-		ServiceReference sref = bctx.getServiceReference(plugin);
+        SvcLogicResource resourcePlugin = getSvcLogicResource(plugin);
 
-		if (sref != null) {
-			SvcLogicResource resourcePlugin = (SvcLogicResource) bctx
-					.getService(sref);
 
 			if (resourcePlugin != null) {
 
@@ -119,10 +114,6 @@
 				LOG.warn("Could not find SvcLogicResource object for plugin "
 						+ plugin);
 			}
-		} else {
-			LOG.warn("Could not find service reference object for plugin "
-					+ plugin);
-		}
 
 		SvcLogicNode nextNode = node.getOutcomeValue(outValue);
 		if (nextNode != null) {
@@ -145,4 +136,19 @@
 		return (nextNode);
 	}
 
+    protected SvcLogicResource getSvcLogicResource(String plugin) {
+        BundleContext bctx = FrameworkUtil.getBundle(this.getClass())
+                .getBundleContext();
+
+        ServiceReference sref = bctx.getServiceReference(plugin);
+        if (sref != null) {
+            SvcLogicResource resourcePlugin = (SvcLogicResource) bctx
+                    .getService(sref);
+            return resourcePlugin;
+        }
+        else {
+            LOG.warn("Could not find service reference object for plugin " + plugin);
+            return null;
+        }
+    }
 }
diff --git a/sli/provider/src/test/java/org/openecomp/sdnc/sli/provider/BadPlugin.java b/sli/provider/src/test/java/org/openecomp/sdnc/sli/provider/BadPlugin.java
new file mode 100644
index 0000000..d1ab4cf
--- /dev/null
+++ b/sli/provider/src/test/java/org/openecomp/sdnc/sli/provider/BadPlugin.java
@@ -0,0 +1,56 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * openECOMP : SDN-C
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights
+ * 						reserved.
+ * ================================================================================
+ * Licensed 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.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.sdnc.sli.provider;
+
+import java.util.Map;
+
+import org.openecomp.sdnc.sli.SvcLogicContext;
+import org.openecomp.sdnc.sli.SvcLogicException;
+import org.openecomp.sdnc.sli.SvcLogicJavaPlugin;
+
+
+public class BadPlugin implements SvcLogicJavaPlugin {
+    public String selectLunch(Map<String, String> parameters, SvcLogicContext ctx) throws SvcLogicException {
+        String day = parameters.get("day");
+        if (day == null || day.length() < 1) {
+            throw new SvcLogicException("What day is it?");
+        }
+        switch (day) {
+        case ("monday"): {
+            return "pizza";
+        }
+        case ("tuesday"): {
+            return "soup";
+        }
+        case ("wednesday"): {
+            return "salad";
+        }
+        case ("thursday"): {
+            return "sushi";
+        }
+        case ("friday"): {
+            return "bbq";
+        }
+        }
+        throw new SvcLogicException("Lunch cannot be served");
+    }
+}
diff --git a/sli/provider/src/test/java/org/openecomp/sdnc/sli/provider/ExecuteNodeExecutorTest.java b/sli/provider/src/test/java/org/openecomp/sdnc/sli/provider/ExecuteNodeExecutorTest.java
new file mode 100644
index 0000000..3d43ee1
--- /dev/null
+++ b/sli/provider/src/test/java/org/openecomp/sdnc/sli/provider/ExecuteNodeExecutorTest.java
@@ -0,0 +1,57 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * openECOMP : SDN-C
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights
+ * 						reserved.
+ * ================================================================================
+ * Licensed 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.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.sdnc.sli.provider;
+
+import java.util.Map.Entry;
+
+import org.openecomp.sdnc.sli.DuplicateValueException;
+import org.openecomp.sdnc.sli.SvcLogicContext;
+import org.openecomp.sdnc.sli.SvcLogicException;
+import org.openecomp.sdnc.sli.SvcLogicExpression;
+import org.openecomp.sdnc.sli.SvcLogicGraph;
+import org.openecomp.sdnc.sli.SvcLogicJavaPlugin;
+import org.openecomp.sdnc.sli.SvcLogicNode;
+
+import junit.framework.TestCase;
+
+public class ExecuteNodeExecutorTest extends TestCase {
+    public class MockExecuteNodeExecutor extends ExecuteNodeExecutor {
+
+        protected SvcLogicJavaPlugin getSvcLogicJavaPlugin(String pluginName) {
+            return (SvcLogicJavaPlugin) new LunchSelectorPlugin();
+        }
+
+        protected String evaluate(SvcLogicExpression expr, SvcLogicNode node,
+                SvcLogicContext ctx) throws SvcLogicException {
+            return "selectLunch";
+        }
+    }
+
+    public void testBadPlugin() throws DuplicateValueException, SvcLogicException {
+        LunchSelectorPlugin p = new LunchSelectorPlugin();
+        MockExecuteNodeExecutor execute = new MockExecuteNodeExecutor();
+        SvcLogicNode node = new SvcLogicNode(0, "", "", new SvcLogicGraph());
+        node.setAttribute("method", "selectLunch");
+        execute.execute(new SvcLogicServiceImpl(), new SvcLogicNode(0, "", "", new SvcLogicGraph()), new SvcLogicContext());
+    }
+
+}
diff --git a/sli/provider/src/test/java/org/openecomp/sdnc/sli/provider/LunchSelectorPlugin.java b/sli/provider/src/test/java/org/openecomp/sdnc/sli/provider/LunchSelectorPlugin.java
new file mode 100644
index 0000000..b9156bc
--- /dev/null
+++ b/sli/provider/src/test/java/org/openecomp/sdnc/sli/provider/LunchSelectorPlugin.java
@@ -0,0 +1,78 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * openECOMP : SDN-C
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights
+ * 						reserved.
+ * ================================================================================
+ * Licensed 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.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.sdnc.sli.provider;
+
+import java.util.Map;
+
+import org.openecomp.sdnc.sli.SvcLogicContext;
+import org.openecomp.sdnc.sli.SvcLogicException;
+import org.openecomp.sdnc.sli.SvcLogicJavaPlugin;
+
+
+
+public class LunchSelectorPlugin implements SvcLogicJavaPlugin {
+    public class UnknownLunchDayException extends Exception{
+
+        public UnknownLunchDayException(String string) {
+            super(string);
+        }
+
+    }
+    class Sandwhich {
+        String meat;
+        String cheese;
+
+        public Sandwhich(String meat, String cheese) {
+            this.meat = meat;
+            this.cheese = cheese;
+        }
+    }
+
+    public String selectLunch(Map<String, String> parameters, SvcLogicContext ctx) throws Exception {
+        String day = parameters.get("day");
+        if (day == null || day.length() < 1) {
+            throw new UnknownLunchDayException("What day is it?");
+        }
+        switch (day) {
+        case ("monday"): {
+            return "pizza";
+        }
+        case ("tuesday"): {
+            return "soup";
+        }
+        case ("wednesday"): {
+            return "salad";
+        }
+        case ("thursday"): {
+            return "sushi";
+        }
+        case ("friday"): {
+            return "bbq";
+        }
+        }
+        throw new SvcLogicException("Lunch cannot be served");
+    }
+
+    public Sandwhich makeLunch(Map<String, String> parameters, SvcLogicContext ctx) throws SvcLogicException {
+        return new Sandwhich("ham", "american");
+    }
+}
diff --git a/sli/provider/src/test/java/org/openecomp/sdnc/sli/provider/MdsalHelperTest.java b/sli/provider/src/test/java/org/openecomp/sdnc/sli/provider/MdsalHelperTest.java
new file mode 100644
index 0000000..a4e41bb
--- /dev/null
+++ b/sli/provider/src/test/java/org/openecomp/sdnc/sli/provider/MdsalHelperTest.java
@@ -0,0 +1,43 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * openECOMP : SDN-C
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights
+ * 						reserved.
+ * ================================================================================
+ * Licensed 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.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.sdnc.sli.provider;
+
+import junit.framework.TestCase;
+
+public class MdsalHelperTest extends TestCase {
+
+    public static final String pathToSdnPropertiesFile = "./src/test/resources/l3sdn.properties";
+
+    public void testSdnProperties() {
+        MdsalHelperTesterUtil.loadProperties(pathToSdnPropertiesFile);
+        assertEquals("synccomplete", MdsalHelperTesterUtil.mapEnumeratedValue("request-status", "Synccomplete"));
+        assertEquals("asynccomplete", MdsalHelperTesterUtil.mapEnumeratedValue("request-status", "asynccomplete"));
+        assertEquals("notifycomplete", MdsalHelperTesterUtil.mapEnumeratedValue("request-status", "notifycomplete"));
+        assertEquals("service-configuration-operation", MdsalHelperTesterUtil.mapEnumeratedValue("rpc-name",
+                "ServiceConfigurationOperation"));
+    }
+
+    public void testNegativeSdnProperties() {
+        assertNotSame("synccomplete", MdsalHelperTesterUtil.mapEnumeratedValue("request-status", "Synccomplete"));
+    }
+
+}
diff --git a/sli/provider/src/test/java/org/openecomp/sdnc/sli/provider/MdsalHelperTesterUtil.java b/sli/provider/src/test/java/org/openecomp/sdnc/sli/provider/MdsalHelperTesterUtil.java
new file mode 100644
index 0000000..01e333f
--- /dev/null
+++ b/sli/provider/src/test/java/org/openecomp/sdnc/sli/provider/MdsalHelperTesterUtil.java
@@ -0,0 +1,37 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * openECOMP : SDN-C
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights
+ * 						reserved.
+ * ================================================================================
+ * Licensed 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.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.sdnc.sli.provider;
+
+import org.openecomp.sdnc.sli.provider.MdsalHelper;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class MdsalHelperTesterUtil extends MdsalHelper {
+
+    private static final Logger LOG = LoggerFactory.getLogger(MdsalHelperTesterUtil.class);
+    
+    //Normally static init of classes goes here for some weird classloader thing
+    static {
+        String str = "Hello World!";
+    }
+
+}
diff --git a/sli/provider/src/test/java/org/openecomp/sdnc/sli/provider/PluginTest.java b/sli/provider/src/test/java/org/openecomp/sdnc/sli/provider/PluginTest.java
new file mode 100644
index 0000000..035cd3e
--- /dev/null
+++ b/sli/provider/src/test/java/org/openecomp/sdnc/sli/provider/PluginTest.java
@@ -0,0 +1,106 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * openECOMP : SDN-C
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights
+ * 						reserved.
+ * ================================================================================
+ * Licensed 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.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.sdnc.sli.provider;
+
+import java.lang.reflect.Method;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.openecomp.sdnc.sli.SvcLogicContext;
+import org.openecomp.sdnc.sli.SvcLogicGraph;
+import org.openecomp.sdnc.sli.SvcLogicJavaPlugin;
+import org.openecomp.sdnc.sli.SvcLogicNode;
+
+import junit.framework.TestCase;
+
+public class PluginTest extends TestCase {
+
+    // The existing plugins work just like a VoidDummyPlugin
+    // They will return null simply because they are all void
+    // The attribute emitsOutcome will not be present, the expected outcome is success when no exception is thrown by the plugin
+    public void testOldPlugin() throws Exception {
+        ExecuteNodeExecutor executor = new ExecuteNodeExecutor();
+        SvcLogicJavaPlugin plugin = new VoidDummyPlugin();
+
+        Class pluginClass = plugin.getClass();
+        Method pluginMethod = pluginClass.getMethod("dummy", Map.class, SvcLogicContext.class);
+        Map<String, String> parmMap = new HashMap<String, String>();
+        SvcLogicContext ctx = new SvcLogicContext();
+        Object o = pluginMethod.invoke(plugin, parmMap, ctx);
+
+        SvcLogicGraph graph = new SvcLogicGraph();
+        SvcLogicNode node = new SvcLogicNode(1, "return", graph);
+        String emitsOutcome = SvcLogicExpressionResolver.evaluate(node.getAttribute("emitsOutcome"),  node, ctx);
+        String outValue = executor.mapOutcome(o, emitsOutcome);
+        assertEquals("success",outValue);
+    }
+
+    //Newer plugins can set the attribute emitsOutcome to true, if so they should return a string
+    //The string represents the outcome value
+    public void testNewPlugin() throws Exception {
+        ExecuteNodeExecutor executor = new ExecuteNodeExecutor();
+        SvcLogicJavaPlugin plugin = new LunchSelectorPlugin();
+
+        Class pluginClass = plugin.getClass();
+        Method pluginMethod = pluginClass.getMethod("selectLunch", Map.class, SvcLogicContext.class);
+
+        Map<String, String> parmMap = new HashMap<String, String>();
+        SvcLogicContext ctx = new SvcLogicContext();
+
+        parmMap.put("day", "monday");
+        Object o = pluginMethod.invoke(plugin, parmMap, ctx);
+        SvcLogicGraph graph = new SvcLogicGraph();
+        SvcLogicNode node = new SvcLogicNode(1, "return", graph);
+        node.setAttribute("emitsOutcome", "true");
+        String emitsOutcome = SvcLogicExpressionResolver.evaluate(node.getAttribute("emitsOutcome"),  node, ctx);
+        String outValue = executor.mapOutcome(o, emitsOutcome);
+        assertEquals("pizza", outValue);
+
+        parmMap.put("day", "tuesday");
+        outValue = (String) pluginMethod.invoke(plugin, parmMap, ctx);
+        o = pluginMethod.invoke(plugin, parmMap, ctx);
+        outValue = executor.mapOutcome(o, emitsOutcome);
+        assertEquals("soup",outValue);
+
+    }
+
+    //APPC had some legacy plugins returning objects which should not be treated as outcomes
+    //The attribute emitsOutcome will not be set
+    //The outcome should be success as it has always been
+    public void testObjPlugin() throws Exception{
+        ExecuteNodeExecutor executor = new ExecuteNodeExecutor();
+        SvcLogicJavaPlugin plugin = new LunchSelectorPlugin();
+
+        Class pluginClass = plugin.getClass();
+        Method pluginMethod = pluginClass.getMethod("makeLunch", Map.class, SvcLogicContext.class);
+
+        Map<String, String> parmMap = new HashMap<String, String>();
+        SvcLogicContext ctx = new SvcLogicContext();
+        Object o = pluginMethod.invoke(plugin, parmMap, ctx);
+        SvcLogicGraph graph = new SvcLogicGraph();
+        SvcLogicNode node = new SvcLogicNode(1, "return", graph);
+        String emitsOutcome = SvcLogicExpressionResolver.evaluate(node.getAttribute("emitsOutcome"),  node, ctx);
+        String outValue = executor.mapOutcome(o, emitsOutcome);
+        assertEquals("success",outValue);
+    }
+
+}
diff --git a/sli/provider/src/test/java/org/openecomp/sdnc/sli/provider/VoidDummyPlugin.java b/sli/provider/src/test/java/org/openecomp/sdnc/sli/provider/VoidDummyPlugin.java
new file mode 100644
index 0000000..6c8214a
--- /dev/null
+++ b/sli/provider/src/test/java/org/openecomp/sdnc/sli/provider/VoidDummyPlugin.java
@@ -0,0 +1,38 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * openECOMP : SDN-C
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights
+ * 						reserved.
+ * ================================================================================
+ * Licensed 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.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.sdnc.sli.provider;
+
+import java.util.Map;
+
+import org.openecomp.sdnc.sli.SvcLogicContext;
+import org.openecomp.sdnc.sli.SvcLogicException;
+import org.openecomp.sdnc.sli.SvcLogicJavaPlugin;
+
+
+
+public class VoidDummyPlugin implements SvcLogicJavaPlugin {
+
+    public void dummy(Map<String, String> parameters, SvcLogicContext ctx) throws SvcLogicException {
+        return;
+    }
+
+}
diff --git a/sliPluginUtils/provider/pom.xml b/sliPluginUtils/provider/pom.xml
index 093d585..739f89d 100755
--- a/sliPluginUtils/provider/pom.xml
+++ b/sliPluginUtils/provider/pom.xml
@@ -51,6 +51,12 @@
 			<artifactId>commons-lang3</artifactId>
 			<version>3.1</version>
 		</dependency>
+		<dependency>
+			<groupId>org.hamcrest</groupId>
+			<artifactId>hamcrest-library</artifactId>
+			<version>1.3</version>
+			<scope>test</scope>
+		</dependency>
 	</dependencies>
 
 	<build>
diff --git a/sliPluginUtils/provider/src/main/java/org/openecomp/sdnc/sli/SliPluginUtils/DME2.java b/sliPluginUtils/provider/src/main/java/org/openecomp/sdnc/sli/SliPluginUtils/DME2.java
new file mode 100644
index 0000000..0acaf5f
--- /dev/null
+++ b/sliPluginUtils/provider/src/main/java/org/openecomp/sdnc/sli/SliPluginUtils/DME2.java
@@ -0,0 +1,110 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * openECOMP : SDN-C
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights
+ * 						reserved.
+ * ================================================================================
+ * Licensed 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.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.sdnc.sli.SliPluginUtils;
+
+import java.util.Map;
+
+import org.openecomp.sdnc.sli.SvcLogicContext;
+import org.openecomp.sdnc.sli.SvcLogicException;
+import org.openecomp.sdnc.sli.SvcLogicJavaPlugin;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+
+
+/**
+ * A SvcLogicJavaPlugin that generates DME2 proxy urls using parameters from context memory.
+ */
+public class DME2 implements SvcLogicJavaPlugin {
+    String aafUserName;
+    String aafPassword;
+    String envContext;
+    String routeOffer;
+    String[] proxyUrls;
+    Integer index;
+    String commonServiceVersion;
+    String partner;
+
+    private static final Logger LOG = LoggerFactory.getLogger(DME2.class);
+
+    public void setPartner(String partner) {
+        if (partner != null && partner.length() > 0) {
+            this.partner = partner;
+        }
+    }
+
+    public DME2(String aafUserName, String aafPassword, String envContext, String routeOffer, String[] proxyUrls, String commonServiceVersion) {
+        this.aafUserName = aafUserName;
+        this.aafPassword = aafPassword;
+        this.envContext = envContext;
+        this.routeOffer = routeOffer;
+        this.proxyUrls = proxyUrls;
+        this.index = 0;
+        this.commonServiceVersion = commonServiceVersion;
+    }
+
+    // constructs a URL to contact the proxy which contacts a DME2 service
+    public String constructUrl(String service, String version, String subContext) {
+        StringBuilder sb = new StringBuilder();
+
+        // The hostname is assigned in a round robin fashion
+        sb.append(acquireHostName());
+        sb.append("/service=" + service);
+
+        //If the directedGraph passes an explicit version use that, if not use the commonServiceVersion found in the properties file
+        if (version == null) {
+            version = this.commonServiceVersion;
+        }
+        sb.append("/version=" + version);
+
+        sb.append("/envContext=" + this.envContext);
+        if (this.routeOffer != null && this.routeOffer.length() > 0) {
+            sb.append("/routeOffer=" + this.routeOffer);
+        }
+        if (subContext != null && subContext.length() > 0) {
+            sb.append("/subContext=" + subContext);
+        }
+        sb.append("?dme2.password=" + this.aafPassword);
+        sb.append("&dme2.username=" + this.aafUserName);
+        if (this.partner != null) {
+            sb.append("&dme2.partner=" + this.partner);
+        }
+        return (sb.toString());
+    }
+
+    public synchronized String acquireHostName() {
+        String retVal = proxyUrls[index];
+        index++;
+        if (index == this.proxyUrls.length) {
+            index = 0;
+        }
+        return retVal;
+    }
+
+    // Node entry point
+    public void constructUrl(Map<String, String> parameters, SvcLogicContext ctx) throws SvcLogicException {
+        SliPluginUtils.checkParameters(parameters, new String[] { "service", "outputPath" }, LOG);
+        String completeProxyUrl = constructUrl(parameters.get("service"), parameters.get("version"), parameters.get("subContext"));
+        ctx.setAttribute(parameters.get("outputPath"), completeProxyUrl);
+    }
+
+}
diff --git a/sliPluginUtils/provider/src/main/java/org/openecomp/sdnc/sli/SliPluginUtils/SliPluginUtils.java b/sliPluginUtils/provider/src/main/java/org/openecomp/sdnc/sli/SliPluginUtils/SliPluginUtils.java
index ea8df51..1dd29a5 100644
--- a/sliPluginUtils/provider/src/main/java/org/openecomp/sdnc/sli/SliPluginUtils/SliPluginUtils.java
+++ b/sliPluginUtils/provider/src/main/java/org/openecomp/sdnc/sli/SliPluginUtils/SliPluginUtils.java
@@ -21,12 +21,18 @@
 
 package org.openecomp.sdnc.sli.SliPluginUtils;
 
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.PrintStream;
+import java.text.SimpleDateFormat;
 import java.util.ArrayList;
 import java.util.Collections;
+import java.util.Date;
 import java.util.HashMap;
 import java.util.Map;
 import java.util.Objects;
 import java.util.Properties;
+import java.util.Set;
 import java.util.UUID;
 
 import org.apache.commons.lang3.StringUtils;
@@ -43,582 +49,706 @@
  * @see org.openecomp.sdnc.sli.SvcLogicContext
  */
 public class SliPluginUtils implements SvcLogicJavaPlugin {
-    public enum LogLevel {
-        TRACE, DEBUG, INFO, WARN, ERROR;
-    }
+	public enum LogLevel {
+		TRACE, DEBUG, INFO, WARN, ERROR;
+	}
 
-    private static final Logger LOG = LoggerFactory.getLogger(SliPluginUtils.class);
+	private static final Logger LOG = LoggerFactory.getLogger(SliPluginUtils.class);
 
 
-    // ========== CONSTRUCTORS ==========
+	// ========== CONSTRUCTORS ==========
 
-    public SliPluginUtils() {}
+	public SliPluginUtils() {}
 
-    public SliPluginUtils( Properties props ) {}
+	public SliPluginUtils( Properties props ) {}
 
 
 
-    // ========== CONTEXT MEMORY FUNCTIONS ==========
+	// ========== CONTEXT MEMORY FUNCTIONS ==========
+
+	/**
+	 * Removes 1 or more elements from a list in context memory.
+	 * <p>
+	 * Values are removed based on either the index in the list, a key-value
+	 * pair, or a list of key-value pairs that all must match in the element.
+	 * @param parameters
+	 * @param ctx Reference to context memory
+	 * @throws SvcLogicException All exceptions are wrapped in
+	 * SvcLogicException for compatibility with SLI.
+	 * @since 7.0.1
+	 */
+	public void ctxListRemove( Map<String,String> parameters, SvcLogicContext ctx ) throws SvcLogicException {
+		try{
+			LOG.debug( "ENTERING Execute Node \"ctxListRemove\"" );
+
+			// Validate, Log, & read parameters
+			checkParameters(parameters, new String[]{"list_pfx"}, LOG);
+			logExecuteNodeParameters(parameters, LOG, LogLevel.DEBUG);
+			String list_pfx = parameters.get("list_pfx");
+			String param_index = parameters.get("index");
+			String param_key = parameters.get("key");
+			String param_value = parameters.get("value");
+			String param_keys_length = parameters.get("keys_length");
+
+			// Initialize context memory list mimic
+			SvcLogicContextList list;
+
+			// Process based on input parameters:
+			//   index: remove object at specific index
+			//   key & value: remove all objects with key-value pair
+			//   keys_length: remove all objects that match all key-value pairs
+			//                in list
+			if( param_index != null ) {
+				// Parse index
+				LOG.trace("executing remove by index logic");
+				int index;
+				try {
+					index = Integer.parseInt(param_index);
+				}
+				catch( NumberFormatException e ) {
+					throw new IllegalArgumentException("\"index\" parameter is not a number. index = " + param_index, e);
+				}
+
+				// Extract list from context memory & remove object @ index
+				LOG.trace("extracting list from context memory");
+				list = SvcLogicContextList.extract(ctx, list_pfx);
+				LOG.trace("removing elements from list");
+				list.remove(index);
+			}
+			else if( param_value != null ) {
+				if( param_key == null ) { param_key = ""; }
+
+				// Extract list from context memory & remove objects with
+				// key-value pair
+				LOG.trace("executing remove by key-value pair logic");
+				LOG.trace("extracting list from context memory");
+				list = SvcLogicContextList.extract(ctx, list_pfx);
+				LOG.trace("removing elements from list");
+				list.remove( param_key, param_value );
+			}
+			else if( param_keys_length != null ) {
+				// Parse keys_length
+				LOG.trace("executing remove by key-value pair list logic");
+				int keys_length;
+				try {
+					keys_length = Integer.parseInt(param_keys_length);
+				}
+				catch( NumberFormatException e ) {
+					throw new IllegalArgumentException("\"keys_length\" parameters is not a number. keys_length = " + param_keys_length, e);
+				}
+
+				// Obtain key-value pairs to check from parameters
+				LOG.trace("reading keys parameter list");
+				HashMap<String,String> keys_values = new HashMap<String,String>();
+				for( int i = 0; i < keys_length; i++ ) {
+					keys_values.put(parameters.get("keys[" + i + "].key"), parameters.get("keys[" + i + "].value"));
+				}
+
+				// Extract list from context memory & remove objects with all
+				// key-value pairs matching
+				LOG.trace("extracting list from context memory");
+				list = SvcLogicContextList.extract(ctx, list_pfx);
+				LOG.trace("removing elements from list");
+				list.remove(keys_values);
+			}
+			else {
+				throw new IllegalArgumentException("Required parameters missing. Requires one of: index, key & value, or keys_length array");
+			}
+
+			// Remove index from list
+			LOG.trace("writing list back into context memory");
+			list.writeToContext(ctx);
+		}
+		catch( Exception e ) {
+			throw new SvcLogicException( "An error occurred in the ctxListRemove Execute node", e );
+		}
+		finally {
+			LOG.debug( "EXITING Execute Node \"ctxListRemove\"" );
+		}
+	}
 
     /**
-     * Removes 1 or more elements from a list in context memory.
-     * <p>
-     * Values are removed based on either the index in the list, a key-value
-     * pair, or a list of key-value pairs that all must match in the element.
-     * @param parameters
+     * ctxSortList
+     * @param parameters - the set of required parameters must contain list and delimiter.
      * @param ctx Reference to context memory
-     * @throws SvcLogicException All exceptions are wrapped in
-     * SvcLogicException for compatibility with SLI.
-     * @since 7.0.1
+     * @throws SvcLogicException if a required parameter is missing an exception is thrown
      */
-    public void ctxListRemove( Map<String,String> parameters, SvcLogicContext ctx ) throws SvcLogicException {
-        try{
-            LOG.debug( "ENTERING Execute Node \"ctxListRemove\"" );
+	public void ctxSortList( Map<String, String> parameters, SvcLogicContext ctx ) throws SvcLogicException {
+		checkParameters(parameters, new String[]{"list","delimiter"}, LOG);
+		ArrayList<SortableCtxListElement> list = new ArrayList<SortableCtxListElement>();
 
-            // Validate, Log, & read parameters
-            checkParameters(parameters, new String[]{"list_pfx"}, LOG);
-            logExecuteNodeParameters(parameters, LOG, LogLevel.DEBUG);
-            String list_pfx = parameters.get("list_pfx");
-            String param_index = parameters.get("index");
-            String param_key = parameters.get("key");
-            String param_value = parameters.get("value");
-            String param_keys_length = parameters.get("keys_length");
+		String[] sort_fields = null;
+		if( parameters.containsKey("sort-fields") ) {
+			sort_fields = parameters.get("sort-fields").split(parameters.get("delimiter"), 0);
+		}
 
-            // Initialize context memory list mimic
-            SvcLogicContextList list;
-
-            // Process based on input parameters:
-            //   index: remove object at specific index
-            //   key & value: remove all objects with key-value pair
-            //   keys_length: remove all objects that match all key-value pairs
-            //                in list
-            if( param_index != null ) {
-                // Parse index
-                LOG.trace("executing remove by index logic");
-                int index;
-                try {
-                    index = Integer.parseInt(param_index);
-                }
-                catch( NumberFormatException e ) {
-                    throw new IllegalArgumentException("\"index\" parameter is not a number. index = " + param_index, e);
-                }
-
-                // Extract list from context memory & remove object @ index
-                LOG.trace("extracting list from context memory");
-                list = SvcLogicContextList.extract(ctx, list_pfx);
-                LOG.trace("removing elements from list");
-                list.remove(index);
-            }
-            else if( param_value != null ) {
-                if( param_key == null ) { param_key = ""; }
-
-                // Extract list from context memory & remove objects with
-                // key-value pair
-                LOG.trace("executing remove by key-value pair logic");
-                LOG.trace("extracting list from context memory");
-                list = SvcLogicContextList.extract(ctx, list_pfx);
-                LOG.trace("removing elements from list");
-                list.remove( param_key, param_value );
-            }
-            else if( param_keys_length != null ) {
-                // Parse keys_length
-                LOG.trace("executing remove by key-value pair list logic");
-                int keys_length;
-                try {
-                    keys_length = Integer.parseInt(param_keys_length);
-                }
-                catch( NumberFormatException e ) {
-                    throw new IllegalArgumentException("\"keys_length\" parameters is not a number. keys_length = " + param_keys_length, e);
-                }
-
-                // Obtain key-value pairs to check from parameters
-                LOG.trace("reading keys parameter list");
-                HashMap<String,String> keys_values = new HashMap<>();
-                for( int i = 0; i < keys_length; i++ ) {
-                    keys_values.put(parameters.get("keys[" + i + "].key"), parameters.get("keys[" + i + "].value"));
-                }
-
-                // Extract list from context memory & remove objects with all
-                // key-value pairs matching
-                LOG.trace("extracting list from context memory");
-                list = SvcLogicContextList.extract(ctx, list_pfx);
-                LOG.trace("removing elements from list");
-                list.remove(keys_values);
-            }
-            else {
-                throw new IllegalArgumentException("Required parameters missing. Requires one of: index, key & value, or keys_length array");
-            }
-
-            // Remove index from list
-            LOG.trace("writing list back into context memory");
-            list.writeToContext(ctx);
-        }
-        catch( Exception e ) {
-            throw new SvcLogicException( "An error occurred in the ctxListRemove Execute node", e );
-        }
-        finally {
-            LOG.debug( "EXITING Execute Node \"ctxListRemove\"" );
-        }
-    }
-
-    // TODO: javadoc
-    public void ctxSortList( Map<String, String> parameters, SvcLogicContext ctx ) throws SvcLogicException {
-        checkParameters(parameters, new String[]{"list","delimiter"}, LOG);
-        ArrayList<SortableCtxListElement> list = new ArrayList<>();
-
-        String[] sort_fields = null;
-        if( parameters.containsKey("sort-fields") ) {
-            sort_fields = parameters.get("sort-fields").split(parameters.get("delimiter"), 0);
-        }
-
-        String ctx_list_str = parameters.get("list");
-        int listSz = getArrayLength(ctx, ctx_list_str);
+		String ctx_list_str = parameters.get("list");
+		int listSz = getArrayLength(ctx, ctx_list_str);
 
 
 
-        for( int i = 0; i < listSz; i++ ) {
-            list.add( new SortableCtxListElement(ctx, ctx_list_str + '[' + i + ']', sort_fields) );
-        }
-        Collections.sort(list);
+		for( int i = 0; i < listSz; i++ ) {
+			list.add( new SortableCtxListElement(ctx, ctx_list_str + '[' + i + ']', sort_fields) );
+		}
+		Collections.sort(list);
 
-        ctxBulkErase(ctx, ctx_list_str);
-        int i = 0;
-        for( SortableCtxListElement list_element : list ) {
-            for( Map.Entry<String,String> entry : list_element.child_elements.entrySet() ) {
-                if( sort_fields == null ) {
-                    ctx.setAttribute(ctx_list_str + '[' + i + ']', entry.getValue());
-                }
-                else {
-                    ctx.setAttribute(ctx_list_str + '[' + i + "]." + entry.getKey(), entry.getValue());
-                }
-            }
-            i++;
-        }
-        // Reset list length (removed by ctxBulkErase above)
-        ctx.setAttribute(ctx_list_str+"_length",  ""+listSz);
-    }
-
-    // TODO: javadoc
-    public void generateUUID( Map<String, String> parameters, SvcLogicContext ctx )  throws SvcLogicException {
-        checkParameters(parameters, new String[]{"ctx-destination"}, LOG);
-        ctx.setAttribute(parameters.get("ctx-destination"), UUID.randomUUID().toString() );
-    }
+		ctxBulkErase(ctx, ctx_list_str);
+		int i = 0;
+		for( SortableCtxListElement list_element : list ) {
+			for( Map.Entry<String,String> entry : list_element.child_elements.entrySet() ) {
+				if( sort_fields == null ) {
+					ctx.setAttribute(ctx_list_str + '[' + i + ']', entry.getValue());
+				}
+				else {
+					ctx.setAttribute(ctx_list_str + '[' + i + "]." + entry.getKey(), entry.getValue());
+				}
+			}
+			i++;
+		}
+		// Reset list length (removed by ctxBulkErase above)
+		ctx.setAttribute(ctx_list_str+"_length",  ""+listSz);
+	}
 
     /**
-     * Provides substring functionality to Directed Graphs.
-     * <p>
-     * Calls either String.substring(String beginIndex) or
-     * String.substring(String beginInded, String endIndex) if the end-index
-     * is present or not.
+     * generates a UUID and writes it to context memory
+     * @param parameters - ctx-destination is a required parameter
+     * @param ctx Reference to context memory
+     * @throws SvcLogicException thrown if a UUID cannot be generated or if ctx-destination is missing or null
+     */
+	public void generateUUID( Map<String, String> parameters, SvcLogicContext ctx )  throws SvcLogicException {
+		checkParameters(parameters, new String[]{"ctx-destination"}, LOG);
+		ctx.setAttribute(parameters.get("ctx-destination"), UUID.randomUUID().toString() );
+	}
+
+	/**
+	 * Provides substring functionality to Directed Graphs.
+	 * <p>
+	 * Calls either String.substring(String beginIndex) or
+	 * String.substring(String beginInded, String endIndex) if the end-index
+	 * is present or not.
+	 * @param parameters HashMap<String,String> of parameters passed by the DG to this function
+	 * <table border="1">
+	 * 	<thead><th>parameter</th><th>Mandatory/Optional</th><th>description</th></thead>
+	 * 	<tbody>
+	 * 		<tr><td>string</td><td>Mandatory</td><td>String to perform substring on</td></tr>
+	 * 		<tr><td>result</td><td>Mandatory</td><td>Key in context memory to populate the resulting string in</td></tr>
+	 * 		<tr><td>begin-index</td><td>Mandatory</td><td>Beginning index to pass to Java substring function</td></tr>
+	 * 		<tr><td>end-index</td><td>Optional</td><td>Ending index to pass to Java substring function. If not included, String.substring(begin) will be called.</td></tr>
+	 * 	</tbody>
+	 * </table>
+	 * @param ctx Reference to context memory
+	 * @throws SvcLogicException
+	 * @since 8.0.1
+	 * @see SliPluginUtils#substring(Map, SvcLogicContext)
+	 */
+	@Deprecated
+	public void substring( Map<String, String> parameters, SvcLogicContext ctx ) throws SvcLogicException {
+		try {
+			checkParameters( parameters, new String[]{"string","begin-index","result"}, LOG );
+			final String string = parameters.get("string");
+			final String result = parameters.get("result");
+			final String begin = parameters.get("begin-index");
+			final String end = parameters.get("end-index");
+
+			if( StringUtils.isEmpty(end) ) {
+				ctx.setAttribute( result, string.substring(Integer.parseInt(begin)) );
+			}
+			else {
+				ctx.setAttribute( result, string.substring(Integer.parseInt(begin), Integer.parseInt(end)) );
+			}
+		}
+		catch( Exception e ) {
+			throw new SvcLogicException( "An error occurred while the Directed Graph was performing a substring", e );
+		}
+	}
+
+
+
+	// ========== PUBLIC STATIC UTILITY FUNCTIONS ==========
+
+	/**
+	 * Throws an exception and writes an error to the log file if a required
+	 * parameters is not found in the parametersMap.
+	 * <p>
+	 * Use at the beginning of functions that can be called by Directed Graphs
+	 * and can take parameters to verify that all parameters have been provided
+	 * by the Directed Graph.
+	 * @param parametersMap parameters Map passed to this node
+	 * @param requiredParams Array of parameters required by the calling function
+	 * @param log Reference to Logger to log to
+	 * @throws SvcLogicException if a String in the requiredParams array is
+	 * not a key in parametersMap.
+	 * @since 1.0
+	 */
+        public static final void checkParameters(Map<String, String> parametersMap, String[] requiredParams, Logger log) throws SvcLogicException {
+        if( requiredParams == null || requiredParams.length < 1){
+            log.debug("required parameters was empty, exiting early.");
+            return;
+        }
+        if (parametersMap == null || parametersMap.keySet().size() < 1){
+            String errorMessage = "This method requires the parameters [" +   StringUtils.join(requiredParams,",") + "], but no parameters were passed in.";
+            log.error(errorMessage);
+            throw new SvcLogicException(errorMessage);
+        }
+
+    	for (String param : requiredParams) {
+    	    if (!parametersMap.containsKey(param)) {
+    		String errorMessage = "Required parameter \"" + param + "\" was not found in parameter list.";
+    		log.error(errorMessage);
+    		log.error("Total list of required parameters is [" + StringUtils.join(requiredParams, ",") + "].");
+    		throw new SvcLogicException(errorMessage);
+    	    }
+    	}
+        }
+
+	/**
+	 * Removes all key-value pairs with keys that begin with pfx
+	 * @param ctx Reference to context memory
+	 * @param pfx Prefix of key-value pairs to remove
+	 * @since 1.0
+	 */
+	public static final void ctxBulkErase( SvcLogicContext ctx, String pfx ) {
+		ArrayList<String> Keys = new ArrayList<String>( ctx.getAttributeKeySet() );
+		for( String key : Keys ) {
+			if( key.startsWith( pfx ) ) {
+				ctx.setAttribute( pfx + key.substring(pfx.length()) , null);
+			}
+		}
+	}
+
+	/**
+	 * Copies all context memory key-value pairs that start with src_pfx to
+	 * the keys that start with dest_pfx + suffix, where suffix is the result
+	 * of {@code key.substring(src_pfx.length())}.
+	 * <p>
+	 * Does NOT guarantee removal of all keys at the destination before
+	 * copying, but will overwrite any destination keys that have a
+	 * corresponding source key. Use {@link #ctxBulkErase(SvcLogicContext, String) ctxBulkErase}
+	 * before copy to erase destination root before copying from source.
+	 * @param ctx Reference to context memory.
+	 * @param src_pfx Prefix of the keys to copy values from.
+	 * @param dest_pfx Prefix of the keys to copy values to.
+	 * @since 1.0
+	 */
+	public static final void ctxBulkCopy( SvcLogicContext ctx, String src_pfx, String dest_pfx ) {
+		// Remove trailing period from dest_pfx
+		if( dest_pfx.charAt(dest_pfx.length()-1) == '.' ) {
+			dest_pfx = dest_pfx.substring(0,dest_pfx.length()-1);
+		}
+
+		// For each context key that begins with src_pfx, set the value of the
+		// key dest_pfx + the suffix of the key to the key's value
+		ArrayList<String> Keys = new ArrayList<String>(ctx.getAttributeKeySet());
+		for( String key : Keys ) {
+			if( key.startsWith(src_pfx) ) {
+				// Get suffix (no leading period)
+				String suffix = key.substring(src_pfx.length());
+				if( suffix.charAt(0) == '.') {
+					suffix = suffix.substring(1);
+				}
+
+				// Set destination's value to key's value
+				ctx.setAttribute(dest_pfx + '.' + suffix, ctx.getAttribute(key));
+			}
+		}
+	}
+
+	/**
+	 * Creates and returns a {@code Map<String, String>} that is a subset of
+	 * context memory where all keys begin with the prefix.
+	 * @param ctx Reference to context memory.
+	 * @param prefix Returned map's keys should all begin with this value.
+	 * @return A {@code Map<String, String>} containing all the key-value pairs
+	 * in ctx whose key begins with prefix.
+	 */
+	public static final Map<String, String> ctxGetBeginsWith( SvcLogicContext ctx, String prefix ) {
+		Map<String, String> prefixMap = new HashMap<String, String>();
+
+		for( String key : ctx.getAttributeKeySet() ) {
+			if( key.startsWith(prefix) ) {
+				prefixMap.put( key, ctx.getAttribute(key) );
+			}
+		}
+
+		return prefixMap;
+	}
+
+	/**
+	 * Returns true if key's value in context memory is "" or if it doesn't
+	 * exist in context memory.
+	 * @param ctx Reference to context memory.
+	 * @param key Key to search for.
+	 * @return true if key's value in context memory is "" or if it doesn't
+	 * exist in context memory.
+	 * @since 1.0
+	 */
+	public static final boolean ctxKeyEmpty( SvcLogicContext ctx, String key ) {
+		String value = ctx.getAttribute(key);
+		return value == null || value.isEmpty();
+	}
+
+	/**
+	 * Adds all key-value pairs in the entries Map to context memory.
+	 * @param ctx Reference to context memory. Value's {@code toString()}
+	 * function is used to add it.
+	 * @param entries {@code Map<String, ?>} of key-value pairs to add to
+	 * context memory. Value's {@code toString()} function is used to add it.
+	 * @return Reference to context memory to be used for function chaining.
+	 */
+	public static final SvcLogicContext ctxPutAll( SvcLogicContext ctx, Map<String, ?> entries ) {
+		for( Map.Entry<String, ?> entry : entries.entrySet() ) {
+			ctxSetAttribute( ctx, entry.getKey(), entry.getValue() );
+			//ctx.setAttribute(entry.getKey(), entry.getValue().toString());
+		}
+
+		return ctx;
+	}
+
+	/**
+	 * Sets a key in context memory to the output of object's toString(). The
+	 * key is deleted from context memory if object is null.
+	 * @param ctx Reference to context memory.
+	 * @param key Key to set.
+	 * @param object Object whose toString() will be the value set
+	 */
+	public static final void ctxSetAttribute( SvcLogicContext ctx, String key, Object object ) {
+		if( object == null ) {
+			ctx.setAttribute(key, null);
+		}
+		else {
+			ctx.setAttribute(key, object.toString());
+		}
+	}
+
+	/**
+	 * Sets a key in context memory to the output of object's toString().
+	 * <p>
+	 * The key is deleted from context memory if object is null. The key and
+	 * value set in context memory are logged to the Logger at the provided
+	 * logLevel level.
+	 * @param <O> Any Java object
+	 * @param ctx Reference to context memory.
+	 * @param key Key to set.
+	 * @param obj Object whose toString() will be the value set
+	 * @param LOG Logger to log to
+	 * @param logLevel level to log at in Logger
+	 */
+	public static final <O extends Object> void ctxSetAttribute( SvcLogicContext ctx, String key, O obj, Logger LOG, LogLevel logLevel ) {
+		String value = Objects.toString( obj, null );
+		ctx.setAttribute( key, value );
+		if( logLevelIsEnabled(LOG, logLevel ) ) {
+			if( value == null ) {
+				logMessageAtLevel( LOG, logLevel, "Deleting " + key );
+			}
+			else {
+				logMessageAtLevel( LOG, logLevel, "Setting " + key + " = " + value );
+			}
+		}
+	}
+
+	/**
+	 * Utility function used to get an array's length from context memory.
+	 * Will return 0 if key doesn't exist in context memory or isn't numeric.
+	 * <p>
+	 * Use to obtain a context memory array length without having to worry
+	 * about throwing a NumberFormatException.
+	 * @param ctx Reference to context memory
+	 * @param key Key in context memory whose value is the array's length. If
+	 * the key doesn't end in "_length", then "_length is appended.
+	 * @param log Reference to Logger to log to
+	 * @return The array length or 0 if the key is not found in context memory.
+	 * @since 1.0
+	 */
+	public static final int getArrayLength( SvcLogicContext ctx, String key ) {
+		return getArrayLength(ctx, key, null, null, null);
+	}
+
+	/**
+	 * Utility function used to get an array's length from context memory.
+	 * Will return 0 if key doesn't exist in context memory or isn't numeric
+	 * and print the provided log message to the configured log file.
+	 * <p>
+	 * Use to obtain a context memory array length without having to worry
+	 * about throwing a NumberFormatException.
+	 * @param ctx Reference to context memory.
+	 * @param key Key in context memory whose value is the array's length. If
+	 * the key doesn't end in "_length", then "_length is appended.
+	 * @param log Reference to Logger to log to. Doesn't log if null.
+	 * @param logLevel Logging level to log the message at if the context
+	 * memory key isn't found. Doesn't log if null.
+	 * @param log_message Message to log if the context memory key isn't found.
+	 * Doesn't log if null.
+	 * @return The array length or 0 if the key is not found in context memory.
+	 * @since 1.0
+	 */
+	public static final int getArrayLength( SvcLogicContext ctx, String key, Logger log, LogLevel logLevel, String log_message ) {
+		String ctxKey = ( key.endsWith("_length") ) ? key : key + "_length";
+		try {
+			return Integer.parseInt(ctx.getAttribute(ctxKey));
+		}
+		catch( NumberFormatException e ) {
+			if( log != null && logLevel != null && log_message != null ) {
+				switch( logLevel ) {
+					case TRACE:
+						log.trace(log_message);
+					case DEBUG:
+						log.debug(log_message);
+						break;
+					case INFO:
+						log.info(log_message);
+						break;
+					case WARN:
+						log.warn(log_message);
+						break;
+					case ERROR:
+						log.error(log_message);
+						break;
+				}
+			}
+		}
+
+		return 0;
+	}
+
+	/**
+	 * Prints sorted context memory key-value pairs to the log file at the log
+	 * level. Returns immediately if the log level isn't enabled.
+	 * <p>
+	 * O(n log(n)) time where n = size of context memory
+	 * @param ctx Reference to context memory
+	 * @param log Reference to Logger to log to
+	 * @param logLevel Logging level to log the context memory key-value pairs
+	 * at.
+	 * @since 1.0
+	 */
+	public static final void logContextMemory( SvcLogicContext ctx, Logger log, LogLevel logLevel ) {
+		logLevelIsEnabled( log, logLevel );
+
+		// Print sorted context memory key-value pairs to the log
+		ArrayList<String> keys = new ArrayList<String>(ctx.getAttributeKeySet());
+		Collections.sort(keys);
+		for( String key : keys ) {
+			logMessageAtLevel( log, logLevel, key + " = " + ctx.getAttribute(key) );
+		}
+	}
+
+
+
+	// ========== PRIVATE FUNCTIONS ==========
+
+	// TODO: javadoc
+	/**
+	 *
+	 * @param parameters
+	 * @param log
+	 * @param loglevel
+	 * @since 7.0.1
+	 */
+	public static final void logExecuteNodeParameters( Map<String,String> parameters, Logger log, LogLevel loglevel ) {
+		logLevelIsEnabled( log, loglevel );
+
+		for( Map.Entry<String,String> param : parameters.entrySet() ) {
+			logMessageAtLevel( log, loglevel, "PARAM: " + param.getKey() + " = " + param.getValue() );
+		}
+	}
+
+	// TODO: javadoc
+	/**
+	 * Returns true if the loglevel is enabled. Otherwise, returns false.
+	 * @param log Reference to logger
+	 * @param loglevel Log level to check if enabled
+	 * @return True if the loglevel is enabled. Otherwise, false
+	 * @since 7.0.1
+	 */
+	private static final boolean logLevelIsEnabled( Logger log, LogLevel loglevel ) {
+		// Return immediately if logging level isn't enabled
+		switch( loglevel ) {
+			case TRACE:
+				if( log.isTraceEnabled() ) { return true; }
+				return false;
+			case DEBUG:
+				if( log.isDebugEnabled() ) { return true; }
+				return false;
+			case INFO:
+				if( log.isInfoEnabled() ) { return true; }
+				return false;
+			case WARN:
+				if( log.isWarnEnabled() ) { return true; }
+				return false;
+			case ERROR:
+				if( log.isErrorEnabled() ) { return true; }
+				return false;
+			default:
+				throw new IllegalArgumentException("Unknown LogLevel: " + loglevel.toString());
+		}
+	}
+
+	// TODO: javadoc
+	/**
+	 *
+	 * @param log
+	 * @param loglevel
+	 * @param msg
+	 * @since 7.0.1
+	 */
+	private static final void logMessageAtLevel( Logger log, LogLevel loglevel, String msg ) {
+		switch( loglevel ) {
+			case TRACE:
+				log.trace(msg);
+				return;
+			case DEBUG:
+				log.debug(msg);
+				return;
+			case INFO:
+				log.info(msg);
+				return;
+			case WARN:
+				log.warn(msg);
+				return;
+			case ERROR:
+				log.error(msg);
+				return;
+		}
+	}
+
+
+
+	// ========== LOCAL CLASSES ==========
+
+	private class SortableCtxListElement implements Comparable<SortableCtxListElement> {
+		HashMap<String,String> child_elements = new HashMap<String,String>();
+		String[] sort_fields;
+
+		public SortableCtxListElement( SvcLogicContext ctx, String root, String[] sort_fields ) {
+			this.sort_fields = sort_fields;
+
+			for( String key : ctx.getAttributeKeySet() ) {
+				if( key.startsWith(root) ) {
+					if( key.length() == root.length() ) {
+						child_elements.put("", ctx.getAttribute(key));
+						break;
+					}
+					else {
+						child_elements.put(key.substring(root.length()+1), ctx.getAttribute(key));
+					}
+				}
+			}
+		}
+
+		@Override
+		public int compareTo(SortableCtxListElement arg0) {
+			if( sort_fields == null ) {
+				return this.child_elements.get("").compareTo(arg0.child_elements.get(""));
+			}
+
+			for( String field : this.sort_fields ) {
+				int result = this.child_elements.get(field).compareTo(arg0.child_elements.get(field));
+				if( result != 0 ) {
+					return result;
+				}
+			}
+
+			return 0;
+		}
+	}
+
+	/**
+     * Creates a file that contains the content of context memory.
+     * @param parameters - must contain the parameter filename
+     * @param ctx Reference to context memory
+     * @throws SvcLogicException thrown if file cannot be created or if parameters are missing
+     */
+	public static void printContext(Map<String, String> parameters, SvcLogicContext ctx) throws SvcLogicException {
+		if (parameters == null || parameters.keySet().size() < 1) {
+			throw new SvcLogicException("no parameters passed");
+		}
+
+		checkParameters(parameters, new String[]{"filename"}, LOG);
+
+		String fileName = parameters.get("filename");
+
+		PrintStream pstr = null;
+
+		try {
+			pstr = new PrintStream(new FileOutputStream(new File(fileName), true));
+		} catch (Exception e) {
+			throw new SvcLogicException("Cannot open file " + fileName, e);
+		}
+	        pstr.println("#######################################");
+		for (String attr : ctx.getAttributeKeySet()) {
+			pstr.println(attr + " = " + ctx.getAttribute(attr));
+		}
+		pstr.flush();
+		pstr.close();
+	}
+
+	 /**
+     * Checks context memory for a set of required parameters
+     * Every parameter aside from prefix will be treated as mandatory
      * @param parameters HashMap<String,String> of parameters passed by the DG to this function
      * <table border="1">
-     *     <thead><th>parameter</th><th>Mandatory/Optional</th><th>description</th></thead>
-     *     <tbody>
-     *         <tr><td>string</td><td>Mandatory</td><td>String to perform substring on</td></tr>
-     *         <tr><td>result</td><td>Mandatory</td><td>Key in context memory to populate the resulting string in</td></tr>
-     *         <tr><td>begin-index</td><td>Mandatory</td><td>Beginning index to pass to Java substring function</td></tr>
-     *         <tr><td>end-index</td><td>Optional</td><td>Ending index to pass to Java substring function. If not included, String.substring(begin) will be called.</td></tr>
-     *     </tbody>
+     *  <thead><th>parameter</th><th>Mandatory/Optional</th><th>description</th></thead>
+     *  <tbody>
+     *      <tr><td>prefix</td><td>Optional</td><td>the prefix will be added to each parameter</td></tr>
+     *  </tbody>
      * </table>
      * @param ctx Reference to context memory
      * @throws SvcLogicException
-     * @since 8.0.1
+     * @since 11.0.2
      */
-    public void substring( Map<String, String> parameters, SvcLogicContext ctx ) throws SvcLogicException {
+	public static void requiredParameters(Map<String, String> parameters, SvcLogicContext ctx) throws SvcLogicException {
+		if (parameters == null || parameters.keySet().size() < 1) {
+            String errorMessage = "requiredParameters should not be called if the parameters hashmap is null or empty!";
+            LOG.error(errorMessage);
+            throw new SvcLogicException(errorMessage);
+		}
+		String prefixValue = null;
+		String prefix = "prefix";
+		if(parameters.containsKey(prefix)){
+		    prefixValue = parameters.get(prefix);
+		    parameters.remove(prefix);
+		}
+		checkParameters(prefixValue, ctx.getAttributeKeySet(), parameters.keySet(), LOG);
+	}
+
+    private static void checkParameters(String prefixValue, Set<String> ctx, Set<String> parameters, Logger log) throws SvcLogicException {
+        for (String param : parameters) {
+            if (prefixValue != null) {
+                param = prefixValue + param;
+            }
+            if (!ctx.contains(param)) {
+                String errorMessage = "This method requires the parameters [" + StringUtils.join(parameters, ",")
+                        + "], but " + param + " was not passed in.";
+                log.error(errorMessage);
+                throw new SvcLogicException(errorMessage);
+            }
+        }
+    }
+
+    /**
+     *  is in a different DG invocation just before/after we call NCS and set the state to InProgress
+     */
+    /**
+    * setTime write the current date time to a string located at outputPath
+    * @param parameters - requires outputPath to not be null
+    * @param ctx Reference to context memory
+    * @throws SvcLogicException if a required parameter is missing an exception is thrown
+    */
+    public static void setTime(Map<String, String> parameters, SvcLogicContext ctx) throws SvcLogicException
+    {
+        checkParameters(parameters, new String[] { "outputPath" }, LOG);
+
+        // Set the DateFormat
+        // "2015-03-16T12:18:35.138Z"
+        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
+
+        // Parse the date
+        String ctxVariable = parameters.get("outputPath");
         try {
-            checkParameters( parameters, new String[]{"string","begin-index","result"}, LOG );
-            final String string = parameters.get("string");
-            final String result = parameters.get("result");
-            final String begin = parameters.get("begin-index");
-            final String end = parameters.get("end-index");
-
-            if( StringUtils.isEmpty(end) ) {
-                ctx.setAttribute( result, string.substring(Integer.parseInt(begin)) );
-            }
-            else {
-                ctx.setAttribute( result, string.substring(Integer.parseInt(begin), Integer.parseInt(end)) );
-            }
-        }
-        catch( Exception e ) {
-            throw new SvcLogicException( "An error occurred while the Directed Graph was performing a substring", e );
-        }
-    }
-
-
-
-    // ========== PUBLIC STATIC UTILITY FUNCTIONS ==========
-
-    /**
-     * Throws an exception and writes an error to the log file if a required
-     * parameters is not found in the parametersMap.
-     * <p>
-     * Use at the beginning of functions that can be called by Directed Graphs
-     * and can take parameters to verify that all parameters have been provided
-     * by the Directed Graph.
-     * @param parametersMap parameters Map passed to this node
-     * @param requiredParams Array of parameters required by the calling function
-     * @param log Reference to Logger to log to
-     * @throws SvcLogicException if a String in the requiredParams array is
-     * not a key in parametersMap.
-     * @since 1.0
-     */
-    public static final void checkParameters( Map<String,String> parametersMap, String[] requiredParams, Logger log ) throws SvcLogicException {
-        for( String param : requiredParams ) {
-            if( !parametersMap.containsKey(param) ) {
-                log.error("Required parameter \"" + param + "\" was not found in parameter list.");
-                throw new SvcLogicException("Required parameter \"" + param + "\" was not found in parameter list");
-            }
-        }
-    }
-
-    /**
-     * Removes all key-value pairs with keys that begin with pfx
-     * @param ctx Reference to context memory
-     * @param pfx Prefix of key-value pairs to remove
-     * @since 1.0
-     */
-    public static final void ctxBulkErase( SvcLogicContext ctx, String pfx ) {
-        ArrayList<String> Keys = new ArrayList<>( ctx.getAttributeKeySet() );
-        for( String key : Keys ) {
-            if( key.startsWith( pfx ) ) {
-                ctx.setAttribute( pfx + key.substring(pfx.length()) , null);
-            }
-        }
-    }
-
-    /**
-     * Copies all context memory key-value pairs that start with src_pfx to
-     * the keys that start with dest_pfx + suffix, where suffix is the result
-     * of {@code key.substring(src_pfx.length())}.
-     * <p>
-     * Does NOT guarantee removal of all keys at the destination before
-     * copying, but will overwrite any destination keys that have a
-     * corresponding source key. Use {@link #ctxBulkErase(SvcLogicContext, String) ctxBulkErase}
-     * before copy to erase destination root before copying from source.
-     * @param ctx Reference to context memory.
-     * @param src_pfx Prefix of the keys to copy values from.
-     * @param dest_pfx Prefix of the keys to copy values to.
-     * @since 1.0
-     */
-    public static final void ctxBulkCopy( SvcLogicContext ctx, String src_pfx, String dest_pfx ) {
-        // Remove trailing period from dest_pfx
-        if( dest_pfx.charAt(dest_pfx.length()-1) == '.' ) {
-            dest_pfx = dest_pfx.substring(0,dest_pfx.length()-1);
-        }
-
-        // For each context key that begins with src_pfx, set the value of the
-        // key dest_pfx + the suffix of the key to the key's value
-        ArrayList<String> Keys = new ArrayList<>(ctx.getAttributeKeySet());
-        for( String key : Keys ) {
-            if( key.startsWith(src_pfx) ) {
-                // Get suffix (no leading period)
-                String suffix = key.substring(src_pfx.length());
-                if( suffix.charAt(0) == '.') {
-                    suffix = suffix.substring(1);
-                }
-
-                // Set destination's value to key's value
-                ctx.setAttribute(dest_pfx + '.' + suffix, ctx.getAttribute(key));
-            }
-        }
-    }
-
-    /**
-     * Creates and returns a {@code Map<String, String>} that is a subset of
-     * context memory where all keys begin with the prefix.
-     * @param ctx Reference to context memory.
-     * @param prefix Returned map's keys should all begin with this value.
-     * @return A {@code Map<String, String>} containing all the key-value pairs
-     * in ctx whose key begins with prefix.
-     */
-    public static final Map<String, String> ctxGetBeginsWith( SvcLogicContext ctx, String prefix ) {
-        Map<String, String> prefixMap = new HashMap<>();
-
-        for( String key : ctx.getAttributeKeySet() ) {
-            if( key.startsWith(prefix) ) {
-                prefixMap.put( key, ctx.getAttribute(key) );
-            }
-        }
-
-        return prefixMap;
-    }
-
-    /**
-     * Returns true if key's value in context memory is "" or if it doesn't
-     * exist in context memory.
-     * @param ctx Reference to context memory.
-     * @param key Key to search for.
-     * @return true if key's value in context memory is "" or if it doesn't
-     * exist in context memory.
-     * @since 1.0
-     */
-    public static final boolean ctxKeyEmpty( SvcLogicContext ctx, String key ) {
-        String value = ctx.getAttribute(key);
-        return value == null || value.isEmpty();
-    }
-
-    /**
-     * Adds all key-value pairs in the entries Map to context memory.
-     * @param ctx Reference to context memory. Value's {@code toString()}
-     * function is used to add it.
-     * @param entries {@code Map<String, ?>} of key-value pairs to add to
-     * context memory. Value's {@code toString()} function is used to add it.
-     * @return Reference to context memory to be used for function chaining.
-     */
-    public static final SvcLogicContext ctxPutAll( SvcLogicContext ctx, Map<String, ?> entries ) {
-        for( Map.Entry<String, ?> entry : entries.entrySet() ) {
-            ctxSetAttribute( ctx, entry.getKey(), entry.getValue() );
-            //ctx.setAttribute(entry.getKey(), entry.getValue().toString());
-        }
-
-        return ctx;
-    }
-
-    /**
-     * Sets a key in context memory to the output of object's toString(). The
-     * key is deleted from context memory if object is null.
-     * @param ctx Reference to context memory.
-     * @param key Key to set.
-     * @param object Object whose toString() will be the value set
-     */
-    public static final void ctxSetAttribute( SvcLogicContext ctx, String key, Object object ) {
-        if( object == null ) {
-            ctx.setAttribute(key, null);
-        }
-        else {
-            ctx.setAttribute(key, object.toString());
-        }
-    }
-
-    /**
-     * Sets a key in context memory to the output of object's toString().
-     * <p>
-     * The key is deleted from context memory if object is null. The key and
-     * value set in context memory are logged to the Logger at the provided
-     * logLevel level.
-     * @param <O> Any Java object
-     * @param ctx Reference to context memory.
-     * @param key Key to set.
-     * @param obj Object whose toString() will be the value set
-     * @param LOG Logger to log to
-     * @param logLevel level to log at in Logger
-     */
-    public static final <O extends Object> void ctxSetAttribute( SvcLogicContext ctx, String key, O obj, Logger LOG, LogLevel logLevel ) {
-        String value = Objects.toString( obj, null );
-        ctx.setAttribute( key, value );
-        if( logLevelIsEnabled(LOG, logLevel ) ) {
-            if( value == null ) {
-                logMessageAtLevel( LOG, logLevel, "Deleting " + key );
-            }
-            else {
-                logMessageAtLevel( LOG, logLevel, "Setting " + key + " = " + value );
-            }
-        }
-    }
-
-    /**
-     * Utility function used to get an array's length from context memory.
-     * Will return 0 if key doesn't exist in context memory or isn't numeric.
-     * <p>
-     * Use to obtain a context memory array length without having to worry
-     * about throwing a NumberFormatException.
-     * @param ctx Reference to context memory
-     * @param key Key in context memory whose value is the array's length. If
-     * the key doesn't end in "_length", then "_length is appended.
-     * @param log Reference to Logger to log to
-     * @return The array length or 0 if the key is not found in context memory.
-     * @since 1.0
-     */
-    public static final int getArrayLength( SvcLogicContext ctx, String key ) {
-        return getArrayLength(ctx, key, null, null, null);
-    }
-
-    /**
-     * Utility function used to get an array's length from context memory.
-     * Will return 0 if key doesn't exist in context memory or isn't numeric
-     * and print the provided log message to the configured log file.
-     * <p>
-     * Use to obtain a context memory array length without having to worry
-     * about throwing a NumberFormatException.
-     * @param ctx Reference to context memory.
-     * @param key Key in context memory whose value is the array's length. If
-     * the key doesn't end in "_length", then "_length is appended.
-     * @param log Reference to Logger to log to. Doesn't log if null.
-     * @param logLevel Logging level to log the message at if the context
-     * memory key isn't found. Doesn't log if null.
-     * @param log_message Message to log if the context memory key isn't found.
-     * Doesn't log if null.
-     * @return The array length or 0 if the key is not found in context memory.
-     * @since 1.0
-     */
-    public static final int getArrayLength( SvcLogicContext ctx, String key, Logger log, LogLevel logLevel, String log_message ) {
-        String ctxKey = key.endsWith("_length") ? key : key + "_length";
-        try {
-            return Integer.parseInt(ctx.getAttribute(ctxKey));
-        }
-        catch( NumberFormatException e ) {
-            if( log != null && logLevel != null && log_message != null ) {
-                switch( logLevel ) {
-                    case TRACE:
-                        log.trace(log_message);
-                    case DEBUG:
-                        log.debug(log_message);
-                        break;
-                    case INFO:
-                        log.info(log_message);
-                        break;
-                    case WARN:
-                        log.warn(log_message);
-                        break;
-                    case ERROR:
-                        log.error(log_message);
-                        break;
-                }
-            }
-        }
-
-        return 0;
-    }
-
-    /**
-     * Prints sorted context memory key-value pairs to the log file at the log
-     * level. Returns immediately if the log level isn't enabled.
-     * <p>
-     * O(n log(n)) time where n = size of context memory
-     * @param ctx Reference to context memory
-     * @param log Reference to Logger to log to
-     * @param logLevel Logging level to log the context memory key-value pairs
-     * at.
-     * @since 1.0
-     */
-    public static final void logContextMemory( SvcLogicContext ctx, Logger log, LogLevel logLevel ) {
-        logLevelIsEnabled( log, logLevel );
-
-        // Print sorted context memory key-value pairs to the log
-        ArrayList<String> keys = new ArrayList<>(ctx.getAttributeKeySet());
-        Collections.sort(keys);
-        for( String key : keys ) {
-            logMessageAtLevel( log, logLevel, key + " = " + ctx.getAttribute(key) );
-        }
-    }
-
-
-
-    // ========== PRIVATE FUNCTIONS ==========
-
-    // TODO: javadoc
-    /**
-     *
-     * @param parameters
-     * @param log
-     * @param loglevel
-     * @since 7.0.1
-     */
-    public static final void logExecuteNodeParameters( Map<String,String> parameters, Logger log, LogLevel loglevel ) {
-        logLevelIsEnabled( log, loglevel );
-
-        for( Map.Entry<String,String> param : parameters.entrySet() ) {
-            logMessageAtLevel( log, loglevel, "PARAM: " + param.getKey() + " = " + param.getValue() );
-        }
-    }
-
-    // TODO: javadoc
-    /**
-     * Returns true if the loglevel is enabled. Otherwise, returns false.
-     * @param log Reference to logger
-     * @param loglevel Log level to check if enabled
-     * @return True if the loglevel is enabled. Otherwise, false
-     * @since 7.0.1
-     */
-    private static final boolean logLevelIsEnabled( Logger log, LogLevel loglevel ) {
-        // Return immediately if logging level isn't enabled
-        switch( loglevel ) {
-            case TRACE:
-                if( log.isTraceEnabled() ) { return true; }
-                return false;
-            case DEBUG:
-                if( log.isDebugEnabled() ) { return true; }
-                return false;
-            case INFO:
-                if( log.isInfoEnabled() ) { return true; }
-                return false;
-            case WARN:
-                if( log.isWarnEnabled() ) { return true; }
-                return false;
-            case ERROR:
-                if( log.isErrorEnabled() ) { return true; }
-                return false;
-            default:
-                throw new IllegalArgumentException("Unknown LogLevel: " + loglevel.toString());
-        }
-    }
-
-    // TODO: javadoc
-    /**
-     *
-     * @param log
-     * @param loglevel
-     * @param msg
-     * @since 7.0.1
-     */
-    private static final void logMessageAtLevel( Logger log, LogLevel loglevel, String msg ) {
-        switch( loglevel ) {
-            case TRACE:
-                log.trace(msg);
-                return;
-            case DEBUG:
-                log.debug(msg);
-                return;
-            case INFO:
-                log.info(msg);
-                return;
-            case WARN:
-                log.warn(msg);
-                return;
-            case ERROR:
-                log.error(msg);
-                return;
-        }
-    }
-
-
-
-    // ========== LOCAL CLASSES ==========
-
-    private class SortableCtxListElement implements Comparable<SortableCtxListElement> {
-        HashMap<String,String> child_elements = new HashMap<>();
-        String[] sort_fields;
-
-        public SortableCtxListElement( SvcLogicContext ctx, String root, String[] sort_fields ) {
-            this.sort_fields = sort_fields;
-
-            for( String key : ctx.getAttributeKeySet() ) {
-                if( key.startsWith(root) ) {
-                    if( key.length() == root.length() ) {
-                        child_elements.put("", ctx.getAttribute(key));
-                        break;
-                    }
-                    else {
-                        child_elements.put(key.substring(root.length()+1), ctx.getAttribute(key));
-                    }
-                }
-            }
-        }
-
-        @Override
-        public int compareTo(SortableCtxListElement arg0) {
-            if( sort_fields == null ) {
-                return this.child_elements.get("").compareTo(arg0.child_elements.get(""));
-            }
-
-            for( String field : this.sort_fields ) {
-                int result = this.child_elements.get(field).compareTo(arg0.child_elements.get(field));
-                if( result != 0 ) {
-                    return result;
-                }
-            }
-
-            return 0;
+            String dateTime = format.format(new Date());
+            ctx.setAttribute(ctxVariable, dateTime);
+        } catch (Exception ex) {
+            throw new SvcLogicException("problem with setTime", ex);
         }
     }
 }
diff --git a/sliPluginUtils/provider/src/main/java/org/openecomp/sdnc/sli/SliPluginUtils/SliPluginUtilsActivator.java b/sliPluginUtils/provider/src/main/java/org/openecomp/sdnc/sli/SliPluginUtils/SliPluginUtilsActivator.java
index 27addba..e0568ab 100644
--- a/sliPluginUtils/provider/src/main/java/org/openecomp/sdnc/sli/SliPluginUtils/SliPluginUtilsActivator.java
+++ b/sliPluginUtils/provider/src/main/java/org/openecomp/sdnc/sli/SliPluginUtils/SliPluginUtilsActivator.java
@@ -21,7 +21,10 @@
 
 package org.openecomp.sdnc.sli.SliPluginUtils;
 
-
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileReader;
+import java.io.IOException;
 import java.util.LinkedList;
 import java.util.List;
 import java.util.Properties;
@@ -32,55 +35,59 @@
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-
 public class SliPluginUtilsActivator implements BundleActivator {
-
-//    private static final String SLIPLUGINUTILS_PROP_VAR = "/slipluginutils.properties";
-//    private static final String SDNC_CONFIG_DIR = "SDNC_CONFIG_DIR";
-
-    @SuppressWarnings("rawtypes")
-    private final List<ServiceRegistration> registrations = new LinkedList<>();
+    @SuppressWarnings("rawtypes") private List<ServiceRegistration> registrations = new LinkedList<ServiceRegistration>();
 
     private static final Logger LOG = LoggerFactory.getLogger(SliPluginUtilsActivator.class);
+    private static final String SDNC_ROOT_DIR = "SDNC_CONFIG_DIR";
+    private static final String DME2_PROPERTIES_FILE_NAME = "dme2.properties";
 
     @Override
     public void start(BundleContext ctx) throws Exception {
-        // Read properties
-        Properties props = new Properties();
+        SliPluginUtils plugin = new SliPluginUtils(new Properties());
+        LOG.info("Registering service " + plugin.getClass().getName());
+        registrations.add(ctx.registerService(plugin.getClass().getName(), plugin, null));
 
-        // ---uncomment below when adding properties file---
-        /*
-        String propDir = System.getenv(SDNC_CONFIG_DIR);
-        if (propDir == null) {
-            throw new ConfigurationException(
-            "Cannot find config file - " + SLIPLUGINUTILS_PROP_VAR + " and " + SDNC_CONFIG_DIR + " unset");
-        }
-        String propPath = propDir + SLIPLUGINUTILS_PROP_VAR;
-
-        File propFile = new File(propPath);
-
-        if (!propFile.exists()) {
-            throw new ConfigurationException("Missing configuration properties file : " + propFile);
-        }
+        SliStringUtils sliStringUtils_Plugin = new SliStringUtils();
+        LOG.info("Registering service " + sliStringUtils_Plugin.getClass().getName());
+        registrations.add(ctx.registerService(sliStringUtils_Plugin.getClass().getName(), sliStringUtils_Plugin, null));
 
         try {
-            props.load(new FileInputStream(propFile));
+            String path = System.getenv(SDNC_ROOT_DIR) + File.separator + DME2_PROPERTIES_FILE_NAME;
+            DME2 dmePlugin = initDme2(path);
+            if (dmePlugin != null) {
+                LOG.info("Registering service " + dmePlugin.getClass().getName());
+                registrations.add(ctx.registerService(dmePlugin.getClass().getName(), dmePlugin, null));
+            }
         } catch (Exception e) {
-            throw new ConfigurationException("Could not load properties file " + propPath, e);
+            LOG.error("DME2 plugin could not be started", e);
         }
-        */
+    }
 
-        SliPluginUtils plugin = new SliPluginUtils(props);
+    public DME2 initDme2(String pathToDmeProperties) {
+        Properties dme2properties = new Properties();
+        String loadPropertiesErrorMessage = "Couldn't load DME2 properties at path " + pathToDmeProperties;
+        File dme2propertiesFile = new File(pathToDmeProperties);
 
-        LOG.info("Registering service "+plugin.getClass().getName());
-        registrations.add(ctx.registerService(plugin.getClass().getName(), plugin, null));
+        try {
+            dme2properties.load(new FileReader(dme2propertiesFile));
+            String proxyUrlProperty = dme2properties.getProperty("proxyUrl");
+            String[] proxyUrls = proxyUrlProperty.split(",");
+            DME2 dmePlugin = new DME2(dme2properties.getProperty("aafUserName"), dme2properties.getProperty("aafPassword"), dme2properties.getProperty("envContext"), dme2properties.getProperty("routeOffer"), proxyUrls, dme2properties.getProperty("commonServiceVersion"));
+            dmePlugin.setPartner(dme2properties.getProperty("partner"));
+            return dmePlugin;
+        } catch (FileNotFoundException e) {
+            LOG.error(loadPropertiesErrorMessage);
+        } catch (IOException e) {
+            LOG.error(loadPropertiesErrorMessage);
+        }
+        LOG.error("Couldn't create DME2 plugin");
+        return null;
     }
 
     @Override
     public void stop(BundleContext ctx) throws Exception {
-
-        for (@SuppressWarnings("rawtypes") ServiceRegistration registration: registrations)
-        {
+        for (@SuppressWarnings("rawtypes") ServiceRegistration registration : registrations) {
             registration.unregister();
             registration = null;
         }
diff --git a/sliPluginUtils/provider/src/main/java/org/openecomp/sdnc/sli/SliPluginUtils/SliStringUtils.java b/sliPluginUtils/provider/src/main/java/org/openecomp/sdnc/sli/SliPluginUtils/SliStringUtils.java
new file mode 100644
index 0000000..43af6f5
--- /dev/null
+++ b/sliPluginUtils/provider/src/main/java/org/openecomp/sdnc/sli/SliPluginUtils/SliStringUtils.java
@@ -0,0 +1,396 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * openECOMP : SDN-C
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights
+ * 						reserved.
+ * ================================================================================
+ * Licensed 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.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.sdnc.sli.SliPluginUtils;
+
+import java.io.UnsupportedEncodingException;
+import java.net.URLEncoder;
+import java.util.Map;
+
+import org.apache.commons.lang3.StringUtils;
+import org.openecomp.sdnc.sli.SvcLogicContext;
+import org.openecomp.sdnc.sli.SvcLogicException;
+import org.openecomp.sdnc.sli.SvcLogicJavaPlugin;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * A SvcLogicJavaPlugin that exposes java.lang.String functions to DirectedGraph
+ */
+public class SliStringUtils implements SvcLogicJavaPlugin {
+	private static final Logger LOG = LoggerFactory.getLogger(SliStringUtils.class);
+
+	public SliStringUtils() {}
+
+	/**
+	 * Provides split functionality to Directed Graphs.
+	 * @param parameters HashMap<String,String> of parameters passed by the DG to this function
+	 * <table border="1">
+	 * 	<thead><th>parameter</th><th>Mandatory/Optional</th><th>description</th></thead>
+	 * 	<tbody>
+	 * 		<tr><td>original_string</td><td>Mandatory</td><td>String to perform split on</td></tr>
+	 * 		<tr><td>regex</td><td>Mandatory</td><td>the delimiting regular expression</td></tr>
+	 * 		<tr><td>limit</td><td>Optional</td><td>result threshold. See String.split method for further description. Defaults to 0</td></tr>
+	 * 		<tr><td>ctx_memory_result_key</td><td>Mandatory</td><td>Key in context memory to populate the resulting array of strings under</td></tr>
+	 * 	</tbody>
+	 * </table>
+	 * @param ctx Reference to context memory
+	 * @throws SvcLogicException
+	 * @since 11.0.2
+	 * @see String#split(String, int)
+	 */
+	public void split( Map<String, String> parameters, SvcLogicContext ctx ) throws SvcLogicException {
+		final String original_string = parameters.get("original_string");
+		LOG.trace("original_string = " + original_string);
+		final String regex = parameters.get("regex");
+		LOG.trace("regex = " + regex);
+		final String limit_str = parameters.get("limit");
+		LOG.trace("limit_str = " + limit_str);
+		final String ctx_memory_result_key = parameters.get("ctx_memory_result_key");
+		LOG.trace("ctx_memory_result_key = " + ctx_memory_result_key);
+
+		try {
+			// Validation that parameters are not null
+			SliPluginUtils.checkParameters( parameters, new String[]{"original_string","regex","ctx_memory_result_key"}, LOG );
+
+			// Read limit from context memory. Default to 0 if null/empty
+			int limit = 0;
+			if( StringUtils.isNotEmpty(limit_str) ) {
+				try {
+					limit = Integer.parseInt(limit_str);
+				}
+				catch( NumberFormatException e ) {
+					throw new IllegalArgumentException( "The limit parameter of the SliStringUtils.split() function must be a number, empty string, or null", e );
+				}
+			}
+
+			// Call String.split(regex,limit) on string passed in
+			String[] split_string = original_string.split(regex, limit);
+
+			// Populate context memory with results
+			for( int i = 0; i < split_string.length; i++ ) {
+				SliPluginUtils.ctxSetAttribute(ctx, ctx_memory_result_key + '[' + i + ']', split_string[i], LOG, SliPluginUtils.LogLevel.DEBUG);
+			}
+			SliPluginUtils.ctxSetAttribute(ctx, ctx_memory_result_key + "_length", new Integer(split_string.length), LOG, SliPluginUtils.LogLevel.DEBUG);
+		}
+		catch( Exception e ) {
+			// Have error message print parameters
+			throw new SvcLogicException( "An error occurred during SliStringUtils.split() where original_string = " + quotedOrNULL(regex) +
+					" regex = " + quotedOrNULL(regex) +
+					" limit = " + quotedOrNULL(regex) +
+					" ctx_memory_result_key = " + quotedOrNULL(regex), e );
+		}
+	}
+
+	private static String quotedOrNULL( String str ) {
+		return (str == null) ? "NULL" : '"' + str + '"';
+	}
+
+    /**
+     * exposes equalsIgnoreCase to directed graph
+     * @param parameters HashMap<String,String> of parameters passed by the DG to this function
+     * emits a true or false outcome
+     * <table border="1">
+     *  <thead><th>parameter</th><th>Mandatory/Optional</th><th>description</th></thead>
+     *  <tbody>
+     *      <tr><td>source</td><td>Mandatory</td><td>source string</td></tr>
+     *      <tr><td>target</td><td>Mandatory</td><td>target string</td></tr>
+     *  </tbody>
+     * </table>
+     * @param ctx Reference to context memory
+     * @throws SvcLogicException
+     * @since 11.0.2
+     */
+    public static String equalsIgnoreCase(Map<String, String> parameters, SvcLogicContext ctx) throws SvcLogicException {
+        SliPluginUtils.checkParameters(parameters, new String[]{"source","target"}, LOG);
+        if(parameters.get("source").equalsIgnoreCase(parameters.get("target"))){
+            return "true";
+        }
+        return "false";
+    }
+
+    /**
+     * exposes toUpperCase to directed graph
+     * writes an upperCase version of source to outputPath
+     * @param parameters HashMap<String,String> of parameters passed by the DG to this function
+     * <table border="1">
+     *  <thead><th>parameter</th><th>Mandatory/Optional</th><th>description</th></thead>
+     *  <tbody>
+     *      <tr><td>source</td><td>Mandatory</td><td>source string</td></tr>
+     *      <tr><td>outputPath</td><td>Mandatory</td><td>the location in context memory the result is written to</td></tr>
+     *  </tbody>
+     * </table>
+     * @param ctx Reference to context memory
+     * @throws SvcLogicException
+     * @since 11.0.2
+     */
+    public static void toUpper(Map<String, String> parameters, SvcLogicContext ctx) throws SvcLogicException {
+        SliPluginUtils.checkParameters(parameters, new String[]{"source","outputPath"}, LOG);
+        ctx.setAttribute(parameters.get("outputPath"), parameters.get("source").toUpperCase());
+    }
+
+    /**
+     * exposes toLowerCase to directed graph
+     * writes a lowerCase version of source to outputPath
+     * @param parameters HashMap<String,String> of parameters passed by the DG to this function
+     * <table border="1">
+     *  <thead><th>parameter</th><th>Mandatory/Optional</th><th>description</th></thead>
+     *  <tbody>
+     *      <tr><td>source</td><td>Mandatory</td><td>source string</td></tr>
+     *      <tr><td>outputPath</td><td>Mandatory</td><td>the location in context memory the result is written to</td></tr>
+     *  </tbody>
+     * </table>
+     * @param ctx Reference to context memory
+     * @throws SvcLogicException
+     * @since 11.0.2
+     */
+    public static void toLower(Map<String, String> parameters, SvcLogicContext ctx) throws SvcLogicException {
+        SliPluginUtils.checkParameters(parameters, new String[]{"source","outputPath"}, LOG);
+        ctx.setAttribute(parameters.get("outputPath"), parameters.get("source").toLowerCase());
+    }
+
+    /**
+     * exposes contains to directed graph to test if one string contains another
+     * tests if the source contains the target
+     * @param parameters HashMap<String,String> of parameters passed by the DG to this function
+     * emits a true or false outcome
+     * <table border="1">
+     *  <thead><th>parameter</th><th>Mandatory/Optional</th><th>description</th></thead>
+     *  <tbody>
+     *      <tr><td>source</td><td>Mandatory</td><td>source string</td></tr>
+     *      <tr><td>target</td><td>Mandatory</td><td>target string</td></tr>
+     *  </tbody>
+     * </table>
+     * @param ctx Reference to context memory
+     * @throws SvcLogicException
+     * @since 11.0.2
+     */
+    public static String contains(Map<String, String> parameters, SvcLogicContext ctx) throws SvcLogicException {
+        SliPluginUtils.checkParameters(parameters, new String[]{"source","target"}, LOG);
+        if(parameters.get("source").contains(parameters.get("target"))){
+            return "true";
+        }
+        return "false";
+    }
+
+    /**
+     * exposes endsWith to directed graph to test if one string endsWith another string
+     * tests if the source ends with the target
+     * @param parameters HashMap<String,String> of parameters passed by the DG to this function
+     * emits a true or false outcome
+     * <table border="1">
+     *  <thead><th>parameter</th><th>Mandatory/Optional</th><th>description</th></thead>
+     *  <tbody>
+     *      <tr><td>source</td><td>Mandatory</td><td>source string</td></tr>
+     *      <tr><td>target</td><td>Mandatory</td><td>target string</td></tr>
+     *  </tbody>
+     * </table>
+     * @param ctx Reference to context memory
+     * @throws SvcLogicException
+     * @since 11.0.2
+     */
+    public static String endsWith(Map<String, String> parameters, SvcLogicContext ctx) throws SvcLogicException {
+        SliPluginUtils.checkParameters(parameters, new String[]{"source","target"}, LOG);
+        if(parameters.get("source").endsWith(parameters.get("target"))){
+            return "true";
+        }
+        return "false";
+    }
+
+    /**
+     * exposes startsWith to directed graph to test if one string endsWith another string
+     * tests if the source ends with the target
+     * @param parameters HashMap<String,String> of parameters passed by the DG to this function
+     * emits a true or false outcome
+     * <table border="1">
+     *  <thead><th>parameter</th><th>Mandatory/Optional</th><th>description</th></thead>
+     *  <tbody>
+     *      <tr><td>source</td><td>Mandatory</td><td>source string</td></tr>
+     *      <tr><td>target</td><td>Mandatory</td><td>target string</td></tr>
+     *  </tbody>
+     * </table>
+     * @param ctx Reference to context memory
+     * @throws SvcLogicException
+     * @since 11.0.2
+     */
+    public static String startsWith(Map<String, String> parameters, SvcLogicContext ctx) throws SvcLogicException {
+        SliPluginUtils.checkParameters(parameters, new String[]{"source","target"}, LOG);
+        if(parameters.get("source").startsWith(parameters.get("target"))){
+            return "true";
+        }
+        return "false";
+    }
+
+    /**
+     * exposes trim to directed graph
+     * writes a trimmed version of the string to the outputPath
+     * @param parameters HashMap<String,String> of parameters passed by the DG to this function
+     * <table border="1">
+     *  <thead><th>parameter</th><th>Mandatory/Optional</th><th>description</th></thead>
+     *  <tbody>
+     *      <tr><td>source</td><td>Mandatory</td><td>source string</td></tr>
+     *      <tr><td>outputPath</td><td>Mandatory</td><td>the location in context memory the result is written to</td></tr>
+     *  </tbody>
+     * </table>
+     * @param ctx Reference to context memory
+     * @throws SvcLogicException
+     * @since 11.0.2
+     */
+    public static void trim(Map<String, String> parameters, SvcLogicContext ctx) throws SvcLogicException {
+        SliPluginUtils.checkParameters(parameters, new String[]{"source","outputPath"}, LOG);
+        ctx.setAttribute(parameters.get("outputPath"), parameters.get("source").trim());
+    }
+
+    /**
+     * exposes String.length() to directed graph
+     * writes the length of source to outputPath
+     * @param parameters HashMap<String,String> of parameters passed by the DG to this function
+     * <table border="1">
+     *  <thead><th>parameter</th><th>Mandatory/Optional</th><th>description</th></thead>
+     *  <tbody>
+     *      <tr><td>source</td><td>Mandatory</td><td>source string</td></tr>
+     *      <tr><td>outputPath</td><td>Mandatory</td><td>the location in context memory the result is written to</td></tr>
+     *  </tbody>
+     * </table>
+     * @param ctx Reference to context memory
+     * @throws SvcLogicException
+     * @since 11.0.2
+     */
+    public static void getLength(Map<String, String> parameters, SvcLogicContext ctx) throws SvcLogicException {
+        SliPluginUtils.checkParameters(parameters, new String[]{"source","outputPath"}, LOG);
+        ctx.setAttribute(parameters.get("outputPath"), String.valueOf(parameters.get("source").length()));
+    }
+
+    /**
+     * exposes replace to directed graph
+     * writes the length of source to outputPath
+     * @param parameters HashMap<String,String> of parameters passed by the DG to this function
+     * <table border="1">
+     *  <thead><th>parameter</th><th>Mandatory/Optional</th><th>description</th></thead>
+     *  <tbody>
+     *      <tr><td>source</td><td>Mandatory</td><td>source string</td></tr>
+     *      <tr><td>target</td><td>Mandatory</td><td>The sequence of char values to be replaced</td></tr>
+     *      <tr><td>replacement</td><td>Mandatory</td><td>The replacement sequence of char values</td></tr>
+     *      <tr><td>outputPath</td><td>Mandatory</td><td>the location in context memory the result is written to</td></tr>
+     *  </tbody>
+     * </table>
+     * @param ctx Reference to context memory
+     * @throws SvcLogicException
+     * @since 11.0.2
+     */
+    public static void replace(Map<String, String> parameters, SvcLogicContext ctx) throws SvcLogicException {
+        SliPluginUtils.checkParameters(parameters, new String[]{"source","outputPath","target","replacement"}, LOG);
+        ctx.setAttribute(parameters.get("outputPath"), (parameters.get("source").replace(parameters.get("target"), parameters.get("replacement"))));
+    }
+
+    /**
+     * Provides substring functionality to Directed Graphs.
+     * <p>
+     * Calls either String.substring(String beginIndex) or
+     * String.substring(String beginInded, String endIndex) if the end-index
+     * is present or not.
+     * @param parameters HashMap<String,String> of parameters passed by the DG to this function
+     * <table border="1">
+     *  <thead><th>parameter</th><th>Mandatory/Optional</th><th>description</th></thead>
+     *  <tbody>
+     *      <tr><td>string</td><td>Mandatory</td><td>String to perform substring on</td></tr>
+     *      <tr><td>result</td><td>Mandatory</td><td>Key in context memory to populate the resulting string in</td></tr>
+     *      <tr><td>begin-index</td><td>Mandatory</td><td>Beginning index to pass to Java substring function</td></tr>
+     *      <tr><td>end-index</td><td>Optional</td><td>Ending index to pass to Java substring function. If not included, String.substring(begin) will be called.</td></tr>
+     *  </tbody>
+     * </table>
+     * @param ctx Reference to context memory
+     * @throws SvcLogicException
+     * @since 11.0.2
+     */
+    public void substring( Map<String, String> parameters, SvcLogicContext ctx ) throws SvcLogicException {
+        try {
+            SliPluginUtils.checkParameters( parameters, new String[]{"string","begin-index","result"}, LOG );
+            final String string = parameters.get("string");
+            final String result = parameters.get("result");
+            final String begin = parameters.get("begin-index");
+            final String end = parameters.get("end-index");
+            if( StringUtils.isEmpty(end) ) {
+                ctx.setAttribute( result, string.substring(Integer.parseInt(begin)) );
+            }
+            else {
+                ctx.setAttribute( result, string.substring(Integer.parseInt(begin), Integer.parseInt(end)) );
+            }
+        }
+        catch( Exception e ) {
+            throw new SvcLogicException( "An error occurred while the Directed Graph was performing a substring", e );
+        }
+    }
+
+    /**
+     * Provides concat functionality to Directed Graphs.
+     * <p>
+     * Will concat target to source and write the result to outputPath
+     * @param parameters HashMap<String,String> of parameters passed by the DG to this function
+     * <table border="1">
+     *  <thead><th>parameter</th><th>Mandatory/Optional</th><th>description</th></thead>
+     *  <tbody>
+     *      <tr><td>source</td><td>Mandatory</td><td>source string</td></tr>
+     *      <tr><td>target</td><td>Mandatory</td><td>The sequence of char values to be replaced</td></tr>
+     *      <tr><td>outputPath</td><td>Mandatory</td><td>the location in context memory the result is written to</td></tr>
+     *  </tbody>
+     * </table>
+     * @param ctx Reference to context memory
+     * @throws SvcLogicException
+     * @since 11.0.2
+     */
+    public static void concat( Map<String, String> parameters, SvcLogicContext ctx ) throws SvcLogicException {
+            SliPluginUtils.checkParameters( parameters, new String[]{"source","target","outputPath"}, LOG );
+            String result = parameters.get("source").concat(parameters.get("target"));
+            ctx.setAttribute(parameters.get("outputPath"), result);
+    }
+
+    /**
+     * Provides url encoding functionality to Directed Graphs.
+     * <p>
+     * Will url encode the source and write the result to outputPath
+     * @param parameters HashMap<String,String> of parameters passed by the DG to this function
+     * <table border="1">
+     *  <thead><th>parameter</th><th>Mandatory/Optional</th><th>description</th></thead>
+     *  <tbody>
+     *      <tr><td>source</td><td>Mandatory</td><td>source string</td></tr>
+     *      <tr><td>encoding</td><td>Optional</td><td>the name of a supported character encoding, defaulted to UTF-8 if not supplied</td></tr>
+     *      <tr><td>outputPath</td><td>Mandatory</td><td>the location in context memory the result is written to</td></tr>
+     *  </tbody>
+     * </table>
+     * @param ctx Reference to context memory
+     * @throws SvcLogicException
+     */
+    public static void urlEncode(Map<String, String> parameters, SvcLogicContext ctx) throws SvcLogicException {
+        SliPluginUtils.checkParameters(parameters, new String[] { "source", "outputPath" }, LOG);
+        String encoding = parameters.get("encoding");
+        if (encoding == null) {
+            encoding = "UTF-8";
+        }
+        try {
+            String result = URLEncoder.encode(parameters.get("source"), encoding);
+            ctx.setAttribute(parameters.get("outputPath"), result);
+        } catch (UnsupportedEncodingException e) {
+            throw new SvcLogicException("Url encode failed.", e);
+        }
+    }
+
+}
diff --git a/sliPluginUtils/provider/src/main/java/org/openecomp/sdnc/sli/SliPluginUtils/SvcLogicContextList.java b/sliPluginUtils/provider/src/main/java/org/openecomp/sdnc/sli/SliPluginUtils/SvcLogicContextList.java
index 22f07f9..89a4a98 100644
--- a/sliPluginUtils/provider/src/main/java/org/openecomp/sdnc/sli/SliPluginUtils/SvcLogicContextList.java
+++ b/sliPluginUtils/provider/src/main/java/org/openecomp/sdnc/sli/SliPluginUtils/SvcLogicContextList.java
@@ -60,14 +60,14 @@
 
         // Initialize list
         int capacity = getCtxListLength(ctx, prefix);
-        this.list = new ArrayList<>( capacity );
+        this.list = new ArrayList<HashMap<String, String>>(capacity);
         for( int i = 0; i < capacity; i++ ) {
             this.list.add(i, new HashMap<String,String>());
         }
 
         // Populate "elements" in list
         String prefix_bracket = this.prefix + '[';
-        for( String key : new HashSet<>(ctx.getAttributeKeySet()) ) {
+        for (String key : new HashSet<String>(ctx.getAttributeKeySet())) {
             if( key.startsWith(prefix_bracket) ) {
                 // Extract the index of the list
                 int index = getCtxListIndex(key, this.prefix, capacity);
@@ -160,8 +160,7 @@
             for( Map.Entry<String,String> entry : this.list.get(i).entrySet() ) {
                 if( entry.getKey().equals("") ) {
                     ctx.setAttribute(prefix + '[' + i + ']', entry.getValue());
-                }
-                else {
+                } else {
                     ctx.setAttribute(prefix + '[' + i + "]." + entry.getKey(), entry.getValue());
                 }
             }
@@ -176,16 +175,9 @@
     private static int getCtxListIndex( String key, String prefix, int list_size ) {
         int index = getCtxListIndex( key, prefix );
         if( index >= list_size ) {
-            throw new IllegalArgumentException(
-                    "Context memory list \"" + prefix + "[]\" contains an index >= the size of the list",
-                    new ArrayIndexOutOfBoundsException( "index \"" + index + "\" is outside the bounds of the context memory list \"" + prefix + "[]. List Length = " + list_size )
-            );
-        }
-        else if( index < 0 ) {
-            throw new IllegalArgumentException(
-                    "Context memory list \"" + prefix + "[]\" contains a negative index",
-                    new NegativeArraySizeException( "index \"" + index + "\" of context memory list is negative" )
-            );
+            throw new IllegalArgumentException("Context memory list \"" + prefix + "[]\" contains an index >= the size of the list", new ArrayIndexOutOfBoundsException("index \"" + index + "\" is outside the bounds of the context memory list \"" + prefix + "[]. List Length = " + list_size));
+        } else if (index < 0) {
+            throw new IllegalArgumentException("Context memory list \"" + prefix + "[]\" contains a negative index", new NegativeArraySizeException("index \"" + index + "\" of context memory list is negative"));
         }
 
         return index;
@@ -196,8 +188,7 @@
         String ctx_index_str = StringUtils.substringBetween(key.substring(prefix.length()), "[", "]");
         try {
             return Integer.parseInt( ctx_index_str );
-        }
-        catch( NumberFormatException e ) {
+        } catch (NumberFormatException e) {
             throw new IllegalStateException("Could not parse index value \"" + ctx_index_str + "\" in context memory key \"" + key + "\"", e);
         }
     }
@@ -208,12 +199,10 @@
         String _length_val_str = ctx.getAttribute(_length_key);
         try {
             return Integer.parseInt(_length_val_str);
-        }
-        catch( NumberFormatException e ) {
+        } catch (NumberFormatException e) {
             if( _length_val_str == null ) {
                 throw new IllegalStateException( "Could not find list length \"" + _length_key + "\" in context memory." );
-            }
-            else {
+            } else {
                 throw new IllegalStateException( "Could not parse index value \"" + _length_val_str + "\" of context memory list length \"" + _length_key + "\"" , e );
             }
         }
diff --git a/sliPluginUtils/provider/src/test/java/org/openecomp/sdnc/sli/SliPluginUtils/CheckParametersTest.java b/sliPluginUtils/provider/src/test/java/org/openecomp/sdnc/sli/SliPluginUtils/CheckParametersTest.java
new file mode 100644
index 0000000..318e464
--- /dev/null
+++ b/sliPluginUtils/provider/src/test/java/org/openecomp/sdnc/sli/SliPluginUtils/CheckParametersTest.java
@@ -0,0 +1,116 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * openECOMP : SDN-C
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights
+ * 						reserved.
+ * ================================================================================
+ * Licensed 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.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.sdnc.sli.SliPluginUtils;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.junit.Test;
+import org.openecomp.sdnc.sli.SvcLogicContext;
+import org.openecomp.sdnc.sli.SvcLogicException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class CheckParametersTest {
+
+    @Test
+    public void nullRequiredParameters() throws Exception {
+        Map<String, String> parametersMap = new HashMap<String, String>();
+        String[] requiredParams = null;
+        Logger Log = LoggerFactory.getLogger(SliPluginUtils.class);
+        SliPluginUtils.checkParameters(parametersMap, requiredParams, Log);
+    }
+
+    @Test(expected = SvcLogicException.class)
+    public void emptyParametersMap() throws Exception {
+        Map<String, String> parametersMap = new HashMap<String, String>();
+        String[] requiredParams = new String[] { "param1", "param2", "param3" };
+        Logger Log = LoggerFactory.getLogger(SliPluginUtils.class);
+        SliPluginUtils.checkParameters(parametersMap, requiredParams, Log);
+    }
+
+    @Test(expected = SvcLogicException.class)
+    public void paramNotFound() throws Exception {
+        Map<String, String> parametersMap = new HashMap<String, String>();
+        parametersMap.put("tst", "me");
+        String[] requiredParams = new String[] { "param1", "parm2", "param3" };
+        Logger Log = LoggerFactory.getLogger(SliPluginUtils.class);
+        SliPluginUtils.checkParameters(parametersMap, requiredParams, Log);
+    }
+
+    @Test
+    public void testSunnyRequiredParameters() throws Exception {
+        SvcLogicContext ctx = new SvcLogicContext();
+        ctx.setAttribute("param1", "hello");
+        ctx.setAttribute("param2", "world");
+        ctx.setAttribute("param3", "!");
+
+        Map<String, String> parameters = new HashMap<String, String>();
+        parameters.put("param1", "dog");
+        parameters.put("param2", "cat");
+        parameters.put("param3", "fish");
+
+        SliPluginUtils.requiredParameters(parameters, ctx);
+    }
+
+    @Test
+    public void testSunnyRequiredParametersWithPrefix() throws Exception {
+        String prefixValue = "my.unique.path.";
+        SvcLogicContext ctx = new SvcLogicContext();
+        ctx.setAttribute(prefixValue + "param1", "hello");
+        ctx.setAttribute(prefixValue + "param2", "world");
+        ctx.setAttribute(prefixValue + "param3", "!");
+
+        Map<String, String> parameters = new HashMap<String, String>();
+        parameters.put("prefix", prefixValue);
+        parameters.put("param1", "dog");
+        parameters.put("param2", "cat");
+        parameters.put("param3", "fish");
+
+        SliPluginUtils.requiredParameters(parameters, ctx);
+    }
+
+    @Test(expected = SvcLogicException.class)
+    public void testRainyMissingRequiredParameters() throws Exception {
+        SvcLogicContext ctx = new SvcLogicContext();
+        ctx.setAttribute("param1", "hello");
+        ctx.setAttribute("param3", "!");
+
+        Map<String, String> parameters = new HashMap<String, String>();
+        parameters.put("param1", null);
+        parameters.put("param2", null);
+        parameters.put("param3", null);
+
+        SliPluginUtils.requiredParameters(parameters, ctx);
+    }
+
+    @Test(expected = SvcLogicException.class)
+    public void testEmptyRequiredParameters() throws Exception {
+        SvcLogicContext ctx = new SvcLogicContext();
+        ctx.setAttribute("param1", "hello");
+        ctx.setAttribute("param3", "!");
+
+        Map<String, String> parameters = new HashMap<String, String>();
+
+        SliPluginUtils.requiredParameters(parameters, ctx);
+    }
+}
diff --git a/sliPluginUtils/provider/src/test/java/org/openecomp/sdnc/sli/SliPluginUtils/Dme2Test.java b/sliPluginUtils/provider/src/test/java/org/openecomp/sdnc/sli/SliPluginUtils/Dme2Test.java
new file mode 100644
index 0000000..d66b011
--- /dev/null
+++ b/sliPluginUtils/provider/src/test/java/org/openecomp/sdnc/sli/SliPluginUtils/Dme2Test.java
@@ -0,0 +1,109 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * openECOMP : SDN-C
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights
+ * 						reserved.
+ * ================================================================================
+ * Licensed 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.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.sdnc.sli.SliPluginUtils;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.junit.Assert;
+import org.junit.Test;
+import org.openecomp.sdnc.sli.SliPluginUtils.DME2;
+import org.openecomp.sdnc.sli.SliPluginUtils.SliPluginUtilsActivator;
+
+public class Dme2Test {
+
+    @Test
+    public void createInstarUrl() {
+        String instarUrl = "http://localhost:25055/service=sample.com/services/eim/v1/rest/version=1702.0/envContext=TEST/routeOffer=DEFAULT/subContext=/enterpriseConnection/getEnterpriseConnectionDetails/v1?dme2.password=fake&dme2.username=user@sample.com";
+        DME2 dme = new DME2("user@sample.com", "fake", "TEST", "DEFAULT", new String[] { "http://localhost:25055" }, "common");
+        String constructedUrl = dme.constructUrl("sample.com/services/eim/v1/rest", "1702.0", "/enterpriseConnection/getEnterpriseConnectionDetails/v1");
+        assertEquals(instarUrl, constructedUrl);
+    }
+
+    @Test
+    public void createInstarUrlNoSubContext() {
+        String instarUrl = "http://localhost:25055/service=sample.com/services/eim/v1/rest/version=1702.0/envContext=TEST/routeOffer=DEFAULT?dme2.password=fake&dme2.username=user@sample.com";
+        DME2 dme = new DME2("user@sample.com", "fake", "TEST", "DEFAULT", new String[] { "http://localhost:25055" }, "common");
+        Map<String, String> parameters = new HashMap<String, String>();
+        String constructedUrl = dme.constructUrl("sample.com/services/eim/v1/rest", "1702.0", parameters.get(null));
+        assertEquals(instarUrl, constructedUrl);
+    }
+
+    @Test
+    public void testRoundRobin() {
+        String[] proxyHostNames = new String[] { "http://one:25055", "http://two:25055", "http://three:25055" };
+        String urlSuffix = "/service=sample.com/services/eim/v1/rest/version=1702.0/envContext=TEST/routeOffer=DEFAULT/subContext=/enterpriseConnection/getEnterpriseConnectionDetails/v1?dme2.password=fake&dme2.username=user@sample.com";
+        DME2 dme = new DME2("user@sample.com", "fake", "TEST", "DEFAULT", proxyHostNames, "common");
+        String constructedUrl = dme.constructUrl("sample.com/services/eim/v1/rest", "1702.0", "/enterpriseConnection/getEnterpriseConnectionDetails/v1");
+        assertEquals(proxyHostNames[0] + urlSuffix, constructedUrl);
+        constructedUrl = dme.constructUrl("sample.com/services/eim/v1/rest", "1702.0", "/enterpriseConnection/getEnterpriseConnectionDetails/v1");
+        assertEquals(proxyHostNames[1] + urlSuffix, constructedUrl);
+        constructedUrl = dme.constructUrl("sample.com/services/eim/v1/rest", "1702.0", "/enterpriseConnection/getEnterpriseConnectionDetails/v1");
+        assertEquals(proxyHostNames[2] + urlSuffix, constructedUrl);
+        constructedUrl = dme.constructUrl("sample.com/services/eim/v1/rest", "1702.0", "/enterpriseConnection/getEnterpriseConnectionDetails/v1");
+        assertEquals(proxyHostNames[0] + urlSuffix, constructedUrl);
+        constructedUrl = dme.constructUrl("sample.com/services/eim/v1/rest", "1702.0", "/enterpriseConnection/getEnterpriseConnectionDetails/v1");
+        assertEquals(proxyHostNames[1] + urlSuffix, constructedUrl);
+        constructedUrl = dme.constructUrl("sample.com/services/eim/v1/rest", "1702.0", "/enterpriseConnection/getEnterpriseConnectionDetails/v1");
+        assertEquals(proxyHostNames[2] + urlSuffix, constructedUrl);
+        constructedUrl = dme.constructUrl("sample.com/services/eim/v1/rest", "1702.0", "/enterpriseConnection/getEnterpriseConnectionDetails/v1");
+        assertEquals(proxyHostNames[0] + urlSuffix, constructedUrl);
+    }
+
+    @Test
+    public void createDme2EndtoEnd() {
+        SliPluginUtilsActivator activator = new SliPluginUtilsActivator();
+        DME2 dme2 = activator.initDme2("src/test/resources/dme2.e2e.properties");
+        assertEquals("user@sample.com", dme2.aafUserName);
+        assertEquals("fake", dme2.aafPassword);
+        assertEquals("UAT", dme2.envContext);
+        assertEquals("UAT", dme2.routeOffer);
+        Assert.assertArrayEquals("http://sample.com:25055,http://sample.com:25055".split(","), dme2.proxyUrls);
+        assertEquals("1702.0", dme2.commonServiceVersion);
+        assertEquals(null, dme2.partner);
+
+        String constructedUrl = dme2.constructUrl("sample.com/restservices/instar/v1/assetSearch", null, "/mySubContext");
+        assertNotNull(constructedUrl);
+        System.out.println(constructedUrl);
+    }
+
+    @Test
+    public void createDme2Prod() {
+        SliPluginUtilsActivator activator = new SliPluginUtilsActivator();
+        DME2 dme2 = activator.initDme2("src/test/resources/dme2.prod.properties");
+        assertEquals("user@sample.com", dme2.aafUserName);
+        assertEquals("fake", dme2.aafPassword);
+        assertEquals("PROD", dme2.envContext);
+        assertEquals("", dme2.routeOffer);
+        Assert.assertArrayEquals("http://sample.com:25055,http://sample.com:25055".split(","), dme2.proxyUrls);
+        assertEquals("1.0", dme2.commonServiceVersion);
+        assertEquals("LPP_PROD", dme2.partner);
+
+        String constructedUrl = dme2.constructUrl("sample.com/restservices/instar/v1/assetSearch", null, "/mySubContext");
+        assertNotNull(constructedUrl);
+        System.out.println(constructedUrl);
+    }
+
+}
diff --git a/sliPluginUtils/provider/src/test/java/org/openecomp/sdnc/sli/SliPluginUtils/SliPluginUtils_StaticFunctionsTest.java b/sliPluginUtils/provider/src/test/java/org/openecomp/sdnc/sli/SliPluginUtils/SliPluginUtils_StaticFunctionsTest.java
new file mode 100644
index 0000000..e69d086
--- /dev/null
+++ b/sliPluginUtils/provider/src/test/java/org/openecomp/sdnc/sli/SliPluginUtils/SliPluginUtils_StaticFunctionsTest.java
@@ -0,0 +1,250 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * openECOMP : SDN-C
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights
+ * 						reserved.
+ * ================================================================================
+ * Licensed 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.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.sdnc.sli.SliPluginUtils;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.openecomp.sdnc.sli.SvcLogicContext;
+import org.openecomp.sdnc.sli.SvcLogicException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class SliPluginUtils_StaticFunctionsTest {
+    private static final Logger LOG = LoggerFactory.getLogger(SliPluginUtils_StaticFunctionsTest.class);
+    SliPluginUtils utils = new SliPluginUtils();
+    private SvcLogicContext ctx;
+    private HashMap<String, String> parameters;
+
+    @Before
+    public void setUp() throws Exception {
+        this.ctx = new SvcLogicContext();
+        parameters = new HashMap<String, String>();
+    }
+
+    // TODO: javadoc
+    @Test
+    public final void testCtxGetBeginsWith() {
+        ctx.setAttribute("service-data.oper-status.order-status", "InProgress");
+        ctx.setAttribute("service-data.service-information.service-instance-id", "my-instance");
+        ctx.setAttribute("service-data.service-information.service-type", "my-service");
+
+        Map<String, String> entries = SliPluginUtils.ctxGetBeginsWith(ctx, "service-data.service-information");
+
+        assertEquals("my-instance", entries.get("service-data.service-information.service-instance-id"));
+        assertEquals("my-service", entries.get("service-data.service-information.service-type"));
+        assertFalse(entries.containsKey("service-data.oper-status.order-status"));
+    }
+
+    // TODO: javadoc
+    @Test
+    public final void testCtxListRemove_index() throws SvcLogicException {
+        LOG.trace("=== testCtxListRemove_index ===");
+        ctx.setAttribute("service-data.vnf-l3[0].vnf-host-name", "vnf-host-name_0");
+        ctx.setAttribute("service-data.vnf-l3[0].device-host-name", "device-host-name_0");
+        ctx.setAttribute("service-data.vnf-l3[1].vnf-host-name", "vnf-host-name_1");
+        ctx.setAttribute("service-data.vnf-l3[1].device-host-name", "device-host-name_1");
+        ctx.setAttribute("service-data.vnf-l3[2].vnf-host-name", "vnf-host-name_2");
+        ctx.setAttribute("service-data.vnf-l3[2].device-host-name", "device-host-name_2");
+        ctx.setAttribute("service-data.vnf-l3_length", "3");
+
+        parameters.put("index", "1");
+        parameters.put("list_pfx", "service-data.vnf-l3");
+
+        utils.ctxListRemove(parameters, ctx);
+        SliPluginUtils.logContextMemory(ctx, LOG, SliPluginUtils.LogLevel.TRACE);
+
+        assertEquals("2", ctx.getAttribute("service-data.vnf-l3_length"));
+        assertEquals("vnf-host-name_0", ctx.getAttribute("service-data.vnf-l3[0].vnf-host-name"));
+        assertEquals("device-host-name_0", ctx.getAttribute("service-data.vnf-l3[0].device-host-name"));
+        assertEquals("vnf-host-name_2", ctx.getAttribute("service-data.vnf-l3[1].vnf-host-name"));
+        assertEquals("device-host-name_2", ctx.getAttribute("service-data.vnf-l3[1].device-host-name"));
+    }
+
+    // TODO: javadoc
+    @Test
+    public final void textCtxListRemove_keyValue() throws SvcLogicException {
+        LOG.trace("=== textCtxListRemove_keyValue ===");
+        ctx.setAttribute("service-data.vnf-l3[0].vnf-host-name", "vnf-host-name_0");
+        ctx.setAttribute("service-data.vnf-l3[0].device-host-name", "device-host-name_0");
+        ctx.setAttribute("service-data.vnf-l3[1].vnf-host-name", "vnf-host-name_1");
+        ctx.setAttribute("service-data.vnf-l3[1].device-host-name", "device-host-name_1");
+        ctx.setAttribute("service-data.vnf-l3[2].vnf-host-name", "vnf-host-name_2");
+        ctx.setAttribute("service-data.vnf-l3[2].device-host-name", "device-host-name_2");
+        // 2nd entry
+        ctx.setAttribute("service-data.vnf-l3[3].vnf-host-name", "vnf-host-name_1");
+        ctx.setAttribute("service-data.vnf-l3[3].device-host-name", "device-host-name_1");
+        ctx.setAttribute("service-data.vnf-l3_length", "4");
+
+        parameters.put("list_pfx", "service-data.vnf-l3");
+        parameters.put("key", "vnf-host-name");
+        parameters.put("value", "vnf-host-name_1");
+
+        utils.ctxListRemove(parameters, ctx);
+        SliPluginUtils.logContextMemory(ctx, LOG, SliPluginUtils.LogLevel.TRACE);
+
+        assertEquals("2", ctx.getAttribute("service-data.vnf-l3_length"));
+        assertEquals("vnf-host-name_0", ctx.getAttribute("service-data.vnf-l3[0].vnf-host-name"));
+        assertEquals("device-host-name_0", ctx.getAttribute("service-data.vnf-l3[0].device-host-name"));
+        assertEquals("vnf-host-name_2", ctx.getAttribute("service-data.vnf-l3[1].vnf-host-name"));
+        assertEquals("device-host-name_2", ctx.getAttribute("service-data.vnf-l3[1].device-host-name"));
+    }
+
+    // TODO: javadoc
+    @Test
+    public final void textCtxListRemove_keyValue_nullkey() throws SvcLogicException {
+        LOG.trace("=== textCtxListRemove_keyValue_nullkey ===");
+        ctx.setAttribute("service-data.vnf-l3[0]", "vnf-host-name_0");
+        ctx.setAttribute("service-data.vnf-l3[1]", "vnf-host-name_1");
+        ctx.setAttribute("service-data.vnf-l3[2]", "vnf-host-name_2");
+        ctx.setAttribute("service-data.vnf-l3_length", "3");
+
+        parameters.put("list_pfx", "service-data.vnf-l3");
+        parameters.put("value", "vnf-host-name_1");
+
+        utils.ctxListRemove(parameters, ctx);
+        SliPluginUtils.logContextMemory(ctx, LOG, SliPluginUtils.LogLevel.TRACE);
+
+        assertEquals("2", ctx.getAttribute("service-data.vnf-l3_length"));
+        assertEquals("vnf-host-name_0", ctx.getAttribute("service-data.vnf-l3[0]"));
+        assertEquals("vnf-host-name_2", ctx.getAttribute("service-data.vnf-l3[1]"));
+    }
+
+    // TODO: javadoc
+    @Test
+    public final void textCtxListRemove_keyValueList() throws SvcLogicException {
+        LOG.trace("=== textCtxListRemove_keyValueList ===");
+        ctx.setAttribute("service-data.vnf-l3[0].vnf-host-name", "vnf-host-name_0");
+        ctx.setAttribute("service-data.vnf-l3[0].device-host-name", "device-host-name_0");
+        ctx.setAttribute("service-data.vnf-l3[1].vnf-host-name", "vnf-host-name_1");
+        ctx.setAttribute("service-data.vnf-l3[1].device-host-name", "device-host-name_1");
+        ctx.setAttribute("service-data.vnf-l3[2].vnf-host-name", "vnf-host-name_2");
+        ctx.setAttribute("service-data.vnf-l3[2].device-host-name", "device-host-name_2");
+        // 2nd entry
+        ctx.setAttribute("service-data.vnf-l3[3].vnf-host-name", "vnf-host-name_1");
+        ctx.setAttribute("service-data.vnf-l3[3].device-host-name", "device-host-name_1");
+        // entries with only 1 of 2 key-value pairs matching
+        ctx.setAttribute("service-data.vnf-l3[4].vnf-host-name", "vnf-host-name_1");
+        ctx.setAttribute("service-data.vnf-l3[4].device-host-name", "device-host-name_4");
+        ctx.setAttribute("service-data.vnf-l3[5].vnf-host-name", "vnf-host-name_5");
+        ctx.setAttribute("service-data.vnf-l3[5].device-host-name", "device-host-name_1");
+        ctx.setAttribute("service-data.vnf-l3_length", "6");
+
+        parameters.put("list_pfx", "service-data.vnf-l3");
+        parameters.put("keys_length", "2");
+        parameters.put("keys[0].key", "vnf-host-name");
+        parameters.put("keys[0].value", "vnf-host-name_1");
+        parameters.put("keys[1].key", "device-host-name");
+        parameters.put("keys[1].value", "device-host-name_1");
+
+        utils.ctxListRemove(parameters, ctx);
+        SliPluginUtils.logContextMemory(ctx, LOG, SliPluginUtils.LogLevel.TRACE);
+
+        assertEquals("4", ctx.getAttribute("service-data.vnf-l3_length"));
+        assertEquals("vnf-host-name_0", ctx.getAttribute("service-data.vnf-l3[0].vnf-host-name"));
+        assertEquals("device-host-name_0", ctx.getAttribute("service-data.vnf-l3[0].device-host-name"));
+        assertEquals("vnf-host-name_2", ctx.getAttribute("service-data.vnf-l3[1].vnf-host-name"));
+        assertEquals("device-host-name_2", ctx.getAttribute("service-data.vnf-l3[1].device-host-name"));
+        assertEquals("vnf-host-name_1", ctx.getAttribute("service-data.vnf-l3[2].vnf-host-name"));
+        assertEquals("device-host-name_4", ctx.getAttribute("service-data.vnf-l3[2].device-host-name"));
+        assertEquals("vnf-host-name_5", ctx.getAttribute("service-data.vnf-l3[3].vnf-host-name"));
+        assertEquals("device-host-name_1", ctx.getAttribute("service-data.vnf-l3[3].device-host-name"));
+    }
+
+    // TODO: javadoc
+    @Test(expected = SvcLogicException.class)
+    public final void testCtxListRemove_nullListLength() throws SvcLogicException {
+        LOG.trace("=== testCtxListRemove_nullListLength ===");
+        ctx.setAttribute("service-data.vnf-l3[0].vnf-host-name", "vnf-host-name_0");
+        ctx.setAttribute("service-data.vnf-l3[0].device-host-name", "device-host-name_0");
+        ctx.setAttribute("service-data.vnf-l3[1].vnf-host-name", "vnf-host-name_1");
+        ctx.setAttribute("service-data.vnf-l3[1].device-host-name", "device-host-name_1");
+        ctx.setAttribute("service-data.vnf-l3[2].vnf-host-name", "vnf-host-name_2");
+        ctx.setAttribute("service-data.vnf-l3[2].device-host-name", "device-host-name_2");
+
+        parameters.put("index", "1");
+        parameters.put("list_pfx", "service-data.vnf-l3");
+
+        utils.ctxListRemove(parameters, ctx);
+    }
+
+    // TODO: javadoc
+    @Test
+    public final void testCtxPutAll() {
+        HashMap<String, Object> entries = new HashMap<String, Object>();
+        entries.put("service-data.oper-status.order-status", "InProgress");
+        entries.put("service-data.service-information.service-instance-id", "my-instance");
+        entries.put("service-data.request-information.order-number", 1234);
+        entries.put("service-data.request-information.request-id", null);
+
+        SliPluginUtils.ctxPutAll(ctx, entries);
+
+        assertEquals("InProgress", ctx.getAttribute("service-data.oper-status.order-status"));
+        assertEquals("my-instance", ctx.getAttribute("service-data.service-information.service-instance-id"));
+        assertEquals("1234", ctx.getAttribute("service-data.request-information.order-number"));
+        assertFalse(ctx.getAttributeKeySet().contains("service-data.request-information.request-id"));
+    }
+
+    // TODO: javadoc
+    @Test
+    public final void testCtxSetAttribute_LOG() {
+        LOG.debug("=== testCtxSetAttribute_LOG ===");
+        Integer i = new Integer(3);
+        SliPluginUtils.ctxSetAttribute(ctx, "test", i, LOG, SliPluginUtils.LogLevel.TRACE);
+    }
+
+    /*@Test
+    public void printContext() throws SvcLogicException, IOException {
+        String filePath = "/src/test/resources/printContext.txt";
+        parameters.put("filename", filePath);
+        File f = new File(filePath);
+        assert (f.exists());
+        assert (!f.isDirectory());
+        ctx.setAttribute("hello", "world");
+        ctx.setAttribute("name", "value");
+
+        SliPluginUtils.printContext(parameters, ctx);
+        BufferedReader br = new BufferedReader(new FileReader(f));
+        String line = br.readLine();
+        assertEquals("#######################################", line);
+        line = br.readLine();
+        assertEquals("hello = world", line);
+        line = br.readLine();
+        assertEquals("name = value", line);
+        br.close();
+        Files.delete(Paths.get(filePath));
+    }*/
+
+    @Test
+    public void setTime() throws SvcLogicException {
+        String outputPath = "output";
+        parameters.put("outputPath", outputPath);
+        SliPluginUtils.setTime(parameters, ctx);
+        assertNotNull(ctx.getAttribute(outputPath));
+    }
+}
diff --git a/sliPluginUtils/provider/src/test/java/org/openecomp/sdnc/sli/SliPluginUtils/SliPluginUtils_ctxSortListTest.java b/sliPluginUtils/provider/src/test/java/org/openecomp/sdnc/sli/SliPluginUtils/SliPluginUtils_ctxSortListTest.java
new file mode 100644
index 0000000..e2fcb33
--- /dev/null
+++ b/sliPluginUtils/provider/src/test/java/org/openecomp/sdnc/sli/SliPluginUtils/SliPluginUtils_ctxSortListTest.java
@@ -0,0 +1,97 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * openECOMP : SDN-C
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights
+ * 						reserved.
+ * ================================================================================
+ * Licensed 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.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.sdnc.sli.SliPluginUtils;
+
+import static org.junit.Assert.assertTrue;
+
+import java.util.HashMap;
+import java.util.Random;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.openecomp.sdnc.sli.SvcLogicContext;
+import org.openecomp.sdnc.sli.SvcLogicException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+@SuppressWarnings("unused")
+public class SliPluginUtils_ctxSortListTest {
+    private static final Logger LOG = LoggerFactory.getLogger(SliPluginUtils_ctxSortListTest.class);
+    SliPluginUtils utils = new SliPluginUtils();
+    SvcLogicContext ctx;
+    HashMap<String, String> parameters;
+    Random rand = new Random();
+
+    @Before
+    public void setUp() throws Exception {
+        this.ctx = new SvcLogicContext();
+        this.parameters = new HashMap<String, String>();
+    }
+
+    @Test
+    public final void list_of_containers() throws SvcLogicException {
+        this.parameters.put("list", "input.list");
+        this.parameters.put("sort-fields", "sort-key");
+        this.parameters.put("delimiter", ",");
+
+        ctx.setAttribute("input.list_length", "10");
+        for (int i = 0; i < 10; i++) {
+            this.ctx.setAttribute("input.list[" + i + "].sort-key", Integer.toString(rand.nextInt(10)));
+            this.ctx.setAttribute("input.list[" + i + "].value", Integer.toString(rand.nextInt(10)));
+        }
+
+        LOG.trace("BEFORE SORT:");
+        SliPluginUtils.logContextMemory(ctx, LOG, SliPluginUtils.LogLevel.TRACE);
+
+        utils.ctxSortList(this.parameters, this.ctx);
+
+        LOG.trace("AFTER SORT:");
+        SliPluginUtils.logContextMemory(ctx, LOG, SliPluginUtils.LogLevel.TRACE);
+
+        for (int i = 0; i < 9; i++) {
+            assertTrue(this.ctx.getAttribute("input.list[" + i + "].sort-key").compareTo(this.ctx.getAttribute("input.list[" + (i + 1) + "].sort-key")) < 1);
+        }
+    }
+
+    @Test
+    public final void list_of_elements() throws SvcLogicException {
+        this.parameters.put("list", "input.list");
+        this.parameters.put("delimiter", ",");
+
+        this.ctx.setAttribute("input.list_length", "10");
+        for (int i = 0; i < 10; i++) {
+            this.ctx.setAttribute("input.list[" + i + ']', Integer.toString(rand.nextInt(10)));
+        }
+
+        LOG.trace("BEFORE SORT:");
+        SliPluginUtils.logContextMemory(ctx, LOG, SliPluginUtils.LogLevel.TRACE);
+
+        utils.ctxSortList(this.parameters, this.ctx);
+
+        LOG.trace("AFTER SORT:");
+        SliPluginUtils.logContextMemory(ctx, LOG, SliPluginUtils.LogLevel.TRACE);
+
+        for (int i = 0; i < 9; i++) {
+            assertTrue(this.ctx.getAttribute("input.list[" + i + ']').compareTo(this.ctx.getAttribute("input.list[" + (i + 1) + ']')) < 1);
+        }
+    }
+}
diff --git a/sliPluginUtils/provider/src/test/java/org/openecomp/sdnc/sli/SliPluginUtils/SliStringUtilsTest.java b/sliPluginUtils/provider/src/test/java/org/openecomp/sdnc/sli/SliPluginUtils/SliStringUtilsTest.java
new file mode 100644
index 0000000..d57cefa
--- /dev/null
+++ b/sliPluginUtils/provider/src/test/java/org/openecomp/sdnc/sli/SliPluginUtils/SliStringUtilsTest.java
@@ -0,0 +1,244 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * openECOMP : SDN-C
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights
+ * 						reserved.
+ * ================================================================================
+ * Licensed 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.
+ * ============LICENSE_END=========================================================
+ */
+
+/**
+ *
+ */
+package org.openecomp.sdnc.sli.SliPluginUtils;
+
+import static org.hamcrest.Matchers.equalTo;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertThat;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.openecomp.sdnc.sli.SvcLogicContext;
+import org.openecomp.sdnc.sli.SvcLogicException;
+
+/**
+ * @author km991u
+ *
+ */
+public class SliStringUtilsTest {
+    private SvcLogicContext ctx;
+    private HashMap<String, String> param;
+    private SliStringUtils stringUtils = new SliStringUtils();
+
+    /**
+     * @throws java.lang.Exception
+     */
+    @Before
+    public void setUp() throws Exception {
+        this.ctx = new SvcLogicContext();
+        param = new HashMap<String, String>();
+    }
+
+    /**
+     * @throws SvcLogicException
+     * @see SliStringUtils#split(Map, SvcLogicContext)
+     */
+    @Test
+    public final void testSplit() throws SvcLogicException {
+        param.put("original_string", "one ## two ## three");
+        param.put("regex", " ## ");
+        param.put("ctx_memory_result_key", "result");
+
+        stringUtils.split(param, ctx);
+
+        assertThat(ctx.getAttribute("result[0]"), equalTo("one"));
+        assertThat(ctx.getAttribute("result[1]"), equalTo("two"));
+        assertThat(ctx.getAttribute("result[2]"), equalTo("three"));
+        assertThat(ctx.getAttribute("result_length"), equalTo("3"));
+    }
+
+    /**
+     * @throws SvcLogicException
+     * @see SliStringUtils#split(Map, SvcLogicContext)
+     */
+    @Test
+    public final void testSplit_limit() throws SvcLogicException {
+        param.put("original_string", "one ## two ## three");
+        param.put("regex", " ## ");
+        param.put("limit", "2");
+        param.put("ctx_memory_result_key", "result");
+
+        stringUtils.split(param, ctx);
+
+        assertThat(ctx.getAttribute("result[0]"), equalTo("one"));
+        assertThat(ctx.getAttribute("result[1]"), equalTo("two ## three"));
+        assertThat(ctx.getAttribute("result_length"), equalTo("2"));
+    }
+
+    @Test
+    public void equalsIgnoreCaseTrue() throws SvcLogicException {
+        String sourceString = "HeLlOwORLD";
+        String targetSTring = "HELLOWORLD";
+        param.put("source", sourceString);
+        param.put("target", targetSTring);
+        assertEquals("true", SliStringUtils.equalsIgnoreCase(param, ctx));
+    }
+
+    @Test
+    public void equalsIgnoreCaseFalse() throws SvcLogicException {
+        String sourceString = "HeLlOwORLD";
+        String targetSTring = "goodbyeWORLD";
+        param.put("source", sourceString);
+        param.put("target", targetSTring);
+        assertEquals("false", SliStringUtils.equalsIgnoreCase(param, ctx));
+    }
+
+    @Test
+    public void toUpper() throws SvcLogicException {
+        String sourceString = "HeLlOwORLD";
+        param.put("source", sourceString);
+        String path = "my.unique.path.";
+        param.put("outputPath", path);
+        SliStringUtils.toUpper(param, ctx);
+        assertEquals(sourceString.toUpperCase(), ctx.getAttribute(path));
+    }
+
+    @Test
+    public void toLower() throws SvcLogicException {
+        String sourceString = "HeLlOwORLD";
+        param.put("source", sourceString);
+        String path = "my.unique.path.";
+        param.put("outputPath", path);
+        SliStringUtils.toLower(param, ctx);
+        assertEquals(sourceString.toLowerCase(), ctx.getAttribute(path));
+    }
+
+    @Test
+    public void containsTrue() throws SvcLogicException {
+        String sourceString = "Pizza";
+        String targetSTring = "izza";
+        param.put("source", sourceString);
+        param.put("target", targetSTring);
+        assertEquals("true", SliStringUtils.contains(param, ctx));
+    }
+
+    @Test
+    public void containsFalse() throws SvcLogicException {
+        String sourceString = "Pizza";
+        String targetSTring = "muffin";
+        param.put("source", sourceString);
+        param.put("target", targetSTring);
+        assertEquals("false", SliStringUtils.contains(param, ctx));
+    }
+
+    @Test
+    public void endsWithTrue() throws SvcLogicException {
+        String sourceString = "Pizza";
+        String targetSTring = "za";
+        param.put("source", sourceString);
+        param.put("target", targetSTring);
+        assertEquals("true", SliStringUtils.endsWith(param, ctx));
+    }
+
+    @Test
+    public void endsWithFalse() throws SvcLogicException {
+        String sourceString = "Pizza";
+        String targetSTring = "muffin";
+        param.put("source", sourceString);
+        param.put("target", targetSTring);
+        assertEquals("false", SliStringUtils.endsWith(param, ctx));
+    }
+
+    @Test
+    public void trim() throws SvcLogicException {
+        String sourceString = " H E L L O W O R L D";
+        String outputPath = "muffin";
+        param.put("source", sourceString);
+        param.put("outputPath", outputPath);
+        SliStringUtils.trim(param, ctx);
+        assertEquals(sourceString.trim(), ctx.getAttribute(outputPath));
+    }
+
+    @Test
+    public void getLength() throws SvcLogicException {
+        String sourceString = "SomeRandomString";
+        String outputPath = "muffin";
+        param.put("source", sourceString);
+        param.put("outputPath", outputPath);
+        SliStringUtils.getLength(param, ctx);
+        assertEquals(String.valueOf(sourceString.length()), ctx.getAttribute(outputPath));
+    }
+
+    @Test
+    public void startsWithFalse() throws SvcLogicException {
+        String sourceString = "Java";
+        String targetSTring = "DG";
+        param.put("source", sourceString);
+        param.put("target", targetSTring);
+        assertEquals("false", SliStringUtils.startsWith(param, ctx));
+    }
+
+    @Test
+    public void startsWithTrue() throws SvcLogicException {
+        String sourceString = "Java";
+        String targetSTring = "Ja";
+        param.put("source", sourceString);
+        param.put("target", targetSTring);
+        assertEquals("true", SliStringUtils.startsWith(param, ctx));
+    }
+
+    @Test
+    public void replace() throws SvcLogicException {
+        String sourceString = "cat Hello World cat";
+        String old = "cat";
+        String neww = "dog";
+        String outputPath = "out";
+
+        param.put("source", sourceString);
+        param.put("target", old);
+        param.put("replacement", neww);
+        param.put("outputPath", outputPath);
+        SliStringUtils.replace(param, ctx);
+        assertEquals(sourceString.replace(old, neww), ctx.getAttribute(outputPath));
+    }
+
+    @Test
+    public void concat() throws SvcLogicException {
+        String sourceString = "cat";
+        String targetString = "dog";
+        String outputPath = "out";
+
+        param.put("source", sourceString);
+        param.put("target", targetString);
+        param.put("outputPath", outputPath);
+        SliStringUtils.concat(param, ctx);
+        assertEquals(sourceString + targetString, ctx.getAttribute(outputPath));
+    }
+
+    @Test
+    public void urlEncode() throws SvcLogicException {
+        String sourceString = "102/GE100/SNJSCAMCJP8/SNJSCAMCJT4";
+        String outputPath = "out";
+
+        param.put("source", sourceString);
+        param.put("outputPath", outputPath);
+        SliStringUtils.urlEncode(param, ctx);
+        assertEquals("102%2FGE100%2FSNJSCAMCJP8%2FSNJSCAMCJT4", ctx.getAttribute(outputPath));
+    }
+
+}
diff --git a/sliapi/installer/pom.xml b/sliapi/installer/pom.xml
index 52237dc..ec54c3e 100755
--- a/sliapi/installer/pom.xml
+++ b/sliapi/installer/pom.xml
@@ -8,7 +8,6 @@
 		<version>1.1.0-SNAPSHOT</version>
 	</parent>
 	<artifactId>sliapi-installer</artifactId>
-	<name>SLI API  - Karaf  Installer</name>
 	<packaging>pom</packaging>
 
 	<properties>
diff --git a/sliapi/model/pom.xml b/sliapi/model/pom.xml
index ae79cb3..7d7e4c9 100755
--- a/sliapi/model/pom.xml
+++ b/sliapi/model/pom.xml
@@ -30,7 +30,7 @@
 					<dependency>
 						<groupId>org.opendaylight.mdsal</groupId>
 						<artifactId>maven-sal-api-gen-plugin</artifactId>
-						<version>${odl.yangtools.version}</version>
+						<version>${odl.sal.api.gen.plugin.version}</version>
 						<type>jar</type>
 					</dependency>
 				</dependencies>
@@ -58,7 +58,7 @@
 		<dependency>
 			<groupId>org.opendaylight.mdsal</groupId>
 			<artifactId>yang-binding</artifactId>
-			<version>${odl.yangtools.version}</version>
+			<version>${odl.mdsal.yang.binding.version}</version>
 		</dependency>
 		<dependency>
 			<groupId>org.opendaylight.yangtools</groupId>
diff --git a/sliapi/model/src/main/yang/sliapi.yang b/sliapi/model/src/main/yang/sliapi.yang
index 2c77331..047fd69 100755
--- a/sliapi/model/src/main/yang/sliapi.yang
+++ b/sliapi/model/src/main/yang/sliapi.yang
@@ -48,7 +48,10 @@
         leaf ack-final-indicator {
             type string;
         }
-        leaf response-text {
+        leaf response-message {
+            type string;
+        }
+        leaf context-memory-json {
             type string;
         }
     }
diff --git a/sliapi/provider/pom.xml b/sliapi/provider/pom.xml
index 96e81b4..62d9cb0 100755
--- a/sliapi/provider/pom.xml
+++ b/sliapi/provider/pom.xml
@@ -54,7 +54,7 @@
 					<dependency>
 						<groupId>org.opendaylight.mdsal</groupId>
 						<artifactId>maven-sal-api-gen-plugin</artifactId>
-						<version>${odl.yangtools.version}</version>
+						<version>${odl.sal.api.gen.plugin.version}</version>
 						<type>jar</type>
 					</dependency>
 					<dependency>
diff --git a/sliapi/provider/src/main/java/org/openecomp/sdnc/sliapi/sliapiProvider.java b/sliapi/provider/src/main/java/org/openecomp/sdnc/sliapi/sliapiProvider.java
index 8189bc0..f8deef2 100644
--- a/sliapi/provider/src/main/java/org/openecomp/sdnc/sliapi/sliapiProvider.java
+++ b/sliapi/provider/src/main/java/org/openecomp/sdnc/sliapi/sliapiProvider.java
@@ -203,7 +203,7 @@
 
 		if (svcLogic == null) {
 			respBuilder.setResponseCode("500");
-			respBuilder.setResponseText("Could not locate OSGi SvcLogicService service");
+			respBuilder.setResponseMessage("Could not locate OSGi SvcLogicService service");
 			respBuilder.setAckFinalIndicator("Y");
 
 		    rpcResult = RpcResultBuilder.<ExecuteGraphOutput> status(true).withResult(respBuilder.build()).build();
@@ -214,7 +214,7 @@
 		try {
 			if (!svcLogic.hasGraph(calledModule, calledRpc, null, modeStr)) {
 				respBuilder.setResponseCode("404");
-				respBuilder.setResponseText("Directed graph for "+calledModule+"/"+calledRpc+"/"+modeStr+" not found");
+				respBuilder.setResponseMessage("Directed graph for "+calledModule+"/"+calledRpc+"/"+modeStr+" not found");
 				respBuilder.setAckFinalIndicator("Y");
 
 			    rpcResult = RpcResultBuilder.<ExecuteGraphOutput> status(true).withResult(respBuilder.build()).build();
@@ -224,7 +224,7 @@
 			LOG.error("Caught exception looking for directed graph for "+calledModule+"/"+calledRpc+"/"+modeStr, e);
 
 			respBuilder.setResponseCode("500");
-			respBuilder.setResponseText("Internal error : could not determine if target graph exists");
+			respBuilder.setResponseMessage("Internal error : could not determine if target graph exists");
 			respBuilder.setAckFinalIndicator("Y");
 
 		    rpcResult = RpcResultBuilder.<ExecuteGraphOutput> status(true).withResult(respBuilder.build()).build();
@@ -265,7 +265,7 @@
 		try {
 			LOG.info("Calling directed graph for "+calledModule+"/"+calledRpc+"/"+modeStr);
 
-			if (LOG.isDebugEnabled()) {
+			if (LOG.isTraceEnabled()) {
 				StringBuffer argList = new StringBuffer();
 				argList.append("Parameters : {");
 				Enumeration e = parms.propertyNames();
@@ -274,7 +274,7 @@
 					argList.append(" ("+propName+","+parms.getProperty(propName)+") ");
 				}
 				argList.append("}");
-				LOG.debug(argList.toString());
+				LOG.trace(argList.toString());
 				argList = null;
 			}
 
@@ -283,9 +283,22 @@
 			Properties respProps = svcLogic.execute(calledModule, calledRpc,
 					null, modeStr, parms, domDataBroker);
 
+			StringBuilder sb = new StringBuilder("{");
+			
+			for (Object key : respProps.keySet()) {
+				String keyValue = (String) key;
+				if (keyValue != null && !"".equals(keyValue) && !keyValue.contains("input.sli-parameter")) {
+					sb.append("\"").append(keyValue).append("\": \"").append(respProps.getProperty(keyValue)).append("\",");
+				}
+			}
+			
+			sb.setLength(sb.length() - 1);
+			sb.append("}");
+			
 			respBuilder.setResponseCode(respProps.getProperty("error-code", "0"));
-			respBuilder.setResponseText(respProps.getProperty("error-message", ""));
+			respBuilder.setResponseMessage(respProps.getProperty("error-message", ""));// TODO change response-text to response-message to match other BVC APIs
 			respBuilder.setAckFinalIndicator(respProps.getProperty("ack-final", "Y"));
+			respBuilder.setContextMemoryJson(sb.toString());
 
 			TestResultBuilder testResultBuilder = new TestResultBuilder();
 
@@ -308,7 +321,7 @@
 
 			respBuilder.setResponseCode("500");
 			respBuilder
-					.setResponseText("Internal error : caught exception executing directed graph "
+					.setResponseMessage("Internal error : caught exception executing directed graph "
 							+ calledModule
 							+ "/"
 							+ calledRpc
@@ -359,7 +372,7 @@
 
 		if (svcLogic == null) {
 			respBuilder.setResponseCode("500");
-			respBuilder.setResponseText("Could not locate OSGi SvcLogicService service");
+			respBuilder.setResponseMessage("Could not locate OSGi SvcLogicService service");
 			respBuilder.setAckFinalIndicator("Y");
 
 		    rpcResult = RpcResultBuilder.<HealthcheckOutput> failed().withResult(respBuilder.build()).build();
@@ -369,7 +382,7 @@
 		try {
 			if (!svcLogic.hasGraph(calledModule, calledRpc, null, modeStr)) {
 				respBuilder.setResponseCode("404");
-				respBuilder.setResponseText("Directed graph for "+calledModule+"/"+calledRpc+"/"+modeStr+" not found");
+				respBuilder.setResponseMessage("Directed graph for "+calledModule+"/"+calledRpc+"/"+modeStr+" not found");
 
 				respBuilder.setAckFinalIndicator("Y");
 
@@ -380,7 +393,7 @@
 			LOG.error("Caught exception looking for directed graph for "+calledModule+"/"+calledRpc+"/"+modeStr, e);
 
 			respBuilder.setResponseCode("500");
-			respBuilder.setResponseText("Internal error : could not determine if target graph exists");
+			respBuilder.setResponseMessage("Internal error : could not determine if target graph exists");
 			respBuilder.setAckFinalIndicator("Y");
 
 		    rpcResult = RpcResultBuilder.<HealthcheckOutput> failed().withResult(respBuilder.build()).build();
@@ -396,7 +409,7 @@
 					null, modeStr, parms);
 
 			respBuilder.setResponseCode(respProps.getProperty("error-code", "0"));
-			respBuilder.setResponseText(respProps.getProperty("error-message", ""));
+			respBuilder.setResponseMessage(respProps.getProperty("error-message", ""));
 			respBuilder.setAckFinalIndicator(respProps.getProperty("ack-final", "Y"));
 
 		} catch (Exception e) {
@@ -405,7 +418,7 @@
 
 			respBuilder.setResponseCode("500");
 			respBuilder
-					.setResponseText("Internal error : caught exception executing directed graph "
+					.setResponseMessage("Internal error : caught exception executing directed graph "
 							+ calledModule
 							+ "/"
 							+ calledRpc
