diff --git a/appserver/jdbc/jdbc-ra/jdbc-core/src/main/java/com/sun/gjc/common/DataSourceObjectBuilder.java b/appserver/jdbc/jdbc-ra/jdbc-core/src/main/java/com/sun/gjc/common/DataSourceObjectBuilder.java
index 72777e1..a6fb3e9 100644
--- a/appserver/jdbc/jdbc-ra/jdbc-core/src/main/java/com/sun/gjc/common/DataSourceObjectBuilder.java
+++ b/appserver/jdbc/jdbc-ra/jdbc-core/src/main/java/com/sun/gjc/common/DataSourceObjectBuilder.java
@@ -16,57 +16,48 @@
 
 package com.sun.gjc.common;
 
-import java.lang.reflect.Method;
-import java.util.*;
+import static java.util.logging.Level.FINEST;
 
+import java.io.Serializable;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.Hashtable;
+import java.util.Locale;
+import java.util.Vector;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import org.glassfish.internal.api.ClassLoaderHierarchy;
+import org.glassfish.internal.api.Globals;
+
+import com.sun.enterprise.util.i18n.StringManager;
 import com.sun.gjc.util.MethodExecutor;
+import com.sun.logging.LogDomains;
 
 import jakarta.resource.ResourceException;
 
-import com.sun.logging.*;
-
-import java.util.logging.Logger;
-import java.util.logging.Level;
-
-import com.sun.enterprise.util.i18n.StringManager;
-import org.glassfish.internal.api.Globals;
-import org.glassfish.internal.api.ClassLoaderHierarchy;
-
 /**
- * Utility class, which would create necessary Datasource object according to the
- * specification.
+ * Utility class, which would create necessary Datasource object according to
+ * the specification.
  *
  * @author Binod P.G
  * @version 1.0, 02/07/23
  * @see com.sun.gjc.common.DataSourceSpec
  * @see com.sun.gjc.util.MethodExcecutor
  */
-public class DataSourceObjectBuilder implements java.io.Serializable {
+public class DataSourceObjectBuilder implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    private static Logger _logger = LogDomains.getLogger(MethodExecutor.class, LogDomains.RSR_LOGGER);
+    private static final StringManager sm = StringManager.getManager(DataSourceObjectBuilder.class);
+
+    private static boolean jdbc40 = detectJDBC40();
+    private static boolean jdbc41 = detectJDBC41();
 
     private DataSourceSpec spec;
-
-    private Hashtable driverProperties = null;
-
-    private MethodExecutor executor = null;
-
-    private static Logger _logger;
-
-    static {
-        _logger = LogDomains.getLogger(MethodExecutor.class, LogDomains.RSR_LOGGER);
-    }
-
-    private static boolean jdbc40;
-    private static boolean jdbc41;
-
-    static {
-        jdbc40 = detectJDBC40();
-        jdbc41 = detectJDBC41();
-    }
-
-    private boolean debug = false;
-
-    private static final StringManager sm = StringManager.getManager(
-            DataSourceObjectBuilder.class);
+    private Hashtable driverProperties;
+    private MethodExecutor executor;
 
     /**
      * Construct a DataSource Object from the spec.
@@ -82,8 +73,8 @@
      * Construct the DataSource Object from the spec.
      *
      * @return Object constructed using the DataSourceSpec.
-     * @throws <code>ResourceException</code> if the class is not found or some issue in executing
-     *                                        some method.
+     * @throws <code>ResourceException</code> if the class is not found or some
+     * issue in executing some method.
      */
     public Object constructDataSourceObject() throws ResourceException {
         driverProperties = parseDriverProperties(spec, true);
@@ -91,8 +82,8 @@
         Method[] methods = dataSourceObject.getClass().getMethods();
         for (int i = 0; i < methods.length; i++) {
             String methodName = methods[i].getName();
-            //Check for driver properties first since some jdbc properties
-            //may be supported in form of driver properties
+            // Check for driver properties first since some jdbc properties
+            // may be supported in form of driver properties
             if (driverProperties.containsKey(methodName.toUpperCase(Locale.getDefault()))) {
                 Vector values = (Vector) driverProperties.get(methodName.toUpperCase(Locale.getDefault()));
                 executor.runMethod(methods[i], dataSourceObject, values);
@@ -118,7 +109,8 @@
                 executor.runJavaBeanMethod(spec.getDetail(DataSourceSpec.DESCRIPTION), methods[i], dataSourceObject);
 
             } else if (methodName.equalsIgnoreCase("setNetworkProtocol")) {
-                executor.runJavaBeanMethod(spec.getDetail(DataSourceSpec.NETWORKPROTOCOL), methods[i], dataSourceObject);
+                executor.runJavaBeanMethod(spec.getDetail(DataSourceSpec.NETWORKPROTOCOL), methods[i],
+                        dataSourceObject);
 
             } else if (methodName.equalsIgnoreCase("setPortNumber")) {
                 executor.runJavaBeanMethod(spec.getDetail(DataSourceSpec.PORTNUMBER), methods[i], dataSourceObject);
@@ -133,7 +125,8 @@
                 executor.runJavaBeanMethod(spec.getDetail(DataSourceSpec.MAXSTATEMENTS), methods[i], dataSourceObject);
 
             } else if (methodName.equalsIgnoreCase("setInitialPoolSize")) {
-                executor.runJavaBeanMethod(spec.getDetail(DataSourceSpec.INITIALPOOLSIZE), methods[i], dataSourceObject);
+                executor.runJavaBeanMethod(spec.getDetail(DataSourceSpec.INITIALPOOLSIZE), methods[i],
+                        dataSourceObject);
 
             } else if (methodName.equalsIgnoreCase("setMinPoolSize")) {
                 executor.runJavaBeanMethod(spec.getDetail(DataSourceSpec.MINPOOLSIZE), methods[i], dataSourceObject);
@@ -153,42 +146,45 @@
     }
 
     /**
-     * Get the extra driver properties from the DataSourceSpec object and
-     * parse them to a set of methodName and parameters. Prepare a hashtable
-     * containing these details and return.
+     * Get the extra driver properties from the DataSourceSpec object and parse them
+     * to a set of methodName and parameters. Prepare a hashtable containing these
+     * details and return.
      *
      * @param spec <code> DataSourceSpec </code> object.
      * @return Hashtable containing method names and parameters,
-     * @throws ResourceException If delimiter is not provided and property string
-     *                           is not null.
+     * @throws ResourceException If delimiter is not provided and property string is
+     * not null.
      */
-    public Hashtable parseDriverProperties(DataSourceSpec spec, boolean returnUpperCase)
-            throws ResourceException {
+    public Hashtable parseDriverProperties(DataSourceSpec spec, boolean returnUpperCase) throws ResourceException {
         String delim = spec.getDetail(DataSourceSpec.DELIMITER);
         String escape = spec.getDetail(DataSourceSpec.ESCAPECHARACTER);
         String prop = spec.getDetail(DataSourceSpec.DRIVERPROPERTIES);
 
         if (prop == null || prop.trim().equals("")) {
             return new Hashtable();
-        } else if (delim == null || delim.equals("")) {
-            String msg = sm.getString("dsob.delim_not_specified");
-            throw new ResourceException(msg);
-        }else if( escape == null  || escape.equals("")){
-            String msg = sm.getString("dsob.escape_char_not_specified");
-            throw new ResourceException(msg);
         }
-        return parseDriverProperties(prop,escape, delim, returnUpperCase);
+
+        if (delim == null || delim.equals("")) {
+            throw new ResourceException(sm.getString("dsob.delim_not_specified"));
+        }
+
+        if (escape == null || escape.equals("")) {
+            throw new ResourceException(sm.getString("dsob.escape_char_not_specified"));
+        }
+
+        return parseDriverProperties(prop, escape, delim, returnUpperCase);
     }
 
     /**
-     * parse the driver properties and re-generate name value pairs with unescaped values.
+     * parse the driver properties and re-generate name value pairs with unescaped
+     * values.
+     *
      * @param values driverProperties
      * @param escape escape character
      * @param delimiter delimiter
      * @return Hashtable
      */
-    public Hashtable parseDriverProperties(String values, String escape,
-                String delimiter, boolean returnUpperCase){
+    public Hashtable parseDriverProperties(String values, String escape, String delimiter, boolean returnUpperCase) {
         Hashtable result = new Hashtable();
         String parsedValue = "";
         String name = "";
@@ -199,15 +195,15 @@
             if (values.charAt(0) == delimiterChar) {
                 if (values.length() > 1 && values.charAt(1) == delimiterChar) {
                     if (values.length() > 2 && values.charAt(2) == delimiterChar) {
-                        //Check for first property that does not have a value
-                        //There is no value specified for this property.
-                        //Store the name or it will be lost
+                        // Check for first property that does not have a value
+                        // There is no value specified for this property.
+                        // Store the name or it will be lost
                         if (returnUpperCase) {
                             name = parsedValue.toUpperCase(Locale.getDefault());
                         } else {
                             name = parsedValue;
                         }
-                        //no value specified for value
+                        // no value specified for value
                         parsedValue = "";
                     }
                     value = parsedValue;
@@ -245,14 +241,15 @@
      * Creates a Datasource object according to the spec.
      *
      * @return Initial DataSource Object instance.
-     * @throws <code>ResourceException</code> If class name is wrong or classpath is not set
-     *                                        properly.
+     * @throws <code>ResourceException</code> If class name is wrong or classpath is
+     * not set properly.
      */
     private Object getDataSourceObject() throws ResourceException {
         String className = spec.getDetail(DataSourceSpec.CLASSNAME);
+
         try {
             ClassLoader cl = Thread.currentThread().getContextClassLoader();
-            Class dataSourceClass;
+            Class<?> dataSourceClass;
             try {
                 dataSourceClass = Class.forName(className, true, cl);
             } catch (ClassNotFoundException cnfe) {
@@ -260,20 +257,17 @@
                 cl = Globals.get(ClassLoaderHierarchy.class).getCommonClassLoader();
                 dataSourceClass = Class.forName(className, true, cl);
             }
-            Object dataSourceObject = dataSourceClass.newInstance();
-            return dataSourceObject;
+
+            return dataSourceClass.getDeclaredConstructor().newInstance();
         } catch (ClassNotFoundException cnfe) {
             _logger.log(Level.SEVERE, "jdbc.exc_cnfe_ds", cnfe);
-            String msg = sm.getString("dsob.class_not_found", className);
-            throw new ResourceException(msg);
-        } catch (InstantiationException ce) {
+            throw new ResourceException(sm.getString("dsob.class_not_found", className), cnfe);
+        } catch (InstantiationException | NoSuchMethodException | InvocationTargetException ce) {
             _logger.log(Level.SEVERE, "jdbc.exc_inst", className);
-            String msg = sm.getString("dsob.error_instantiating", className);
-            throw new ResourceException(msg);
+            throw new ResourceException(sm.getString("dsob.error_instantiating", className), ce);
         } catch (IllegalAccessException ce) {
             _logger.log(Level.SEVERE, "jdbc.exc_acc_inst", className);
-            String msg = sm.getString("dsob.access_error", className);
-            throw new ResourceException(msg);
+            throw new ResourceException(sm.getString("dsob.access_error", className), ce);
         }
     }
 
@@ -296,11 +290,9 @@
             Class.forName("java.sql.Wrapper");
             jdbc40 = true;
         } catch (ClassNotFoundException cnfe) {
-            if(_logger.isLoggable(Level.FINEST)) {
-                _logger.log(Level.FINEST,
-                    "could not find Wrapper(available in jdbc-40), jdk supports only jdbc-30");
-            }
+            _logger.log(FINEST, "could not find Wrapper(available in jdbc-40), jdk supports only jdbc-30");
         }
+
         return jdbc40;
     }
 
@@ -315,12 +307,10 @@
             Class.forName("java.sql.PseudoColumnUsage");
             jdbc41 = true;
         } catch (ClassNotFoundException cnfe) {
-            if(_logger.isLoggable(Level.FINEST)) {
-                _logger.log(Level.FINEST,
-                    "could not find PseudoColumnUsage(enum available in jdbc-41)," +
-                    " jdk supports jdbc-40 or lesser");
-            }
+            _logger.log(FINEST, "could not find PseudoColumnUsage(enum available in jdbc-41),"
+                        + " jdk supports jdbc-40 or lesser");
         }
+
         return jdbc41;
     }
 }
diff --git a/appserver/jdbc/jdbc-ra/jdbc-core/src/main/java/com/sun/gjc/common/DataSourceSpec.java b/appserver/jdbc/jdbc-ra/jdbc-core/src/main/java/com/sun/gjc/common/DataSourceSpec.java
index 3c75710..34aec58 100644
--- a/appserver/jdbc/jdbc-ra/jdbc-core/src/main/java/com/sun/gjc/common/DataSourceSpec.java
+++ b/appserver/jdbc/jdbc-ra/jdbc-core/src/main/java/com/sun/gjc/common/DataSourceSpec.java
@@ -16,6 +16,7 @@
 
 package com.sun.gjc.common;
 
+import java.io.Serializable;
 import java.util.concurrent.ConcurrentHashMap;
 
 /**
@@ -25,7 +26,9 @@
  * @author Binod P.G
  * @version 1.0, 02/07/23
  */
-public class DataSourceSpec implements java.io.Serializable {
+public class DataSourceSpec implements Serializable {
+
+    private static final long serialVersionUID = 1L;
 
     public static final int USERNAME = 1;
     public static final int PASSWORD = 2;
@@ -53,7 +56,6 @@
     public static final int DATASOURCE = 23;
     public static final int CONNECTIONPOOLDATASOURCE = 24;
 
-    //GJCINT
     public static final int CONNECTIONVALIDATIONREQUIRED = 25;
     public static final int VALIDATIONMETHOD = 26;
     public static final int VALIDATIONTABLENAME = 27;
@@ -87,7 +89,7 @@
      * Set the property.
      *
      * @param property Property Name to be set.
-     * @param value    Value of property to be set.
+     * @param value Value of property to be set.
      */
     public void setDetail(int property, String value) {
         details.put(property, value);
@@ -102,14 +104,13 @@
     public String getDetail(int property) {
         if (details.containsKey(property)) {
             return details.get(property);
-        } else {
-            return null;
         }
+
+        return null;
     }
 
     /**
-     * Checks whether two <code>DataSourceSpec</code> objects
-     * are equal or not.
+     * Checks whether two <code>DataSourceSpec</code> objects are equal or not.
      *
      * @param obj Instance of <code>DataSourceSpec</code> object.
      */
@@ -117,6 +118,7 @@
         if (obj instanceof DataSourceSpec) {
             return this.details.equals(((DataSourceSpec) obj).details);
         }
+
         return false;
     }
 
diff --git a/appserver/jdbc/jdbc-ra/jdbc-core/src/main/java/com/sun/gjc/monitoring/JdbcRAConstants.java b/appserver/jdbc/jdbc-ra/jdbc-core/src/main/java/com/sun/gjc/monitoring/JdbcRAConstants.java
index 1282639..8538df0 100644
--- a/appserver/jdbc/jdbc-ra/jdbc-core/src/main/java/com/sun/gjc/monitoring/JdbcRAConstants.java
+++ b/appserver/jdbc/jdbc-ra/jdbc-core/src/main/java/com/sun/gjc/monitoring/JdbcRAConstants.java
@@ -69,17 +69,15 @@
     /**
      * Dotted name used in monitoring for Statement caching.
      */
-    public static final String STATEMENT_CACHE_DOTTED_NAME = GLASSFISH + ":" +
-            JDBCRA + ":" + STATEMENT_CACHE_PROBE + ":";
+    public static final String STATEMENT_CACHE_DOTTED_NAME = GLASSFISH + ":" + JDBCRA + ":" + STATEMENT_CACHE_PROBE
+            + ":";
 
     /**
      * Dotted name used in monitoring for Sql Tracing.
      */
-    public static final String SQL_TRACING_DOTTED_NAME = GLASSFISH + ":" +
-            JDBCRA + ":" + SQL_TRACING_PROBE + ":";
+    public static final String SQL_TRACING_DOTTED_NAME = GLASSFISH + ":" + JDBCRA + ":" + SQL_TRACING_PROBE + ":";
 
-    public static final String STATEMENT_LEAK_DOTTED_NAME = GLASSFISH + ":" +
-            JDBCRA + ":" + STATEMENT_LEAK_PROBE + ":";
+    public static final String STATEMENT_LEAK_DOTTED_NAME = GLASSFISH + ":" + JDBCRA + ":" + STATEMENT_LEAK_PROBE + ":";
 
     /**
      * Represents top queries to report.
@@ -89,15 +87,6 @@
     /**
      * List of valid method names that can be used for sql trace monitoring.
      */
-    public static final List<String> validSqlTracingMethodNames =
-            Collections.unmodifiableList(
-            Arrays.asList(
-                "nativeSQL",
-                "prepareCall",
-                "prepareStatement",
-                "addBatch",
-                "execute",
-                "executeQuery",
-                "executeUpdate"
-            ));
+    public static final List<String> validSqlTracingMethodNames = Collections.unmodifiableList(Arrays.asList(
+            "nativeSQL", "prepareCall", "prepareStatement", "addBatch", "execute", "executeQuery", "executeUpdate"));
 }
diff --git a/appserver/jdbc/jdbc-ra/jdbc-core/src/main/java/com/sun/gjc/monitoring/JdbcStatsProvider.java b/appserver/jdbc/jdbc-ra/jdbc-core/src/main/java/com/sun/gjc/monitoring/JdbcStatsProvider.java
index 6368475..821b783 100644
--- a/appserver/jdbc/jdbc-ra/jdbc-core/src/main/java/com/sun/gjc/monitoring/JdbcStatsProvider.java
+++ b/appserver/jdbc/jdbc-ra/jdbc-core/src/main/java/com/sun/gjc/monitoring/JdbcStatsProvider.java
@@ -16,8 +16,6 @@
 
 package com.sun.gjc.monitoring;
 
-import com.sun.gjc.util.SQLTrace;
-import com.sun.gjc.util.SQLTraceCache;
 import org.glassfish.external.probe.provider.annotations.ProbeListener;
 import org.glassfish.external.probe.provider.annotations.ProbeParam;
 import org.glassfish.external.statistics.CountStatistic;
@@ -31,6 +29,9 @@
 import org.glassfish.gmbal.ManagedObject;
 import org.glassfish.resourcebase.resources.api.PoolInfo;
 
+import com.sun.gjc.util.SQLTrace;
+import com.sun.gjc.util.SQLTraceCache;
+
 /**
  * Provides the monitoring data for JDBC RA module
  *
diff --git a/appserver/jdbc/jdbc-ra/jdbc-core/src/main/java/com/sun/gjc/spi/CPManagedConnectionFactory.java b/appserver/jdbc/jdbc-ra/jdbc-core/src/main/java/com/sun/gjc/spi/CPManagedConnectionFactory.java
index 05f42e4..f8b2f6c 100644
--- a/appserver/jdbc/jdbc-ra/jdbc-core/src/main/java/com/sun/gjc/spi/CPManagedConnectionFactory.java
+++ b/appserver/jdbc/jdbc-ra/jdbc-core/src/main/java/com/sun/gjc/spi/CPManagedConnectionFactory.java
@@ -16,20 +16,33 @@
 
 package com.sun.gjc.spi;
 
-import com.sun.enterprise.util.i18n.StringManager;
-import com.sun.gjc.common.DataSourceObjectBuilder;
-import com.sun.gjc.common.DataSourceSpec;
-import com.sun.gjc.util.SecurityUtils;
-import com.sun.logging.LogDomains;
+import static com.sun.gjc.util.SecurityUtils.getPasswordCredential;
+import static java.util.logging.Level.FINEST;
+import static java.util.logging.Level.SEVERE;
 
-import jakarta.resource.ResourceException;
-import jakarta.resource.spi.ConnectionRequestInfo;
-import jakarta.resource.spi.ResourceAllocationException;
-import jakarta.resource.spi.security.PasswordCredential;
+import java.sql.Connection;
 import java.sql.SQLException;
 import java.util.logging.Level;
 import java.util.logging.Logger;
+
+import javax.security.auth.Subject;
+import javax.sql.ConnectionPoolDataSource;
+import javax.sql.DataSource;
+import javax.sql.PooledConnection;
+
+import com.sun.enterprise.util.i18n.StringManager;
+import com.sun.gjc.common.DataSourceObjectBuilder;
+import com.sun.gjc.common.DataSourceSpec;
+import com.sun.gjc.spi.base.AbstractDataSource;
+import com.sun.gjc.spi.base.ConnectionHolder;
+import com.sun.logging.LogDomains;
+
+import jakarta.resource.ResourceException;
 import jakarta.resource.spi.ConnectionDefinition;
+import jakarta.resource.spi.ConnectionRequestInfo;
+import jakarta.resource.spi.ManagedConnection;
+import jakarta.resource.spi.ResourceAllocationException;
+import jakarta.resource.spi.security.PasswordCredential;
 
 
 /**
@@ -39,20 +52,17 @@
  * @version 1.0, 02/07/30
  */
 @ConnectionDefinition(
-    connectionFactory = javax.sql.DataSource.class,
-    connectionFactoryImpl = com.sun.gjc.spi.base.AbstractDataSource.class,
-    connection = java.sql.Connection.class,
-    connectionImpl = com.sun.gjc.spi.base.ConnectionHolder.class
+    connectionFactory = DataSource.class,
+    connectionFactoryImpl = AbstractDataSource.class,
+    connection = Connection.class,
+    connectionImpl = ConnectionHolder.class
 )
 public class CPManagedConnectionFactory extends ManagedConnectionFactoryImpl {
 
-    private transient javax.sql.ConnectionPoolDataSource cpDataSourceObj;
+    private static Logger _logger = LogDomains.getLogger(CPManagedConnectionFactory.class, LogDomains.RSR_LOGGER);
 
-    private static Logger _logger;
+    private transient ConnectionPoolDataSource connectionPoolDataSource;
 
-    static {
-        _logger = LogDomains.getLogger(CPManagedConnectionFactory.class, LogDomains.RSR_LOGGER);
-    }
 
     /**
      * Returns the underlying datasource
@@ -60,119 +70,86 @@
      * @return DataSource of jdbc vendor
      * @throws ResourceException
      */
-    public javax.sql.ConnectionPoolDataSource getDataSource() throws ResourceException {
-        if (cpDataSourceObj == null) {
+    public ConnectionPoolDataSource getDataSource() throws ResourceException {
+        if (connectionPoolDataSource == null) {
             try {
-                cpDataSourceObj = (javax.sql.ConnectionPoolDataSource) super.getDataSource();
+                connectionPoolDataSource = (ConnectionPoolDataSource) super.getDataSource();
             } catch (ClassCastException cce) {
-                _logger.log(Level.SEVERE, "jdbc.exc_cce_CP", cce);
-                throw new ResourceException(cce.getMessage());
+                _logger.log(SEVERE, "jdbc.exc_cce_CP", cce);
+                throw new ResourceException(cce.getMessage(), cce);
             }
         }
-        return cpDataSourceObj;
+
+        return connectionPoolDataSource;
     }
 
     /**
-     * Creates a new physical connection to the underlying EIS resource
-     * manager.
+     * Creates a new physical connection to the underlying EIS resource manager.
      *
-     * @param subject       <code>Subject</code> instance passed by the application server
+     * @param subject <code>Subject</code> instance passed by the application server
      * @param cxRequestInfo <code>ConnectionRequestInfo</code> which may be created
-     *                      as a result of the invocation <code>getConnection(user, password)</code>
-     *                      on the <code>DataSource</code> object
+     * as a result of the invocation <code>getConnection(user, password)</code> on
+     * the <code>DataSource</code> object
+     *
      * @return <code>ManagedConnection</code> object created
-     * @throws ResourceException           if there is an error in instantiating the
-     *                                     <code>DataSource</code> object used for the
-     *                                     creation of the <code>ManagedConnection</code> object
-     * @throws SecurityException           if there ino <code>PasswordCredential</code> object
-     *                                     satisfying this request
+     *
+     * @throws ResourceException if there is an error in instantiating the
+     * <code>DataSource</code> object used for the creation of the
+     * <code>ManagedConnection</code> object
+     * @throws SecurityException if there ino <code>PasswordCredential</code> object
+     * satisfying this request
      * @throws ResourceAllocationException if there is an error in allocating the
-     *                                     physical connection
+     * physical connection
      */
-    public jakarta.resource.spi.ManagedConnection createManagedConnection(javax.security.auth.Subject subject,
-                                                                        ConnectionRequestInfo cxRequestInfo) throws ResourceException {
+    public ManagedConnection createManagedConnection(Subject subject, ConnectionRequestInfo cxRequestInfo) throws ResourceException {
         logFine("In createManagedConnection");
-        PasswordCredential pc = SecurityUtils.getPasswordCredential(this, subject, cxRequestInfo);
 
-        javax.sql.ConnectionPoolDataSource dataSource = getDataSource();
+        PasswordCredential passwordCredential = getPasswordCredential(this, subject, cxRequestInfo);
 
-        javax.sql.PooledConnection cpConn = null;
-        ManagedConnectionImpl mc = null;
+        ConnectionPoolDataSource dataSource = getDataSource();
+
+        PooledConnection pooledConnection = null;
+        ManagedConnectionImpl managedConnectionImpl = null;
 
         try {
-            /* For the case where the user/passwd of the connection pool is
-            * equal to the PasswordCredential for the connection request
-            * get a connection from this pool directly.
-            * for all other conditions go create a new connection
-            */
-            if (isEqual(pc, getUser(), getPassword())) {
-                cpConn = dataSource.getPooledConnection();
+            /*
+             * For the case where the user/passwd of the connection pool is equal to the
+             * PasswordCredential for the connection request get a connection from this pool
+             * directly. for all other conditions go create a new connection
+             */
+            if (isEqual(passwordCredential, getUser(), getPassword())) {
+                pooledConnection = dataSource.getPooledConnection();
             } else {
-                cpConn = dataSource.getPooledConnection(pc.getUserName(),
-                        new String(pc.getPassword()));
+                pooledConnection = dataSource.getPooledConnection(passwordCredential.getUserName(), new String(passwordCredential.getPassword()));
             }
 
-        } catch (java.sql.SQLException sqle) {
-            //_logger.log(Level.SEVERE, "jdbc.exc_create_ds_conn",sqle);
-            if(_logger.isLoggable(Level.FINE)) {
-                _logger.log(Level.FINE, "jdbc.exc_create_ds_conn", sqle);
-            }
-            StringManager sm =
-                    StringManager.getManager(DataSourceObjectBuilder.class);
-            String msg = sm.getString("jdbc.cannot_allocate_connection", sqle.getMessage());
-            ResourceAllocationException rae = new ResourceAllocationException(
-                    msg, sqle);
-            throw rae;
+        } catch (SQLException sqle) {
+            _logger.log(Level.FINE, "jdbc.exc_create_ds_conn", sqle);
+
+            throw new ResourceAllocationException(
+                StringManager.getManager(DataSourceObjectBuilder.class).getString("jdbc.cannot_allocate_connection", sqle.getMessage()),
+                sqle);
         }
 
         try {
+            managedConnectionImpl = constructManagedConnection(pooledConnection, null, passwordCredential, this);
+            managedConnectionImpl.initializeConnectionType(ManagedConnectionImpl.ISPOOLEDCONNECTION);
 
-            mc = constructManagedConnection(cpConn, null, pc, this);
-
-            mc.initializeConnectionType(ManagedConnectionImpl.ISPOOLEDCONNECTION);
-
-            //GJCINT
-            validateAndSetIsolation(mc);
+            validateAndSetIsolation(managedConnectionImpl);
         } finally {
-            if (mc == null) {
-                if (cpConn != null) {
+            if (managedConnectionImpl == null) {
+                if (pooledConnection != null) {
                     try {
-                        cpConn.close();
+                        pooledConnection.close();
                     } catch (SQLException e) {
-                        _logger.log(Level.FINEST, "Exception while closing connection : createManagedConnection" + cpConn);
+                        _logger.log(FINEST,
+                            "Exception while closing connection : createManagedConnection" + pooledConnection);
                     }
                 }
             }
         }
-        return mc;
-    }
 
-    /**
-     * Check if this <code>ManagedConnectionFactory</code> is equal to
-     * another <code>ManagedConnectionFactory</code>.
-     *
-     * @param other <code>ManagedConnectionFactory</code> object for checking equality with
-     * @return true    if the property sets of both the
-     *         <code>ManagedConnectionFactory</code> objects are the same
-     *         false    otherwise
-     */
-    public boolean equals(Object other) {
-        logFine("In equals");
-        /**
-         * The check below means that two ManagedConnectionFactory objects are equal
-         * if and only if their properties are the same.
-         */
-        if (other instanceof com.sun.gjc.spi.CPManagedConnectionFactory) {
-            com.sun.gjc.spi.CPManagedConnectionFactory otherMCF =
-                    (com.sun.gjc.spi.CPManagedConnectionFactory) other;
-            return this.spec.equals(otherMCF.spec);
-        }
-        return false;
-    }
-
-    @Override
-    public int hashCode() {
-        return 31 * 7 + (spec.hashCode());
+        return managedConnectionImpl;
     }
 
     /**
@@ -294,4 +271,33 @@
     public String getPropertyCycle() {
         return spec.getDetail(DataSourceSpec.PROPERTYCYCLE);
     }
+
+    /**
+     * Check if this <code>ManagedConnectionFactory</code> is equal to another
+     * <code>ManagedConnectionFactory</code>.
+     *
+     * @param other <code>ManagedConnectionFactory</code> object for checking
+     * equality with
+     * @return true if the property sets of both the
+     * <code>ManagedConnectionFactory</code> objects are the same false otherwise
+     */
+    public boolean equals(Object other) {
+        logFine("In equals");
+
+        /**
+         * The check below means that two ManagedConnectionFactory objects are equal if
+         * and only if their properties are the same.
+         */
+        if (other instanceof CPManagedConnectionFactory) {
+            CPManagedConnectionFactory otherMCF = (CPManagedConnectionFactory) other;
+            return this.spec.equals(otherMCF.spec);
+        }
+
+        return false;
+    }
+
+    @Override
+    public int hashCode() {
+        return 31 * 7 + (spec.hashCode());
+    }
 }
diff --git a/appserver/jdbc/jdbc-ra/jdbc-core/src/main/java/com/sun/gjc/spi/ConnectionManagerImplementation.java b/appserver/jdbc/jdbc-ra/jdbc-core/src/main/java/com/sun/gjc/spi/ConnectionManagerImplementation.java
index 6bef1fc..bd7ddca 100644
--- a/appserver/jdbc/jdbc-ra/jdbc-core/src/main/java/com/sun/gjc/spi/ConnectionManagerImplementation.java
+++ b/appserver/jdbc/jdbc-ra/jdbc-core/src/main/java/com/sun/gjc/spi/ConnectionManagerImplementation.java
@@ -17,8 +17,8 @@
 package com.sun.gjc.spi;
 
 import jakarta.resource.ResourceException;
+import jakarta.resource.spi.ConnectionManager;
 import jakarta.resource.spi.ConnectionRequestInfo;
-import jakarta.resource.spi.ManagedConnection;
 import jakarta.resource.spi.ManagedConnectionFactory;
 
 /**
@@ -27,25 +27,26 @@
  * @author Binod P.G
  * @version 1.0, 02/07/31
  */
-public class ConnectionManagerImplementation implements jakarta.resource.spi.ConnectionManager {
+public class ConnectionManagerImplementation implements ConnectionManager {
+
+    private static final long serialVersionUID = 1L;
 
     /**
-     * Returns a <code>Connection </code> object to the <code>ConnectionFactory</code>
+     * Returns a <code>Connection </code> object to the
+     * <code>ConnectionFactory</code>
      *
-     * @param mcf  <code>ManagedConnectionFactory</code> object.
-     * @param info <code>ConnectionRequestInfo</code> object.
+     * @param managedConnectionFactory <code>ManagedConnectionFactory</code> object.
+     * @param connectionRequestInfo <code>ConnectionRequestInfo</code> object.
      * @return A <code>Connection</code> Object.
      * @throws ResourceException In case of an error in getting the <code>Connection</code>.
      */
-    public Object allocateConnection(ManagedConnectionFactory mcf,
-                                     ConnectionRequestInfo info)
-            throws ResourceException {
-        ManagedConnection mc = mcf.createManagedConnection(null, info);
-        return mc.getConnection(null, info);
+    public Object allocateConnection(ManagedConnectionFactory managedConnectionFactory, ConnectionRequestInfo connectionRequestInfo) throws ResourceException {
+        return managedConnectionFactory.createManagedConnection(null, connectionRequestInfo)
+                                       .getConnection(null, connectionRequestInfo);
     }
 
     /*
-    * This class could effectively implement Connection pooling also.
-    * Could be done for FCS.
-    */
+     * This class could effectively implement Connection pooling also. Could be done
+     * for FCS.
+     */
 }
diff --git a/appserver/jdbc/jdbc-ra/jdbc-core/src/main/java/com/sun/gjc/spi/ConnectionRequestInfoImpl.java b/appserver/jdbc/jdbc-ra/jdbc-core/src/main/java/com/sun/gjc/spi/ConnectionRequestInfoImpl.java
index 3e9fefd..385cdbf 100644
--- a/appserver/jdbc/jdbc-ra/jdbc-core/src/main/java/com/sun/gjc/spi/ConnectionRequestInfoImpl.java
+++ b/appserver/jdbc/jdbc-ra/jdbc-core/src/main/java/com/sun/gjc/spi/ConnectionRequestInfoImpl.java
@@ -18,13 +18,15 @@
 
 import java.util.Arrays;
 
+import jakarta.resource.spi.ConnectionRequestInfo;
+
 /**
  * ConnectionRequestInfo implementation for Generic JDBC Connector.
  *
  * @author Binod P.G
  * @version 1.0, 02/07/31
  */
-public class ConnectionRequestInfoImpl implements jakarta.resource.spi.ConnectionRequestInfo {
+public class ConnectionRequestInfoImpl implements ConnectionRequestInfo {
 
     private String user;
     private char[] password;
@@ -32,7 +34,7 @@
     /**
      * Constructs a new <code>ConnectionRequestInfoImpl</code> object
      *
-     * @param user     User Name.
+     * @param user User Name.
      * @param password Password
      */
     public ConnectionRequestInfoImpl(String user, char[] password) {
@@ -64,14 +66,16 @@
      * @return True, if they are equal and false otherwise.
      */
     public boolean equals(Object obj) {
-        if (obj == null) return false;
-        if (obj instanceof ConnectionRequestInfoImpl) {
-            ConnectionRequestInfoImpl other = (ConnectionRequestInfoImpl) obj;
-            return (isEqual(this.user, other.user) &&
-                    Arrays.equals(this.password, other.password));
-        } else {
+        if (obj == null) {
             return false;
         }
+
+        if (obj instanceof ConnectionRequestInfoImpl) {
+            ConnectionRequestInfoImpl other = (ConnectionRequestInfoImpl) obj;
+            return (isEqual(this.user, other.user) && Arrays.equals(this.password, other.password));
+        }
+
+        return false;
     }
 
     /**
@@ -93,9 +97,9 @@
     private boolean isEqual(Object o1, Object o2) {
         if (o1 == null) {
             return (o2 == null);
-        } else {
-            return o1.equals(o2);
         }
+
+        return o1.equals(o2);
     }
 
 }
diff --git a/appserver/jdbc/jdbc-ra/jdbc-core/src/main/java/com/sun/gjc/spi/DMManagedConnectionFactory.java b/appserver/jdbc/jdbc-ra/jdbc-core/src/main/java/com/sun/gjc/spi/DMManagedConnectionFactory.java
index 423a52e..ea7f356 100644
--- a/appserver/jdbc/jdbc-ra/jdbc-core/src/main/java/com/sun/gjc/spi/DMManagedConnectionFactory.java
+++ b/appserver/jdbc/jdbc-ra/jdbc-core/src/main/java/com/sun/gjc/spi/DMManagedConnectionFactory.java
@@ -16,14 +16,12 @@
 
 package com.sun.gjc.spi;
 
-import com.sun.gjc.common.DataSourceObjectBuilder;
-import com.sun.gjc.common.DataSourceSpec;
-import com.sun.gjc.util.SecurityUtils;
-import com.sun.logging.LogDomains;
+import static com.sun.gjc.util.SecurityUtils.getPasswordCredential;
+import static java.util.logging.Level.FINE;
+import static java.util.logging.Level.FINEST;
+import static java.util.logging.Level.SEVERE;
 
-import jakarta.resource.ResourceException;
-import jakarta.resource.spi.ConnectionRequestInfo;
-import jakarta.resource.spi.security.PasswordCredential;
+import java.sql.Connection;
 import java.sql.DriverManager;
 import java.sql.SQLException;
 import java.util.Hashtable;
@@ -31,135 +29,141 @@
 import java.util.Properties;
 import java.util.Set;
 import java.util.Vector;
-import java.util.logging.Level;
 import java.util.logging.Logger;
+
+import javax.security.auth.Subject;
+import javax.sql.DataSource;
+
+import com.sun.gjc.common.DataSourceObjectBuilder;
+import com.sun.gjc.common.DataSourceSpec;
+import com.sun.gjc.spi.base.AbstractDataSource;
+import com.sun.gjc.spi.base.ConnectionHolder;
+import com.sun.logging.LogDomains;
+
+import jakarta.resource.ResourceException;
 import jakarta.resource.spi.ConfigProperty;
 import jakarta.resource.spi.ConnectionDefinition;
+import jakarta.resource.spi.ConnectionRequestInfo;
+import jakarta.resource.spi.ManagedConnection;
+import jakarta.resource.spi.ResourceAllocationException;
+import jakarta.resource.spi.security.PasswordCredential;
 
 /**
- * Driver Manager <code>ManagedConnectionFactory</code> implementation for Generic JDBC Connector.
+ * Driver Manager <code>ManagedConnectionFactory</code> implementation for
+ * Generic JDBC Connector.
  *
  * @author Evani Sai Surya Kiran
  * @version 1.0, 02/07/31
  */
-@ConnectionDefinition(
-    connectionFactory = javax.sql.DataSource.class,
-    connectionFactoryImpl = com.sun.gjc.spi.base.AbstractDataSource.class,
-    connection = java.sql.Connection.class,
-    connectionImpl = com.sun.gjc.spi.base.ConnectionHolder.class
-)
+@ConnectionDefinition(connectionFactory = DataSource.class, connectionFactoryImpl = AbstractDataSource.class, connection = Connection.class, connectionImpl = ConnectionHolder.class)
 public class DMManagedConnectionFactory extends ManagedConnectionFactoryImpl {
 
+    private static Logger _logger = LogDomains.getLogger(DMManagedConnectionFactory.class, LogDomains.RSR_LOGGER);
+    private boolean debug = _logger.isLoggable(FINE);
+
     Properties props;
 
-    private static Logger _logger;
-
-    static {
-        _logger = LogDomains.getLogger(DMManagedConnectionFactory.class, LogDomains.RSR_LOGGER);
-    }
-
-    private boolean debug = _logger.isLoggable(Level.FINE);
-
     /**
-     * Creates a new physical connection to the underlying EIS resource
-     * manager.
+     * Creates a new physical connection to the underlying EIS resource manager.
      *
-     * @param subject       <code>Subject</code> instance passed by the application server
+     * @param subject <code>Subject</code> instance passed by the application server
      * @param cxRequestInfo <code>ConnectionRequestInfo</code> which may be created
-     *                      as a result of the invocation <code>getConnection(user, password)</code>
-     *                      on the <code>DataSource</code> object
+     * as a result of the invocation <code>getConnection(user, password)</code> on
+     * the <code>DataSource</code> object
+     *
      * @return <code>ManagedConnection</code> object created
+     *
      * @throws ResourceException if there is an error in instantiating the
-     *                           <code>DataSource</code> object used for the
-     *                           creation of the <code>ManagedConnection</code> object
+     * <code>DataSource</code> object used for the creation of the
+     * <code>ManagedConnection</code> object
      * @throws SecurityException if there ino <code>PasswordCredential</code> object
-     *                           satisfying this request
+     * satisfying this request
      */
-    public jakarta.resource.spi.ManagedConnection createManagedConnection(javax.security.auth.Subject subject,
-                                                                        ConnectionRequestInfo cxRequestInfo) throws ResourceException {
+    public ManagedConnection createManagedConnection(Subject subject, ConnectionRequestInfo cxRequestInfo) throws ResourceException {
         logFine("In createManagedConnection");
-        if (dsObjBuilder == null) {
-            dsObjBuilder = new DataSourceObjectBuilder(spec);
+
+        if (dataSourceObjectBuilder == null) {
+            dataSourceObjectBuilder = new DataSourceObjectBuilder(spec);
         }
-        PasswordCredential pc = SecurityUtils.getPasswordCredential(this, subject, cxRequestInfo);
+
+        PasswordCredential passwordCredential = getPasswordCredential(this, subject, cxRequestInfo);
 
         try {
             Class.forName(spec.getDetail(DataSourceSpec.CLASSNAME));
         } catch (ClassNotFoundException cnfe) {
-            _logger.log(Level.SEVERE, "jdbc.exc_cnfe", cnfe);
+            _logger.log(SEVERE, "jdbc.exc_cnfe", cnfe);
             throw new ResourceException("The driver could not be loaded: " + spec.getDetail(DataSourceSpec.CLASSNAME));
         }
 
-        java.sql.Connection dsConn = null;
-        ManagedConnectionImpl mc = null;
+        Connection connection = null;
+        ManagedConnectionImpl managedConnectionImpl = null;
 
         Properties driverProps = new Properties();
-        //Will return a set of properties that would have setURL and <url> as objects
-        //Get a set of normal case properties
-        Hashtable properties = dsObjBuilder.parseDriverProperties(spec, false);
-        Set<Map.Entry<String,Vector>> entries =
-                (Set<Map.Entry<String, Vector>>) properties.entrySet();
-        for(Map.Entry<String, Vector> entry : entries) {
+
+        // Will return a set of properties that would have setURL and <url> as objects
+        // Get a set of normal case properties
+        Hashtable properties = dataSourceObjectBuilder.parseDriverProperties(spec, false);
+        Set<Map.Entry<String, Vector>> entries = properties.entrySet();
+        for (Map.Entry<String, Vector> entry : entries) {
             String value = "";
-            String key = (String) entry.getKey();
-            Vector values = (Vector) entry.getValue();
-            if(!values.isEmpty() && values.size() == 1) {
+            String key = entry.getKey();
+            Vector values = entry.getValue();
+            if (!values.isEmpty() && values.size() == 1) {
                 value = (String) values.firstElement();
-            } else if(values.size() > 1) {
+            } else if (values.size() > 1) {
                 logFine("More than one value for key : " + key);
             }
+
             String prop = getParsedKey(key);
             driverProps.put(prop, value);
-            if(prop.equalsIgnoreCase("URL")) {
-                if(spec.getDetail(DataSourceSpec.URL) == null) {
+            if (prop.equalsIgnoreCase("URL")) {
+                if (spec.getDetail(DataSourceSpec.URL) == null) {
                     setConnectionURL(value);
                 }
             }
         }
+
         try {
             if (cxRequestInfo != null) {
-                driverProps.setProperty("user", pc.getUserName());
-                driverProps.setProperty("password", new String(pc.getPassword()));
+                driverProps.setProperty("user", passwordCredential.getUserName());
+                driverProps.setProperty("password", new String(passwordCredential.getPassword()));
             } else {
                 String user = spec.getDetail(DataSourceSpec.USERNAME);
                 String password = spec.getDetail(DataSourceSpec.PASSWORD);
-                if(user != null) {
+                if (user != null) {
                     driverProps.setProperty("user", user);
                 }
-                if(password != null) {
+                if (password != null) {
                     driverProps.setProperty("password", password);
                 }
             }
 
-            dsConn = DriverManager.getConnection(spec.getDetail(DataSourceSpec.URL), driverProps);
+            connection = DriverManager.getConnection(spec.getDetail(DataSourceSpec.URL), driverProps);
 
-        } catch (java.sql.SQLException sqle) {
-            _logger.log(Level.SEVERE, "jdbc.exc_create_mc", sqle);
-            throw new jakarta.resource.spi.ResourceAllocationException("The connection could not be allocated: " +
-                    sqle.getMessage());
+        } catch (SQLException sqle) {
+            _logger.log(SEVERE, "jdbc.exc_create_mc", sqle);
+            throw new ResourceAllocationException("The connection could not be allocated: " + sqle.getMessage());
         }
 
         try {
-
-            mc = constructManagedConnection(null, dsConn, pc, this);
-
-            //GJCINT
-            validateAndSetIsolation(mc);
+            managedConnectionImpl = constructManagedConnection(null, connection, passwordCredential, this);
+            validateAndSetIsolation(managedConnectionImpl);
         } finally {
-            if (mc == null) {
+            if (managedConnectionImpl == null) {
                 try {
-                    dsConn.close();
+                    connection.close();
                 } catch (SQLException e) {
-                    _logger.log(Level.FINEST, "Exception while closing connection : createManagedConnection" + dsConn);
+                    _logger.log(FINEST, "Exception while closing connection : createManagedConnection" + connection, e);
                 }
             }
         }
-        return mc;
+
+        return managedConnectionImpl;
     }
 
     /**
-     * Parses the key and removes the "set" string at the beginning of the
-     * property.
+     * Parses the key and removes the "set" string at the beginning of the property.
+     *
      * @param key
      * @return
      */
@@ -170,138 +174,25 @@
             indexOfSet = key.indexOf("set");
         } catch (NullPointerException npe) {
             if (debug) {
-                _logger.log(Level.FINE, "jdbc.exc_caught_ign", npe.getMessage());
+                _logger.log(FINE, "jdbc.exc_caught_ign", npe.getMessage());
             }
 
         }
         if (indexOfSet == 0) {
-            //Find the key String
-
+            // Find the key String
             try {
                 parsedKey = key.substring(indexOfSet + 3, key.length()).trim();
             } catch (IndexOutOfBoundsException iobe) {
                 if (debug) {
-                    _logger.log(Level.FINE, "jdbc.exc_caught_ign", iobe.getMessage());
+                    _logger.log(FINE, "jdbc.exc_caught_ign", iobe.getMessage());
                 }
             }
             if (parsedKey != null && parsedKey.equals("")) {
-                throw new ResourceException("Invalid driver properties string - " +
-                        "Key cannot be an empty string");
+                throw new ResourceException("Invalid driver properties string - " + "Key cannot be an empty string");
             }
         }
+
         return parsedKey;
-
-    }
-
-    /**
-     * This method checks if the properties object is null or not.
-     * If the properties object is null, it creates a new Properties
-     * object and inserts the default "user" and "password" key value
-     * pairs. It checks if any other properties have been set or not
-     * and includes the key value pairs for those properties.
-     *
-     * @return props    <code>Properties</code> object conatining properties for getting a connection
-     * @throws ResourceException if the driver properties string and delimiter are not proper
-     */
-    //TODO remove unused method
-    /*private Properties getPropertiesObj() throws ResourceException {
-        if (props != null) {
-            return props;
-        }
-
-        props = new Properties();
-        props.setProperty("user", getUser());
-        props.setProperty("password", getPassword());
-
-        String driverProps = spec.getDetail(DataSourceSpec.DRIVERPROPERTIES);
-        String delimiter = spec.getDetail(DataSourceSpec.DELIMITER);
-
-        if (driverProps != null && driverProps.trim().equals("") == false) {
-            if (delimiter == null || delimiter.equals("")) {
-                throw new ResourceException("Invalid driver properties string - " +
-                        "delimiter not properly set!!");
-            }
-
-            StringTokenizer st = new StringTokenizer(driverProps, delimiter);
-            while (st.hasMoreTokens()) {
-                String keyValuePair = null;
-                try {
-                    keyValuePair = st.nextToken();
-                } catch (NoSuchElementException nsee) {
-                    throw new ResourceException("Invalid driver properties string - " +
-                            "Key value pair not available: " + nsee.getMessage());
-                }
-
-                int indexOfEqualsSign = -1;
-                try {
-                    indexOfEqualsSign = keyValuePair.indexOf("=");
-                    if (indexOfEqualsSign == -1) {
-                        throw new ResourceException("Invalid driver properties string - " +
-                                "Key value pair should be of the form key = value");
-                    }
-                } catch (NullPointerException npe) {
-                    if (debug) {
-                        _logger.log(Level.FINE, "jdbc.exc_caught_ign", npe.getMessage());
-                    }
-
-                }
-
-                String key = null;
-                try {
-                    key = keyValuePair.substring(0, indexOfEqualsSign).trim();
-                } catch (IndexOutOfBoundsException iobe) {
-                    if (debug) {
-                        _logger.log(Level.FINE, "jdbc.exc_caught_ign", iobe.getMessage());
-                    }
-                }
-                if (key != null && key.equals("")) {
-                    throw new ResourceException("Invalid driver properties string - " +
-                            "Key cannot be an empty string");
-                }
-
-                String value = null;
-                try {
-                    value = keyValuePair.substring(indexOfEqualsSign + 1).trim();
-                } catch (IndexOutOfBoundsException iobe) {
-                    if (debug) {
-                        _logger.log(Level.FINE, "jdbc.exc_caught_ign", iobe.getMessage());
-                    }
-                }
-
-                props.setProperty(key, value);
-            }
-        }
-
-        return props;
-    } */
-
-    /**
-     * Check if this <code>ManagedConnectionFactory</code> is equal to
-     * another <code>ManagedConnectionFactory</code>.
-     *
-     * @param other <code>ManagedConnectionFactory</code> object for checking equality with
-     * @return true    if the property sets of both the
-     *         <code>ManagedConnectionFactory</code> objects are the same
-     *         false    otherwise
-     */
-    public boolean equals(Object other) {
-        logFine("In equals");
-
-        /**
-         * The check below means that two ManagedConnectionFactory objects are equal
-         * if and only if their properties are the same.
-         */
-        if (other instanceof com.sun.gjc.spi.DMManagedConnectionFactory) {
-            com.sun.gjc.spi.DMManagedConnectionFactory otherMCF =
-                    (com.sun.gjc.spi.DMManagedConnectionFactory) other;
-            return this.spec.equals(otherMCF.spec);
-        }
-        return false;
-    }
-
-    @Override
-    public int hashCode() {
-        return 31 * 7 + (spec.hashCode());
     }
 
     /**
@@ -311,14 +202,12 @@
      * @see <code>getLoginTimeOut</code>
      */
     public void setLoginTimeOut(String loginTimeOut) {
-        int timeOut = 0;
         try {
-            timeOut = Integer.parseInt(loginTimeOut);
-            DriverManager.setLoginTimeout(timeOut);
+            DriverManager.setLoginTimeout(Integer.parseInt(loginTimeOut));
             spec.setDetail(DataSourceSpec.LOGINTIMEOUT, loginTimeOut);
         } catch (Exception e) {
             if (debug) {
-                _logger.log(Level.FINE, "jdbc.exc_caught_ign", e.getMessage());
+                _logger.log(FINE, "jdbc.exc_caught_ign", e.getMessage());
             }
         }
     }
@@ -365,4 +254,33 @@
     public Object getDataSource() throws ResourceException {
         return null;
     }
+
+    /**
+     * Check if this <code>ManagedConnectionFactory</code> is equal to another
+     * <code>ManagedConnectionFactory</code>.
+     *
+     * @param other <code>ManagedConnectionFactory</code> object for checking
+     * equality with
+     * @return true if the property sets of both the
+     * <code>ManagedConnectionFactory</code> objects are the same false otherwise
+     */
+    public boolean equals(Object other) {
+        logFine("In equals");
+
+        /**
+         * The check below means that two ManagedConnectionFactory objects are equal if
+         * and only if their properties are the same.
+         */
+        if (other instanceof DMManagedConnectionFactory) {
+            DMManagedConnectionFactory otherMCF = (DMManagedConnectionFactory) other;
+            return this.spec.equals(otherMCF.spec);
+        }
+
+        return false;
+    }
+
+    @Override
+    public int hashCode() {
+        return 31 * 7 + (spec.hashCode());
+    }
 }
diff --git a/appserver/jdbc/jdbc-ra/jdbc-core/src/main/java/com/sun/gjc/spi/DSManagedConnectionFactory.java b/appserver/jdbc/jdbc-ra/jdbc-core/src/main/java/com/sun/gjc/spi/DSManagedConnectionFactory.java
index 9bb6a24..90cc252 100644
--- a/appserver/jdbc/jdbc-ra/jdbc-core/src/main/java/com/sun/gjc/spi/DSManagedConnectionFactory.java
+++ b/appserver/jdbc/jdbc-ra/jdbc-core/src/main/java/com/sun/gjc/spi/DSManagedConnectionFactory.java
@@ -16,19 +16,30 @@
 
 package com.sun.gjc.spi;
 
+import static com.sun.gjc.util.SecurityUtils.getPasswordCredential;
+import static java.util.logging.Level.FINE;
+import static java.util.logging.Level.FINEST;
+import static java.util.logging.Level.SEVERE;
+
+import java.sql.Connection;
+import java.sql.SQLException;
+import java.util.logging.Logger;
+
+import javax.security.auth.Subject;
+import javax.sql.DataSource;
+
 import com.sun.enterprise.util.i18n.StringManager;
 import com.sun.gjc.common.DataSourceObjectBuilder;
-import com.sun.gjc.util.SecurityUtils;
+import com.sun.gjc.spi.base.AbstractDataSource;
+import com.sun.gjc.spi.base.ConnectionHolder;
 import com.sun.logging.LogDomains;
 
 import jakarta.resource.ResourceException;
+import jakarta.resource.spi.ConnectionDefinition;
 import jakarta.resource.spi.ConnectionRequestInfo;
+import jakarta.resource.spi.ManagedConnection;
 import jakarta.resource.spi.ResourceAllocationException;
 import jakarta.resource.spi.security.PasswordCredential;
-import java.sql.SQLException;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-import jakarta.resource.spi.ConnectionDefinition;
 
 /**
  * Data Source <code>ManagedConnectionFactory</code> implementation for Generic JDBC Connector.
@@ -38,93 +49,82 @@
  */
 
 @ConnectionDefinition(
-    connectionFactory = javax.sql.DataSource.class,
-    connectionFactoryImpl = com.sun.gjc.spi.base.AbstractDataSource.class,
+    connectionFactory = DataSource.class,
+    connectionFactoryImpl = AbstractDataSource.class,
     connection = java.sql.Connection.class,
-    connectionImpl = com.sun.gjc.spi.base.ConnectionHolder.class
+    connectionImpl = ConnectionHolder.class
 )
 public class DSManagedConnectionFactory extends ManagedConnectionFactoryImpl {
 
-    private transient javax.sql.DataSource dataSourceObj;
+    private static Logger _logger = LogDomains.getLogger(DSManagedConnectionFactory.class, LogDomains.RSR_LOGGER);
 
-    private static Logger _logger;
-
-    static {
-        _logger = LogDomains.getLogger(DSManagedConnectionFactory.class, LogDomains.RSR_LOGGER);
-    }
+    private transient DataSource dataSourceObj;
 
     /**
-     * Creates a new physical connection to the underlying EIS resource
-     * manager.
+     * Creates a new physical connection to the underlying EIS resource manager.
      *
-     * @param subject       <code>Subject</code> instance passed by the application server
-     * @param cxRequestInfo <code>ConnectionRequestInfo</code> which may be created
-     *                      as a result of the invocation <code>getConnection(user, password)</code>
-     *                      on the <code>DataSource</code> object
+     * @param subject <code>Subject</code> instance passed by the application server
+     * @param connectionRequestInfo <code>ConnectionRequestInfo</code> which may be created
+     * as a result of the invocation <code>getConnection(user, password)</code> on
+     * the <code>DataSource</code> object
+     *
      * @return <code>ManagedConnection</code> object created
-     * @throws ResourceException           if there is an error in instantiating the
-     *                                     <code>DataSource</code> object used for the
-     *                                     creation of the <code>ManagedConnection</code> object
-     * @throws SecurityException           if there ino <code>PasswordCredential</code> object
-     *                                     satisfying this request
+     *
+     * @throws ResourceException if there is an error in instantiating the
+     * <code>DataSource</code> object used for the creation of the
+     * <code>ManagedConnection</code> object
+     * @throws SecurityException if there ino <code>PasswordCredential</code> object
+     * satisfying this request
      * @throws ResourceAllocationException if there is an error in allocating the
-     *                                     physical connection
+     * physical connection
      */
-    public jakarta.resource.spi.ManagedConnection createManagedConnection(javax.security.auth.Subject subject,
-                                                                        ConnectionRequestInfo cxRequestInfo) throws ResourceException {
+    public ManagedConnection createManagedConnection(Subject subject, ConnectionRequestInfo connectionRequestInfo) throws ResourceException {
         logFine("In createManagedConnection");
-        PasswordCredential pc = SecurityUtils.getPasswordCredential(this, subject, cxRequestInfo);
+        PasswordCredential passwordCredential = getPasswordCredential(this, subject, connectionRequestInfo);
 
-        javax.sql.DataSource dataSource = getDataSource();
+        DataSource dataSource = getDataSource();
 
-        java.sql.Connection dsConn = null;
-        ManagedConnectionImpl mc = null;
+        Connection connection = null;
+        ManagedConnectionImpl managedConnectionImpl = null;
 
         try {
-            /* For the case where the user/passwd of the connection pool is
-            * equal to the PasswordCredential for the connection request
-            * get a connection from this pool directly.
-            * for all other conditions go create a new connection
-            */
 
-            if (isEqual(pc, getUser(), getPassword())) {
-                dsConn = dataSource.getConnection();
+            /*
+             * For the case where the user/passwd of the connection pool is equal to the
+             * PasswordCredential for the connection request get a connection from this pool
+             * directly. for all other conditions go create a new connection
+             */
+            if (isEqual(passwordCredential, getUser(), getPassword())) {
+                connection = dataSource.getConnection();
             } else {
-                dsConn = dataSource.getConnection(pc.getUserName(),
-                        new String(pc.getPassword()));
+                connection = dataSource.getConnection(passwordCredential.getUserName(), new String(passwordCredential.getPassword()));
             }
-        } catch (java.sql.SQLException sqle) {
-            //_logger.log(Level.WARNING, "jdbc.exc_create_conn", sqle.getMessage());
-            if(_logger.isLoggable(Level.FINE)) {
-                _logger.log(Level.FINE, "jdbc.exc_create_conn", sqle.getMessage());
-            }
-            StringManager localStrings =
-                    StringManager.getManager(DataSourceObjectBuilder.class);
-            String msg = localStrings.getString("jdbc.cannot_allocate_connection"
-                    , sqle.getMessage());
-            ResourceAllocationException rae = new ResourceAllocationException(msg);
-            rae.initCause(sqle);
-            throw rae;
+        } catch (SQLException sqle) {
+            _logger.log(FINE, "jdbc.exc_create_conn", sqle.getMessage());
+
+            throw new ResourceAllocationException(
+                StringManager.getManager(DataSourceObjectBuilder.class).getString("jdbc.cannot_allocate_connection", sqle.getMessage()),
+                sqle);
         }
 
         try {
-            mc = constructManagedConnection(null, dsConn, pc, this);
+            managedConnectionImpl = constructManagedConnection(null, connection, passwordCredential, this);
 
-            //GJCINT
-            validateAndSetIsolation(mc);
+            validateAndSetIsolation(managedConnectionImpl);
         } finally {
-            if (mc == null) {
-                if (dsConn != null) {
+            if (managedConnectionImpl == null) {
+                if (connection != null) {
                     try {
-                        dsConn.close();
+                        connection.close();
                     } catch (SQLException e) {
-                        _logger.log(Level.FINEST, "Exception while closing connection : " +
-                                "createManagedConnection" + dsConn);
+                        _logger.log(FINEST,
+                            "Exception while closing connection : " + "createManagedConnection" + connection);
                     }
                 }
             }
         }
-        return mc;
+
+        return managedConnectionImpl;
     }
 
     /**
@@ -133,38 +133,40 @@
      * @return DataSource of jdbc vendor
      * @throws ResourceException
      */
-    public javax.sql.DataSource getDataSource() throws ResourceException {
+    public DataSource getDataSource() throws ResourceException {
         if (dataSourceObj == null) {
             try {
-                dataSourceObj = (javax.sql.DataSource) super.getDataSource();
+                dataSourceObj = (DataSource) super.getDataSource();
             } catch (ClassCastException cce) {
-                _logger.log(Level.SEVERE, "jdbc.exc_cce", cce);
+                _logger.log(SEVERE, "jdbc.exc_cce", cce);
                 throw new ResourceException(cce.getMessage());
             }
         }
+
         return dataSourceObj;
     }
 
     /**
-     * Check if this <code>ManagedConnectionFactory</code> is equal to
-     * another <code>ManagedConnectionFactory</code>.
+     * Check if this <code>ManagedConnectionFactory</code> is equal to another
+     * <code>ManagedConnectionFactory</code>.
      *
-     * @param other <code>ManagedConnectionFactory</code> object for checking equality with
-     * @return true    if the property sets of both the
-     *         <code>ManagedConnectionFactory</code> objects are the same
-     *         false    otherwise
+     * @param other <code>ManagedConnectionFactory</code> object for checking
+     * equality with
+     * @return true if the property sets of both the
+     * <code>ManagedConnectionFactory</code> objects are the same false otherwise
      */
     public boolean equals(Object other) {
         logFine("In equals");
+
         /**
-         * The check below means that two ManagedConnectionFactory objects are equal
-         * if and only if their properties are the same.
+         * The check below means that two ManagedConnectionFactory objects are equal if
+         * and only if their properties are the same.
          */
-        if (other instanceof com.sun.gjc.spi.DSManagedConnectionFactory) {
-            com.sun.gjc.spi.DSManagedConnectionFactory otherMCF =
-                    (com.sun.gjc.spi.DSManagedConnectionFactory) other;
+        if (other instanceof DSManagedConnectionFactory) {
+            DSManagedConnectionFactory otherMCF = (DSManagedConnectionFactory) other;
             return this.spec.equals(otherMCF.spec);
         }
+
         return false;
     }
 
diff --git a/appserver/jdbc/jdbc-ra/jdbc-core/src/main/java/com/sun/gjc/spi/JdbcObjectsFactory.java b/appserver/jdbc/jdbc-ra/jdbc-core/src/main/java/com/sun/gjc/spi/JdbcObjectsFactory.java
index d3af802..899e581 100644
--- a/appserver/jdbc/jdbc-ra/jdbc-core/src/main/java/com/sun/gjc/spi/JdbcObjectsFactory.java
+++ b/appserver/jdbc/jdbc-ra/jdbc-core/src/main/java/com/sun/gjc/spi/JdbcObjectsFactory.java
@@ -16,50 +16,62 @@
 
 package com.sun.gjc.spi;
 
-import com.sun.gjc.common.DataSourceObjectBuilder;
-import com.sun.gjc.spi.base.ConnectionHolder;
-import com.sun.gjc.util.SQLTraceDelegator;
-import com.sun.logging.LogDomains;
+import static java.util.logging.Level.SEVERE;
+import static java.util.logging.Level.WARNING;
 
 import java.io.Serializable;
 import java.lang.reflect.InvocationHandler;
 import java.lang.reflect.Method;
 import java.lang.reflect.Proxy;
 import java.sql.Connection;
-import java.util.logging.Level;
 import java.util.logging.Logger;
+
+import javax.sql.DataSource;
+
 import org.glassfish.api.jdbc.SQLTraceRecord;
 
+import com.sun.gjc.common.DataSourceObjectBuilder;
+import com.sun.gjc.spi.base.ConnectionHolder;
+import com.sun.gjc.util.SQLTraceDelegator;
+import com.sun.logging.LogDomains;
+
+import jakarta.resource.spi.ConnectionManager;
+import jakarta.resource.spi.ConnectionRequestInfo;
 
 /**
  * Factory to create JDBC objects
  */
 public abstract class JdbcObjectsFactory implements Serializable {
 
-    protected final static Logger _logger;
-
-    static {
-        _logger = LogDomains.getLogger(JdbcObjectsFactory.class, LogDomains.RSR_LOGGER);
-    }
+    private static final long serialVersionUID = 1L;
+    protected final static Logger _logger = LogDomains.getLogger(JdbcObjectsFactory.class, LogDomains.RSR_LOGGER);
 
     /**
-     * Returns JDBC Objet Factory for JDBC 3.0 or JDBC 4.0 depending upon the jdbc version<br>
-     * available in JDK.<br>
+     * Returns JDBC Object Factory for JDBC 3.0 or JDBC 4.0 depending upon the jdbc
+     * version available in JDK.
      *
      * @return JdbcObjectsFactory
      */
     public static JdbcObjectsFactory getInstance() {
         boolean jdbc40 = DataSourceObjectBuilder.isJDBC40();
+
         JdbcObjectsFactory factory = null;
         try {
             if (jdbc40) {
-                factory = (JdbcObjectsFactory) Class.forName("com.sun.gjc.spi.jdbc40.Jdbc40ObjectsFactory").newInstance();
+                factory = (JdbcObjectsFactory)
+                    Class.forName("com.sun.gjc.spi.jdbc40.Jdbc40ObjectsFactory")
+                         .getDeclaredConstructor()
+                         .newInstance();
             } else {
-                factory = (JdbcObjectsFactory) Class.forName("com.sun.gjc.spi.jdbc30.Jdbc30ObjectsFactory").newInstance();
+                factory = (JdbcObjectsFactory)
+                    Class.forName("com.sun.gjc.spi.jdbc30.Jdbc30ObjectsFactory")
+                         .getDeclaredConstructor()
+                         .newInstance();
             }
         } catch (Exception e) {
-            _logger.log(Level.WARNING, "jdbc.jdbc_factory_class_load_exception", e);
+            _logger.log(WARNING, "jdbc.jdbc_factory_class_load_exception", e);
         }
+
         return factory;
     }
 
@@ -67,45 +79,38 @@
      * Returns a DataSource instance.
      *
      * @param mcfObject Managed Connection Factory
-     * @param cmObject  Connection Manager
+     * @param cmObject Connection Manager
      * @return DataSource
      */
-    public abstract javax.sql.DataSource getDataSourceInstance(ManagedConnectionFactoryImpl mcfObject,
-                                                               jakarta.resource.spi.ConnectionManager cmObject);
+    public abstract DataSource getDataSourceInstance(ManagedConnectionFactoryImpl mcfObject, ConnectionManager cmObject);
 
     /**
      * To get an instance of ConnectionHolder.<br>
      * Will return a ConnectionHolder with or without wrapper<br>
      *
-     * @param conObject         Connection
-     * @param mcObject          ManagedConnection
-     * @param criObject         Connection Request Info
+     * @param conObject Connection
+     * @param mcObject ManagedConnection
+     * @param criObject Connection Request Info
      * @param statementWrapping Whether to wrap statement objects or not.
      * @return ConnectionHolder
      */
-    public abstract ConnectionHolder getConnection(Connection conObject,
-                                                   ManagedConnectionImpl mcObject,
-                                                   jakarta.resource.spi.ConnectionRequestInfo criObject,
-                                                   boolean statementWrapping,
-                                                   SQLTraceDelegator sqlTraceDelegator);
+    public abstract ConnectionHolder getConnection(Connection conObject, ManagedConnectionImpl mcObject,
+            ConnectionRequestInfo criObject, boolean statementWrapping,
+            SQLTraceDelegator sqlTraceDelegator);
 
-    protected Connection getProxiedConnection(final Object conObject, Class[] connIntf,
-            final SQLTraceDelegator sqlTraceDelegator) {
+    protected Connection getProxiedConnection(final Object conObject, Class[] connIntf, final SQLTraceDelegator sqlTraceDelegator) {
         Connection proxiedConn = null;
         try {
-
             proxiedConn = (Connection) getProxyObject(conObject, connIntf, sqlTraceDelegator);
         } catch (Exception ex) {
-            _logger.log(Level.SEVERE, "jdbc.jdbc_proxied_connection_get_exception", ex.getMessage());
+            _logger.log(SEVERE, "jdbc.jdbc_proxied_connection_get_exception", ex.getMessage());
         }
+
         return proxiedConn;
     }
 
-    protected <T> T getProxyObject(final Object actualObject, Class<T>[] ifaces,
-            final SQLTraceDelegator sqlTraceDelegator) throws Exception {
-
-        T result;
-        InvocationHandler ih = new InvocationHandler() {
+    protected <T> T getProxyObject(final Object actualObject, Class<T>[] ifaces, final SQLTraceDelegator sqlTraceDelegator) throws Exception {
+        InvocationHandler invocationHandler = new InvocationHandler() {
 
             public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                 SQLTraceRecord record = new SQLTraceRecord();
@@ -116,11 +121,12 @@
                 record.setThreadID(Thread.currentThread().getId());
                 record.setTimeStamp(System.currentTimeMillis());
                 sqlTraceDelegator.sqlTrace(record);
+
                 return method.invoke(actualObject, args);
             }
         };
-        result = (T) Proxy.newProxyInstance(actualObject.getClass().getClassLoader(), ifaces, ih);
-        return result;
+
+        return (T) Proxy.newProxyInstance(actualObject.getClass().getClassLoader(), ifaces, invocationHandler);
     }
 
 }
diff --git a/appserver/jdbc/jdbc-ra/jdbc-core/src/main/java/com/sun/gjc/spi/LocalTransactionImpl.java b/appserver/jdbc/jdbc-ra/jdbc-core/src/main/java/com/sun/gjc/spi/LocalTransactionImpl.java
index 7a8f77b..f3501eb 100644
--- a/appserver/jdbc/jdbc-ra/jdbc-core/src/main/java/com/sun/gjc/spi/LocalTransactionImpl.java
+++ b/appserver/jdbc/jdbc-ra/jdbc-core/src/main/java/com/sun/gjc/spi/LocalTransactionImpl.java
@@ -16,13 +16,15 @@
 
 package com.sun.gjc.spi;
 
+import static java.util.logging.Level.FINEST;
+
+import java.sql.SQLException;
+import java.util.logging.Logger;
 
 import com.sun.logging.LogDomains;
 
 import jakarta.resource.ResourceException;
 import jakarta.resource.spi.LocalTransactionException;
-import java.util.logging.Level;
-import java.util.logging.Logger;
 
 /**
  * <code>LocalTransactionImpl</code> implementation for Generic JDBC Connector.
@@ -32,40 +34,37 @@
  */
 public class LocalTransactionImpl implements jakarta.resource.spi.LocalTransaction {
 
-    private ManagedConnectionImpl mc;
-    protected final static Logger _logger;
+    protected final static Logger _logger = LogDomains.getLogger(LocalTransactionImpl.class, LogDomains.RSR_LOGGER);
 
-    static {
-        _logger = LogDomains.getLogger(LocalTransactionImpl.class, LogDomains.RSR_LOGGER);
-    }
+    private ManagedConnectionImpl managedConnectionImpl;
 
     /**
      * Constructor for <code>LocalTransactionImpl</code>.
      *
-     * @param mc <code>ManagedConnection</code> that returns
-     *           this <code>LocalTransactionImpl</code> object as
-     *           a result of <code>getLocalTransaction</code>
+     * @param managedConnectionImpl <code>ManagedConnection</code> that returns this
+     * <code>LocalTransactionImpl</code> object as a result of
+     * <code>getLocalTransaction</code>
      */
-    public LocalTransactionImpl(ManagedConnectionImpl mc) {
-        this.mc = mc;
+    public LocalTransactionImpl(ManagedConnectionImpl managedConnectionImpl) {
+        this.managedConnectionImpl = managedConnectionImpl;
     }
 
     /**
      * Begin a local transaction.
      *
-     * @throws LocalTransactionException if there is an error in changing
-     *                                   the autocommit mode of the physical
-     *                                   connection
+     * @throws LocalTransactionException if there is an error in changing the
+     * autocommit mode of the physical connection
      */
     public void begin() throws ResourceException {
-        //GJCINT
-        mc.transactionStarted();
+        managedConnectionImpl.transactionStarted();
+
         try {
-            mc.getActualConnection().setAutoCommit(false);
-        } catch (java.sql.SQLException sqle) {
-            if(_logger.isLoggable(Level.FINEST)){
+            managedConnectionImpl.getActualConnection().setAutoCommit(false);
+        } catch (SQLException sqle) {
+            if (_logger.isLoggable(FINEST)) {
                 _logger.finest("Exception during begin() : " + sqle);
             }
+
             throw new LocalTransactionException(sqle.getMessage(), sqle);
         }
     }
@@ -73,44 +72,42 @@
     /**
      * Commit a local transaction.
      *
-     * @throws LocalTransactionException if there is an error in changing
-     *                                   the autocommit mode of the physical
-     *                                   connection or committing the transaction
+     * @throws LocalTransactionException if there is an error in changing the
+     * autocommit mode of the physical connection or committing the transaction
      */
     public void commit() throws ResourceException {
         try {
-            mc.getActualConnection().commit();
-            mc.getActualConnection().setAutoCommit(true);
-        } catch (java.sql.SQLException sqle) {
-            if(_logger.isLoggable(Level.FINEST)){
+            managedConnectionImpl.getActualConnection().commit();
+            managedConnectionImpl.getActualConnection().setAutoCommit(true);
+        } catch (SQLException sqle) {
+            if (_logger.isLoggable(FINEST)) {
                 _logger.finest("Exception during commit() : " + sqle);
             }
+
             throw new LocalTransactionException(sqle.getMessage(), sqle);
         } finally {
-            //GJCINT
-            mc.transactionCompleted();
+            managedConnectionImpl.transactionCompleted();
         }
     }
 
     /**
      * Rollback a local transaction.
      *
-     * @throws LocalTransactionException if there is an error in changing
-     *                                   the autocommit mode of the physical
-     *                                   connection or rolling back the transaction
+     * @throws LocalTransactionException if there is an error in changing the
+     * autocommit mode of the physical connection or rolling back the transaction
      */
     public void rollback() throws ResourceException {
         try {
-            mc.getActualConnection().rollback();
-            mc.getActualConnection().setAutoCommit(true);
-        } catch (java.sql.SQLException sqle) {
-            if(_logger.isLoggable(Level.FINEST)){
+            managedConnectionImpl.getActualConnection().rollback();
+            managedConnectionImpl.getActualConnection().setAutoCommit(true);
+        } catch (SQLException sqle) {
+            if (_logger.isLoggable(FINEST)) {
                 _logger.finest("Exception during rollback() : " + sqle);
             }
+
             throw new LocalTransactionException(sqle.getMessage(), sqle);
         } finally {
-            //GJCINT
-            mc.transactionCompleted();
+            managedConnectionImpl.transactionCompleted();
         }
     }
 
diff --git a/appserver/jdbc/jdbc-ra/jdbc-core/src/main/java/com/sun/gjc/spi/ManagedConnectionFactoryImpl.java b/appserver/jdbc/jdbc-ra/jdbc-core/src/main/java/com/sun/gjc/spi/ManagedConnectionFactoryImpl.java
index 59f307b..998a02f 100644
--- a/appserver/jdbc/jdbc-ra/jdbc-core/src/main/java/com/sun/gjc/spi/ManagedConnectionFactoryImpl.java
+++ b/appserver/jdbc/jdbc-ra/jdbc-core/src/main/java/com/sun/gjc/spi/ManagedConnectionFactoryImpl.java
@@ -17,86 +17,106 @@
 
 package com.sun.gjc.spi;
 
-import com.sun.appserv.connectors.internal.spi.MCFLifecycleListener;
-import com.sun.enterprise.util.i18n.StringManager;
-import com.sun.gjc.common.DataSourceObjectBuilder;
-import com.sun.gjc.common.DataSourceSpec;
-import com.sun.gjc.monitoring.JdbcStatsProvider;
-import com.sun.gjc.util.SQLTraceDelegator;
-import com.sun.gjc.util.SecurityUtils;
-import com.sun.logging.LogDomains;
+import static com.sun.gjc.util.SecurityUtils.getPasswordCredential;
+import static com.sun.gjc.util.SecurityUtils.isPasswordCredentialEqual;
+import static java.util.logging.Level.FINE;
+import static java.util.logging.Level.SEVERE;
+
+import java.io.Externalizable;
+import java.io.IOException;
+import java.io.ObjectInput;
+import java.io.ObjectOutput;
+import java.io.PrintWriter;
+import java.io.Serializable;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Locale;
+import java.util.NoSuchElementException;
+import java.util.Set;
+import java.util.StringTokenizer;
+import java.util.Timer;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import javax.security.auth.Subject;
+import javax.sql.DataSource;
+import javax.sql.PooledConnection;
+
 import org.glassfish.api.jdbc.ConnectionValidation;
 import org.glassfish.api.jdbc.SQLTraceListener;
 import org.glassfish.external.probe.provider.PluginPoint;
 import org.glassfish.external.probe.provider.StatsProviderManager;
 import org.glassfish.resourcebase.resources.api.PoolInfo;
 
+import com.sun.appserv.connectors.internal.spi.MCFLifecycleListener;
+import com.sun.enterprise.util.i18n.StringManager;
+import com.sun.gjc.common.DataSourceObjectBuilder;
+import com.sun.gjc.common.DataSourceSpec;
+import com.sun.gjc.monitoring.JdbcStatsProvider;
+import com.sun.gjc.util.SQLTraceDelegator;
+import com.sun.logging.LogDomains;
+
 import jakarta.resource.ResourceException;
 import jakarta.resource.spi.ConfigProperty;
+import jakarta.resource.spi.ConnectionManager;
 import jakarta.resource.spi.ConnectionRequestInfo;
+import jakarta.resource.spi.LazyEnlistableConnectionManager;
+import jakarta.resource.spi.ManagedConnection;
+import jakarta.resource.spi.ManagedConnectionFactory;
+import jakarta.resource.spi.ResourceAdapter;
 import jakarta.resource.spi.ResourceAdapterAssociation;
 import jakarta.resource.spi.ResourceAllocationException;
+import jakarta.resource.spi.ValidatingManagedConnectionFactory;
 import jakarta.resource.spi.security.PasswordCredential;
-import javax.sql.PooledConnection;
-import java.io.Externalizable;
-import java.io.IOException;
-import java.io.ObjectInput;
-import java.io.ObjectOutput;
-import java.lang.reflect.Constructor;
-import java.lang.reflect.InvocationTargetException;
-import java.sql.Connection;
-import java.util.*;
-import java.util.logging.Level;
-import java.util.logging.Logger;
 
 /**
- * <code>ManagedConnectionFactory</code> implementation for Generic JDBC Connector.
- * This class is extended by the DataSource specific <code>ManagedConnection</code> factories
- * and the <code>ManagedConnectionFactory</code> for the <code>DriverManager</code>.
+ * <code>ManagedConnectionFactory</code> implementation for Generic JDBC
+ * Connector. This class is extended by the DataSource specific
+ * <code>ManagedConnection</code> factories and the
+ * <code>ManagedConnectionFactory</code> for the <code>DriverManager</code>.
  *
  * @author Evani Sai Surya Kiran, Aditya Gore
  * @version 1.0, 02/08/03
  */
 
-public abstract class ManagedConnectionFactoryImpl implements jakarta.resource.spi.ManagedConnectionFactory,
-        jakarta.resource.spi.ValidatingManagedConnectionFactory,
-        MCFLifecycleListener, ResourceAdapterAssociation,
-        java.io.Serializable, Externalizable {
+public abstract class ManagedConnectionFactoryImpl
+        implements ManagedConnectionFactory, ValidatingManagedConnectionFactory, MCFLifecycleListener,
+        ResourceAdapterAssociation, Serializable, Externalizable {
+
+    private static Logger _logger = LogDomains.getLogger(ManagedConnectionFactoryImpl.class, LogDomains.RSR_LOGGER);
+    protected static final StringManager localStrings = StringManager.getManager(DataSourceObjectBuilder.class);
 
     protected DataSourceSpec spec = new DataSourceSpec();
-    protected transient DataSourceObjectBuilder dsObjBuilder;
-
-    protected java.io.PrintWriter logWriter = null;
-    protected transient jakarta.resource.spi.ResourceAdapter ra = null;
-
-    private static Logger _logger;
+    protected transient DataSourceObjectBuilder dataSourceObjectBuilder;
+    protected PrintWriter logWriter;
+    protected transient ResourceAdapter resourceAdapter;
     protected boolean statementWrapping;
+    protected SQLTraceDelegator sqlTraceDelegator;
+    protected LazyEnlistableConnectionManager connectionManager;
+    protected boolean isLazyConnectionManager;
 
     private JdbcObjectsFactory jdbcObjectsFactory = JdbcObjectsFactory.getInstance();
-    protected SQLTraceDelegator sqlTraceDelegator;
+    private int statementCacheSize;
+    private String statementCacheType;
+    private long statementLeakTimeout;
+    private boolean statementLeakReclaim;
 
-    static {
-        _logger = LogDomains.getLogger(ManagedConnectionFactoryImpl.class, LogDomains.RSR_LOGGER);
-    }
-
-    protected jakarta.resource.spi.LazyEnlistableConnectionManager cm_;
-    protected boolean isLazyCm_;
-    private int statementCacheSize = 0;
-    private String statementCacheType = null;
-    private long statementLeakTimeout = 0;
-    private boolean statementLeakReclaim = false;
-
-    //Jdbc Stats provider that is created
-    private JdbcStatsProvider jdbcStatsProvider = null;
-
-    protected static final StringManager localStrings =
-            StringManager.getManager(DataSourceObjectBuilder.class);
+    // Jdbc Stats provider that is created
+    private JdbcStatsProvider jdbcStatsProvider;
 
     /**
-     * Creates a Connection Factory instance. The <code>ConnectionManager</code> implementation
-     * of the resource adapter is used here.
+     * Creates a Connection Factory instance. The <code>ConnectionManager</code>
+     * implementation of the resource adapter is used here.
      *
-     * @return Generic JDBC Connector implementation of <code>javax.sql.DataSource</code>
+     * @return Generic JDBC Connector implementation of
+     * <code>javax.sql.DataSource</code>
      */
     public Object createConnectionFactory() {
         logFine("In createConnectionFactory()");
@@ -104,59 +124,64 @@
     }
 
     /**
-     * Creates a Connection Factory instance. The <code>ConnectionManager</code> implementation
-     * of the application server is used here.
+     * Creates a Connection Factory instance. The <code>ConnectionManager</code>
+     * implementation of the application server is used here.
      *
-     * @param cxManager <code>ConnectionManager</code> passed by the application server
-     * @return Generic JDBC Connector implementation of <code>javax.sql.DataSource</code>
+     * @param connectionManager <code>ConnectionManager</code> passed by the application
+     * server
+     * @return Generic JDBC Connector implementation of
+     * <code>javax.sql.DataSource</code>
      */
-    public Object createConnectionFactory(jakarta.resource.spi.ConnectionManager cxManager) {
+    public Object createConnectionFactory(ConnectionManager connectionManager) {
         logFine("In createConnectionFactory(jakarta.resource.spi.ConnectionManager cxManager)");
 
-        javax.sql.DataSource cf = jdbcObjectsFactory.getDataSourceInstance(this, cxManager);
+        DataSource connectionFactory = jdbcObjectsFactory.getDataSourceInstance(this, connectionManager);
 
-        if (cxManager instanceof jakarta.resource.spi.LazyEnlistableConnectionManager) {
-            cm_ = (jakarta.resource.spi.LazyEnlistableConnectionManager) cxManager;
-            isLazyCm_ = true;
+        if (connectionManager instanceof LazyEnlistableConnectionManager) {
+            this.connectionManager = (LazyEnlistableConnectionManager) connectionManager;
+            isLazyConnectionManager = true;
         }
-        return cf;
+
+        return connectionFactory;
     }
 
     /**
-     * Creates a new physical connection to the underlying EIS resource
-     * manager.
+     * Creates a new physical connection to the underlying EIS resource manager.
      *
-     * @param subject       <code>Subject</code> instance passed by the application server
+     * @param subject <code>Subject</code> instance passed by the application server
      * @param cxRequestInfo <code>ConnectionRequestInfo</code> which may be created
-     *                      as a result of the invocation <code>getConnection(user, password)</code>
-     *                      on the <code>DataSource</code> object
+     * as a result of the invocation <code>getConnection(user, password)</code> on
+     * the <code>DataSource</code> object
+     *
      * @return <code>ManagedConnection</code> object created
      * @throws ResourceException if there is an error in instantiating the
-     *                           <code>DataSource</code> object used for the
-     *                           creation of the <code>ManagedConnection</code> object
+     * <code>DataSource</code> object used for the creation of the
+     * <code>ManagedConnection</code> object
      * @throws SecurityException if there ino <code>PasswordCredential</code> object
-     *                           satisfying this request
-     * @throws ResourceException if there is an error in allocating the
-     *                           physical connection
+     * satisfying this request
+     * @throws ResourceException if there is an error in allocating the physical
+     * connection
      */
-    public abstract jakarta.resource.spi.ManagedConnection createManagedConnection
-            (javax.security.auth.Subject subject, ConnectionRequestInfo cxRequestInfo) throws ResourceException;
+    public abstract ManagedConnection createManagedConnection(Subject subject, ConnectionRequestInfo cxRequestInfo) throws ResourceException;
 
     /**
-     * Check if this <code>ManagedConnectionFactoryImpl</code> is equal to
-     * another <code>ManagedConnectionFactoryImpl</code>.
+     * Check if this <code>ManagedConnectionFactoryImpl</code> is equal to another
+     * <code>ManagedConnectionFactoryImpl</code>.
      *
-     * @param other <code>ManagedConnectionFactoryImpl</code> object for checking equality with
-     * @return true    if the property sets of both the
-     *         <code>ManagedConnectionFactoryImpl</code> objects are the same
-     *         false    otherwise
+     * @param other <code>ManagedConnectionFactoryImpl</code> object for checking
+     * equality with
+     * @return true if the property sets of both the
+     * <code>ManagedConnectionFactoryImpl</code> objects are the same false
+     * otherwise
      */
     public abstract boolean equals(Object other);
 
     /**
-     * Get the log writer for this <code>ManagedConnectionFactoryImpl</code> instance.
+     * Get the log writer for this <code>ManagedConnectionFactoryImpl</code>
+     * instance.
      *
-     * @return <code>PrintWriter</code> associated with this <code>ManagedConnectionFactoryImpl</code> instance
+     * @return <code>PrintWriter</code> associated with this
+     * <code>ManagedConnectionFactoryImpl</code> instance
      * @see <code>setLogWriter</code>
      */
     public java.io.PrintWriter getLogWriter() {
@@ -164,14 +189,16 @@
     }
 
     /**
-     * Get the <code>ResourceAdapterImpl</code> for this <code>ManagedConnectionFactoryImpl</code> instance.
+     * Get the <code>ResourceAdapterImpl</code> for this
+     * <code>ManagedConnectionFactoryImpl</code> instance.
      *
-     * @return <code>ResourceAdapterImpl</code> associated with this <code>ManagedConnectionFactoryImpl</code> instance
+     * @return <code>ResourceAdapterImpl</code> associated with this
+     * <code>ManagedConnectionFactoryImpl</code> instance
      * @see <code>setResourceAdapter</code>
      */
     public jakarta.resource.spi.ResourceAdapter getResourceAdapter() {
         logFine("In getResourceAdapter");
-        return ra;
+        return resourceAdapter;
     }
 
     /**
@@ -185,58 +212,58 @@
     }
 
     /**
-     * Returns a matched <code>ManagedConnection</code> from the candidate
-     * set of <code>ManagedConnection</code> objects.
+     * Returns a matched <code>ManagedConnection</code> from the candidate set of
+     * <code>ManagedConnection</code> objects.
      *
-     * @param connectionSet <code>Set</code> of  <code>ManagedConnection</code>
-     *                      objects passed by the application server
-     * @param subject       passed by the application server
-     *                      for retrieving information required for matching
-     * @param cxRequestInfo <code>ConnectionRequestInfo</code> passed by the application server
-     *                      for retrieving information required for matching
-     * @return <code>ManagedConnection</code> that is the best match satisfying this request
-     * @throws ResourceException if there is an error accessing the <code>Subject</code>
-     *                           parameter or the <code>Set</code> of <code>ManagedConnection</code>
-     *                           objects passed by the application server
+     * @param connectionSet <code>Set</code> of <code>ManagedConnection</code>
+     * objects passed by the application server
+     * @param subject passed by the application server for retrieving information
+     * required for matching
+     * @param cxRequestInfo <code>ConnectionRequestInfo</code> passed by the
+     * application server for retrieving information required for matching
+     * @return <code>ManagedConnection</code> that is the best match satisfying this
+     * request
+     * @throws ResourceException if there is an error accessing the
+     * <code>Subject</code> parameter or the <code>Set</code> of
+     * <code>ManagedConnection</code> objects passed by the application server
      */
-    public jakarta.resource.spi.ManagedConnection matchManagedConnections(
-            java.util.Set connectionSet, javax.security.auth.Subject subject, ConnectionRequestInfo cxRequestInfo)
-            throws ResourceException {
+    public ManagedConnection matchManagedConnections(Set connectionSet, Subject subject, ConnectionRequestInfo cxRequestInfo) throws ResourceException {
         logFine("In matchManagedConnections");
 
         if (connectionSet == null) {
             return null;
         }
 
+        PasswordCredential passwordCredential = getPasswordCredential(this, subject, cxRequestInfo);
 
-        PasswordCredential pc = SecurityUtils.getPasswordCredential(this, subject, cxRequestInfo);
-
-        java.util.Iterator iter = connectionSet.iterator();
-        ManagedConnectionImpl mc = null;
+        Iterator<ManagedConnectionImpl> iter = connectionSet.iterator();
+        ManagedConnectionImpl managedConnectionImpl = null;
 
         while (iter.hasNext()) {
             try {
-                mc = (ManagedConnectionImpl) iter.next();
-            } catch (java.util.NoSuchElementException nsee) {
-                _logger.log(Level.SEVERE, "jdbc.exc_iter");
+                managedConnectionImpl = iter.next();
+            } catch (NoSuchElementException nsee) {
+                _logger.log(SEVERE, "jdbc.exc_iter");
                 throw new ResourceException(nsee.getMessage());
             }
-            if (pc == null && this.equals(mc.getManagedConnectionFactory())) {
-                return mc;
-            } else if (SecurityUtils.isPasswordCredentialEqual(pc, mc.getPasswordCredential())) {
-                return mc;
+            if (passwordCredential == null && this.equals(managedConnectionImpl.getManagedConnectionFactory())) {
+                return managedConnectionImpl;
+            }
+
+            if (isPasswordCredentialEqual(passwordCredential, managedConnectionImpl.getPasswordCredential())) {
+                return managedConnectionImpl;
             }
         }
+
         return null;
     }
 
     /**
-     * This method returns a set of invalid <code>ManagedConnection</code>
-     * objects chosen from a specified set of <code>ManagedConnection</code>
-     * objects.
+     * This method returns a set of invalid <code>ManagedConnection</code> objects
+     * chosen from a specified set of <code>ManagedConnection</code> objects.
      *
-     * @param connectionSet a set of <code>ManagedConnection</code> objects
-     *                      that need to be validated.
+     * @param connectionSet a set of <code>ManagedConnection</code> objects that
+     * need to be validated.
      * @return a set of invalid <code>ManagedConnection</code> objects.
      * @throws ResourceException generic exception.
      */
@@ -244,55 +271,49 @@
         Iterator iter = connectionSet.iterator();
         Set<ManagedConnectionImpl> invalidConnections = new HashSet<ManagedConnectionImpl>();
         while (iter.hasNext()) {
-            ManagedConnectionImpl mc = (ManagedConnectionImpl) iter.next();
+            ManagedConnectionImpl managedConnectionImpl = (ManagedConnectionImpl) iter.next();
             try {
-                isValid(mc);
+                isValid(managedConnectionImpl);
             } catch (ResourceException re) {
-                invalidConnections.add(mc);
-                mc.connectionErrorOccurred(re, null);
-                if (_logger.isLoggable(Level.FINE)) {
-                    _logger.log(Level.FINE, "jdbc.invalid_connection", re);
-                }
+                invalidConnections.add(managedConnectionImpl);
+                managedConnectionImpl.connectionErrorOccurred(re, null);
+                _logger.log(FINE, "jdbc.invalid_connection", re);
             }
         }
+
         return invalidConnections;
     }
 
-    //GJCINT
-
     /**
-     * Checks if a <code>ManagedConnection</code> is to be validated or not
-     * and validates it or returns.
+     * Checks if a <code>ManagedConnection</code> is to be validated or not and
+     * validates it or returns.
      *
      * @param mc <code>ManagedConnection</code> to be validated
-     * @throws ResourceException if the connection is not valid or
-     *                           if validation method is not proper
+     * @throws ResourceException if the connection is not valid or if validation
+     * method is not proper
      */
     void isValid(ManagedConnectionImpl mc) throws ResourceException {
-
         if (mc == null || mc.isTransactionInProgress()) {
             return;
         }
 
         String conVal = spec.getDetail(DataSourceSpec.CONNECTIONVALIDATIONREQUIRED);
 
-        boolean connectionValidationRequired =
-                (conVal == null) ? false : Boolean.valueOf(conVal.toLowerCase(Locale.getDefault()));
+        boolean connectionValidationRequired = (conVal == null) ? false
+                : Boolean.valueOf(conVal.toLowerCase(Locale.getDefault()));
         if (!connectionValidationRequired) {
             return;
         }
 
-
         String validationMethod = spec.getDetail(DataSourceSpec.VALIDATIONMETHOD).toLowerCase(Locale.getDefault());
 
         mc.checkIfValid();
         /**
-         * The above call checks if the actual physical connection
-         * is usable or not.
+         * The above call checks if the actual physical connection is usable or not.
          */
         java.sql.Connection con = mc.getActualConnection();
 
-        if(validationMethod.equals("custom-validation")) {
+        if (validationMethod.equals("custom-validation")) {
             isValidByCustomValidation(con, spec.getDetail(DataSourceSpec.VALIDATIONCLASSNAME));
         } else if (validationMethod.equals("auto-commit")) {
             isValidByAutoCommit(con);
@@ -306,18 +327,17 @@
     }
 
     /**
-     * Checks if a <code>java.sql.Connection</code> is valid or not
-     * by doing a custom validation using the validation class name specified.
+     * Checks if a <code>java.sql.Connection</code> is valid or not by doing a
+     * custom validation using the validation class name specified.
      *
      * @param con <code>java.sql.Connection</code> to be validated
      * @throws ResourceException if the connection is not valid
      */
-    protected void isValidByCustomValidation(java.sql.Connection con,
-            String validationClassName) throws ResourceException {
+    protected void isValidByCustomValidation(java.sql.Connection con, String validationClassName)
+            throws ResourceException {
         boolean isValid = false;
         if (con == null) {
-            throw new ResourceException("The connection is not valid as "
-                    + "the connection is null");
+            throw new ResourceException("The connection is not valid as " + "the connection is null");
         }
 
         try {
@@ -335,16 +355,15 @@
     }
 
     /**
-     * Checks if a <code>java.sql.Connection</code> is valid or not
-     * by checking its auto commit property.
+     * Checks if a <code>java.sql.Connection</code> is valid or not by checking its
+     * auto commit property.
      *
      * @param con <code>java.sql.Connection</code> to be validated
      * @throws ResourceException if the connection is not valid
      */
     protected void isValidByAutoCommit(java.sql.Connection con) throws ResourceException {
         if (con == null) {
-            throw new ResourceException("The connection is not valid as "
-                    + "the connection is null");
+            throw new ResourceException("The connection is not valid as " + "the connection is null");
         }
 
         try {
@@ -352,7 +371,7 @@
             // dbCon.setAutoCommit(dbCon.getAutoCommit()) will cause problems with
             // some drivers like sybase
             // We do not validate connections that are already enlisted
-            //in a transaction
+            // in a transaction
             // We cycle autocommit to true and false to by-pass drivers that
             // might cache the call to set autocomitt
             // Also notice that some XA data sources will throw and exception if
@@ -375,16 +394,15 @@
     }
 
     /**
-     * Checks if a <code>java.sql.Connection</code> is valid or not
-     * by checking its meta data.
+     * Checks if a <code>java.sql.Connection</code> is valid or not by checking its
+     * meta data.
      *
      * @param con <code>java.sql.Connection</code> to be validated
      * @throws ResourceException if the connection is not valid
      */
     protected void isValidByMetaData(java.sql.Connection con) throws ResourceException {
         if (con == null) {
-            throw new ResourceException("The connection is not valid as "
-                    + "the connection is null");
+            throw new ResourceException("The connection is not valid as " + "the connection is null");
         }
 
         try {
@@ -396,40 +414,37 @@
     }
 
     /**
-     * Checks if a <code>java.sql.Connection</code> is valid or not
-     * by querying a table.
+     * Checks if a <code>java.sql.Connection</code> is valid or not by querying a
+     * table.
      *
-     * @param con       <code>java.sql.Connection</code> to be validated
+     * @param connection <code>java.sql.Connection</code> to be validated
      * @param tableName table which should be queried
      * @throws ResourceException if the connection is not valid
      */
-    protected void isValidByTableQuery(java.sql.Connection con,
-                                       String tableName) throws ResourceException {
-        if (con == null) {
-            throw new ResourceException("The connection is not valid as "
-                    + "the connection is null");
+    protected void isValidByTableQuery(Connection connection, String tableName) throws ResourceException {
+        if (connection == null) {
+            throw new ResourceException("The connection is not valid as " + "the connection is null");
         }
 
-        java.sql.PreparedStatement stmt = null;
-        java.sql.ResultSet rs = null;
+        PreparedStatement preparedStatement = null;
+        ResultSet resultSet = null;
         try {
-            final String statement = "SELECT COUNT(*) FROM " + tableName;
-            stmt = con.prepareStatement(statement);
-            rs = stmt.executeQuery();
+            preparedStatement = connection.prepareStatement("SELECT COUNT(*) FROM " + tableName);
+            resultSet = preparedStatement.executeQuery();
         } catch (Exception sqle) {
             _logger.log(Level.INFO, "jdbc.exc_table_validation", tableName);
             throw new ResourceException(sqle);
         } finally {
             try {
-                if (rs != null) {
-                    rs.close();
+                if (resultSet != null) {
+                    resultSet.close();
                 }
             } catch (Exception e1) {
             }
 
             try {
-                if (stmt != null) {
-                    stmt.close();
+                if (preparedStatement != null) {
+                    preparedStatement.close();
                 }
             } catch (Exception e2) {
             }
@@ -440,14 +455,13 @@
      * Sets the isolation level specified in the <code>ConnectionRequestInfo</code>
      * for the <code>ManagedConnection</code> passed.
      *
-     * @param mc <code>ManagedConnection</code>
-     * @throws ResourceException if the isolation property is invalid
-     *                           or if the isolation cannot be set over the connection
+     * @param managedConnectionImpl <code>ManagedConnection</code>
+     * @throws ResourceException if the isolation property is invalid or if the
+     * isolation cannot be set over the connection
      */
-    protected void setIsolation(ManagedConnectionImpl mc) throws ResourceException {
-
-        java.sql.Connection con = mc.getActualConnection();
-        if (con == null) {
+    protected void setIsolation(ManagedConnectionImpl managedConnectionImpl) throws ResourceException {
+        Connection connection = managedConnectionImpl.getActualConnection();
+        if (connection == null) {
             return;
         }
 
@@ -455,63 +469,59 @@
         if (tranIsolation != null && !tranIsolation.equals("")) {
             int tranIsolationInt = getTransactionIsolationInt(tranIsolation);
             try {
-                con.setTransactionIsolation(tranIsolationInt);
-                mc.setLastTransactionIsolationLevel(tranIsolationInt);
-            } catch (java.sql.SQLException sqle) {
-                _logger.log(Level.SEVERE, "jdbc.exc_tx_iso", sqle);
-                throw new ResourceException("The transaction isolation could "
-                        + "not be set: " + sqle.getMessage());
+                connection.setTransactionIsolation(tranIsolationInt);
+                managedConnectionImpl.setLastTransactionIsolationLevel(tranIsolationInt);
+            } catch (SQLException sqle) {
+                _logger.log(SEVERE, "jdbc.exc_tx_iso", sqle);
+                throw new ResourceException("The transaction isolation could " + "not be set: " + sqle.getMessage());
             }
         }
     }
 
     /**
-     * Resets the isolation level for the <code>ManagedConnection</code> passed.
-     * If the transaction level is to be guaranteed to be the same as the one
-     * present when this <code>ManagedConnection</code> was created, as specified
-     * by the <code>ConnectionRequestInfo</code> passed, it sets the transaction
-     * isolation level from the <code>ConnectionRequestInfo</code> passed. Else,
-     * it sets it to the transaction isolation passed.
+     * Resets the isolation level for the <code>ManagedConnection</code> passed. If
+     * the transaction level is to be guaranteed to be the same as the one present
+     * when this <code>ManagedConnection</code> was created, as specified by the
+     * <code>ConnectionRequestInfo</code> passed, it sets the transaction isolation
+     * level from the <code>ConnectionRequestInfo</code> passed. Else, it sets it to
+     * the transaction isolation passed.
      *
-     * @param mc       <code>ManagedConnection</code>
+     * @param managedConnectionImpl <code>ManagedConnection</code>
      * @param tranIsol int
-     * @throws ResourceException if the isolation property is invalid
-     *                           or if the isolation cannot be set over the connection
+     * @throws ResourceException if the isolation property is invalid or if the
+     * isolation cannot be set over the connection
      */
-    void resetIsolation(ManagedConnectionImpl mc, int tranIsol) throws ResourceException {
-
-        java.sql.Connection con = mc.getActualConnection();
-        if (con == null) {
+    void resetIsolation(ManagedConnectionImpl managedConnectionImpl, int tranIsol) throws ResourceException {
+        Connection connection = managedConnectionImpl.getActualConnection();
+        if (connection == null) {
             return;
         }
 
-        String tranIsolation = spec.getDetail(DataSourceSpec.TRANSACTIONISOLATION);
-        if (tranIsolation != null && !tranIsolation.equals("")) {
+        String transactionIsolation = spec.getDetail(DataSourceSpec.TRANSACTIONISOLATION);
+        if (transactionIsolation != null && !transactionIsolation.equals("")) {
             String guaranteeIsolationLevel = spec.getDetail(DataSourceSpec.GUARANTEEISOLATIONLEVEL);
 
             if (guaranteeIsolationLevel != null && !guaranteeIsolationLevel.equals("")) {
                 boolean guarantee = Boolean.valueOf(guaranteeIsolationLevel.toLowerCase(Locale.getDefault()));
 
                 if (guarantee) {
-                    int tranIsolationInt = getTransactionIsolationInt(tranIsolation);
+                    int tranIsolationInt = getTransactionIsolationInt(transactionIsolation);
                     try {
-                        if (tranIsolationInt != con.getTransactionIsolation()) {
-                            con.setTransactionIsolation(tranIsolationInt);
+                        if (tranIsolationInt != connection.getTransactionIsolation()) {
+                            connection.setTransactionIsolation(tranIsolationInt);
                         }
-                    } catch (java.sql.SQLException sqle) {
-                        _logger.log(Level.SEVERE, "jdbc.exc_tx_iso", sqle);
-                        throw new ResourceException("The isolation level could not be set: "
-                                + sqle.getMessage());
+                    } catch (SQLException sqle) {
+                        _logger.log(SEVERE, "jdbc.exc_tx_iso", sqle);
+                        throw new ResourceException("The isolation level could not be set: " + sqle.getMessage());
                     }
                 } else {
                     try {
-                        if (tranIsol != con.getTransactionIsolation()) {
-                            con.setTransactionIsolation(tranIsol);
+                        if (tranIsol != connection.getTransactionIsolation()) {
+                            connection.setTransactionIsolation(tranIsol);
                         }
-                    } catch (java.sql.SQLException sqle) {
-                        _logger.log(Level.SEVERE, "jdbc.exc_tx_iso", sqle);
-                        throw new ResourceException("The isolation level could not be set: "
-                                + sqle.getMessage());
+                    } catch (SQLException sqle) {
+                        _logger.log(SEVERE, "jdbc.exc_tx_iso", sqle);
+                        throw new ResourceException("The isolation level could not be set: " + sqle.getMessage());
                     }
                 }
             }
@@ -519,26 +529,27 @@
     }
 
     private void detectSqlTraceListeners() {
-        //Check for sql-trace-listeners attribute.
+        // Check for sql-trace-listeners attribute.
         String sqlTraceListeners = getSqlTraceListeners();
         String delimiter = ",";
 
-        if(sqlTraceListeners != null && !sqlTraceListeners.equals("null")) {
+        if (sqlTraceListeners != null && !sqlTraceListeners.equals("null")) {
             sqlTraceDelegator = new SQLTraceDelegator(getPoolName(), getApplicationName(), getModuleName());
             StringTokenizer st = new StringTokenizer(sqlTraceListeners, delimiter);
+
             while (st.hasMoreTokens()) {
                 String sqlTraceListener = st.nextToken().trim();
-                if(!sqlTraceListener.equals("")) {
+                if (!sqlTraceListener.equals("")) {
                     Class listenerClass = null;
                     SQLTraceListener listener = null;
                     Constructor[] constructors = null;
                     Class[] parameterTypes = null;
                     Object[] initargs = null;
-                    //Load the listener class
+                    // Load the listener class
                     try {
                         listenerClass = Thread.currentThread().getContextClassLoader().loadClass(sqlTraceListener);
                     } catch (ClassNotFoundException ex) {
-                        _logger.log(Level.SEVERE, "jdbc.sql_trace_listener_cnfe", sqlTraceListener);
+                        _logger.log(SEVERE, "jdbc.sql_trace_listener_cnfe", sqlTraceListener);
                     }
                     Class intf[] = listenerClass.getInterfaces();
                     for (int i = 0; i < intf.length; i++) {
@@ -550,22 +561,22 @@
                                 constructors = listenerClass.getConstructors();
                                 for (Constructor constructor : constructors) {
                                     parameterTypes = constructor.getParameterTypes();
-                                    //For now only the no argument constructors are allowed.
-                                    //TODO should this be documented?
+                                    // For now only the no argument constructors are allowed.
+                                    // TODO should this be documented?
                                     if (parameterTypes.length == 0) {
                                         listener = (SQLTraceListener) constructor.newInstance(initargs);
                                     }
                                 }
                             } catch (InstantiationException ex) {
-                                _logger.log(Level.SEVERE, "jdbc.sql_trace_listener_exception", ex.getMessage());
+                                _logger.log(SEVERE, "jdbc.sql_trace_listener_exception", ex.getMessage());
                             } catch (IllegalAccessException ex) {
-                                _logger.log(Level.SEVERE, "jdbc.sql_trace_listener_exception", ex.getMessage());
+                                _logger.log(SEVERE, "jdbc.sql_trace_listener_exception", ex.getMessage());
                             } catch (IllegalArgumentException ex) {
-                                _logger.log(Level.SEVERE, "jdbc.sql_trace_listener_exception", ex.getMessage());
+                                _logger.log(SEVERE, "jdbc.sql_trace_listener_exception", ex.getMessage());
                             } catch (InvocationTargetException ex) {
-                                _logger.log(Level.SEVERE, "jdbc.sql_trace_listener_exception", ex.getMessage());
+                                _logger.log(SEVERE, "jdbc.sql_trace_listener_exception", ex.getMessage());
                             } catch (SecurityException ex) {
-                                _logger.log(Level.SEVERE, "jdbc.sql_trace_listener_exception", ex.getMessage());
+                                _logger.log(SEVERE, "jdbc.sql_trace_listener_exception", ex.getMessage());
                             }
                             sqlTraceDelegator.registerSQLTraceListener(listener);
                         }
@@ -575,74 +586,79 @@
         }
     }
 
-
     /**
-     * Gets the integer equivalent of the string specifying
-     * the transaction isolation.
+     * Gets the integer equivalent of the string specifying the transaction
+     * isolation.
      *
      * @param tranIsolation string specifying the isolation level
-     * @return tranIsolationInt    the <code>java.sql.Connection</code> constant
-     *         for the string specifying the isolation.
+     * @return tranIsolationInt the <code>java.sql.Connection</code> constant for
+     * the string specifying the isolation.
      */
     private int getTransactionIsolationInt(String tranIsolation) throws ResourceException {
         if (tranIsolation.equalsIgnoreCase("read-uncommitted")) {
-            return java.sql.Connection.TRANSACTION_READ_UNCOMMITTED;
-        } else if (tranIsolation.equalsIgnoreCase("read-committed")) {
-            return java.sql.Connection.TRANSACTION_READ_COMMITTED;
-        } else if (tranIsolation.equalsIgnoreCase("repeatable-read")) {
-            return java.sql.Connection.TRANSACTION_REPEATABLE_READ;
-        } else if (tranIsolation.equalsIgnoreCase("serializable")) {
-            return java.sql.Connection.TRANSACTION_SERIALIZABLE;
-        } else {
-            throw new ResourceException("Invalid transaction isolation; the transaction "
-                    + "isolation level can be empty or any of the following: "
-                    + "read-uncommitted, read-committed, repeatable-read, serializable");
+            return Connection.TRANSACTION_READ_UNCOMMITTED;
         }
+
+        if (tranIsolation.equalsIgnoreCase("read-committed")) {
+            return Connection.TRANSACTION_READ_COMMITTED;
+        }
+
+        if (tranIsolation.equalsIgnoreCase("repeatable-read")) {
+            return Connection.TRANSACTION_REPEATABLE_READ;
+        }
+
+        if (tranIsolation.equalsIgnoreCase("serializable")) {
+            return Connection.TRANSACTION_SERIALIZABLE;
+        }
+
+        throw new ResourceException(
+            "Invalid transaction isolation; the transaction " +
+            "isolation level can be empty or any of the following: " +
+            "read-uncommitted, read-committed, repeatable-read, serializable");
     }
 
     /**
-     * Common operation performed by all the child MCFs before returning a created mc
+     * Common operation performed by all the child MCFs before returning a created
+     * mc
      */
-    protected void validateAndSetIsolation(ManagedConnectionImpl mc) throws ResourceException {
+    protected void validateAndSetIsolation(ManagedConnectionImpl managedConnectionImpl) throws ResourceException {
         try {
-            isValid(mc);
-            setIsolation(mc);
+            isValid(managedConnectionImpl);
+            setIsolation(managedConnectionImpl);
         } catch (ResourceException e) {
-            if (mc != null) {
+            if (managedConnectionImpl != null) {
                 try {
-                    mc.destroy();
+                    managedConnectionImpl.destroy();
                 } catch (ResourceException e1) {
                     _logger.log(Level.WARNING, "jdbc.exc_destroy", e1);
                 }
             }
-            String msg = localStrings.getString("jdbc.exc_destroy", e.getMessage());
-            ResourceAllocationException rae = new ResourceAllocationException(
-                    msg, e);
-            throw rae;
+
+            throw new ResourceAllocationException(localStrings.getString("jdbc.exc_destroy", e.getMessage()), e);
         }
     }
 
     private void detectStatementCachingSupport() {
         String cacheSize = getStatementCacheSize();
-        if(cacheSize != null){
-            try{
+        if (cacheSize != null) {
+            try {
                 statementCacheSize = Integer.parseInt(cacheSize);
-                //TODO-SC FINE log-level with Pool Name (if possible)
-                if(_logger.isLoggable(Level.FINE)) {
-                    _logger.log(Level.FINE, "StatementCaching Size : " + statementCacheSize);
+                // TODO-SC FINE log-level with Pool Name (if possible)
+                if (_logger.isLoggable(FINE)) {
+                    _logger.log(FINE, "StatementCaching Size : " + statementCacheSize);
                 }
-            }catch(NumberFormatException nfe){
-                if(_logger.isLoggable(Level.FINE)) {
-                    _logger.fine("Exception while setting StatementCacheSize : " +
-                        nfe.getMessage());
+            } catch (NumberFormatException nfe) {
+                if (_logger.isLoggable(FINE)) {
+                    _logger.fine("Exception while setting StatementCacheSize : " + nfe.getMessage());
                 }
-                //ignore
+                // ignore
             }
         }
     }
 
     /**
-     * Set the log writer for this <code>ManagedConnectionFactoryImpl</code> instance.
+     * Set the log writer for this <code>ManagedConnectionFactoryImpl</code>
+     * instance.
      *
      * @param out <code>PrintWriter</code> passed by the application server
      * @see <code>getLogWriter</code>
@@ -655,11 +671,11 @@
      * Set the associated <code>ResourceAdapterImpl</code> JavaBean.
      *
      * @param ra <code>ResourceAdapterImpl</code> associated with this
-     *           <code>ManagedConnectionFactoryImpl</code> instance
+     * <code>ManagedConnectionFactoryImpl</code> instance
      * @see <code>getResourceAdapter</code>
      */
     public void setResourceAdapter(jakarta.resource.spi.ResourceAdapter ra) {
-        this.ra = ra;
+        this.resourceAdapter = ra;
     }
 
     /**
@@ -788,18 +804,15 @@
             if (isAssignable) {
                 spec.setDetail(DataSourceSpec.VALIDATIONCLASSNAME, className);
             } else {
-                //Validation Failed
-                _logger.log(Level.SEVERE, "jdbc.set_custom_validation_class_name_failure", className);
-                throw new ResourceException("The Custom validation class name is " +
-                        "not valid as it does not implement " +
-                        ConnectionValidation.class.getName());
+                // Validation Failed
+                _logger.log(SEVERE, "jdbc.set_custom_validation_class_name_failure", className);
+                throw new ResourceException("The Custom validation class name is "
+                        + "not valid as it does not implement " + ConnectionValidation.class.getName());
             }
         } catch (ResourceException ex) {
-            _logger.log(Level.SEVERE, "jdbc.set_custom_validation_class_name_failure",
-                    ex.getMessage());
+            _logger.log(SEVERE, "jdbc.set_custom_validation_class_name_failure", ex.getMessage());
         } catch (ClassNotFoundException ex) {
-            _logger.log(Level.SEVERE, "jdbc.set_custom_validation_class_name_failure",
-                    ex.getMessage());
+            _logger.log(SEVERE, "jdbc.set_custom_validation_class_name_failure", ex.getMessage());
         }
     }
 
@@ -850,18 +863,16 @@
         return spec.getDetail(DataSourceSpec.GUARANTEEISOLATIONLEVEL);
     }
 
-    protected boolean isEqual(PasswordCredential pc, String user,
-                              String password) {
+    protected boolean isEqual(PasswordCredential pc, String user, String password) {
 
-        //if equal get direct connection else
-        //get connection with user and password.
+        // if equal get direct connection else
+        // get connection with user and password.
 
         String thisUser = (pc == null) ? null : pc.getUserName();
         char[] passwordArray = (pc == null) ? null : pc.getPassword();
         char[] tmpPasswordArray = (password == null) ? null : password.toCharArray();
 
-        return (isStringEqual(thisUser, user) &&
-                Arrays.equals(passwordArray, tmpPasswordArray));
+        return (isStringEqual(thisUser, user) && Arrays.equals(passwordArray, tmpPasswordArray));
 
     }
 
@@ -982,21 +993,21 @@
         return spec.getDetail(DataSourceSpec.STATEMENTWRAPPING);
     }
 
-    public void setStatementCacheSize(String value){
+    public void setStatementCacheSize(String value) {
         spec.setDetail(DataSourceSpec.STATEMENTCACHESIZE, value);
         detectStatementCachingSupport();
     }
 
-    public String getStatementCacheSize(){
+    public String getStatementCacheSize() {
         return spec.getDetail(DataSourceSpec.STATEMENTCACHESIZE);
     }
 
-    public void setStatementLeakTimeoutInSeconds(String value){
+    public void setStatementLeakTimeoutInSeconds(String value) {
         spec.setDetail(DataSourceSpec.STATEMENTLEAKTIMEOUTINSECONDS, value);
         detectStatementLeakSupport();
     }
 
-    public String getStatementLeakTimeoutInSeconds(){
+    public String getStatementLeakTimeoutInSeconds() {
         return spec.getDetail(DataSourceSpec.STATEMENTLEAKTIMEOUTINSECONDS);
     }
 
@@ -1047,13 +1058,14 @@
     public void setStatementCacheType(String statementCacheType) {
         spec.setDetail(DataSourceSpec.STATEMENTCACHETYPE, statementCacheType);
         this.statementCacheType = getStatementCacheType();
-        if(this.statementCacheType == null || this.statementCacheType.trim().equals("")) {
-            if(_logger.isLoggable(Level.FINE)) {
-                _logger.fine(" Default StatementCaching Type : " +
-                        localStrings.getString("jdbc.statement-cache.default.datastructure"));
+        if (this.statementCacheType == null || this.statementCacheType.trim().equals("")) {
+            if (_logger.isLoggable(FINE)) {
+                _logger.fine(
+                    " Default StatementCaching Type : " +
+                    localStrings.getString("jdbc.statement-cache.default.datastructure"));
             }
         } else {
-            if(_logger.isLoggable(Level.FINE)) {
+            if (_logger.isLoggable(FINE)) {
                 _logger.fine("StatementCaching Type : " + this.statementCacheType);
             }
         }
@@ -1080,9 +1092,8 @@
     }
 
     public void setInitSql(String initSql) {
-        //TODO remove case where "null" is checked. Might be a CLI/GUI bug.
-        if(initSql != null && !initSql.equalsIgnoreCase("null") &&
-                !initSql.equals("")) {
+        // TODO remove case where "null" is checked. Might be a CLI/GUI bug.
+        if (initSql != null && !initSql.equalsIgnoreCase("null") && !initSql.equals("")) {
             spec.setDetail(DataSourceSpec.INITSQL, initSql);
         }
     }
@@ -1112,7 +1123,7 @@
     }
 
     public void setSqlTraceListeners(String sqlTraceListeners) {
-        if(sqlTraceListeners != null) {
+        if (sqlTraceListeners != null) {
             spec.setDetail(DataSourceSpec.SQLTRACELISTENERS, sqlTraceListeners);
             detectSqlTraceListeners();
         }
@@ -1223,15 +1234,15 @@
         return spec.getDetail(DataSourceSpec.DELIMITER);
     }
 
-    public void setEscapeCharacter(String escapeCharacter){
+    public void setEscapeCharacter(String escapeCharacter) {
         spec.setDetail(DataSourceSpec.ESCAPECHARACTER, escapeCharacter);
     }
 
-    public String getEscapeCharacter(){
+    public String getEscapeCharacter() {
         return spec.getDetail(DataSourceSpec.ESCAPECHARACTER);
     }
 
-      /**
+    /**
      * Sets the driver specific properties.
      *
      * @param driverProps <code>String</code>
@@ -1252,16 +1263,14 @@
         return spec.getDetail(DataSourceSpec.DRIVERPROPERTIES);
     }
 
-    protected PoolInfo getPoolInfo(){
+    protected PoolInfo getPoolInfo() {
         return new PoolInfo(getPoolName(), getApplicationName(), getModuleName());
     }
 
-    protected ManagedConnectionImpl constructManagedConnection(PooledConnection pc,
-                                                           Connection sqlCon, PasswordCredential passCred,
-                                                           ManagedConnectionFactoryImpl mcf) throws ResourceException {
-        return new ManagedConnectionImpl(pc, sqlCon, passCred, mcf,
-                getPoolInfo(), statementCacheSize, statementCacheType, sqlTraceDelegator,
-                statementLeakTimeout, statementLeakReclaim);
+    protected ManagedConnectionImpl constructManagedConnection(PooledConnection pc, Connection sqlCon,
+            PasswordCredential passCred, ManagedConnectionFactoryImpl mcf) throws ResourceException {
+        return new ManagedConnectionImpl(pc, sqlCon, passCred, mcf, getPoolInfo(), statementCacheSize,
+                statementCacheType, sqlTraceDelegator, statementLeakTimeout, statementLeakReclaim);
     }
 
     /**
@@ -1271,10 +1280,10 @@
      * @throws ResourceException
      */
     public Object getDataSource() throws ResourceException {
-        if (dsObjBuilder == null) {
-            dsObjBuilder = new DataSourceObjectBuilder(spec);
+        if (dataSourceObjectBuilder == null) {
+            dataSourceObjectBuilder = new DataSourceObjectBuilder(spec);
         }
-        return dsObjBuilder.constructDataSourceObject();
+        return dataSourceObjectBuilder.constructDataSourceObject();
     }
 
     protected static final int JVM_OPTION_STATEMENT_WRAPPING_ON = 1;
@@ -1282,12 +1291,10 @@
     protected static final int JVM_OPTION_STATEMENT_WRAPPING_NOT_SET = -1;
 
     /**
-     * This wrapStatement flag is used to enable disable wrapping the
-     * statement objects. This can be enabled by passing jvm option,
-     * com.sun.appserv.jdbc.wrapstatement = true.
-     * This can be disabled by removing this option or by passing non true
-     * value.
-     * By default this will be disabled
+     * This wrapStatement flag is used to enable disable wrapping the statement
+     * objects. This can be enabled by passing jvm option,
+     * com.sun.appserv.jdbc.wrapstatement = true. This can be disabled by removing
+     * this option or by passing non true value. By default this will be disabled
      */
     private static int wrapStatement = JVM_OPTION_STATEMENT_WRAPPING_NOT_SET;
 
@@ -1303,8 +1310,7 @@
      */
     private static int getStatementWrappingJVMOption() {
         int result = JVM_OPTION_STATEMENT_WRAPPING_NOT_SET;
-        String str = System.getProperty(
-                "com.sun.appserv.jdbc.wrapJdbcObjects");
+        String str = System.getProperty("com.sun.appserv.jdbc.wrapJdbcObjects");
         if ("true".equalsIgnoreCase(str)) {
             result = JVM_OPTION_STATEMENT_WRAPPING_ON;
         } else if ("false".equalsIgnoreCase(str)) {
@@ -1314,9 +1320,9 @@
     }
 
     /**
-     * 9.1 has attribute "wrap-statements" which will be overriden
-     * when JVM option is specified as "true" or "false"
-     * JVM Option will be deprecated in future versions.
+     * 9.1 has attribute "wrap-statements" which will be overridden when JVM option
+     * is specified as "true" or "false" JVM Option will be deprecated in future
+     * versions.
      */
     protected void computeStatementWrappingStatus() {
 
@@ -1325,8 +1331,8 @@
         if (statementWrappingString != null)
             poolProperty = Boolean.valueOf(statementWrappingString);
 
-        if (wrapStatement == JVM_OPTION_STATEMENT_WRAPPING_ON ||
-                (wrapStatement == JVM_OPTION_STATEMENT_WRAPPING_NOT_SET && poolProperty)) {
+        if (wrapStatement == JVM_OPTION_STATEMENT_WRAPPING_ON
+                || (wrapStatement == JVM_OPTION_STATEMENT_WRAPPING_NOT_SET && poolProperty)) {
             statementWrapping = true;
         } else {
             statementWrapping = false;
@@ -1345,10 +1351,9 @@
     public JdbcObjectsFactory getJdbcObjectsFactory() {
         return jdbcObjectsFactory;
     }
-    protected void logFine(String logMessage){
-        if(_logger.isLoggable(Level.FINE)) {
-            _logger.log(Level.FINE, logMessage);
-        }
+
+    protected void logFine(String logMessage) {
+        _logger.log(FINE, logMessage);
     }
 
     @Override
@@ -1356,71 +1361,63 @@
         String poolMonitoringSubTreeRoot = getPoolMonitoringSubTreeRoot();
         String sqlTraceListeners = getSqlTraceListeners();
 
-        //Default values used in case sql tracing is OFF
+        // Default values used in case sql tracing is OFF
         int sqlTraceCacheSize = 0;
         long timeToKeepQueries = 0;
-        if(sqlTraceListeners != null && !sqlTraceListeners.equals("null")) {
-            if(getNumberOfTopQueriesToReport() != null && !getNumberOfTopQueriesToReport().equals("null")) {
-                //Some value is set for this property
+        if (sqlTraceListeners != null && !sqlTraceListeners.equals("null")) {
+            if (getNumberOfTopQueriesToReport() != null && !getNumberOfTopQueriesToReport().equals("null")) {
+                // Some value is set for this property
                 sqlTraceCacheSize = Integer.parseInt(getNumberOfTopQueriesToReport());
             } else {
-                //No property by this name. default to 10 queries
+                // No property by this name. default to 10 queries
                 sqlTraceCacheSize = 10;
             }
-            if(getTimeToKeepQueriesInMinutes() != null && !getTimeToKeepQueriesInMinutes().equals("null")) {
-                //Time-To-Keep-Queries property has been set
+            if (getTimeToKeepQueriesInMinutes() != null && !getTimeToKeepQueriesInMinutes().equals("null")) {
+                // Time-To-Keep-Queries property has been set
                 timeToKeepQueries = Integer.parseInt(getTimeToKeepQueriesInMinutes());
             } else {
-                //Default to 5 minutes after which cache is pruned.
+                // Default to 5 minutes after which cache is pruned.
                 timeToKeepQueries = 5;
-                //Time to keep queries is set to 5 minutes because the timer
-                //task will keep running till mcf is destroyed even if
-                //monitoring is turned OFF.
+                // Time to keep queries is set to 5 minutes because the timer
+                // task will keep running till mcf is destroyed even if
+                // monitoring is turned OFF.
             }
         }
-        if(_logger.isLoggable(Level.FINEST)) {
-            _logger.finest("MCF Created");
-        }
-        if (statementCacheSize > 0 ||
-                (sqlTraceListeners != null && !sqlTraceListeners.equals("null")) ||
-                statementLeakTimeout > 0) {
+
+        _logger.finest("MCF Created");
+
+        if (statementCacheSize > 0 || (sqlTraceListeners != null && !sqlTraceListeners.equals("null"))
+                || statementLeakTimeout > 0) {
             jdbcStatsProvider = new JdbcStatsProvider(getPoolName(), getApplicationName(), getModuleName(),
                     sqlTraceCacheSize, timeToKeepQueries);
-            //get the poolname and use it to initialize the stats provider n register
-            StatsProviderManager.register(
-                    "jdbc-connection-pool",
-                    PluginPoint.SERVER,
-                    poolMonitoringSubTreeRoot, jdbcStatsProvider);
-            if(jdbcStatsProvider.getSqlTraceCache() != null) {
-                if(_logger.isLoggable(Level.FINEST)) {
-                    _logger.finest("Scheduling timer task for sql trace caching");
-                }
-                Timer timer = ((com.sun.gjc.spi.ResourceAdapterImpl) ra).getTimer();
+
+            // Get the poolname and use it to initialize the stats provider n register
+            StatsProviderManager.register("jdbc-connection-pool", PluginPoint.SERVER, poolMonitoringSubTreeRoot,
+                    jdbcStatsProvider);
+
+            if (jdbcStatsProvider.getSqlTraceCache() != null) {
+                _logger.finest("Scheduling timer task for sql trace caching");
+                Timer timer = ((ResourceAdapterImpl) resourceAdapter).getTimer();
                 jdbcStatsProvider.getSqlTraceCache().scheduleTimerTask(timer);
             }
-            if(_logger.isLoggable(Level.FINEST)) {
-                _logger.finest("Registered JDBCRA Stats Provider");
-            }
+
+            _logger.finest("Registered JDBCRA Stats Provider");
         }
     }
 
     @Override
     public void mcfDestroyed() {
-        if(_logger.isLoggable(Level.FINEST)) {
-            _logger.finest("MCF Destroyed");
-        }
-        if(jdbcStatsProvider != null) {
-            if(jdbcStatsProvider.getSqlTraceCache() != null) {
-                if(_logger.isLoggable(Level.FINEST)) {
-                    _logger.finest("Canceling timer task for sql trace caching");
-                }
+        _logger.finest("MCF Destroyed");
+
+        if (jdbcStatsProvider != null) {
+            if (jdbcStatsProvider.getSqlTraceCache() != null) {
+                _logger.finest("Canceling timer task for sql trace caching");
                 jdbcStatsProvider.getSqlTraceCache().cancelTimerTask();
             }
+
             StatsProviderManager.unregister(jdbcStatsProvider);
             jdbcStatsProvider = null;
-            if(_logger.isLoggable(Level.FINEST)) {
-                _logger.finest("Unregistered JDBCRA Stats Provider");
-            }
+            _logger.finest("Unregistered JDBCRA Stats Provider");
         }
     }
 
@@ -1430,10 +1427,9 @@
         if (stmtLeakTimeout != null) {
             statementLeakTimeout = Integer.parseInt(stmtLeakTimeout) * 1000L;
             statementLeakReclaim = Boolean.valueOf(stmtLeakReclaim);
-            if (_logger.isLoggable(Level.FINE)) {
-                _logger.log(Level.FINE, "StatementLeakTimeout in seconds: "
-                        + statementLeakTimeout + " & StatementLeakReclaim: "
-                        + statementLeakReclaim + " for pool : " + getPoolInfo());
+            if (_logger.isLoggable(FINE)) {
+                _logger.log(FINE, "StatementLeakTimeout in seconds: " + statementLeakTimeout
+                        + " & StatementLeakReclaim: " + statementLeakReclaim + " for pool : " + getPoolInfo());
             }
         }
     }
@@ -1442,6 +1438,6 @@
     }
 
     public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
-        ra = com.sun.gjc.spi.ResourceAdapterImpl.getInstance();
+        resourceAdapter = ResourceAdapterImpl.getInstance();
     }
 }
diff --git a/appserver/jdbc/jdbc-ra/jdbc-core/src/main/java/com/sun/gjc/spi/ManagedConnectionImpl.java b/appserver/jdbc/jdbc-ra/jdbc-core/src/main/java/com/sun/gjc/spi/ManagedConnectionImpl.java
index b15dcc6..1ba4153 100644
--- a/appserver/jdbc/jdbc-ra/jdbc-core/src/main/java/com/sun/gjc/spi/ManagedConnectionImpl.java
+++ b/appserver/jdbc/jdbc-ra/jdbc-core/src/main/java/com/sun/gjc/spi/ManagedConnectionImpl.java
@@ -16,86 +16,103 @@
 
 package com.sun.gjc.spi;
 
-import com.sun.appserv.connectors.internal.spi.BadConnectionEventListener;
-import com.sun.enterprise.util.i18n.StringManager;
-import com.sun.gjc.common.DataSourceObjectBuilder;
-import com.sun.gjc.spi.base.*;
-import com.sun.gjc.spi.base.datastructure.Cache;
-import com.sun.gjc.spi.base.datastructure.CacheFactory;
-import com.sun.gjc.util.SQLTraceDelegator;
-import com.sun.gjc.util.StatementLeakDetector;
-import com.sun.logging.LogDomains;
-import org.glassfish.resourcebase.resources.api.PoolInfo;
+import static jakarta.resource.spi.ConnectionEvent.CONNECTION_ERROR_OCCURRED;
+import static java.util.logging.Level.FINE;
+import static java.util.logging.Level.INFO;
+import static java.util.logging.Level.WARNING;
 
-import jakarta.resource.NotSupportedException;
-import jakarta.resource.ResourceException;
-import jakarta.resource.spi.ConnectionEvent;
-import jakarta.resource.spi.ConnectionEventListener;
-import jakarta.resource.spi.security.PasswordCredential;
-import javax.security.auth.Subject;
-import javax.sql.PooledConnection;
-import javax.sql.XAConnection;
-import javax.transaction.xa.XAResource;
 import java.io.PrintWriter;
 import java.sql.CallableStatement;
+import java.sql.Connection;
 import java.sql.DatabaseMetaData;
 import java.sql.PreparedStatement;
 import java.sql.SQLException;
 import java.util.Hashtable;
 import java.util.Iterator;
+import java.util.NoSuchElementException;
 import java.util.Set;
-import java.util.logging.Level;
 import java.util.logging.Logger;
 
+import javax.security.auth.Subject;
+import javax.sql.PooledConnection;
+import javax.sql.XAConnection;
+import javax.transaction.xa.XAResource;
+
+import org.glassfish.resourcebase.resources.api.PoolInfo;
+
+import com.sun.appserv.connectors.internal.spi.BadConnectionEventListener;
+import com.sun.enterprise.util.i18n.StringManager;
+import com.sun.gjc.common.DataSourceObjectBuilder;
+import com.sun.gjc.spi.base.CacheObjectKey;
+import com.sun.gjc.spi.base.CallableStatementWrapper;
+import com.sun.gjc.spi.base.ConnectionHolder;
+import com.sun.gjc.spi.base.ConnectionWrapper;
+import com.sun.gjc.spi.base.PreparedStatementWrapper;
+import com.sun.gjc.spi.base.datastructure.Cache;
+import com.sun.gjc.spi.base.datastructure.CacheFactory;
+import com.sun.gjc.util.SQLTraceDelegator;
+import com.sun.gjc.util.StatementLeakDetector;
+import com.sun.logging.LogDomains;
+
+import jakarta.resource.NotSupportedException;
+import jakarta.resource.ResourceException;
+import jakarta.resource.spi.ConnectionEvent;
+import jakarta.resource.spi.ConnectionEventListener;
+import jakarta.resource.spi.DissociatableManagedConnection;
+import jakarta.resource.spi.LazyEnlistableManagedConnection;
+import jakarta.resource.spi.LocalTransaction;
+import jakarta.resource.spi.ManagedConnection;
+import jakarta.resource.spi.ManagedConnectionFactory;
+import jakarta.resource.spi.ManagedConnectionMetaData;
+import jakarta.resource.spi.security.PasswordCredential;
+
 /**
  * <code>ManagedConnection</code> implementation for Generic JDBC Connector.
  *
  * @author Evani Sai Surya Kiran
  * @version 1.0, 02/07/22
  */
-public class ManagedConnectionImpl implements jakarta.resource.spi.ManagedConnection,
-        jakarta.resource.spi.LazyEnlistableManagedConnection,
-        jakarta.resource.spi.DissociatableManagedConnection {
+public class ManagedConnectionImpl
+        implements ManagedConnection, LazyEnlistableManagedConnection, DissociatableManagedConnection {
+
+    protected static final Logger _logger = LogDomains.getLogger(ManagedConnectionImpl.class, LogDomains.RSR_LOGGER);
+    protected static final StringManager localStrings = StringManager.getManager(DataSourceObjectBuilder.class);
 
     public static final int ISNOTAPOOLEDCONNECTION = 0;
     public static final int ISPOOLEDCONNECTION = 1;
     public static final int ISXACONNECTION = 2;
 
-    protected boolean isDestroyed = false;
+    protected boolean isDestroyed;
     protected boolean isUsable = true;
-    protected boolean initSqlExecuted = false;
-    protected int connectionCount = 0;
+    protected boolean initSqlExecuted;
+    protected int connectionCount;
 
     protected int connectionType = ISNOTAPOOLEDCONNECTION;
-    protected PooledConnection pc = null;
-    protected java.sql.Connection actualConnection = null;
+    protected PooledConnection pooledConnection;
+    protected java.sql.Connection actualConnection;
     protected Hashtable connectionHandles;
     protected PrintWriter logWriter;
     protected PasswordCredential passwdCredential;
-    private jakarta.resource.spi.ManagedConnectionFactory mcf = null;
-    protected XAResource xar = null;
+    private ManagedConnectionFactory managedConnectionFactory;
+    protected XAResource xaResource;
 
-    protected ConnectionHolder myLogicalConnection = null;
+    protected ConnectionHolder myLogicalConnection;
 
-    //GJCINT
     protected int lastTransactionIsolationLevel;
     protected boolean isClean = true;
 
-    protected boolean transactionInProgress = false;
+    protected boolean transactionInProgress;
 
-    protected ConnectionEventListener listener = null;
-
-    protected ConnectionEvent ce = null;
+    protected ConnectionEventListener listener;
+    protected ConnectionEvent connectionEvent;
 
     private boolean defaultAutoCommitValue = true;
     private boolean lastAutoCommitValue = defaultAutoCommitValue;
 
-    private boolean markedForRemoval = false;
-
-    //private boolean statemntWrapping;
+    private boolean markedForRemoval;
     private int statementTimeout;
 
-    private Cache statementCache = null;
+    private Cache statementCache;
     private int cacheSize;
     private String cacheType;
     private boolean statementCaching;
@@ -106,53 +123,39 @@
 
     private SQLTraceDelegator sqlTraceDelegator;
 
-    protected final static Logger _logger;
+    private boolean aborted;
 
-    static {
-        _logger = LogDomains.getLogger(ManagedConnectionImpl.class, LogDomains.RSR_LOGGER);
-    }
-
-    protected static final StringManager localStrings =
-            StringManager.getManager(DataSourceObjectBuilder.class);
-
-    private boolean aborted = false;
-
-    private DatabaseMetaData cachedDatabaseMetaData = null;
-    private Boolean isClientInfoSupported = null;
+    private DatabaseMetaData cachedDatabaseMetaData;
+    private Boolean isClientInfoSupported;
 
     /**
-     * Constructor for <code>ManagedConnectionImpl</code>. The pooledConn parameter is expected
-     * to be null and sqlConn parameter is the actual connection in case where
-     * the actual connection is got from a non pooled datasource object. The
-     * pooledConn parameter is expected to be non null and sqlConn parameter
-     * is expected to be null in the case where the datasource object is a
-     * connection pool datasource or an xa datasource.
+     * Constructor for <code>ManagedConnectionImpl</code>. The pooledConn parameter
+     * is expected to be null and sqlConn parameter is the actual connection in case
+     * where the actual connection is got from a non pooled datasource object. The
+     * pooledConn parameter is expected to be non null and sqlConn parameter is
+     * expected to be null in the case where the datasource object is a connection
+     * pool datasource or an xa datasource.
      *
-     * @param pooledConn <code>PooledConnection</code> object in case the
-     *                   physical connection is to be obtained from a pooled
-     *                   <code>DataSource</code>; null otherwise
-     * @param sqlConn    <code>java.sql.Connection</code> object in case the physical
-     *                   connection is to be obtained from a non pooled <code>DataSource</code>;
-     *                   null otherwise
-     * @param passwdCred object conatining the
-     *                   user and password for allocating the connection
+     * @param pooledConn <code>PooledConnection</code> object in case the physical
+     * connection is to be obtained from a pooled <code>DataSource</code>; null
+     * otherwise
+     * @param sqlConn <code>java.sql.Connection</code> object in case the physical
+     * connection is to be obtained from a non pooled <code>DataSource</code>; null
+     * otherwise
+     * @param passwdCred object conatining the user and password for allocating the
+     * connection
      * @throws ResourceException if the <code>ManagedConnectionFactory</code> object
-     *                           that created this <code>ManagedConnectionImpl</code> object
-     *                           is not the same as returned by <code>PasswordCredential</code>
-     *                           object passed
+     * that created this <code>ManagedConnectionImpl</code> object is not the same
+     * as returned by <code>PasswordCredential</code> object passed
      */
-    public ManagedConnectionImpl(PooledConnection pooledConn, java.sql.Connection sqlConn,
-                             PasswordCredential passwdCred,
-                             jakarta.resource.spi.ManagedConnectionFactory mcf,
-                             PoolInfo poolInfo,
-                             int statementCacheSize, String statementCacheType,
-                             SQLTraceDelegator delegator,
-                             long statementLeakTimeout, boolean statementLeakReclaim)
+    public ManagedConnectionImpl(PooledConnection pooledConn, Connection sqlConn, PasswordCredential passwdCred,
+            ManagedConnectionFactory mcf, PoolInfo poolInfo, int statementCacheSize, String statementCacheType,
+            SQLTraceDelegator delegator, long statementLeakTimeout, boolean statementLeakReclaim)
             throws ResourceException {
+
         if (pooledConn == null && sqlConn == null) {
 
-            String i18nMsg = localStrings.getString(
-                    "jdbc.conn_obj_null");
+            String i18nMsg = localStrings.getString("jdbc.conn_obj_null");
             throw new ResourceException(i18nMsg);
         }
 
@@ -160,21 +163,19 @@
             actualConnection = sqlConn;
         }
 
-        pc = pooledConn;
+        pooledConnection = pooledConn;
         connectionHandles = new Hashtable();
         passwdCredential = passwdCred;
         sqlTraceDelegator = delegator;
 
-        this.mcf = mcf;
-        if (passwdCredential != null &&
-                this.mcf.equals(passwdCredential.getManagedConnectionFactory()) == false) {
+        this.managedConnectionFactory = mcf;
+        if (passwdCredential != null && this.managedConnectionFactory.equals(passwdCredential.getManagedConnectionFactory()) == false) {
 
-            String i18nMsg = localStrings.getString(
-                    "jdbc.mc_construct_err");
+            String i18nMsg = localStrings.getString("jdbc.mc_construct_err");
             throw new ResourceException(i18nMsg);
         }
         logWriter = mcf.getLogWriter();
-        ce = new ConnectionEvent(this, ConnectionEvent.CONNECTION_CLOSED);
+        connectionEvent = new ConnectionEvent(this, ConnectionEvent.CONNECTION_CLOSED);
         tuneStatementCaching(poolInfo, statementCacheSize, statementCacheType);
         tuneStatementLeakTracing(poolInfo, statementLeakTimeout, statementLeakReclaim);
     }
@@ -184,42 +185,34 @@
     }
 
     private void executeInitSql(final String initSql) {
-        if(_logger.isLoggable(Level.FINE)) {
-            _logger.log(Level.FINE, "jdbc.execute_init_sql_start");
-        }
-        java.sql.PreparedStatement stmt = null;
+        _logger.log(FINE, "jdbc.execute_init_sql_start");
+        PreparedStatement statement = null;
 
-        if (initSql != null && !initSql.equalsIgnoreCase("null") &&
-                !initSql.equals("")) {
-        try {
-                stmt = actualConnection.prepareStatement(initSql);
-                if(_logger.isLoggable(Level.FINE)) {
-                    _logger.log(Level.FINE, "jdbc.executing_init_sql", initSql);
-                }
-                stmt.execute();
+        if (initSql != null && !initSql.equalsIgnoreCase("null") && !initSql.equals("")) {
+            try {
+                statement = actualConnection.prepareStatement(initSql);
+                _logger.log(FINE, "jdbc.executing_init_sql", initSql);
+                statement.execute();
             } catch (SQLException sqle) {
-                _logger.log(Level.WARNING, "jdbc.exc_init_sql_error", initSql);
+                _logger.log(WARNING, "jdbc.exc_init_sql_error", initSql);
                 initSqlExecuted = false;
             } finally {
                 try {
-                    if (stmt != null) {
-                        stmt.close();
+                    if (statement != null) {
+                        statement.close();
                     }
                 } catch (Exception e) {
-                    if(_logger.isLoggable(Level.FINE)) {
-                        _logger.log(Level.FINE, "jdbc.exc_init_sql_error_stmt_close", e.getMessage());
+                    if (_logger.isLoggable(FINE)) {
+                        _logger.log(FINE, "jdbc.exc_init_sql_error_stmt_close", e.getMessage());
                     }
                 }
             }
             initSqlExecuted = true;
         }
-        if(_logger.isLoggable(Level.FINE)) {
-            _logger.log(Level.FINE, "jdbc.execute_init_sql_end");
-        }
+        _logger.log(FINE, "jdbc.execute_init_sql_end");
     }
 
-    private void tuneStatementCaching(PoolInfo poolInfo, int statementCacheSize,
-            String statementCacheType) {
+    private void tuneStatementCaching(PoolInfo poolInfo, int statementCacheSize, String statementCacheType) {
         cacheSize = statementCacheSize;
         cacheType = statementCacheType;
         if (cacheSize > 0) {
@@ -232,21 +225,23 @@
         }
     }
 
-    private void tuneStatementLeakTracing(PoolInfo poolInfo, long statementLeakTimeout,
-            boolean statementLeakReclaim) {
+    private void tuneStatementLeakTracing(PoolInfo poolInfo, long statementLeakTimeout, boolean statementLeakReclaim) {
         stmtLeakTimeout = statementLeakTimeout;
         stmtLeakReclaim = statementLeakReclaim;
 
-        if(stmtLeakTimeout > 0) {
-            ManagedConnectionFactoryImpl spiMCF = (ManagedConnectionFactoryImpl) mcf;
+        if (stmtLeakTimeout > 0) {
+            ManagedConnectionFactoryImpl managedConnectionFactoryImpl = (ManagedConnectionFactoryImpl) managedConnectionFactory;
             statementLeakTracing = true;
             if (leakDetector == null) {
-                leakDetector = new StatementLeakDetector(poolInfo, statementLeakTracing,
-                        stmtLeakTimeout, stmtLeakReclaim,
-                        ((com.sun.gjc.spi.ResourceAdapterImpl) spiMCF.getResourceAdapter()).getTimer());
+                leakDetector =
+                    new StatementLeakDetector(
+                        poolInfo, statementLeakTracing, stmtLeakTimeout,
+                        stmtLeakReclaim,
+                        ((ResourceAdapterImpl) managedConnectionFactoryImpl.getResourceAdapter()).getTimer());
             }
         }
     }
+
     /**
      * Adds a connection event listener to the ManagedConnectionImpl instance.
      *
@@ -261,75 +256,72 @@
      * Used by the container to change the association of an application-level
      * connection handle with a <code>ManagedConnectionImpl</code> instance.
      *
-     * @param connection <code>ConnectionHolder30</code> to be associated with
-     *                   this <code>ManagedConnectionImpl</code> instance
-     * @throws ResourceException if the physical connection is no more
-     *                           valid or the connection handle passed is null
+     * @param connection <code>ConnectionHolder30</code> to be associated with this
+     * <code>ManagedConnectionImpl</code> instance
+     * @throws ResourceException if the physical connection is no more valid or the
+     * connection handle passed is null
      */
     public void associateConnection(Object connection) throws ResourceException {
         logFine("In associateConnection");
         checkIfValid();
         if (connection == null) {
-            String i18nMsg = localStrings.getString(
-                    "jdbc.conn_handle_null");
-            throw new ResourceException(i18nMsg);
+            throw new ResourceException(localStrings.getString("jdbc.conn_handle_null"));
         }
-        ConnectionHolder ch = (ConnectionHolder) connection;
 
-        com.sun.gjc.spi.ManagedConnectionImpl mc = ch.getManagedConnection();
+        ConnectionHolder connectionHolder = (ConnectionHolder) connection;
+        ManagedConnectionImpl managedConnectionImpl = connectionHolder.getManagedConnection();
         isClean = false;
 
-        ch.associateConnection(actualConnection, this);
+        connectionHolder.associateConnection(actualConnection, this);
+
         /**
-         * The expectation from the above method is that the connection holder
-         * replaces the actual sql connection it holds with the sql connection
-         * handle being passed in this method call. Also, it replaces the reference
-         * to the ManagedConnectionImpl instance with this ManagedConnectionImpl instance.
-         * Any previous statements and result sets also need to be removed.
+         * The expectation from the above method is that the connection holder replaces
+         * the actual sql connection it holds with the sql connection handle being
+         * passed in this method call. Also, it replaces the reference to the
+         * ManagedConnectionImpl instance with this ManagedConnectionImpl instance. Any
+         * previous statements and result sets also need to be removed.
          */
 
-
-        ch.setActive(true);
+        connectionHolder.setActive(true);
         incrementCount();
-        //associate the MC to the supplied logical connection similar to associating the logical connection
-        //with this MC and actual-connection.
-        myLogicalConnection = ch;
 
-        //mc will be null in case we are lazily associating
-        if (mc != null) {
-            mc.decrementCount();
+        // associate the MC to the supplied logical connection similar to associating
+        // the logical connection
+        // with this MC and actual-connection.
+        myLogicalConnection = connectionHolder;
+
+        // managedConnection will be null in case we are lazily associating
+        if (managedConnectionImpl != null) {
+            managedConnectionImpl.decrementCount();
         }
     }
 
     /**
      * Application server calls this method to force any cleanup on the
      * <code>ManagedConnectionImpl</code> instance. This method calls the invalidate
-     * method on all ConnectionHandles associated with this <code>ManagedConnectionImpl</code>.
+     * method on all ConnectionHandles associated with this
+     * <code>ManagedConnectionImpl</code>.
      *
      * @throws ResourceException if the physical connection is no more valid
      */
     public void cleanup() throws ResourceException {
         logFine("In cleanup");
-        //commenting this as cleanup is called after destroy in case of markConnectionAsBad()
-        //checkIfValid();
 
         /**
          * may need to set the autocommit to true for the non-pooled case.
          */
-        //GJCINT
         isClean = true;
 
-        ManagedConnectionFactoryImpl spiMCF = (ManagedConnectionFactoryImpl) mcf;
-        resetConnectionProperties(spiMCF);
+        resetConnectionProperties((ManagedConnectionFactoryImpl) managedConnectionFactory);
     }
 
     /**
-     * This method removes all the connection handles from the table
-     * of connection handles and invalidates all of them so that any
-     * operation on those connection handles throws an exception.
+     * This method removes all the connection handles from the table of connection
+     * handles and invalidates all of them so that any operation on those connection
+     * handles throws an exception.
      *
-     * @throws ResourceException if there is a problem in retrieving
-     *                           the connection handles
+     * @throws ResourceException if there is a problem in retrieving the connection
+     * handles
      */
     protected void invalidateAllConnectionHandles() throws ResourceException {
         Set handles = connectionHandles.keySet();
@@ -339,17 +331,15 @@
                 ConnectionHolder ch = (ConnectionHolder) iter.next();
                 ch.invalidate();
             }
-        } catch (java.util.NoSuchElementException nsee) {
-            throw new ResourceException("Could not find the connection handle: " + nsee.getMessage());
+        } catch (NoSuchElementException nsee) {
+            throw new ResourceException("Could not find the connection handle: " + nsee.getMessage(), nsee);
         }
         connectionHandles.clear();
     }
 
     private void clearStatementCache() {
         if (statementCache != null) {
-            if(_logger.isLoggable(Level.FINE)) {
-                _logger.fine("Closing statements in statement cache");
-            }
+            _logger.fine("Closing statements in statement cache");
             statementCache.flushCache();
             statementCache.clearCache();
         }
@@ -358,27 +348,28 @@
     /**
      * Destroys the physical connection to the underlying resource manager.
      *
-     * @throws ResourceException if there is an error in closing the physical connection
+     * @throws ResourceException if there is an error in closing the physical
+     * connection
      */
     public void destroy() throws ResourceException {
         logFine("In destroy");
-        //GJCINT
         if (isDestroyed) {
             return;
         }
         clearStatementCache();
-        //Connection could be closed even before statement is closed. Connection
-        //close need not call statement close() method.
-        //When application uses a statement, leakDetector could be started.At
-        //this point, there is a need to clear the statement leak tasks
+
+        // Connection could be closed even before statement is closed. Connection
+        // close need not call statement close() method.
+        // When application uses a statement, leakDetector could be started.At
+        // this point, there is a need to clear the statement leak tasks
         if (leakDetector != null) {
             leakDetector.clearAllStatementLeakTasks();
         }
 
         try {
             if (connectionType == ISXACONNECTION || connectionType == ISPOOLEDCONNECTION) {
-                pc.close();
-                pc = null;
+                pooledConnection.close();
+                pooledConnection = null;
                 actualConnection = null;
             } else {
                 actualConnection.close();
@@ -388,49 +379,35 @@
             isDestroyed = true;
             passwdCredential = null;
             connectionHandles = null;
-            String i18nMsg = localStrings.getString(
-                    "jdbc.error_in_destroy");
-            ResourceException re = new ResourceException(
-                    i18nMsg + sqle.getMessage(), sqle);
-            throw re;
+            throw new ResourceException(localStrings.getString("jdbc.error_in_destroy") + sqle.getMessage(), sqle);
         }
+
         isDestroyed = true;
         passwdCredential = null;
         connectionHandles = null;
     }
 
     /**
-     * Creates a new connection handle for the underlying physical
-     * connection represented by the <code>ManagedConnectionImpl</code> instance.
+     * Creates a new connection handle for the underlying physical connection
+     * represented by the <code>ManagedConnectionImpl</code> instance.
      *
-     * @param sub       <code>Subject</code> parameter needed for authentication
-     * @param cxReqInfo <code>ConnectionRequestInfo</code> carries the user
-     *                  and password required for getting this connection.
-     * @return Connection    the connection handle <code>Object</code>
-     * @throws ResourceException if there is an error in allocating the
-     *                           physical connection from the pooled connection
-     * @throws jakarta.resource.spi.SecurityException
-     *                           if there is a mismatch between the
-     *                           password credentials or reauthentication is requested
+     * @param sub <code>Subject</code> parameter needed for authentication
+     * @param cxReqInfo <code>ConnectionRequestInfo</code> carries the user and
+     * password required for getting this connection.
+     * @return Connection the connection handle <code>Object</code>
+     * @throws ResourceException if there is an error in allocating the physical
+     * connection from the pooled connection
+     * @throws jakarta.resource.spi.SecurityException if there is a mismatch between
+     * the password credentials or reauthentication is requested
      */
-    public Object getConnection(Subject sub, jakarta.resource.spi.ConnectionRequestInfo cxReqInfo)
-            throws ResourceException {
+    public Object getConnection(Subject sub, jakarta.resource.spi.ConnectionRequestInfo cxReqInfo) throws ResourceException {
         logFine("In getConnection");
         checkIfValid();
-        /** Appserver any way doesnt bother about re-authentication today. So commenting this out now.
-         com.sun.gjc.spi.ConnectionRequestInfo cxRequestInfo = (com.sun.gjc.spi.ConnectionRequestInfo) cxReqInfo;
-         PasswordCredential passwdCred = SecurityUtils.getPasswordCredential(this.mcf, sub, cxRequestInfo);
 
-         if(SecurityUtils.isPasswordCredentialEqual(this.passwdCredential, passwdCred) == false) {
-         throw new jakarta.resource.spi.SecurityException("Re-authentication not supported");
-         }
-         **/
-
-        //GJCINT
         getActualConnection();
-        ManagedConnectionFactoryImpl spiMCF = (ManagedConnectionFactoryImpl) mcf;
+        ManagedConnectionFactoryImpl managedConnectionFactoryImpl = (ManagedConnectionFactoryImpl) managedConnectionFactory;
 
-        String statementTimeoutString = spiMCF.getStatementTimeout();
+        String statementTimeoutString = managedConnectionFactoryImpl.getStatementTimeout();
         if (statementTimeoutString != null) {
             int timeoutValue = Integer.parseInt(statementTimeoutString);
             if (timeoutValue >= 0) {
@@ -438,14 +415,17 @@
             }
         }
 
-        myLogicalConnection = spiMCF.getJdbcObjectsFactory().getConnection(
-                actualConnection, this, cxReqInfo, spiMCF.isStatementWrappingEnabled(),
-                sqlTraceDelegator);
+        myLogicalConnection =
+            managedConnectionFactoryImpl.getJdbcObjectsFactory()
+                                        .getConnection(
+                                            actualConnection, this, cxReqInfo,
+                                            managedConnectionFactoryImpl.isStatementWrappingEnabled(),
+                                            sqlTraceDelegator);
 
-        //TODO : need to see if this should be executed for every getConnection
+        // TODO : need to see if this should be executed for every getConnection
         if (!initSqlExecuted) {
-            //Check if Initsql is set and execute it
-            String initSql = spiMCF.getInitSql();
+            // Check if Initsql is set and execute it
+            String initSql = managedConnectionFactoryImpl.getInitSql();
             executeInitSql(initSql);
         }
         incrementCount();
@@ -457,28 +437,30 @@
     }
 
     /**
-     * Resett connection properties as connections are pooled by application server<br>
+     * Resett connection properties as connections are pooled by application
+     * server<br>
      *
-     * @param spiMCF
+     * @param managedConnectionFactoryImpl
      * @throws ResourceException
      */
-    private void resetConnectionProperties(ManagedConnectionFactoryImpl spiMCF) throws ResourceException {
+    private void resetConnectionProperties(ManagedConnectionFactoryImpl managedConnectionFactoryImpl) throws ResourceException {
         if (isClean) {
 
-            // If the ManagedConnection is clean, reset the transaction isolation level to what
-            // it was when it was when this ManagedConnection was cleaned up depending on the
-            // ConnectionRequestInfo passed.
-            spiMCF.resetIsolation(this, lastTransactionIsolationLevel);
+            // If the ManagedConnection is clean, reset the transaction isolation level to
+            // what it was when it was when this ManagedConnection was cleaned up depending on
+            // the ConnectionRequestInfo passed.
+            managedConnectionFactoryImpl.resetIsolation(this, lastTransactionIsolationLevel);
 
-            // reset the autocommit value of the connection if application has modified it.
+            // Reset the autocommit value of the connection if application has modified it.
             resetAutoCommit();
         }
     }
 
     /**
-     * To reset AutoCommit of actual connection.
-     * If the last-auto-commit value is different from default-auto-commit value, reset will happen.
-     * If there is a transaction in progress (because of connection sharing), reset will not happen.
+     * To reset AutoCommit of actual connection. If the last-auto-commit value is
+     * different from default-auto-commit value, reset will happen. If there is a
+     * transaction in progress (because of connection sharing), reset will not
+     * happen.
      *
      * @throws ResourceException
      */
@@ -487,32 +469,32 @@
             try {
                 actualConnection.setAutoCommit(defaultAutoCommitValue);
             } catch (SQLException sqle) {
-                String i18nMsg = localStrings.getString(
-                        "jdbc.error_during_setAutoCommit");
-                throw new ResourceException(i18nMsg + sqle.getMessage(), sqle);
+                throw new ResourceException(localStrings.getString("jdbc.error_during_setAutoCommit") + sqle.getMessage(), sqle);
             }
+
             setLastAutoCommitValue(defaultAutoCommitValue);
         }
     }
 
     /**
-     * Returns an <code>LocalTransactionImpl</code> instance. The <code>LocalTransactionImpl</code> interface
-     * is used by the container to manage local transactions for a RM instance.
+     * Returns an <code>LocalTransactionImpl</code> instance. The
+     * <code>LocalTransactionImpl</code> interface is used by the container to
+     * manage local transactions for a RM instance.
      *
      * @return <code>LocalTransactionImpl</code> instance
      * @throws ResourceException if the physical connection is not valid
      */
-    public jakarta.resource.spi.LocalTransaction getLocalTransaction() throws ResourceException {
+    public LocalTransaction getLocalTransaction() throws ResourceException {
         logFine("In getLocalTransaction");
         checkIfValid();
-        return new com.sun.gjc.spi.LocalTransactionImpl(this);
+        return new LocalTransactionImpl(this);
     }
 
     /**
      * Gets the log writer for this <code>ManagedConnectionImpl</code> instance.
      *
      * @return <code>PrintWriter</code> instance associated with this
-     *         <code>ManagedConnectionImpl</code> instance
+     * <code>ManagedConnectionImpl</code> instance
      * @throws ResourceException if the physical connection is not valid
      * @see <code>setLogWriter</code>
      */
@@ -524,28 +506,27 @@
     }
 
     /**
-     * Gets the metadata information for this connection's underlying EIS
-     * resource manager instance.
+     * Gets the metadata information for this connection's underlying EIS resource
+     * manager instance.
      *
      * @return <code>ManagedConnectionMetaData</code> instance
      * @throws ResourceException if the physical connection is not valid
      */
-    public jakarta.resource.spi.ManagedConnectionMetaData getMetaData() throws ResourceException {
+    public ManagedConnectionMetaData getMetaData() throws ResourceException {
         logFine("In getMetaData");
         checkIfValid();
 
-        return new com.sun.gjc.spi.ManagedConnectionMetaDataImpl(this);
+        return new ManagedConnectionMetaDataImpl(this);
     }
 
     /**
      * Returns an <code>XAResource</code> instance.
      *
      * @return <code>XAResource</code> instance
-     * @throws ResourceException     if the physical connection is not valid or
-     *                               there is an error in allocating the
-     *                               <code>XAResource</code> instance
+     * @throws ResourceException if the physical connection is not valid or there is
+     * an error in allocating the <code>XAResource</code> instance
      * @throws NotSupportedException if underlying datasource is not an
-     *                               <code>XADataSource</code>
+     * <code>XADataSource</code>
      */
     public XAResource getXAResource() throws ResourceException {
         logFine("In getXAResource");
@@ -553,13 +534,13 @@
 
         if (connectionType == ISXACONNECTION) {
             try {
-                if (xar == null) {
+                if (xaResource == null) {
                     /**
                      * Using the wrapper XAResource.
                      */
-                    xar = new com.sun.gjc.spi.XAResourceImpl(((XAConnection) pc).getXAResource(), this);
+                    xaResource = new XAResourceImpl(((XAConnection) pooledConnection).getXAResource(), this);
                 }
-                return xar;
+                return xaResource;
             } catch (SQLException sqle) {
                 throw new ResourceException(sqle.getMessage(), sqle);
             }
@@ -579,18 +560,18 @@
     }
 
     /**
-     * This method is called from XAResource wrapper object
-     * when its XAResource.start() has been called or from
-     * LocalTransactionImpl object when its begin() method is called.
+     * This method is called from XAResource wrapper object when its
+     * XAResource.start() has been called or from LocalTransactionImpl object when
+     * its begin() method is called.
      */
     void transactionStarted() {
         transactionInProgress = true;
     }
 
     /**
-     * This method is called from XAResource wrapper object
-     * when its XAResource.end() has been called or from
-     * LocalTransactionImpl object when its end() method is called.
+     * This method is called from XAResource wrapper object when its
+     * XAResource.end() has been called or from LocalTransactionImpl object when its
+     * end() method is called.
      */
     void transactionCompleted() {
         try {
@@ -606,22 +587,19 @@
                 }
             }
         } catch (java.lang.NullPointerException e) {
-            if(_logger.isLoggable(Level.FINE)) {
-                _logger.log(Level.FINE, "jdbc.duplicateTxCompleted");
-            }
+            _logger.log(FINE, "jdbc.duplicateTxCompleted");
         }
 
         if (markedForRemoval) {
             if (aborted) {
-                com.sun.appserv.connectors.internal.spi.BadConnectionEventListener bcel =
-                        (BadConnectionEventListener) listener;
-                bcel.connectionAbortOccurred(ce);
-                _logger.log(Level.INFO, "jdbc.markedForRemoval_conAborted");
+                BadConnectionEventListener badConnectionEventListener = (BadConnectionEventListener) listener;
+                badConnectionEventListener.connectionAbortOccurred(connectionEvent);
+                _logger.log(INFO, "jdbc.markedForRemoval_conAborted");
                 markedForRemoval = false;
                 myLogicalConnection.setClosed(true);
             } else {
                 connectionErrorOccurred(null, null);
-                _logger.log(Level.INFO, "jdbc.markedForRemoval_txCompleted");
+                _logger.log(INFO, "jdbc.markedForRemoval_txCompleted");
                 markedForRemoval = false;
             }
         }
@@ -630,8 +608,7 @@
     }
 
     /**
-     * Checks if a this ManagedConnection is involved in a transaction
-     * or not.
+     * Checks if a this ManagedConnection is involved in a transaction or not.
      */
     public boolean isTransactionInProgress() {
         return transactionInProgress;
@@ -641,7 +618,7 @@
      * Sets the log writer for this <code>ManagedConnectionImpl</code> instance.
      *
      * @param out <code>PrintWriter</code> to be associated with this
-     *            <code>ManagedConnectionImpl</code> instance
+     * <code>ManagedConnectionImpl</code> instance
      * @throws ResourceException if the physical connection is not valid
      * @see <code>getLogWriter</code>
      */
@@ -651,8 +628,8 @@
     }
 
     /**
-     * This method determines the type of the connection being held
-     * in this <code>ManagedConnectionImpl</code>.
+     * This method determines the type of the connection being held in this
+     * <code>ManagedConnectionImpl</code>.
      *
      * @param pooledConn <code>PooledConnection</code>
      * @return connection type
@@ -660,22 +637,24 @@
     protected int getConnectionType(PooledConnection pooledConn) {
         if (pooledConn == null) {
             return ISNOTAPOOLEDCONNECTION;
-        } else if (pooledConn instanceof XAConnection) {
-            return ISXACONNECTION;
-        } else {
-            return ISPOOLEDCONNECTION;
         }
+
+        if (pooledConn instanceof XAConnection) {
+            return ISXACONNECTION;
+        }
+
+        return ISPOOLEDCONNECTION;
     }
 
     /**
-     * Returns the <code>ManagedConnectionFactory</code> instance that
-     * created this <code>ManagedConnection</code> instance.
+     * Returns the <code>ManagedConnectionFactory</code> instance that created this
+     * <code>ManagedConnection</code> instance.
      *
      * @return <code>ManagedConnectionFactory</code> instance that created this
-     *         <code>ManagedConnection</code> instance
+     * <code>ManagedConnection</code> instance
      */
-    public com.sun.gjc.spi.ManagedConnectionFactoryImpl getManagedConnectionFactory() {
-        return (com.sun.gjc.spi.ManagedConnectionFactoryImpl) mcf;
+    public ManagedConnectionFactoryImpl getManagedConnectionFactory() {
+        return (ManagedConnectionFactoryImpl) managedConnectionFactory;
     }
 
     /**
@@ -683,15 +662,13 @@
      *
      * @return the physical <code>java.sql.Connection</code>
      */
-    //GJCINT
-    java.sql.Connection getActualConnection() throws ResourceException {
-        //GJCINT
+    Connection getActualConnection() throws ResourceException {
         if (connectionType == ISXACONNECTION || connectionType == ISPOOLEDCONNECTION) {
             try {
                 if (actualConnection == null) {
-                    actualConnection = pc.getConnection();
+                    actualConnection = pooledConnection.getConnection();
 
-                    //re-initialize lastAutoCommitValue such that resetAutoCommit() wont
+                    // re-initialize lastAutoCommitValue such that resetAutoCommit() wont
                     // affect autoCommit of actualConnection
                     setLastAutoCommitValue(defaultAutoCommitValue);
                 }
@@ -700,14 +677,16 @@
                 throw new ResourceException(sqle.getMessage(), sqle);
             }
         }
+
         return actualConnection;
     }
 
     /**
-     * Returns the <code>PasswordCredential</code> object associated with this <code>ManagedConnection</code>.
+     * Returns the <code>PasswordCredential</code> object associated with this
+     * <code>ManagedConnection</code>.
      *
      * @return <code>PasswordCredential</code> associated with this
-     *         <code>ManagedConnection</code> instance
+     * <code>ManagedConnection</code> instance
      */
     PasswordCredential getPasswordCredential() {
         return passwdCredential;
@@ -715,129 +694,121 @@
 
     /**
      * Checks if this <code>ManagedConnection</code> is valid or not and throws an
-     * exception if it is not valid. A <code>ManagedConnection</code> is not valid if
-     * destroy has not been called and no physical connection error has
-     * occurred rendering the physical connection unusable.
+     * exception if it is not valid. A <code>ManagedConnection</code> is not valid
+     * if destroy has not been called and no physical connection error has occurred
+     * rendering the physical connection unusable.
      *
      * @throws ResourceException if <code>destroy</code> has been called on this
-     *                           <code>ManagedConnection</code> instance or if a
-     *                           physical connection error occurred rendering it unusable
+     * <code>ManagedConnection</code> instance or if a physical connection error
+     * occurred rendering it unusable
      */
-    //GJCINT
     void checkIfValid() throws ResourceException {
         if (isDestroyed || !isUsable) {
-
-            String i18nMsg = localStrings.getString(
-                    "jdbc.mc_not_usable");
-            throw new ResourceException(i18nMsg);
+            throw new ResourceException(localStrings.getString("jdbc.mc_not_usable"));
         }
     }
 
     /**
-     * This method is called by the <code>ConnectionHolder30</code> when its close method is
-     * called. This <code>ManagedConnection</code> instance  invalidates the connection handle
-     * and sends a CONNECTION_CLOSED event to all the registered event listeners.
+     * This method is called by the <code>ConnectionHolder30</code> when its close
+     * method is called. This <code>ManagedConnection</code> instance invalidates
+     * the connection handle and sends a CONNECTION_CLOSED event to all the
+     * registered event listeners.
      *
-     * @param e                  Exception that may have occured while closing the connection handle
-     * @param connHolder30Object <code>ConnectionHolder30</code> that has been closed
+     * @param e Exception that may have occured while closing the connection handle
+     * @param connHolder30Object <code>ConnectionHolder30</code> that has been
+     * closed
      * @throws SQLException in case closing the sql connection got out of
-     *                      <code>getConnection</code> on the underlying
-     *                      <code>PooledConnection</code> throws an exception
+     * <code>getConnection</code> on the underlying <code>PooledConnection</code>
+     * throws an exception
      */
     public void connectionClosed(Exception e, ConnectionHolder connHolder30Object) throws SQLException {
-
         connHolder30Object.invalidate();
         decrementCount();
-        ce.setConnectionHandle(connHolder30Object);
+        connectionEvent.setConnectionHandle(connHolder30Object);
 
         if (markedForRemoval && !transactionInProgress) {
-            com.sun.appserv.connectors.internal.spi.BadConnectionEventListener bcel = (BadConnectionEventListener) listener;
-            bcel.badConnectionClosed(ce);
-            _logger.log(Level.INFO, "jdbc.markedForRemoval_conClosed");
+            BadConnectionEventListener badConnectionEventListener = (BadConnectionEventListener) listener;
+            badConnectionEventListener.badConnectionClosed(connectionEvent);
+            _logger.log(INFO, "jdbc.markedForRemoval_conClosed");
             markedForRemoval = false;
         } else {
-            listener.connectionClosed(ce);
+            listener.connectionClosed(connectionEvent);
         }
     }
 
     /**
-     * This method is called by the <code>ConnectionHolder30</code> when it detects a connecion
-     * related error.
+     * This method is called by the <code>ConnectionHolder30</code> when it detects
+     * a connecion related error.
      *
-     * @param e                Exception that has occurred during an operation on the physical connection
-     * @param connHolderObject <code>ConnectionHolder</code> that detected the physical
-     *                         connection error
+     * @param e Exception that has occurred during an operation on the physical
+     * connection
+     * @param connectionHolder <code>ConnectionHolder</code> that detected the
+     * physical connection error
      */
-    void connectionErrorOccurred(Exception e,
-                                 ConnectionHolder connHolderObject) {
+    void connectionErrorOccurred(Exception e, ConnectionHolder connectionHolder) {
+        ConnectionEventListener connectionEventListener = this.listener;
 
-        ConnectionEventListener cel = this.listener;
-        ConnectionEvent ce = null;
-        ce = e == null ? new ConnectionEvent(this, ConnectionEvent.CONNECTION_ERROR_OCCURRED)
-                : new ConnectionEvent(this, ConnectionEvent.CONNECTION_ERROR_OCCURRED, e);
-        if (connHolderObject != null) {
-            ce.setConnectionHandle(connHolderObject);
+        ConnectionEvent connectionEvent = e == null ?
+            new ConnectionEvent(this, CONNECTION_ERROR_OCCURRED) :
+            new ConnectionEvent(this, CONNECTION_ERROR_OCCURRED, e);
+
+        if (connectionHolder != null) {
+            connectionEvent.setConnectionHandle(connectionHolder);
         }
 
-        cel.connectionErrorOccurred(ce);
+        connectionEventListener.connectionErrorOccurred(connectionEvent);
         isUsable = false;
     }
 
-
     /**
-     * This method is called by the <code>XAResource</code> object when its start method
-     * has been invoked.
+     * This method is called by the <code>XAResource</code> object when its start
+     * method has been invoked.
      */
     void XAStartOccurred() {
         try {
             actualConnection.setAutoCommit(false);
         } catch (Exception e) {
-            _logger.log(Level.WARNING, "XA Start [ setAutoCommit ] failure ", e);
+            _logger.log(WARNING, "XA Start [ setAutoCommit ] failure ", e);
             connectionErrorOccurred(e, null);
         }
     }
 
     /**
-     * This method is called by the <code>XAResource</code> object when its end method
-     * has been invoked.
+     * This method is called by the <code>XAResource</code> object when its end
+     * method has been invoked.
      */
     void XAEndOccurred() {
         try {
             actualConnection.setAutoCommit(true);
         } catch (Exception e) {
-            _logger.log(Level.WARNING, "XA End [ setAutoCommit ] failure ", e);
+            _logger.log(WARNING, "XA End [ setAutoCommit ] failure ", e);
             connectionErrorOccurred(e, null);
         }
     }
 
     /**
-     * This method is called by a Connection Handle to check if it is
-     * the active Connection Handle. If it is not the active Connection
-     * Handle, this method throws an SQLException. Else, it
-     * returns setting the active Connection Handle to the calling
-     * Connection Handle object to this object if the active Connection
-     * Handle is null.
+     * This method is called by a Connection Handle to check if it is the active
+     * Connection Handle. If it is not the active Connection Handle, this method
+     * throws an SQLException. Else, it returns setting the active Connection Handle
+     * to the calling Connection Handle object to this object if the active
+     * Connection Handle is null.
      *
      * @param ch <code>ConnectionHolder30</code> that requests this
-     *           <code>ManagedConnection</code> instance whether
-     *           it can be active or not
-     * @throws SQLException in case the physical is not valid or
-     *                      there is already an active connection handle
+     * <code>ManagedConnection</code> instance whether it can be active or not
+     * @throws SQLException in case the physical is not valid or there is already an
+     * active connection handle
      */
 
     public void checkIfActive(ConnectionHolder ch) throws SQLException {
         if (isDestroyed || !isUsable) {
-
-            String i18nMsg = localStrings.getString(
-                    "jdbc.conn_not_usable");
-            throw new SQLException(i18nMsg);
+            throw new SQLException(localStrings.getString("jdbc.conn_not_usable"));
         }
     }
 
     /**
-     * sets the connection type of this connection. This method is called
-     * by the MCF while creating this ManagedConnection. Saves us a costly
-     * instanceof operation in the getConnectionType
+     * sets the connection type of this connection. This method is called by the MCF
+     * while creating this ManagedConnection. Saves us a costly instanceof operation
+     * in the getConnectionType
      */
     public void initializeConnectionType(int _connectionType) {
         connectionType = _connectionType;
@@ -852,7 +823,7 @@
     }
 
     public void dissociateConnections() {
-        if(myLogicalConnection != null){
+        if (myLogicalConnection != null) {
             myLogicalConnection.dissociateConnection();
             myLogicalConnection = null;
         }
@@ -863,8 +834,8 @@
     }
 
     /**
-     * To keep track of last auto commit value.
-     * Helps to reset the auto-commit-value while giving new connection-handle.
+     * To keep track of last auto commit value. Helps to reset the auto-commit-value
+     * while giving new connection-handle.
      *
      * @param lastAutoCommitValue
      */
@@ -872,20 +843,17 @@
         this.lastAutoCommitValue = lastAutoCommitValue;
     }
 
-
     public void markForRemoval(boolean flag) {
         markedForRemoval = flag;
     }
 
-    public jakarta.resource.spi.ManagedConnectionFactory getMcf() {
-        return mcf;
+    public ManagedConnectionFactory getMcf() {
+        return managedConnectionFactory;
     }
 
-/*
-    public boolean getStatementWrapping(){
-        return statemntWrapping;
-    }
-*/
+    /*
+     * public boolean getStatementWrapping(){ return statemntWrapping; }
+     */
 
     public int getStatementTimeout() {
         return statementTimeout;
@@ -901,7 +869,7 @@
      * @return <code>DatabaseMetaData</code>
      */
     public DatabaseMetaData getCachedDatabaseMetaData() throws ResourceException {
-        if(cachedDatabaseMetaData == null){
+        if (cachedDatabaseMetaData == null) {
             try {
                 cachedDatabaseMetaData = getActualConnection().getMetaData();
             } catch (SQLException sqle) {
@@ -919,308 +887,291 @@
         this.isClientInfoSupported = isClientInfoSupported;
     }
 
-    private void logFine(String logMessage){
-        if(_logger.isLoggable(Level.FINE)) {
-            _logger.log(Level.FINE, logMessage);
-        }
+    private void logFine(String logMessage) {
+        _logger.log(FINE, logMessage);
     }
 
-    public PreparedStatement prepareCachedStatement(
-            ConnectionWrapper conWrapper, String sql, int resultSetType,
-            int resultSetConcurrency) throws SQLException {
+    public PreparedStatement prepareCachedStatement(ConnectionWrapper connection, String sql, int resultSetType, int resultSetConcurrency) throws SQLException {
         if (statementCaching) {
-            CacheObjectKey key = new CacheObjectKey(sql,
-                    CacheObjectKey.PREPARED_STATEMENT, resultSetType, resultSetConcurrency);
-            //TODO-SC should a null check be done for statementCache?
-            //TODO-SC refactor this method.
-            PreparedStatementWrapper ps =
-                    (PreparedStatementWrapper)
-                    statementCache.checkAndUpdateCache(key);
-            //TODO-SC-DEFER can the usability (isFree()) check be done by the cache itself and make sure that only a free stmt is returned
-            if (ps != null) {
-                if (isFree(ps)) {
-                    //Find if this ps is a valid one. If invalid, remove it
-                    //from the cache and prepare a new stmt & add it to cache
-                    if(!ps.isValid()) {
-                        statementCache.purge(ps);
-                        ps = conWrapper.prepareCachedStatement(sql, resultSetType,
-                                resultSetConcurrency, true);
-                        ps.setBusy(true);
-                        statementCache.addToCache(key, ps, false);
+            CacheObjectKey key =
+                new CacheObjectKey(sql, CacheObjectKey.PREPARED_STATEMENT, resultSetType, resultSetConcurrency);
+
+            // TODO-SC should a null check be done for statementCache?
+            // TODO-SC refactor this method.
+            PreparedStatementWrapper preparedStatement = (PreparedStatementWrapper) statementCache.checkAndUpdateCache(key);
+
+            // TODO-SC-DEFER can the usability (isFree()) check be done by the cache itself
+            // and make sure that only a free stmt is returned
+            if (preparedStatement != null) {
+                if (isFree(preparedStatement)) {
+                    // Find if this preparedStatement is a valid one. If invalid, remove it
+                    // from the cache and prepare a new stmt & add it to cache
+                    if (!preparedStatement.isValid()) {
+                        statementCache.purge(preparedStatement);
+                        preparedStatement = connection.prepareCachedStatement(sql, resultSetType, resultSetConcurrency, true);
+                        preparedStatement.setBusy(true);
+                        statementCache.addToCache(key, preparedStatement, false);
                     } else {
-                        //Valid ps
-                        ps.setBusy(true);
+                        // Valid preparedStatement
+                        preparedStatement.setBusy(true);
                     }
                 } else {
-                    return conWrapper.prepareCachedStatement(sql, resultSetType,
-                            resultSetConcurrency, false);
+                    return connection.prepareCachedStatement(sql, resultSetType, resultSetConcurrency, false);
                 }
             } else {
-                ps = conWrapper.prepareCachedStatement(sql, resultSetType,
-                        resultSetConcurrency, true);
+                preparedStatement = connection.prepareCachedStatement(sql, resultSetType, resultSetConcurrency, true);
 
-                ps.setBusy(true);
-                statementCache.addToCache(key, ps, false);
-
+                preparedStatement.setBusy(true);
+                statementCache.addToCache(key, preparedStatement, false);
             }
-            return ps;
-        } else
-            return conWrapper.prepareCachedStatement(sql, resultSetType,
-                    resultSetConcurrency, false);
+
+            return preparedStatement;
+        }
+
+        return connection.prepareCachedStatement(sql, resultSetType, resultSetConcurrency, false);
     }
 
-    public PreparedStatement prepareCachedStatement(
-            ConnectionWrapper conWrapper, String sql, int resultSetType,
+    public PreparedStatement prepareCachedStatement(ConnectionWrapper connection, String sql, int resultSetType,
             int resultSetConcurrency, int resultSetHoldability) throws SQLException {
         if (statementCaching) {
-            CacheObjectKey key = new CacheObjectKey(sql,
-                    CacheObjectKey.PREPARED_STATEMENT, resultSetType,
-                    resultSetConcurrency, resultSetHoldability);
-            //TODO-SC should a null check be done for statementCache?
-            PreparedStatementWrapper ps =
-                    (PreparedStatementWrapper)
-                    statementCache.checkAndUpdateCache(key);
-            //TODO-SC-DEFER can the usability (isFree()) check be done by the cache itself and make sure that only a free stmt is returned
-            if (ps != null) {
-                if (isFree(ps)) {
-                    //Find if this ps is a valid one. If invalid, remove it
-                    //from the cache and prepare a new stmt & add it to cache
-                    if(!ps.isValid()) {
-                        statementCache.purge(ps);
-                        ps = conWrapper.prepareCachedStatement(sql, resultSetType,
-                                resultSetConcurrency, resultSetHoldability, true);
-                        ps.setBusy(true);
-                        statementCache.addToCache(key, ps, false);
+            CacheObjectKey key =
+                new CacheObjectKey(sql, CacheObjectKey.PREPARED_STATEMENT, resultSetType, resultSetConcurrency, resultSetHoldability);
+
+            // TODO-SC should a null check be done for statementCache?
+            PreparedStatementWrapper preparedStatement = (PreparedStatementWrapper) statementCache.checkAndUpdateCache(key);
+
+            // TODO-SC-DEFER can the usability (isFree()) check be done by the cache itself
+            // and make sure that only a free stmt is returned
+            if (preparedStatement != null) {
+                if (isFree(preparedStatement)) {
+                    // Find if this preparedStatement is a valid one. If invalid, remove it
+                    // from the cache and prepare a new stmt & add it to cache
+                    if (!preparedStatement.isValid()) {
+                        statementCache.purge(preparedStatement);
+                        preparedStatement = connection.prepareCachedStatement(sql, resultSetType, resultSetConcurrency,
+                                resultSetHoldability, true);
+                        preparedStatement.setBusy(true);
+                        statementCache.addToCache(key, preparedStatement, false);
                     } else {
-                        //Valid ps
-                        ps.setBusy(true);
+                        // Valid preparedStatement
+                        preparedStatement.setBusy(true);
                     }
 
                 } else {
-                    return conWrapper.prepareCachedStatement(sql, resultSetType,
-                            resultSetConcurrency, resultSetHoldability, false);
-                }
-            } else {
-                ps = conWrapper.prepareCachedStatement(sql, resultSetType,
-                        resultSetConcurrency, resultSetHoldability, true);
-
-                statementCache.addToCache(key, ps, false);
-                ps.setBusy(true);
-            }
-            return ps;
-        } else
-            return conWrapper.prepareCachedStatement(sql, resultSetType,
-                    resultSetConcurrency, resultSetHoldability, false);
-    }
-
-    public PreparedStatement prepareCachedStatement(
-            ConnectionWrapper conWrapper, String sql, String[] columnNames)
-            throws SQLException {
-        if (statementCaching) {
-            CacheObjectKey key = new CacheObjectKey(sql,
-                    CacheObjectKey.PREPARED_STATEMENT, columnNames);
-            //TODO-SC should a null check be done for statementCache?
-            PreparedStatementWrapper ps =
-                    (PreparedStatementWrapper)
-                    statementCache.checkAndUpdateCache(key);
-            //TODO-SC-DEFER can the usability (isFree()) check be done by the cache itself and make sure that only a free stmt is returned
-            if (ps != null) {
-                if (isFree(ps)) {
-                    //Find if this ps is a valid one. If invalid, remove it
-                    //from the cache and prepare a new stmt & add it to cache
-                    if(!ps.isValid()) {
-                        statementCache.purge(ps);
-                        ps = conWrapper.prepareCachedStatement(sql,
-                                columnNames, true);
-                        ps.setBusy(true);
-                        statementCache.addToCache(key, ps, false);
-                    } else {
-                        //Valid ps
-                        ps.setBusy(true);
-                    }
-
-                } else {
-                    return conWrapper.prepareCachedStatement(sql, columnNames, false);
-                }
-            } else {
-                ps = conWrapper.prepareCachedStatement(sql, columnNames, true);
-
-                statementCache.addToCache(key, ps, false);
-                ps.setBusy(true);
-            }
-            return ps;
-        } else
-            return conWrapper.prepareCachedStatement(sql, columnNames, false);
-    }
-
-    public PreparedStatement prepareCachedStatement(
-            ConnectionWrapper conWrapper, String sql, int[] columnIndexes)
-            throws SQLException {
-        if (statementCaching) {
-            CacheObjectKey key = new CacheObjectKey(sql,
-                    CacheObjectKey.PREPARED_STATEMENT, columnIndexes);
-            //TODO-SC should a null check be done for statementCache?
-            PreparedStatementWrapper ps =
-                    (PreparedStatementWrapper)
-                    statementCache.checkAndUpdateCache(key);
-            //TODO-SC-DEFER can the usability (isFree()) check be done by the cache itself and make sure that only a free stmt is returned
-            if (ps != null) {
-                if (isFree(ps)) {
-                    //Find if this ps is a valid one. If invalid, remove it
-                    //from the cache and prepare a new stmt & add it to cache
-                    if(!ps.isValid()) {
-                        statementCache.purge(ps);
-                        ps = conWrapper.prepareCachedStatement(sql,
-                                columnIndexes, true);
-                        ps.setBusy(true);
-                        statementCache.addToCache(key, ps, false);
-                    } else {
-                        //Valid ps
-                        ps.setBusy(true);
-                    }
-
-                } else {
-                    return conWrapper.prepareCachedStatement(sql, columnIndexes, false);
-                }
-            } else {
-                ps = conWrapper.prepareCachedStatement(sql, columnIndexes, true);
-
-                statementCache.addToCache(key, ps, false);
-                ps.setBusy(true);
-            }
-            return ps;
-        } else
-            return conWrapper.prepareCachedStatement(sql, columnIndexes, false);
-    }
-
-    public PreparedStatement prepareCachedStatement(
-            ConnectionWrapper conWrapper, String sql, int autoGeneratedKeys)
-            throws SQLException {
-        if (statementCaching) {
-            CacheObjectKey key = new CacheObjectKey(sql,
-                    CacheObjectKey.PREPARED_STATEMENT, autoGeneratedKeys);
-            //TODO-SC should a null check be done for statementCache?
-            PreparedStatementWrapper ps =
-                    (PreparedStatementWrapper)
-                    statementCache.checkAndUpdateCache(key);
-            //TODO-SC-DEFER can the usability (isFree()) check be done by the cache itself and make sure that only a free stmt is returned
-            if (ps != null) {
-                if (isFree(ps)) {
-                    //Find if this ps is a valid one. If invalid, remove it
-                    //from the cache and prepare a new stmt & add it to cache
-                    if(!ps.isValid()) {
-                        statementCache.purge(ps);
-                        ps = conWrapper.prepareCachedStatement(sql,
-                                autoGeneratedKeys, true);
-                        ps.setBusy(true);
-                        statementCache.addToCache(key, ps, false);
-                    } else {
-                        //Valid ps
-                        ps.setBusy(true);
-                    }
-
-                } else {
-                    return conWrapper.prepareCachedStatement(sql, autoGeneratedKeys, false);
-                }
-            } else {
-                ps = conWrapper.prepareCachedStatement(sql, autoGeneratedKeys, true);
-
-                statementCache.addToCache(key, ps, false);
-                ps.setBusy(true);
-            }
-            return ps;
-        } else
-            return conWrapper.prepareCachedStatement(sql, autoGeneratedKeys, false);
-    }
-
-    public CallableStatement prepareCachedCallableStatement(
-           ConnectionWrapper conWrapper, String sql, int resultSetType,
-           int resultSetConcurrency) throws SQLException {
-        if (statementCaching) {
-            //Adding the sql as well as the Statement type "CS" to the CacheObjectKey object
-            CacheObjectKey key = new CacheObjectKey(sql,
-                    CacheObjectKey.CALLABLE_STATEMENT, resultSetType, resultSetConcurrency);
-            CallableStatementWrapper cs =
-                    (CallableStatementWrapper)
-                    statementCache.checkAndUpdateCache(key);
-            //TODO-SC-DEFER can the usability (isFree()) check be done by the cache
-            //itself and make sure that only a free stmt is returned
-            if (cs != null) {
-                if (isFree(cs)) {
-                    //Find if this cs is a valid one. If invalid, remove it
-                    //from the cache and prepare a new stmt & add it to cache
-                    if(!cs.isValid()) {
-                        statementCache.purge(cs);
-                        cs = conWrapper.callableCachedStatement(sql, resultSetType,
-                                resultSetConcurrency, true);
-                        cs.setBusy(true);
-                        statementCache.addToCache(key, cs, false);
-                    } else {
-                        //Valid ps
-                        cs.setBusy(true);
-                    }
-
-                } else {
-                    return conWrapper.callableCachedStatement(sql,
-                            resultSetType, resultSetConcurrency, false);
-                }
-            } else {
-                cs = conWrapper.callableCachedStatement(sql, resultSetType,
-                        resultSetConcurrency, true);
-
-                statementCache.addToCache(key, cs, false);
-                cs.setBusy(true);
-            }
-            return cs;
-        } else
-            return conWrapper.callableCachedStatement(sql, resultSetType,
-                    resultSetConcurrency, false);
-    }
-
-    public CallableStatement prepareCachedCallableStatement(
-           ConnectionWrapper conWrapper, String sql, int resultSetType,
-           int resultSetConcurrency, int resultSetHoldability) throws SQLException {
-        if (statementCaching) {
-            //Adding the sql as well as the Statement type "CS" to the CacheObjectKey object
-            CacheObjectKey key = new CacheObjectKey(sql,
-                    CacheObjectKey.CALLABLE_STATEMENT, resultSetType,
-                    resultSetConcurrency, resultSetHoldability);
-            CallableStatementWrapper cs =
-                    (CallableStatementWrapper)
-                    statementCache.checkAndUpdateCache(key);
-            //TODO-SC-DEFER can the usability (isFree()) check be done by the cache
-            //itself and make sure that only a free stmt is returned
-            if (cs != null) {
-                if (isFree(cs)) {
-                    //Find if this cs is a valid one. If invalid, remove it
-                    //from the cache and prepare a new stmt & add it to cache
-                    if(!cs.isValid()) {
-                        statementCache.purge(cs);
-                        cs = conWrapper.callableCachedStatement(sql, resultSetType,
-                                resultSetConcurrency, resultSetHoldability, true);
-                        cs.setBusy(true);
-                        statementCache.addToCache(key, cs, false);
-                    } else {
-                        //Valid ps
-                        cs.setBusy(true);
-                    }
-
-                } else {
-                    return conWrapper.callableCachedStatement(sql,
-                            resultSetType, resultSetConcurrency,
+                    return connection.prepareCachedStatement(sql, resultSetType, resultSetConcurrency,
                             resultSetHoldability, false);
                 }
             } else {
-                cs = conWrapper.callableCachedStatement(sql, resultSetType,
-                        resultSetConcurrency, resultSetHoldability, true);
+                preparedStatement = connection.prepareCachedStatement(sql, resultSetType, resultSetConcurrency, resultSetHoldability,
+                        true);
 
-                statementCache.addToCache(key, cs, false);
-                cs.setBusy(true);
+                statementCache.addToCache(key, preparedStatement, false);
+                preparedStatement.setBusy(true);
             }
-            return cs;
-        } else
-            return conWrapper.callableCachedStatement(sql, resultSetType,
-                    resultSetConcurrency, resultSetHoldability, false);
+            return preparedStatement;
+        }
+
+        return connection.prepareCachedStatement(
+                   sql, resultSetType, resultSetConcurrency, resultSetHoldability, false);
+    }
+
+    public PreparedStatement prepareCachedStatement(ConnectionWrapper connection, String sql, String[] columnNames) throws SQLException {
+        if (statementCaching) {
+            CacheObjectKey key = new CacheObjectKey(sql, CacheObjectKey.PREPARED_STATEMENT, columnNames);
+
+            // TODO-SC should a null check be done for statementCache?
+            PreparedStatementWrapper preparedStatement = (PreparedStatementWrapper) statementCache.checkAndUpdateCache(key);
+
+            // TODO-SC-DEFER can the usability (isFree()) check be done by the cache itself
+            // and make sure that only a free stmt is returned
+            if (preparedStatement != null) {
+                if (isFree(preparedStatement)) {
+                    // Find if this preparedStatement is a valid one. If invalid, remove it
+                    // from the cache and prepare a new stmt & add it to cache
+                    if (!preparedStatement.isValid()) {
+                        statementCache.purge(preparedStatement);
+                        preparedStatement = connection.prepareCachedStatement(sql, columnNames, true);
+                        preparedStatement.setBusy(true);
+                        statementCache.addToCache(key, preparedStatement, false);
+                    } else {
+                        // Valid preparedStatement
+                        preparedStatement.setBusy(true);
+                    }
+
+                } else {
+                    return connection.prepareCachedStatement(sql, columnNames, false);
+                }
+            } else {
+                preparedStatement = connection.prepareCachedStatement(sql, columnNames, true);
+
+                statementCache.addToCache(key, preparedStatement, false);
+                preparedStatement.setBusy(true);
+            }
+
+            return preparedStatement;
+        }
+
+        return connection.prepareCachedStatement(sql, columnNames, false);
+    }
+
+    public PreparedStatement prepareCachedStatement(ConnectionWrapper connection, String sql, int[] columnIndexes) throws SQLException {
+        if (statementCaching) {
+            CacheObjectKey key = new CacheObjectKey(sql, CacheObjectKey.PREPARED_STATEMENT, columnIndexes);
+
+            // TODO-SC should a null check be done for statementCache?
+            PreparedStatementWrapper preparedStatement = (PreparedStatementWrapper) statementCache.checkAndUpdateCache(key);
+
+            // TODO-SC-DEFER can the usability (isFree()) check be done by the cache itself
+            // and make sure that only a free stmt is returned
+            if (preparedStatement != null) {
+                if (isFree(preparedStatement)) {
+                    // Find if this preparedStatement is a valid one. If invalid, remove it
+                    // from the cache and prepare a new stmt & add it to cache
+                    if (!preparedStatement.isValid()) {
+                        statementCache.purge(preparedStatement);
+                        preparedStatement = connection.prepareCachedStatement(sql, columnIndexes, true);
+                        preparedStatement.setBusy(true);
+                        statementCache.addToCache(key, preparedStatement, false);
+                    } else {
+                        // Valid preparedStatement
+                        preparedStatement.setBusy(true);
+                    }
+
+                } else {
+                    return connection.prepareCachedStatement(sql, columnIndexes, false);
+                }
+            } else {
+                preparedStatement = connection.prepareCachedStatement(sql, columnIndexes, true);
+
+                statementCache.addToCache(key, preparedStatement, false);
+                preparedStatement.setBusy(true);
+            }
+
+            return preparedStatement;
+        }
+
+        return connection.prepareCachedStatement(sql, columnIndexes, false);
+    }
+
+    public PreparedStatement prepareCachedStatement(ConnectionWrapper connection, String sql, int autoGeneratedKeys) throws SQLException {
+        if (statementCaching) {
+            CacheObjectKey key = new CacheObjectKey(sql, CacheObjectKey.PREPARED_STATEMENT, autoGeneratedKeys);
+
+            // TODO-SC should a null check be done for statementCache?
+            PreparedStatementWrapper preparedStatement = (PreparedStatementWrapper) statementCache.checkAndUpdateCache(key);
+
+            // TODO-SC-DEFER can the usability (isFree()) check be done by the cache itself
+            // and make sure that only a free stmt is returned
+            if (preparedStatement != null) {
+                if (isFree(preparedStatement)) {
+                    // Find if this preparedStatement is a valid one. If invalid, remove it
+                    // from the cache and prepare a new stmt & add it to cache
+                    if (!preparedStatement.isValid()) {
+                        statementCache.purge(preparedStatement);
+                        preparedStatement = connection.prepareCachedStatement(sql, autoGeneratedKeys, true);
+                        preparedStatement.setBusy(true);
+                        statementCache.addToCache(key, preparedStatement, false);
+                    } else {
+                        // Valid preparedStatement
+                        preparedStatement.setBusy(true);
+                    }
+
+                } else {
+                    return connection.prepareCachedStatement(sql, autoGeneratedKeys, false);
+                }
+            } else {
+                preparedStatement = connection.prepareCachedStatement(sql, autoGeneratedKeys, true);
+
+                statementCache.addToCache(key, preparedStatement, false);
+                preparedStatement.setBusy(true);
+            }
+
+            return preparedStatement;
+        }
+
+        return connection.prepareCachedStatement(sql, autoGeneratedKeys, false);
+    }
+
+    public CallableStatement prepareCachedCallableStatement(ConnectionWrapper connection, String sql, int resultSetType, int resultSetConcurrency) throws SQLException {
+        if (statementCaching) {
+            // Adding the sql as well as the Statement type "CS" to the CacheObjectKey
+            // object
+            CacheObjectKey key = new CacheObjectKey(sql, CacheObjectKey.CALLABLE_STATEMENT, resultSetType, resultSetConcurrency);
+            CallableStatementWrapper callableStatement = (CallableStatementWrapper) statementCache.checkAndUpdateCache(key);
+
+            // TODO-SC-DEFER can the usability (isFree()) check be done by the cache
+            // itself and make sure that only a free stmt is returned
+            if (callableStatement != null) {
+                if (isFree(callableStatement)) {
+                    // Find if this callableStatement is a valid one. If invalid, remove it
+                    // from the cache and prepare a new stmt & add it to cache
+                    if (!callableStatement.isValid()) {
+                        statementCache.purge(callableStatement);
+                        callableStatement = connection.callableCachedStatement(sql, resultSetType, resultSetConcurrency, true);
+                        callableStatement.setBusy(true);
+                        statementCache.addToCache(key, callableStatement, false);
+                    } else {
+                        // Valid callableStatement
+                        callableStatement.setBusy(true);
+                    }
+
+                } else {
+                    return connection.callableCachedStatement(sql, resultSetType, resultSetConcurrency, false);
+                }
+            } else {
+                callableStatement = connection.callableCachedStatement(sql, resultSetType, resultSetConcurrency, true);
+
+                statementCache.addToCache(key, callableStatement, false);
+                callableStatement.setBusy(true);
+            }
+            return callableStatement;
+        }
+
+        return connection.callableCachedStatement(sql, resultSetType, resultSetConcurrency, false);
+    }
+
+    public CallableStatement prepareCachedCallableStatement(ConnectionWrapper connection, String sql, int resultSetType,
+            int resultSetConcurrency, int resultSetHoldability) throws SQLException {
+        if (statementCaching) {
+
+            // Adding the sql as well as the Statement type "CS" to the CacheObjectKey object
+            CacheObjectKey key = new CacheObjectKey(sql, CacheObjectKey.CALLABLE_STATEMENT, resultSetType,
+                    resultSetConcurrency, resultSetHoldability);
+            CallableStatementWrapper callableStatement = (CallableStatementWrapper) statementCache.checkAndUpdateCache(key);
+
+            // TODO-SC-DEFER can the usability (isFree()) check be done by the cache
+            // itself and make sure that only a free stmt is returned
+            if (callableStatement != null) {
+                if (isFree(callableStatement)) {
+                    // Find if this cs is a valid one. If invalid, remove it
+                    // from the cache and prepare a new stmt & add it to cache
+                    if (!callableStatement.isValid()) {
+                        statementCache.purge(callableStatement);
+                        callableStatement = connection.callableCachedStatement(sql, resultSetType, resultSetConcurrency,
+                                resultSetHoldability, true);
+                        callableStatement.setBusy(true);
+                        statementCache.addToCache(key, callableStatement, false);
+                    } else {
+                        // Valid ps
+                        callableStatement.setBusy(true);
+                    }
+
+                } else {
+                    return connection.callableCachedStatement(sql, resultSetType, resultSetConcurrency,
+                            resultSetHoldability, false);
+                }
+            } else {
+                callableStatement = connection.callableCachedStatement(sql, resultSetType, resultSetConcurrency, resultSetHoldability,
+                        true);
+
+                statementCache.addToCache(key, callableStatement, false);
+                callableStatement.setBusy(true);
+            }
+
+            return callableStatement;
+        }
+
+        return connection.callableCachedStatement(sql, resultSetType, resultSetConcurrency, resultSetHoldability, false);
     }
 
     boolean isFree(PreparedStatementWrapper cachedps) {
@@ -1236,7 +1187,7 @@
     }
 
     public void purgeStatementFromCache(PreparedStatement preparedStatement) {
-        //TODO isValid check for preparedStatement?
+        // TODO isValid check for preparedStatement?
         statementCache.purge(preparedStatement);
     }
 }
diff --git a/appserver/jdbc/jdbc-ra/jdbc-core/src/main/java/com/sun/gjc/spi/ManagedConnectionMetaDataImpl.java b/appserver/jdbc/jdbc-ra/jdbc-core/src/main/java/com/sun/gjc/spi/ManagedConnectionMetaDataImpl.java
index 0ec7c53..f12cd20 100644
--- a/appserver/jdbc/jdbc-ra/jdbc-core/src/main/java/com/sun/gjc/spi/ManagedConnectionMetaDataImpl.java
+++ b/appserver/jdbc/jdbc-ra/jdbc-core/src/main/java/com/sun/gjc/spi/ManagedConnectionMetaDataImpl.java
@@ -16,110 +16,111 @@
 
 package com.sun.gjc.spi;
 
+import static java.util.logging.Level.SEVERE;
+
+import java.sql.DatabaseMetaData;
+import java.sql.SQLException;
+import java.util.logging.Logger;
+
 import com.sun.logging.LogDomains;
 
 import jakarta.resource.ResourceException;
-import java.sql.SQLException;
-import java.util.logging.Level;
-import java.util.logging.Logger;
+import jakarta.resource.spi.ManagedConnectionMetaData;
+import jakarta.resource.spi.security.PasswordCredential;
 
 /**
- * <code>ManagedConnectionMetaData</code> implementation for Generic JDBC Connector.
+ * <code>ManagedConnectionMetaData</code> implementation for Generic JDBC
+ * Connector.
  *
  * @author Evani Sai Surya Kiran
  * @version 1.0, 02/08/03
  */
-public class ManagedConnectionMetaDataImpl implements jakarta.resource.spi.ManagedConnectionMetaData {
+public class ManagedConnectionMetaDataImpl implements ManagedConnectionMetaData {
 
-    private java.sql.DatabaseMetaData dmd = null;
-    private ManagedConnectionImpl mc;
+    private static Logger _logger = LogDomains.getLogger(ManagedConnectionMetaDataImpl.class, LogDomains.RSR_LOGGER);
 
-    private static Logger _logger;
-
-    static {
-        _logger = LogDomains.getLogger(ManagedConnectionMetaDataImpl.class, LogDomains.RSR_LOGGER);
-    }
-
-    private boolean debug = false;
+    private DatabaseMetaData databaseMetaData;
+    private ManagedConnectionImpl managedConnection;
 
     /**
      * Constructor for <code>ManagedConnectionMetaDataImpl</code>
      *
-     * @param mc <code>ManagedConnection</code>
-     * @throws <code>ResourceException</code> if getting the DatabaseMetaData object fails
+     * @param managedConnection <code>ManagedConnection</code>
+     * @throws <code>ResourceException</code> if getting the DatabaseMetaData object
+     * fails
      */
-    public ManagedConnectionMetaDataImpl(ManagedConnectionImpl mc) throws ResourceException {
+    public ManagedConnectionMetaDataImpl(ManagedConnectionImpl managedConnection) throws ResourceException {
         try {
-            this.mc = mc;
-            dmd = mc.getActualConnection().getMetaData();
+            this.managedConnection = managedConnection;
+            databaseMetaData = managedConnection.getActualConnection().getMetaData();
         } catch (SQLException sqle) {
-            _logger.log(Level.SEVERE, "jdbc.exc_md", sqle);
-            throw new ResourceException(sqle.getMessage());
+            _logger.log(SEVERE, "jdbc.exc_md", sqle);
+            throw new ResourceException(sqle.getMessage(), sqle);
         }
     }
 
     /**
-     * Returns product name of the underlying EIS instance connected
-     * through the ManagedConnection.
+     * Returns product name of the underlying EIS instance connected through the
+     * ManagedConnection.
      *
      * @return Product name of the EIS instance
      * @throws <code>ResourceException</code>
      */
     public String getEISProductName() throws ResourceException {
         try {
-            return dmd.getDatabaseProductName();
+            return databaseMetaData.getDatabaseProductName();
         } catch (SQLException sqle) {
-            _logger.log(Level.SEVERE, "jdbc.exc_eis_prodname", sqle);
-            throw new ResourceException(sqle.getMessage());
+            _logger.log(SEVERE, "jdbc.exc_eis_prodname", sqle);
+            throw new ResourceException(sqle.getMessage(), sqle);
         }
     }
 
     /**
-     * Returns product version of the underlying EIS instance connected
-     * through the ManagedConnection.
+     * Returns product version of the underlying EIS instance connected through the
+     * ManagedConnection.
      *
      * @return Product version of the EIS instance
      * @throws <code>ResourceException</code>
      */
     public String getEISProductVersion() throws ResourceException {
         try {
-            return dmd.getDatabaseProductVersion();
+            return databaseMetaData.getDatabaseProductVersion();
         } catch (SQLException sqle) {
-            _logger.log(Level.SEVERE, "jdbc.exc_eis_prodvers", sqle);
+            _logger.log(SEVERE, "jdbc.exc_eis_prodvers", sqle);
             throw new ResourceException(sqle.getMessage(), sqle.getMessage());
         }
     }
 
     /**
-     * Returns maximum limit on number of active concurrent connections
-     * that an EIS instance can support across client processes.
+     * Returns maximum limit on number of active concurrent connections that an EIS
+     * instance can support across client processes.
      *
      * @return Maximum limit for number of active concurrent connections
      * @throws <code>ResourceException</code>
      */
     public int getMaxConnections() throws ResourceException {
         try {
-            return dmd.getMaxConnections();
+            return databaseMetaData.getMaxConnections();
         } catch (SQLException sqle) {
-            _logger.log(Level.SEVERE, "jdbc.exc_eis_maxconn");
-            throw new ResourceException(sqle.getMessage());
+            _logger.log(SEVERE, "jdbc.exc_eis_maxconn");
+            throw new ResourceException(sqle.getMessage(), sqle);
         }
     }
 
     /**
-     * Returns name of the user associated with the ManagedConnection instance. The name
-     * corresponds to the resource principal under whose whose security context, a connection
-     * to the EIS instance has been established.
+     * Returns name of the user associated with the ManagedConnection instance. The
+     * name corresponds to the resource principal under whose whose security
+     * context, a connection to the EIS instance has been established.
      *
      * @return name of the user
      * @throws <code>ResourceException</code>
      */
     public String getUserName() throws ResourceException {
-        jakarta.resource.spi.security.PasswordCredential pc = mc.getPasswordCredential();
-        if (pc != null) {
-            return pc.getUserName();
+        PasswordCredential passwordCredential = managedConnection.getPasswordCredential();
+        if (passwordCredential != null) {
+            return passwordCredential.getUserName();
         }
 
-        return mc.getManagedConnectionFactory().getUser();
+        return managedConnection.getManagedConnectionFactory().getUser();
     }
 }
diff --git a/appserver/jdbc/jdbc-ra/jdbc-core/src/main/java/com/sun/gjc/spi/ResourceAdapterImpl.java b/appserver/jdbc/jdbc-ra/jdbc-core/src/main/java/com/sun/gjc/spi/ResourceAdapterImpl.java
index 953a414..4cf1148 100644
--- a/appserver/jdbc/jdbc-ra/jdbc-core/src/main/java/com/sun/gjc/spi/ResourceAdapterImpl.java
+++ b/appserver/jdbc/jdbc-ra/jdbc-core/src/main/java/com/sun/gjc/spi/ResourceAdapterImpl.java
@@ -16,18 +16,24 @@
 
 package com.sun.gjc.spi;
 
-import com.sun.logging.LogDomains;
+import static jakarta.resource.spi.AuthenticationMechanism.CredentialInterface.PasswordCredential;
+import static java.util.logging.Level.SEVERE;
+
 import java.util.Timer;
-import java.util.logging.Level;
 import java.util.logging.Logger;
+
+import javax.transaction.xa.XAResource;
+
+import com.sun.logging.LogDomains;
+
 import jakarta.resource.NotSupportedException;
 import jakarta.resource.spi.ActivationSpec;
 import jakarta.resource.spi.AuthenticationMechanism;
 import jakarta.resource.spi.BootstrapContext;
 import jakarta.resource.spi.Connector;
+import jakarta.resource.spi.ResourceAdapter;
 import jakarta.resource.spi.UnavailableException;
 import jakarta.resource.spi.endpoint.MessageEndpointFactory;
-import javax.transaction.xa.XAResource;
 
 /**
  * <code>ResourceAdapterImpl</code> implementation for Generic JDBC Connector.
@@ -42,36 +48,40 @@
     eisType = "Database",
     version = "1.0",
     authMechanisms = {
-        @AuthenticationMechanism(authMechanism="BasicPassword",
-            credentialInterface=AuthenticationMechanism.CredentialInterface.PasswordCredential)
+        @AuthenticationMechanism(
+            authMechanism = "BasicPassword",
+            credentialInterface = PasswordCredential)
     }
 )
-public class ResourceAdapterImpl implements jakarta.resource.spi.ResourceAdapter {
-    private static ResourceAdapterImpl ra;
+public class ResourceAdapterImpl implements ResourceAdapter {
+
+    private static Logger logger = LogDomains.getLogger(ResourceAdapterImpl.class, LogDomains.RSR_LOGGER);
+
+    private static ResourceAdapterImpl resourceAdapterImpl;
     private BootstrapContext bootstrapContext;
     private Timer timer;
-    private static Logger _logger = LogDomains.getLogger(ResourceAdapterImpl.class, LogDomains.RSR_LOGGER);
 
     public ResourceAdapterImpl() {
-        if(ra == null){
-            //we do not expect RA to be initialized multiple times as this is a System RAR
-            ra = this;
+        if (resourceAdapterImpl == null) {
+            // We do not expect RA to be initialized multiple times as this is a System RAR
+            resourceAdapterImpl = this;
         }
     }
 
     public static ResourceAdapterImpl getInstance() {
-        if(ra == null) {
+        if (resourceAdapterImpl == null) {
             throw new IllegalStateException("ResourceAdapter not initialized");
         }
-        return ra;
+
+        return resourceAdapterImpl;
     }
 
     /**
-     * Empty method implementation for endpointActivation
-     * which just throws <code>NotSupportedException</code>
+     * Empty method implementation for endpointActivation which just throws
+     * <code>NotSupportedException</code>
      *
      * @param mef <code>MessageEndpointFactory</code>
-     * @param as  <code>ActivationSpec</code>
+     * @param as <code>ActivationSpec</code>
      * @throws <code>NotSupportedException</code>
      *
      */
@@ -83,15 +93,15 @@
      * Empty method implementation for endpointDeactivation
      *
      * @param mef <code>MessageEndpointFactory</code>
-     * @param as  <code>ActivationSpec</code>
+     * @param as <code>ActivationSpec</code>
      */
     public void endpointDeactivation(MessageEndpointFactory mef, ActivationSpec as) {
 
     }
 
     /**
-     * Empty method implementation for getXAResources
-     * which just throws <code>NotSupportedException</code>
+     * Empty method implementation for getXAResources which just throws
+     * <code>NotSupportedException</code>
      *
      * @param specs <code>ActivationSpec</code> array
      * @throws <code>NotSupportedException</code>
@@ -104,38 +114,35 @@
     /**
      * Empty implementation of start method
      *
-     * @param ctx <code>BootstrapContext</code>
+     * @param bootstrapContext <code>BootstrapContext</code>
      */
-    public void start(BootstrapContext ctx) {
-        this.bootstrapContext = ctx;
+    public void start(BootstrapContext bootstrapContext) {
+        this.bootstrapContext = bootstrapContext;
     }
 
     /**
      * Empty implementation of stop method
      */
     public void stop() {
-        if(_logger.isLoggable(Level.FINEST)) {
-            _logger.finest("Cancelling the timer");
-        }
-        if(timer != null) {
+        logger.finest("Cancelling the timer");
+        if (timer != null) {
             timer.purge();
             timer.cancel();
         }
     }
 
     public Timer getTimer() {
-        if(bootstrapContext != null) {
+        if (bootstrapContext != null) {
             if (timer == null) {
-                if(_logger.isLoggable(Level.FINEST)) {
-                    _logger.finest("Creating the timer");
-                }
+                logger.finest("Creating the timer");
                 try {
                     timer = bootstrapContext.createTimer();
                 } catch (UnavailableException ex) {
-                    _logger.log(Level.SEVERE, "jdbc-ra.timer_creation_exception", ex.getMessage());
+                    logger.log(SEVERE, "jdbc-ra.timer_creation_exception", ex.getMessage());
                 }
             }
         }
+
         return timer;
     }
 }
diff --git a/appserver/jdbc/jdbc-ra/jdbc-core/src/main/java/com/sun/gjc/spi/XAManagedConnectionFactory.java b/appserver/jdbc/jdbc-ra/jdbc-core/src/main/java/com/sun/gjc/spi/XAManagedConnectionFactory.java
index 25e1526..814239b 100644
--- a/appserver/jdbc/jdbc-ra/jdbc-core/src/main/java/com/sun/gjc/spi/XAManagedConnectionFactory.java
+++ b/appserver/jdbc/jdbc-ra/jdbc-core/src/main/java/com/sun/gjc/spi/XAManagedConnectionFactory.java
@@ -16,116 +16,119 @@
 
 package com.sun.gjc.spi;
 
+import static com.sun.gjc.spi.ManagedConnectionImpl.ISXACONNECTION;
+import static com.sun.gjc.util.SecurityUtils.getPasswordCredential;
+import static java.util.logging.Level.FINE;
+import static java.util.logging.Level.FINEST;
+import static java.util.logging.Level.SEVERE;
+
+import java.sql.Connection;
+import java.sql.SQLException;
+import java.util.logging.Logger;
+
+import javax.security.auth.Subject;
+import javax.sql.DataSource;
+import javax.sql.XAConnection;
+import javax.sql.XADataSource;
+
 import com.sun.enterprise.util.i18n.StringManager;
 import com.sun.gjc.common.DataSourceObjectBuilder;
 import com.sun.gjc.common.DataSourceSpec;
 import com.sun.gjc.spi.base.AbstractDataSource;
-import com.sun.gjc.util.SecurityUtils;
+import com.sun.gjc.spi.base.ConnectionHolder;
 import com.sun.logging.LogDomains;
 
 import jakarta.resource.ResourceException;
+import jakarta.resource.spi.ConfigProperty;
+import jakarta.resource.spi.ConnectionDefinition;
 import jakarta.resource.spi.ConnectionRequestInfo;
 import jakarta.resource.spi.ResourceAllocationException;
 import jakarta.resource.spi.security.PasswordCredential;
-import java.sql.SQLException;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-import jakarta.resource.spi.ConfigProperty;
-import jakarta.resource.spi.ConnectionDefinition;
 
 /**
- * XA <code>ManagedConnectionFactory</code> implementation for Generic JDBC Connector.
+ * XA <code>ManagedConnectionFactory</code> implementation for Generic JDBC
+ * Connector.
  *
  * @author Evani Sai Surya Kiran
  * @version 1.0, 02/07/27
  */
 @ConnectionDefinition(
-    connectionFactory = javax.sql.DataSource.class,
+    connectionFactory = DataSource.class,
     connectionFactoryImpl = AbstractDataSource.class,
-    connection = java.sql.Connection.class,
-    connectionImpl = com.sun.gjc.spi.base.ConnectionHolder.class
+    connection = Connection.class,
+    connectionImpl = ConnectionHolder.class
 )
 public class XAManagedConnectionFactory extends ManagedConnectionFactoryImpl {
 
     private transient javax.sql.XADataSource xaDataSourceObj;
 
-    private static Logger _logger;
-
-    static {
-        _logger = LogDomains.getLogger(XAManagedConnectionFactory.class, LogDomains.RSR_LOGGER);
-    }
+    private static Logger _logger = LogDomains.getLogger(XAManagedConnectionFactory.class, LogDomains.RSR_LOGGER);
 
     /**
-     * Creates a new physical connection to the underlying EIS resource
-     * manager.
+     * Creates a new physical connection to the underlying EIS resource manager.
      *
-     * @param subject       <code>Subject</code> instance passed by the application server
-     * @param cxRequestInfo <code>ConnectionRequestInfo</code> which may be created
-     *                      as a result of the invocation <code>getConnection(user, password)</code>
-     *                      on the <code>DataSource</code> object
+     * @param subject <code>Subject</code> instance passed by the application server
+     * @param connectionRequestInfo <code>ConnectionRequestInfo</code> which may be created
+     * as a result of the invocation <code>getConnection(user, password)</code> on
+     * the <code>DataSource</code> object
+     *
      * @return <code>ManagedConnection</code> object created
-     * @throws ResourceException           if there is an error in instantiating the
-     *                                     <code>DataSource</code> object used for the
-     *                                     creation of the <code>ManagedConnection</code> object
-     * @throws SecurityException           if there ino <code>PasswordCredential</code> object
-     *                                     satisfying this request
+     * @throws ResourceException if there is an error in instantiating the
+     * <code>DataSource</code> object used for the creation of the
+     * <code>ManagedConnection</code> object
+     * @throws SecurityException if there ino <code>PasswordCredential</code> object
+     * satisfying this request
      * @throws ResourceAllocationException if there is an error in allocating the
-     *                                     physical connection
+     * physical connection
      */
-    public jakarta.resource.spi.ManagedConnection createManagedConnection(javax.security.auth.Subject subject,
-                                                                        ConnectionRequestInfo cxRequestInfo) throws ResourceException {
+    public jakarta.resource.spi.ManagedConnection createManagedConnection(Subject subject, ConnectionRequestInfo connectionRequestInfo) throws ResourceException {
         logFine("In createManagedConnection");
-        PasswordCredential pc = SecurityUtils.getPasswordCredential(this, subject, cxRequestInfo);
+        PasswordCredential passwordCredential = getPasswordCredential(this, subject, connectionRequestInfo);
+        XADataSource dataSource = getDataSource();
 
-        javax.sql.XADataSource dataSource = getDataSource();
-
-        javax.sql.XAConnection xaConn = null;
-        ManagedConnectionImpl mc = null;
+        XAConnection xaConnection = null;
+        ManagedConnectionImpl managedConnection = null;
 
         try {
-            /* For the case where the user/passwd of the connection pool is
-            * equal to the PasswordCredential for the connection request
-            * get a connection from this pool directly.
-            * for all other conditions go create a new connection
-            */
-            if (isEqual(pc, getUser(), getPassword())) {
-                xaConn = dataSource.getXAConnection();
+            /*
+             * For the case where the user/passwd of the connection pool is equal to the
+             * PasswordCredential for the connection request get a connection from this pool
+             * directly. for all other conditions go create a new connection
+             */
+            if (isEqual(passwordCredential, getUser(), getPassword())) {
+                xaConnection = dataSource.getXAConnection();
             } else {
-                xaConn = dataSource.getXAConnection(pc.getUserName(),
-                        new String(pc.getPassword()));
+                xaConnection = dataSource.getXAConnection(
+                                passwordCredential.getUserName(),
+                                new String(passwordCredential.getPassword()));
             }
 
-
-        } catch (java.sql.SQLException sqle) {
-            //_logger.log(Level.WARNING, "jdbc.exc_create_xa_conn",sqle);
-            if(_logger.isLoggable(Level.FINE)) {
-                _logger.log(Level.FINE, "jdbc.exc_create_xa_conn", sqle);
-            }
-            StringManager sm = StringManager.getManager(
-                    DataSourceObjectBuilder.class);
+        } catch (SQLException sqle) {
+            _logger.log(FINE, "jdbc.exc_create_xa_conn", sqle);
+            StringManager sm = StringManager.getManager(DataSourceObjectBuilder.class);
             String msg = sm.getString("jdbc.cannot_allocate_connection", sqle.getMessage());
             throw new ResourceAllocationException(msg, sqle);
         }
 
-        try{
-            mc = constructManagedConnection(
-                    xaConn, null, pc, this);
-
-            mc.initializeConnectionType(ManagedConnectionImpl.ISXACONNECTION);
-            //GJCINT
-            validateAndSetIsolation(mc);
+        try {
+            managedConnection = constructManagedConnection(xaConnection, null, passwordCredential, this);
+            managedConnection.initializeConnectionType(ISXACONNECTION);
+            // GJCINT
+            validateAndSetIsolation(managedConnection);
         } finally {
-            if (mc == null) {
-                if (xaConn != null) {
+            if (managedConnection == null) {
+                if (xaConnection != null) {
                     try {
-                        xaConn.close();
+                        xaConnection.close();
                     } catch (SQLException e) {
-                        _logger.log(Level.FINEST, "Exception while closing connection : createManagedConnection" + xaConn);
+                        _logger.log(FINEST,
+                            "Exception while closing connection : createManagedConnection" + xaConnection);
                     }
                 }
             }
         }
-        return mc;
+
+        return managedConnection;
     }
 
     /**
@@ -137,44 +140,17 @@
     public javax.sql.XADataSource getDataSource() throws ResourceException {
         if (xaDataSourceObj == null) {
             try {
-                xaDataSourceObj = (javax.sql.XADataSource) super.getDataSource();
+                xaDataSourceObj = (XADataSource) super.getDataSource();
             } catch (ClassCastException cce) {
-                _logger.log(Level.SEVERE, "jdbc.exc_cce_XA", cce);
+                _logger.log(SEVERE, "jdbc.exc_cce_XA", cce);
                 throw new ResourceException(cce.getMessage());
             }
         }
+
         return xaDataSourceObj;
     }
 
     /**
-     * Check if this <code>ManagedConnectionFactory</code> is equal to
-     * another <code>ManagedConnectionFactory</code>.
-     *
-     * @param other <code>ManagedConnectionFactory</code> object for checking equality with
-     * @return true    if the property sets of both the
-     *         <code>ManagedConnectionFactory</code> objects are the same
-     *         false    otherwise
-     */
-    public boolean equals(Object other) {
-        logFine("In equals");
-        /**
-         * The check below means that two ManagedConnectionFactory objects are equal
-         * if and only if their properties are the same.
-         */
-        if (other instanceof com.sun.gjc.spi.XAManagedConnectionFactory) {
-            com.sun.gjc.spi.XAManagedConnectionFactory otherMCF =
-                    (com.sun.gjc.spi.XAManagedConnectionFactory) other;
-            return this.spec.equals(otherMCF.spec);
-        }
-        return false;
-    }
-
-    @Override
-    public int hashCode() {
-        return 31 * 7 + (spec.hashCode());
-    }
-
-    /**
      * Sets the class name of the data source
      *
      * @param className <code>String</code>
@@ -304,4 +280,32 @@
     public String getPropertyCycle() {
         return spec.getDetail(DataSourceSpec.PROPERTYCYCLE);
     }
+
+    /**
+     * Check if this <code>ManagedConnectionFactory</code> is equal to another
+     * <code>ManagedConnectionFactory</code>.
+     *
+     * @param other <code>ManagedConnectionFactory</code> object for checking
+     * equality with
+     * @return true if the property sets of both the
+     * <code>ManagedConnectionFactory</code> objects are the same false otherwise
+     */
+    public boolean equals(Object other) {
+        logFine("In equals");
+        /**
+         * The check below means that two ManagedConnectionFactory objects are equal if
+         * and only if their properties are the same.
+         */
+        if (other instanceof XAManagedConnectionFactory) {
+            XAManagedConnectionFactory otherMCF = (XAManagedConnectionFactory) other;
+            return this.spec.equals(otherMCF.spec);
+        }
+
+        return false;
+    }
+
+    @Override
+    public int hashCode() {
+        return 31 * 7 + (spec.hashCode());
+    }
 }
diff --git a/appserver/jdbc/jdbc-ra/jdbc-core/src/main/java/com/sun/gjc/spi/XAResourceImpl.java b/appserver/jdbc/jdbc-ra/jdbc-core/src/main/java/com/sun/gjc/spi/XAResourceImpl.java
index 67fb1eb..bf4905f 100644
--- a/appserver/jdbc/jdbc-ra/jdbc-core/src/main/java/com/sun/gjc/spi/XAResourceImpl.java
+++ b/appserver/jdbc/jdbc-ra/jdbc-core/src/main/java/com/sun/gjc/spi/XAResourceImpl.java
@@ -28,65 +28,64 @@
  */
 public class XAResourceImpl implements XAResource {
 
-    XAResource xar;
-    ManagedConnectionImpl mc;
+    XAResource xaResource;
+    ManagedConnectionImpl managedConnectionImpl;
 
     /**
      * Constructor for XAResourceImpl
      *
-     * @param xar <code>XAResource</code>
-     * @param mc  <code>ManagedConnection</code>
+     * @param xaResource <code>XAResource</code>
+     * @param managedConnection <code>ManagedConnection</code>
      */
-    public XAResourceImpl(XAResource xar, ManagedConnectionImpl mc) {
-        this.xar = xar;
-        this.mc = mc;
+    public XAResourceImpl(XAResource xaResource, ManagedConnectionImpl managedConnection) {
+        this.xaResource = xaResource;
+        this.managedConnectionImpl = managedConnection;
     }
 
     /**
      * Commit the global transaction specified by xid.
      *
-     * @param xid      A global transaction identifier
+     * @param xid A global transaction identifier
      * @param onePhase If true, the resource manager should use a one-phase commit
-     *                 protocol to commit the work done on behalf of xid.
+     * protocol to commit the work done on behalf of xid.
      */
     public void commit(Xid xid, boolean onePhase) throws XAException {
-        //the mc.transactionCompleted call has come here because
-        //the transaction *actually* completes after the flow
-        //reaches here. the end() method might not really signal
-        //completion of transaction in case the transaction is
-        //suspended. In case of transaction suspension, the end
-        //method is still called by the transaction manager
+        // the mc.transactionCompleted call has come here because
+        // the transaction *actually* completes after the flow
+        // reaches here. the end() method might not really signal
+        // completion of transaction in case the transaction is
+        // suspended. In case of transaction suspension, the end
+        // method is still called by the transaction manager
         try {
-            xar.commit(xid, onePhase);
+            xaResource.commit(xid, onePhase);
         } catch (XAException xae) {
             throw xae;
         } catch (Exception e) {
             throw new XAException(e.getMessage());
         } finally {
-            mc.transactionCompleted();
+            managedConnectionImpl.transactionCompleted();
         }
     }
 
     /**
      * Ends the work performed on behalf of a transaction branch.
      *
-     * @param xid   A global transaction identifier that is the same as what
-     *              was used previously in the start method.
+     * @param xid A global transaction identifier that is the same as what was used
+     * previously in the start method.
      * @param flags One of TMSUCCESS, TMFAIL, or TMSUSPEND
      */
     public void end(Xid xid, int flags) throws XAException {
-        xar.end(xid, flags);
-        //GJCINT
-        //mc.transactionCompleted();
+        xaResource.end(xid, flags);
     }
 
     /**
-     * Tell the resource manager to forget about a heuristically completed transaction branch.
+     * Tell the resource manager to forget about a heuristically completed
+     * transaction branch.
      *
      * @param xid A global transaction identifier
      */
     public void forget(Xid xid) throws XAException {
-        xar.forget(xid);
+        xaResource.forget(xid);
     }
 
     /**
@@ -96,47 +95,47 @@
      * @return the transaction timeout value in seconds
      */
     public int getTransactionTimeout() throws XAException {
-        return xar.getTransactionTimeout();
+        return xaResource.getTransactionTimeout();
     }
 
     /**
      * This method is called to determine if the resource manager instance
-     * represented by the target object is the same as the resouce manager
-     * instance represented by the parameter xares.
+     * represented by the target object is the same as the resouce manager instance
+     * represented by the parameter xares.
      *
-     * @param xares An <code>XAResource</code> object whose resource manager
-     *              instance is to be compared with the resource
+     * @param xaResource An <code>XAResource</code> object whose resource manager
+     * instance is to be compared with the resource
      * @return true if it's the same RM instance; otherwise false.
      */
-    public boolean isSameRM(XAResource xares) throws XAException {
-        return xar.isSameRM(xares);
+    public boolean isSameRM(XAResource xaResource) throws XAException {
+        return this.xaResource.isSameRM(xaResource);
     }
 
     /**
-     * Ask the resource manager to prepare for a transaction commit
-     * of the transaction specified in xid.
+     * Ask the resource manager to prepare for a transaction commit of the
+     * transaction specified in xid.
      *
      * @param xid A global transaction identifier
-     * @return A value indicating the resource manager's vote on the
-     *         outcome of the transaction. The possible values
-     *         are: XA_RDONLY or XA_OK. If the resource manager wants
-     *         to roll back the transaction, it should do so
-     *         by raising an appropriate <code>XAException</code> in the prepare method.
+     * @return A value indicating the resource manager's vote on the outcome of the
+     * transaction. The possible values are: XA_RDONLY or XA_OK. If the resource
+     * manager wants to roll back the transaction, it should do so by raising an
+     * appropriate <code>XAException</code> in the prepare method.
      */
     public int prepare(Xid xid) throws XAException {
         try {
-            int result = xar.prepare(xid);
-            //When the VOTE from resource manager is XA_RDONLY , we will not get commit() call from TxManager.
-            //Hence calling txCompleted.
+            int result = xaResource.prepare(xid);
+            // When the VOTE from resource manager is XA_RDONLY , we will not get commit()
+            // call from TxManager.
+            // Hence calling txCompleted.
             if (result == XAResource.XA_RDONLY) {
-                mc.transactionCompleted();
+                managedConnectionImpl.transactionCompleted();
             }
             return result;
         } catch (XAException xae) {
-            mc.transactionCompleted();
+            managedConnectionImpl.transactionCompleted();
             throw xae;
         } catch (Exception e) {
-            mc.transactionCompleted();
+            managedConnectionImpl.transactionCompleted();
             throw new XAException(e.getMessage());
         }
     }
@@ -144,59 +143,61 @@
     /**
      * Obtain a list of prepared transaction branches from a resource manager.
      *
-     * @param flag One of TMSTARTRSCAN, TMENDRSCAN, TMNOFLAGS. TMNOFLAGS
-     *             must be used when no other flags are set in flags.
+     * @param flag One of TMSTARTRSCAN, TMENDRSCAN, TMNOFLAGS. TMNOFLAGS must be
+     * used when no other flags are set in flags.
      * @return The resource manager returns zero or more XIDs for the transaction
-     *         branches that are currently in a prepared or heuristically
-     *         completed state. If an error occurs during the operation, the resource
-     *         manager should throw the appropriate <code>XAException</code>.
+     * branches that are currently in a prepared or heuristically completed state.
+     * If an error occurs during the operation, the resource manager should throw
+     * the appropriate <code>XAException</code>.
      */
     public Xid[] recover(int flag) throws XAException {
-        return xar.recover(flag);
+        return xaResource.recover(flag);
     }
 
     /**
-     * Inform the resource manager to roll back work done on behalf of a transaction branch
+     * Inform the resource manager to roll back work done on behalf of a transaction
+     * branch
      *
      * @param xid A global transaction identifier
      */
     public void rollback(Xid xid) throws XAException {
-        //the mc.transactionCompleted call has come here becasue
-        //the transaction *actually* completes after the flow
-        //reaches here. the end() method might not really signal
-        //completion of transaction in case the transaction is
-        //suspended. In case of transaction suspension, the end
-        //method is still called by the transaction manager
+        // the mc.transactionCompleted call has come here becasue
+        // the transaction *actually* completes after the flow
+        // reaches here. the end() method might not really signal
+        // completion of transaction in case the transaction is
+        // suspended. In case of transaction suspension, the end
+        // method is still called by the transaction manager
         try {
-            xar.rollback(xid);
+            xaResource.rollback(xid);
         } catch (XAException xae) {
             throw xae;
         } catch (Exception e) {
             throw new XAException(e.getMessage());
         } finally {
-            mc.transactionCompleted();
+            managedConnectionImpl.transactionCompleted();
         }
     }
 
     /**
-     * Set the current transaction timeout value for this <code>XAResource</code> instance.
+     * Set the current transaction timeout value for this <code>XAResource</code>
+     * instance.
      *
      * @param seconds the transaction timeout value in seconds.
-     * @return true if transaction timeout value is set successfully; otherwise false.
+     * @return true if transaction timeout value is set successfully; otherwise
+     * false.
      */
     public boolean setTransactionTimeout(int seconds) throws XAException {
-        return xar.setTransactionTimeout(seconds);
+        return xaResource.setTransactionTimeout(seconds);
     }
 
     /**
      * Start work on behalf of a transaction branch specified in xid.
      *
      * @param xid A global transaction identifier to be associated with the resource
-     * @return flags    One of TMNOFLAGS, TMJOIN, or TMRESUME
+     * @return flags One of TMNOFLAGS, TMJOIN, or TMRESUME
      */
     public void start(Xid xid, int flags) throws XAException {
-        //GJCINT
-        mc.transactionStarted();
-        xar.start(xid, flags);
+        managedConnectionImpl.transactionStarted();
+        xaResource.start(xid, flags);
     }
 }
diff --git a/appserver/jdbc/jdbc-ra/jdbc-core/src/main/java/com/sun/gjc/spi/base/AbstractDataSource.java b/appserver/jdbc/jdbc-ra/jdbc-core/src/main/java/com/sun/gjc/spi/base/AbstractDataSource.java
index 8391c6e..101c412 100644
--- a/appserver/jdbc/jdbc-ra/jdbc-core/src/main/java/com/sun/gjc/spi/base/AbstractDataSource.java
+++ b/appserver/jdbc/jdbc-ra/jdbc-core/src/main/java/com/sun/gjc/spi/base/AbstractDataSource.java
@@ -16,36 +16,45 @@
 
 package com.sun.gjc.spi.base;
 
+import static java.util.logging.Level.WARNING;
+
+import java.io.PrintWriter;
+import java.io.Serializable;
+import java.sql.Connection;
+import java.sql.SQLException;
+import java.util.logging.Logger;
+
+import javax.naming.Reference;
+import javax.sql.DataSource;
+
+import com.sun.appserv.connectors.internal.api.ConnectorConstants;
 import com.sun.appserv.connectors.internal.spi.BadConnectionEventListener;
 import com.sun.gjc.spi.ConnectionManagerImplementation;
 import com.sun.gjc.spi.ConnectionRequestInfoImpl;
 import com.sun.gjc.spi.ManagedConnectionFactoryImpl;
-import com.sun.logging.LogDomains;
-import com.sun.appserv.connectors.internal.api.ConnectorConstants;
 import com.sun.gjc.util.MethodExecutor;
+import com.sun.logging.LogDomains;
 
-import javax.naming.Reference;
+import jakarta.resource.Referenceable;
 import jakarta.resource.ResourceException;
 import jakarta.resource.spi.ConnectionManager;
-import java.io.PrintWriter;
-import java.sql.Connection;
-import java.sql.SQLException;
-import java.util.logging.Level;
-import java.util.logging.Logger;
 
 /**
- * Holds the <code>java.sql.Connection</code> object, which is to be
- * passed to the application program.
+ * Holds the <code>java.sql.Connection</code> object, which is to be passed to
+ * the application program.
  *
  * @author Binod P.G
  * @version 1.0, 02/07/31
  */
-public abstract class AbstractDataSource implements javax.sql.DataSource, java.io.Serializable,
-        com.sun.appserv.jdbc.DataSource, jakarta.resource.Referenceable {
+public abstract class AbstractDataSource implements DataSource, Serializable, com.sun.appserv.jdbc.DataSource, Referenceable {
 
-    protected ManagedConnectionFactoryImpl mcf;
-    protected MethodExecutor executor = null;
-    private ConnectionManager cm;
+    private static final long serialVersionUID = 1L;
+
+    protected final static Logger _logger = LogDomains.getLogger(ManagedConnectionFactoryImpl.class, LogDomains.RSR_LOGGER);
+
+    protected ManagedConnectionFactoryImpl managedConnectionFactoryImpl;
+    protected MethodExecutor executor;
+    private ConnectionManager connectionManager;
     private int loginTimeout;
     private PrintWriter logWriter;
     private String description;
@@ -53,28 +62,22 @@
 
     private ConnectionHolder.ConnectionType conType_;
 
-    protected final static Logger _logger;
-
-    static {
-        _logger = LogDomains.getLogger(ManagedConnectionFactoryImpl.class, LogDomains.RSR_LOGGER);
-    }
 
     /**
      * Constructs <code>DataSource</code> object. This is created by the
      * <code>ManagedConnectionFactory</code> object.
      *
-     * @param mcf <code>ManagedConnectionFactory</code> object
-     *            creating this object.
-     * @param cm  <code>ConnectionManager</code> object either associated
-     *            with Application server or Resource Adapter.
+     * @param managedConnectionFactoryImpl <code>ManagedConnectionFactory</code> object creating this object.
+     * @param connectionManager <code>ConnectionManager</code> object either associated with
+     * Application server or Resource Adapter.
      */
-    public AbstractDataSource(ManagedConnectionFactoryImpl mcf, ConnectionManager cm) {
-        this.mcf = mcf;
+    public AbstractDataSource(ManagedConnectionFactoryImpl managedConnectionFactoryImpl, ConnectionManager connectionManager) {
+        this.managedConnectionFactoryImpl = managedConnectionFactoryImpl;
         executor = new MethodExecutor();
-        if (cm == null) {
-            this.cm = new ConnectionManagerImplementation();
+        if (connectionManager == null) {
+            this.connectionManager = new ConnectionManagerImplementation();
         } else {
-            this.cm = cm;
+            this.connectionManager = connectionManager;
             conType_ = findConnectionType();
         }
     }
@@ -87,11 +90,10 @@
      */
     public Connection getConnection() throws SQLException {
         try {
-            ConnectionHolder con = (ConnectionHolder)
-                    cm.allocateConnection(mcf, null);
-            setConnectionType(con);
+            ConnectionHolder connection = (ConnectionHolder) connectionManager.allocateConnection(managedConnectionFactoryImpl, null);
+            setConnectionType(connection);
 
-            return con;
+            return connection;
         } catch (ResourceException re) {
             logNonTransientException(re);
             throw new SQLException(re.getMessage(), re);
@@ -100,11 +102,12 @@
 
     /**
      * log the exception if it is a non-transient exception <br>
+     *
      * @param re Exception to log
      */
     private void logNonTransientException(ResourceException re) {
-        if(!BadConnectionEventListener.POOL_RECONFIGURED_ERROR_CODE.equals(re.getErrorCode())){
-            _logger.log(Level.WARNING, "jdbc.exc_get_conn", re.getMessage());
+        if (!BadConnectionEventListener.POOL_RECONFIGURED_ERROR_CODE.equals(re.getErrorCode())) {
+            _logger.log(WARNING, "jdbc.exc_get_conn", re.getMessage());
         }
     }
 
@@ -112,15 +115,14 @@
      * Retrieves the <code> Connection </code> object.
      *
      * @param user User name for the Connection.
-     * @param pwd  Password for the Connection.
+     * @param pwd Password for the Connection.
      * @return <code> Connection </code> object.
      * @throws SQLException In case of an error.
      */
     public Connection getConnection(String user, String pwd) throws SQLException {
         try {
             ConnectionRequestInfoImpl info = new ConnectionRequestInfoImpl(user, pwd.toCharArray());
-            ConnectionHolder con = (ConnectionHolder)
-                    cm.allocateConnection(mcf, info);
+            ConnectionHolder con = (ConnectionHolder) connectionManager.allocateConnection(managedConnectionFactoryImpl, info);
             setConnectionType(con);
             return con;
         } catch (ResourceException re) {
@@ -130,14 +132,13 @@
     }
 
     /**
-     * Retrieves the actual SQLConnection from the Connection wrapper
-     * implementation of SunONE application server. If an actual connection is
-     * supplied as argument, then it will be just returned.
+     * Retrieves the actual SQLConnection from the Connection wrapper implementation
+     * of SunONE application server. If an actual connection is supplied as
+     * argument, then it will be just returned.
      *
      * @param con Connection obtained from <code>Datasource.getConnection()</code>
      * @return <code>java.sql.Connection</code> implementation of the driver.
-     * @throws <code>java.sql.SQLException</code>
-     *          If connection cannot be obtained.
+     * @throws <code>java.sql.SQLException</code> If connection cannot be obtained.
      */
     public Connection getConnection(Connection con) throws SQLException {
 
@@ -150,24 +151,22 @@
     }
 
     /**
-     * Gets a connection that is not in the scope of any transaction. This
-     * can be used to save performance overhead incurred on enlisting/delisting
-     * each connection got, irrespective of whether its required or not.
-     * Note here that this meethod does not fit in the connector contract
-     * per se.
+     * Gets a connection that is not in the scope of any transaction. This can be
+     * used to save performance overhead incurred on enlisting/delisting each
+     * connection got, irrespective of whether its required or not. Note here that
+     * this meethod does not fit in the connector contract per se.
      *
      * @return <code>java.sql.Connection</code>
-     * @throws <code>java.sql.SQLException</code>
-     *          If connection cannot be obtained
+     * @throws <code>java.sql.SQLException</code> If connection cannot be obtained
      */
     public Connection getNonTxConnection() throws SQLException {
         try {
-            ConnectionHolder con = (ConnectionHolder)
-                    ((com.sun.appserv.connectors.internal.spi.ConnectionManager)
-                            cm).allocateNonTxConnection(mcf, null);
-            setConnectionType(con, true);
+            ConnectionHolder connection =
+                (ConnectionHolder) ((com.sun.appserv.connectors.internal.spi.ConnectionManager) connectionManager)
+                    .allocateNonTxConnection(managedConnectionFactoryImpl, null);
+            setConnectionType(connection, true);
 
-            return con;
+            return connection;
         } catch (ResourceException re) {
             logNonTransientException(re);
             throw new SQLException(re.getMessage(), re);
@@ -175,24 +174,21 @@
     }
 
     /**
-     * Gets a connection that is not in the scope of any transaction. This
-     * can be used to save performance overhead incurred on enlisting/delisting
-     * each connection got, irrespective of whether its required or not.
-     * Note here that this meethod does not fit in the connector contract
-     * per se.
+     * Gets a connection that is not in the scope of any transaction. This can be
+     * used to save performance overhead incurred on enlisting/delisting each
+     * connection got, irrespective of whether its required or not. Note here that
+     * this meethod does not fit in the connector contract per se.
      *
-     * @param user     User name for authenticating the connection
+     * @param user User name for authenticating the connection
      * @param password Password for authenticating the connection
      * @return <code>java.sql.Connection</code>
-     * @throws <code>java.sql.SQLException</code>
-     *          If connection cannot be obtained
+     * @throws <code>java.sql.SQLException</code> If connection cannot be obtained
      */
     public Connection getNonTxConnection(String user, String password) throws SQLException {
         try {
             ConnectionRequestInfoImpl cxReqInfo = new ConnectionRequestInfoImpl(user, password.toCharArray());
-            ConnectionHolder con = (ConnectionHolder)
-                    ((com.sun.appserv.connectors.internal.spi.ConnectionManager)
-                            cm).allocateNonTxConnection(mcf, cxReqInfo);
+            ConnectionHolder con = (ConnectionHolder) ((com.sun.appserv.connectors.internal.spi.ConnectionManager) connectionManager)
+                    .allocateNonTxConnection(managedConnectionFactoryImpl, cxReqInfo);
 
             setConnectionType(con, true);
 
@@ -282,17 +278,16 @@
     private ConnectionHolder.ConnectionType findConnectionType() {
         ConnectionHolder.ConnectionType cmType = ConnectionHolder.ConnectionType.STANDARD;
 
-        if (cm instanceof jakarta.resource.spi.LazyAssociatableConnectionManager) {
-            if (!((com.sun.appserv.connectors.internal.spi.ConnectionManager) cm).
-                    getJndiName().endsWith(ConnectorConstants.PM_JNDI_SUFFIX)) {
+        if (connectionManager instanceof jakarta.resource.spi.LazyAssociatableConnectionManager) {
+            if (!((com.sun.appserv.connectors.internal.spi.ConnectionManager) connectionManager).getJndiName()
+                    .endsWith(ConnectorConstants.PM_JNDI_SUFFIX)) {
                 cmType = ConnectionHolder.ConnectionType.LAZY_ASSOCIATABLE;
             }
-        } else if (cm instanceof
-                jakarta.resource.spi.LazyEnlistableConnectionManager) {
-            if (!((com.sun.appserv.connectors.internal.spi.ConnectionManager) cm).
-                    getJndiName().endsWith(ConnectorConstants.PM_JNDI_SUFFIX) &&
-                    !((com.sun.appserv.connectors.internal.spi.ConnectionManager) cm).
-                            getJndiName().endsWith(ConnectorConstants.NON_TX_JNDI_SUFFIX)) {
+        } else if (connectionManager instanceof jakarta.resource.spi.LazyEnlistableConnectionManager) {
+            if (!((com.sun.appserv.connectors.internal.spi.ConnectionManager) connectionManager).getJndiName()
+                    .endsWith(ConnectorConstants.PM_JNDI_SUFFIX)
+                    && !((com.sun.appserv.connectors.internal.spi.ConnectionManager) connectionManager).getJndiName()
+                            .endsWith(ConnectorConstants.NON_TX_JNDI_SUFFIX)) {
                 cmType = ConnectionHolder.ConnectionType.LAZY_ENLISTABLE;
             }
         }
@@ -306,27 +301,26 @@
 
     private void setConnectionType(ConnectionHolder con, boolean isNonTx) {
         con.setConnectionType(conType_);
-        if (conType_ == ConnectionHolder.ConnectionType.LAZY_ASSOCIATABLE &&
-                cm instanceof jakarta.resource.spi.LazyAssociatableConnectionManager) {
-            con.setLazyAssociatableConnectionManager(
-                    (jakarta.resource.spi.LazyAssociatableConnectionManager) cm);
+        if (conType_ == ConnectionHolder.ConnectionType.LAZY_ASSOCIATABLE
+                && connectionManager instanceof jakarta.resource.spi.LazyAssociatableConnectionManager) {
+            con.setLazyAssociatableConnectionManager((jakarta.resource.spi.LazyAssociatableConnectionManager) connectionManager);
         } else if (conType_ == ConnectionHolder.ConnectionType.LAZY_ENLISTABLE) {
             if (isNonTx) {
-                //if this is a getNonTxConnection call on the DataSource, we
-                //should not LazyEnlist
+                // if this is a getNonTxConnection call on the DataSource, we
+                // should not LazyEnlist
                 con.setConnectionType(ConnectionHolder.ConnectionType.STANDARD);
-            } else if(cm instanceof jakarta.resource.spi.LazyEnlistableConnectionManager) {
-                con.setLazyEnlistableConnectionManager(
-                        (jakarta.resource.spi.LazyEnlistableConnectionManager) cm);
+            } else if (connectionManager instanceof jakarta.resource.spi.LazyEnlistableConnectionManager) {
+                con.setLazyEnlistableConnectionManager((jakarta.resource.spi.LazyEnlistableConnectionManager) connectionManager);
             }
         }
     }
 
     /**
-     * API to mark a connection as bad. If the application can determine that the connection
-     * is bad, using this api, it can notify the resource-adapter which inturn will notify the
-     * connection-pool. Connection-pool will drop and create a new connection.
-     * eg:
+     * API to mark a connection as bad. If the application can determine that the
+     * connection is bad, using this api, it can notify the resource-adapter which
+     * inturn will notify the connection-pool. Connection-pool will drop and create
+     * a new connection. eg:
+     *
      * <pre>
         com.sun.appserv.jdbc.DataSource ds=
            (com.sun.appserv.jdbc.DataSource)context.lookup("dataSource");
@@ -343,12 +337,12 @@
             }
      * </pre>
      *
-     * @param conn <code>java.sql.Connection</code>
+     * @param connection <code>java.sql.Connection</code>
      */
-    public void markConnectionAsBad(Connection conn) {
-        if (conn instanceof ConnectionHolder) {
-            ConnectionHolder userConn = ((ConnectionHolder) conn);
-            userConn.getManagedConnection().markForRemoval(true);
+    public void markConnectionAsBad(Connection connection) {
+        if (connection instanceof ConnectionHolder) {
+            ConnectionHolder userConnection = ((ConnectionHolder) connection);
+            userConnection.getManagedConnection().markForRemoval(true);
         }
     }
 }
diff --git a/appserver/jdbc/jdbc-ra/jdbc-core/src/main/java/com/sun/gjc/spi/base/CacheObjectKey.java b/appserver/jdbc/jdbc-ra/jdbc-core/src/main/java/com/sun/gjc/spi/base/CacheObjectKey.java
index 3aa5234..2fc5d7f 100644
--- a/appserver/jdbc/jdbc-ra/jdbc-core/src/main/java/com/sun/gjc/spi/base/CacheObjectKey.java
+++ b/appserver/jdbc/jdbc-ra/jdbc-core/src/main/java/com/sun/gjc/spi/base/CacheObjectKey.java
@@ -26,8 +26,8 @@
     public static final String CALLABLE_STATEMENT = "CS";
     public static final String PREPARED_STATEMENT = "PS";
 
-    protected String sql = null;
-    protected String statementType = null;
+    protected String sql;
+    protected String statementType;
     protected int resultSetType;
     protected int resultSetConcurrency;
     protected int resultSetHoldability;
@@ -71,16 +71,14 @@
         this.columnIndexes = columnIndexes;
     }
 
-    public CacheObjectKey(String sql, String statementType,
-            int resultSetType, int resultSetConcurrency) {
+    public CacheObjectKey(String sql, String statementType, int resultSetType, int resultSetConcurrency) {
         this.sql = sql;
         this.statementType = statementType;
         this.resultSetType = resultSetType;
         this.resultSetConcurrency = resultSetConcurrency;
     }
 
-    public CacheObjectKey(String sql, String statementType,
-            int resultSetType, int resultSetConcurrency,
+    public CacheObjectKey(String sql, String statementType, int resultSetType, int resultSetConcurrency,
             int resultSetHoldability) {
         this.sql = sql;
         this.statementType = statementType;
@@ -89,22 +87,19 @@
         this.resultSetHoldability = resultSetHoldability;
     }
 
-    public CacheObjectKey(String sql, String statementType,
-            int[] columnIndexes) {
+    public CacheObjectKey(String sql, String statementType, int[] columnIndexes) {
         this.sql = sql;
         this.statementType = statementType;
         this.columnIndexes = columnIndexes;
     }
 
-    public CacheObjectKey(String sql, String statementType,
-            String[] columnNames) {
+    public CacheObjectKey(String sql, String statementType, String[] columnNames) {
         this.sql = sql;
         this.statementType = statementType;
         this.columnNames = columnNames;
     }
 
-    public CacheObjectKey(String sql, String statementType,
-            int autoGeneratedKeys) {
+    public CacheObjectKey(String sql, String statementType, int autoGeneratedKeys) {
         this.sql = sql;
         this.statementType = statementType;
         this.autoGeneratedKeys = autoGeneratedKeys;
@@ -153,6 +148,7 @@
     public void setResultSetType(int resultSetType) {
         this.resultSetType = resultSetType;
     }
+
     /**
      * Get the value of resultSetHoldability
      *
@@ -175,86 +171,6 @@
     }
 
     /**
-     * Check for the equality of the CacheObjectKey with the object passed by
-     * 1. comparing the sql string values
-     * 2. comparing the statement type values
-     * 3. comapring the getClass() values
-     * @param obj obj which is to be checked against this object
-     * @return boolean
-     */
-    @Override
-    public boolean equals(Object obj) {
-        if (obj == null) {
-            return false;
-        }
-        if (getClass() != obj.getClass()) {
-            return false;
-        }
-        final CacheObjectKey other = (CacheObjectKey) obj;
-        if (this.sql == null || other.sql == null || !this.sql.equals(other.sql)) {
-            return false;
-        }
-        if (this.statementType == null || other.statementType == null ||
-                !this.statementType.equals(other.statementType)) {
-            return false;
-        }
-        if (this.resultSetType != other.resultSetType) {
-            return false;
-        }
-        if (this.resultSetConcurrency != other.resultSetConcurrency) {
-            return false;
-        }
-        if (this.resultSetHoldability != other.resultSetHoldability) {
-            return false;
-        }
-        if(CacheObjectKey.PREPARED_STATEMENT.equals(other.statementType)) {
-            if (this.autoGeneratedKeys != other.autoGeneratedKeys) {
-                return false;
-            }
-            //Iterate through the columnNames/columnIndexes to see if equal
-            if(this.columnIndexes != null && other.columnIndexes != null) {
-                if (!Arrays.equals(this.columnIndexes, other.columnIndexes)) {
-                    return false;
-                }
-            }
-            if(this.columnNames != null && other.columnNames != null) {
-                if(!Arrays.equals(this.columnNames, other.columnNames)) {
-                    return false;
-                }
-            }
-        }
-        return true;
-    }
-
-    /**
-     * Generate hashCode for this object using the sql and statementType fields
-     * @return has integer value
-     */
-    @Override
-    public int hashCode() {
-        int hash = 7;
-        hash = 41 * hash + (this.sql != null ? this.sql.hashCode() : 0);
-        hash = 41 * hash + (this.statementType != null ? this.statementType.hashCode() : 0);
-        hash = 41 * hash + this.resultSetType;
-        hash = 41 * hash + this.resultSetConcurrency;
-        hash = 41 * hash + this.resultSetHoldability;
-        if(CacheObjectKey.PREPARED_STATEMENT.equals(this.statementType)) {
-            hash = 41 * hash + this.autoGeneratedKeys;
-            if(this.columnIndexes != null) {
-                for(int i : this.columnIndexes) {
-                    hash = 41 * hash + ((Integer) i).hashCode();
-                }
-            }
-            if(this.columnNames != null) {
-                for(String str : columnNames) {
-                    hash = 41 * hash + str.hashCode();
-                }
-            }
-        }
-        return hash;
-    }
-
-    /**
      * Get the value of statementType
      *
      * @return the value of statementType
@@ -289,4 +205,85 @@
     public void setSql(String sql) {
         this.sql = sql;
     }
+
+    /**
+     * Check for the equality of the CacheObjectKey with the object passed by 1.
+     * comparing the sql string values 2. comparing the statement type values 3.
+     * comapring the getClass() values
+     *
+     * @param obj obj which is to be checked against this object
+     * @return boolean
+     */
+    @Override
+    public boolean equals(Object obj) {
+        if (obj == null) {
+            return false;
+        }
+        if (getClass() != obj.getClass()) {
+            return false;
+        }
+        final CacheObjectKey other = (CacheObjectKey) obj;
+        if (this.sql == null || other.sql == null || !this.sql.equals(other.sql)) {
+            return false;
+        }
+        if (this.statementType == null || other.statementType == null
+                || !this.statementType.equals(other.statementType)) {
+            return false;
+        }
+        if (this.resultSetType != other.resultSetType) {
+            return false;
+        }
+        if (this.resultSetConcurrency != other.resultSetConcurrency) {
+            return false;
+        }
+        if (this.resultSetHoldability != other.resultSetHoldability) {
+            return false;
+        }
+        if (CacheObjectKey.PREPARED_STATEMENT.equals(other.statementType)) {
+            if (this.autoGeneratedKeys != other.autoGeneratedKeys) {
+                return false;
+            }
+            // Iterate through the columnNames/columnIndexes to see if equal
+            if (this.columnIndexes != null && other.columnIndexes != null) {
+                if (!Arrays.equals(this.columnIndexes, other.columnIndexes)) {
+                    return false;
+                }
+            }
+            if (this.columnNames != null && other.columnNames != null) {
+                if (!Arrays.equals(this.columnNames, other.columnNames)) {
+                    return false;
+                }
+            }
+        }
+        return true;
+    }
+
+    /**
+     * Generate hashCode for this object using the sql and statementType fields
+     *
+     * @return has integer value
+     */
+    @Override
+    public int hashCode() {
+        int hash = 7;
+        hash = 41 * hash + (this.sql != null ? this.sql.hashCode() : 0);
+        hash = 41 * hash + (this.statementType != null ? this.statementType.hashCode() : 0);
+        hash = 41 * hash + this.resultSetType;
+        hash = 41 * hash + this.resultSetConcurrency;
+        hash = 41 * hash + this.resultSetHoldability;
+        if (CacheObjectKey.PREPARED_STATEMENT.equals(this.statementType)) {
+            hash = 41 * hash + this.autoGeneratedKeys;
+            if (this.columnIndexes != null) {
+                for (int i : this.columnIndexes) {
+                    hash = 41 * hash + ((Integer) i).hashCode();
+                }
+            }
+            if (this.columnNames != null) {
+                for (String str : columnNames) {
+                    hash = 41 * hash + str.hashCode();
+                }
+            }
+        }
+        return hash;
+    }
 }
diff --git a/appserver/jdbc/jdbc-ra/jdbc-core/src/main/java/com/sun/gjc/spi/base/CallableStatementWrapper.java b/appserver/jdbc/jdbc-ra/jdbc-core/src/main/java/com/sun/gjc/spi/base/CallableStatementWrapper.java
index f09dc06..3b9a808 100644
--- a/appserver/jdbc/jdbc-ra/jdbc-core/src/main/java/com/sun/gjc/spi/base/CallableStatementWrapper.java
+++ b/appserver/jdbc/jdbc-ra/jdbc-core/src/main/java/com/sun/gjc/spi/base/CallableStatementWrapper.java
@@ -20,51 +20,56 @@
 import java.io.Reader;
 import java.math.BigDecimal;
 import java.net.URL;
-import java.sql.*;
+import java.sql.Array;
+import java.sql.Blob;
+import java.sql.CallableStatement;
+import java.sql.Clob;
+import java.sql.Connection;
+import java.sql.Date;
+import java.sql.Ref;
+import java.sql.SQLException;
+import java.sql.Time;
+import java.sql.Timestamp;
 import java.util.Calendar;
 import java.util.Map;
 
-
 /**
  * Abstract class for wrapping PreparedStatement<br>
  */
 public abstract class CallableStatementWrapper extends PreparedStatementWrapper implements CallableStatement {
-    protected CallableStatement callableStatement = null;
+
+    protected CallableStatement callableStatement;
 
     /**
      * Creates a new instance of CallableStatementWrapper<br>
      *
-     * @param con       ConnectionWrapper <br>
+     * @param con ConnectionWrapper <br>
      * @param statement Statement that is to be wrapped<br>
      */
-    public CallableStatementWrapper(Connection con, CallableStatement statement,
-                                    boolean cachingEnabled) throws SQLException{
+    public CallableStatementWrapper(Connection con, CallableStatement statement, boolean cachingEnabled) throws SQLException {
         super(con, statement, cachingEnabled);
         callableStatement = statement;
     }
 
     /**
-     * Registers the OUT parameter in ordinal position
-     * <code>parameterIndex</code> to the JDBC type
-     * <code>sqlType</code>.  All OUT parameters must be registered
+     * Registers the OUT parameter in ordinal position <code>parameterIndex</code>
+     * to the JDBC type <code>sqlType</code>. All OUT parameters must be registered
      * before a stored procedure is executed.
      * <p/>
-     * The JDBC type specified by <code>sqlType</code> for an OUT
-     * parameter determines the Java type that must be used
-     * in the <code>get</code> method to read the value of that parameter.
+     * The JDBC type specified by <code>sqlType</code> for an OUT parameter
+     * determines the Java type that must be used in the <code>get</code> method to
+     * read the value of that parameter.
      * <p/>
-     * If the JDBC type expected to be returned to this output parameter
-     * is specific to this particular database, <code>sqlType</code>
-     * should be <code>java.sql.Types.OTHER</code>.  The method
-     * {@link #getObject} retrieves the value.
+     * If the JDBC type expected to be returned to this output parameter is specific
+     * to this particular database, <code>sqlType</code> should be
+     * <code>java.sql.Types.OTHER</code>. The method {@link #getObject} retrieves
+     * the value.
      *
-     * @param parameterIndex the first parameter is 1, the second is 2,
-     *                       and so on
-     * @param sqlType        the JDBC type code defined by <code>java.sql.Types</code>.
-     *                       If the parameter is of JDBC type <code>NUMERIC</code>
-     *                       or <code>DECIMAL</code>, the version of
-     *                       <code>registerOutParameter</code> that accepts a scale value
-     *                       should be used.
+     * @param parameterIndex the first parameter is 1, the second is 2, and so on
+     * @param sqlType the JDBC type code defined by <code>java.sql.Types</code>. If
+     * the parameter is of JDBC type <code>NUMERIC</code> or <code>DECIMAL</code>,
+     * the version of <code>registerOutParameter</code> that accepts a scale value
+     * should be used.
      * @throws java.sql.SQLException if a database access error occurs
      * @see java.sql.Types
      */
@@ -73,24 +78,21 @@
     }
 
     /**
-     * Registers the parameter in ordinal position
-     * <code>parameterIndex</code> to be of JDBC type
-     * <code>sqlType</code>.  This method must be called
-     * before a stored procedure is executed.
+     * Registers the parameter in ordinal position <code>parameterIndex</code> to be
+     * of JDBC type <code>sqlType</code>. This method must be called before a stored
+     * procedure is executed.
      * <p/>
-     * The JDBC type specified by <code>sqlType</code> for an OUT
-     * parameter determines the Java type that must be used
-     * in the <code>get</code> method to read the value of that parameter.
+     * The JDBC type specified by <code>sqlType</code> for an OUT parameter
+     * determines the Java type that must be used in the <code>get</code> method to
+     * read the value of that parameter.
      * <p/>
-     * This version of <code>registerOutParameter</code> should be
-     * used when the parameter is of JDBC type <code>NUMERIC</code>
-     * or <code>DECIMAL</code>.
+     * This version of <code>registerOutParameter</code> should be used when the
+     * parameter is of JDBC type <code>NUMERIC</code> or <code>DECIMAL</code>.
      *
-     * @param parameterIndex the first parameter is 1, the second is 2,
-     *                       and so on
-     * @param sqlType        the SQL type code defined by <code>java.sql.Types</code>.
-     * @param scale          the desired number of digits to the right of the
-     *                       decimal point.  It must be greater than or equal to zero.
+     * @param parameterIndex the first parameter is 1, the second is 2, and so on
+     * @param sqlType the SQL type code defined by <code>java.sql.Types</code>.
+     * @param scale the desired number of digits to the right of the decimal point.
+     * It must be greater than or equal to zero.
      * @throws java.sql.SQLException if a database access error occurs
      * @see java.sql.Types
      */
@@ -99,13 +101,13 @@
     }
 
     /**
-     * Retrieves whether the last OUT parameter read had the value of
-     * SQL <code>NULL</code>.  Note that this method should be called only after
-     * calling a getter method; otherwise, there is no value to use in
-     * determining whether it is <code>null</code> or not.
+     * Retrieves whether the last OUT parameter read had the value of SQL
+     * <code>NULL</code>. Note that this method should be called only after calling
+     * a getter method; otherwise, there is no value to use in determining whether
+     * it is <code>null</code> or not.
      *
      * @return <code>true</code> if the last parameter read was SQL
-     *         <code>NULL</code>; <code>false</code> otherwise
+     * <code>NULL</code>; <code>false</code> otherwise
      * @throws java.sql.SQLException if a database access error occurs
      */
     public boolean wasNull() throws SQLException {
@@ -117,17 +119,13 @@
      * <code>VARCHAR</code>, or <code>LONGVARCHAR</code> parameter as a
      * <code>String</code> in the Java programming language.
      * <p/>
-     * For the fixed-length type JDBC <code>CHAR</code>,
-     * the <code>String</code> object
-     * returned has exactly the same value the JDBC
-     * <code>CHAR</code> value had in the
-     * database, including any padding added by the database.
+     * For the fixed-length type JDBC <code>CHAR</code>, the <code>String</code>
+     * object returned has exactly the same value the JDBC <code>CHAR</code> value
+     * had in the database, including any padding added by the database.
      *
-     * @param parameterIndex the first parameter is 1, the second is 2,
-     *                       and so on
-     * @return the parameter value. If the value is SQL <code>NULL</code>,
-     *         the result
-     *         is <code>null</code>.
+     * @param parameterIndex the first parameter is 1, the second is 2, and so on
+     * @return the parameter value. If the value is SQL <code>NULL</code>, the
+     * result is <code>null</code>.
      * @throws java.sql.SQLException if a database access error occurs
      * @see #setString
      */
@@ -139,10 +137,9 @@
      * Retrieves the value of the designated JDBC <code>BIT</code> parameter as a
      * <code>boolean</code> in the Java programming language.
      *
-     * @param parameterIndex the first parameter is 1, the second is 2,
-     *                       and so on
-     * @return the parameter value.  If the value is SQL <code>NULL</code>,
-     *         the result is <code>false</code>.
+     * @param parameterIndex the first parameter is 1, the second is 2, and so on
+     * @return the parameter value. If the value is SQL <code>NULL</code>, the
+     * result is <code>false</code>.
      * @throws java.sql.SQLException if a database access error occurs
      * @see #setBoolean
      */
@@ -151,13 +148,12 @@
     }
 
     /**
-     * Retrieves the value of the designated JDBC <code>TINYINT</code> parameter
-     * as a <code>byte</code> in the Java programming language.
+     * Retrieves the value of the designated JDBC <code>TINYINT</code> parameter as
+     * a <code>byte</code> in the Java programming language.
      *
-     * @param parameterIndex the first parameter is 1, the second is 2,
-     *                       and so on
-     * @return the parameter value.  If the value is SQL <code>NULL</code>, the result
-     *         is <code>0</code>.
+     * @param parameterIndex the first parameter is 1, the second is 2, and so on
+     * @return the parameter value. If the value is SQL <code>NULL</code>, the
+     * result is <code>0</code>.
      * @throws java.sql.SQLException if a database access error occurs
      * @see #setByte
      */
@@ -166,13 +162,12 @@
     }
 
     /**
-     * Retrieves the value of the designated JDBC <code>SMALLINT</code> parameter
-     * as a <code>short</code> in the Java programming language.
+     * Retrieves the value of the designated JDBC <code>SMALLINT</code> parameter as
+     * a <code>short</code> in the Java programming language.
      *
-     * @param parameterIndex the first parameter is 1, the second is 2,
-     *                       and so on
-     * @return the parameter value.  If the value is SQL <code>NULL</code>, the result
-     *         is <code>0</code>.
+     * @param parameterIndex the first parameter is 1, the second is 2, and so on
+     * @return the parameter value. If the value is SQL <code>NULL</code>, the
+     * result is <code>0</code>.
      * @throws java.sql.SQLException if a database access error occurs
      * @see #setShort
      */
@@ -181,13 +176,12 @@
     }
 
     /**
-     * Retrieves the value of the designated JDBC <code>INTEGER</code> parameter
-     * as an <code>int</code> in the Java programming language.
+     * Retrieves the value of the designated JDBC <code>INTEGER</code> parameter as
+     * an <code>int</code> in the Java programming language.
      *
-     * @param parameterIndex the first parameter is 1, the second is 2,
-     *                       and so on
-     * @return the parameter value.  If the value is SQL <code>NULL</code>, the result
-     *         is <code>0</code>.
+     * @param parameterIndex the first parameter is 1, the second is 2, and so on
+     * @return the parameter value. If the value is SQL <code>NULL</code>, the
+     * result is <code>0</code>.
      * @throws java.sql.SQLException if a database access error occurs
      * @see #setInt
      */
@@ -196,13 +190,12 @@
     }
 
     /**
-     * Retrieves the value of the designated JDBC <code>BIGINT</code> parameter
-     * as a <code>long</code> in the Java programming language.
+     * Retrieves the value of the designated JDBC <code>BIGINT</code> parameter as a
+     * <code>long</code> in the Java programming language.
      *
-     * @param parameterIndex the first parameter is 1, the second is 2,
-     *                       and so on
-     * @return the parameter value.  If the value is SQL <code>NULL</code>, the result
-     *         is <code>0</code>.
+     * @param parameterIndex the first parameter is 1, the second is 2, and so on
+     * @return the parameter value. If the value is SQL <code>NULL</code>, the
+     * result is <code>0</code>.
      * @throws java.sql.SQLException if a database access error occurs
      * @see #setLong
      */
@@ -211,13 +204,12 @@
     }
 
     /**
-     * Retrieves the value of the designated JDBC <code>FLOAT</code> parameter
-     * as a <code>float</code> in the Java programming language.
+     * Retrieves the value of the designated JDBC <code>FLOAT</code> parameter as a
+     * <code>float</code> in the Java programming language.
      *
-     * @param parameterIndex the first parameter is 1, the second is 2,
-     *                       and so on
-     * @return the parameter value.  If the value is SQL <code>NULL</code>, the result
-     *         is <code>0</code>.
+     * @param parameterIndex the first parameter is 1, the second is 2, and so on
+     * @return the parameter value. If the value is SQL <code>NULL</code>, the
+     * result is <code>0</code>.
      * @throws java.sql.SQLException if a database access error occurs
      * @see #setFloat
      */
@@ -226,13 +218,12 @@
     }
 
     /**
-     * Retrieves the value of the designated JDBC <code>DOUBLE</code> parameter as a <code>double</code>
-     * in the Java programming language.
+     * Retrieves the value of the designated JDBC <code>DOUBLE</code> parameter as a
+     * <code>double</code> in the Java programming language.
      *
-     * @param parameterIndex the first parameter is 1, the second is 2,
-     *                       and so on
-     * @return the parameter value.  If the value is SQL <code>NULL</code>, the result
-     *         is <code>0</code>.
+     * @param parameterIndex the first parameter is 1, the second is 2, and so on
+     * @return the parameter value. If the value is SQL <code>NULL</code>, the
+     * result is <code>0</code>.
      * @throws java.sql.SQLException if a database access error occurs
      * @see #setDouble
      */
@@ -241,19 +232,18 @@
     }
 
     /**
-     * Retrieves the value of the designated JDBC <code>NUMERIC</code> parameter as a
-     * <code>java.math.BigDecimal</code> object with <i>scale</i> digits to
-     * the right of the decimal point.
+     * Retrieves the value of the designated JDBC <code>NUMERIC</code> parameter as
+     * a <code>java.math.BigDecimal</code> object with <i>scale</i> digits to the
+     * right of the decimal point.
      *
-     * @param parameterIndex the first parameter is 1, the second is 2,
-     *                       and so on
-     * @param scale          the number of digits to the right of the decimal point
-     * @return the parameter value.  If the value is SQL <code>NULL</code>, the result
-     *         is <code>null</code>.
+     * @param parameterIndex the first parameter is 1, the second is 2, and so on
+     * @param scale the number of digits to the right of the decimal point
+     * @return the parameter value. If the value is SQL <code>NULL</code>, the
+     * result is <code>null</code>.
      * @throws java.sql.SQLException if a database access error occurs
      * @see #setBigDecimal
-     * @deprecated use <code>getBigDecimal(int parameterIndex)</code>
-     *             or <code>getBigDecimal(String parameterName)</code>
+     * @deprecated use <code>getBigDecimal(int parameterIndex)</code> or
+     * <code>getBigDecimal(String parameterName)</code>
      */
     @Deprecated
     public BigDecimal getBigDecimal(int parameterIndex, int scale) throws SQLException {
@@ -262,13 +252,12 @@
 
     /**
      * Retrieves the value of the designated JDBC <code>BINARY</code> or
-     * <code>VARBINARY</code> parameter as an array of <code>byte</code>
-     * values in the Java programming language.
+     * <code>VARBINARY</code> parameter as an array of <code>byte</code> values in
+     * the Java programming language.
      *
-     * @param parameterIndex the first parameter is 1, the second is 2,
-     *                       and so on
-     * @return the parameter value.  If the value is SQL <code>NULL</code>, the result
-     *         is <code>null</code>.
+     * @param parameterIndex the first parameter is 1, the second is 2, and so on
+     * @return the parameter value. If the value is SQL <code>NULL</code>, the
+     * result is <code>null</code>.
      * @throws java.sql.SQLException if a database access error occurs
      * @see #setBytes
      */
@@ -280,10 +269,9 @@
      * Retrieves the value of the designated JDBC <code>DATE</code> parameter as a
      * <code>java.sql.Date</code> object.
      *
-     * @param parameterIndex the first parameter is 1, the second is 2,
-     *                       and so on
-     * @return the parameter value.  If the value is SQL <code>NULL</code>, the result
-     *         is <code>null</code>.
+     * @param parameterIndex the first parameter is 1, the second is 2, and so on
+     * @return the parameter value. If the value is SQL <code>NULL</code>, the
+     * result is <code>null</code>.
      * @throws java.sql.SQLException if a database access error occurs
      * @see #setDate
      */
@@ -295,10 +283,9 @@
      * Retrieves the value of the designated JDBC <code>TIME</code> parameter as a
      * <code>java.sql.Time</code> object.
      *
-     * @param parameterIndex the first parameter is 1, the second is 2,
-     *                       and so on
-     * @return the parameter value.  If the value is SQL <code>NULL</code>, the result
-     *         is <code>null</code>.
+     * @param parameterIndex the first parameter is 1, the second is 2, and so on
+     * @return the parameter value. If the value is SQL <code>NULL</code>, the
+     * result is <code>null</code>.
      * @throws java.sql.SQLException if a database access error occurs
      * @see #setTime
      */
@@ -307,13 +294,12 @@
     }
 
     /**
-     * Retrieves the value of the designated JDBC <code>TIMESTAMP</code> parameter as a
-     * <code>java.sql.Timestamp</code> object.
+     * Retrieves the value of the designated JDBC <code>TIMESTAMP</code> parameter
+     * as a <code>java.sql.Timestamp</code> object.
      *
-     * @param parameterIndex the first parameter is 1, the second is 2,
-     *                       and so on
-     * @return the parameter value.  If the value is SQL <code>NULL</code>, the result
-     *         is <code>null</code>.
+     * @param parameterIndex the first parameter is 1, the second is 2, and so on
+     * @return the parameter value. If the value is SQL <code>NULL</code>, the
+     * result is <code>null</code>.
      * @throws java.sql.SQLException if a database access error occurs
      * @see #setTimestamp
      */
@@ -322,18 +308,17 @@
     }
 
     /**
-     * Retrieves the value of the designated parameter as an <code>Object</code>
-     * in the Java programming language. If the value is an SQL <code>NULL</code>,
-     * the driver returns a Java <code>null</code>.
+     * Retrieves the value of the designated parameter as an <code>Object</code> in
+     * the Java programming language. If the value is an SQL <code>NULL</code>, the
+     * driver returns a Java <code>null</code>.
      * <p/>
-     * This method returns a Java object whose type corresponds to the JDBC
-     * type that was registered for this parameter using the method
-     * <code>registerOutParameter</code>.  By registering the target JDBC
-     * type as <code>java.sql.Types.OTHER</code>, this method can be used
-     * to read database-specific abstract data types.
+     * This method returns a Java object whose type corresponds to the JDBC type
+     * that was registered for this parameter using the method
+     * <code>registerOutParameter</code>. By registering the target JDBC type as
+     * <code>java.sql.Types.OTHER</code>, this method can be used to read
+     * database-specific abstract data types.
      *
-     * @param parameterIndex the first parameter is 1, the second is 2,
-     *                       and so on
+     * @param parameterIndex the first parameter is 1, the second is 2, and so on
      * @return A <code>java.lang.Object</code> holding the OUT parameter value
      * @throws java.sql.SQLException if a database access error occurs
      * @see java.sql.Types
@@ -344,14 +329,13 @@
     }
 
     /**
-     * Retrieves the value of the designated JDBC <code>NUMERIC</code> parameter as a
-     * <code>java.math.BigDecimal</code> object with as many digits to the
-     * right of the decimal point as the value contains.
+     * Retrieves the value of the designated JDBC <code>NUMERIC</code> parameter as
+     * a <code>java.math.BigDecimal</code> object with as many digits to the right
+     * of the decimal point as the value contains.
      *
-     * @param parameterIndex the first parameter is 1, the second is 2,
-     *                       and so on
-     * @return the parameter value in full precision.  If the value is
-     *         SQL <code>NULL</code>, the result is <code>null</code>.
+     * @param parameterIndex the first parameter is 1, the second is 2, and so on
+     * @return the parameter value in full precision. If the value is SQL
+     * <code>NULL</code>, the result is <code>null</code>.
      * @throws java.sql.SQLException if a database access error occurs
      * @see #setBigDecimal
      * @since 1.2
@@ -361,14 +345,14 @@
     }
 
     /**
-     * Retrieves the value of the designated JDBC <code>REF(&lt;structured-type&gt;)</code>
-     * parameter as a {@link java.sql.Ref} object in the Java programming language.
+     * Retrieves the value of the designated JDBC
+     * <code>REF(&lt;structured-type&gt;)</code> parameter as a {@link java.sql.Ref}
+     * object in the Java programming language.
      *
-     * @param i the first parameter is 1, the second is 2,
-     *          and so on
-     * @return the parameter value as a <code>Ref</code> object in the
-     *         Java programming language.  If the value was SQL <code>NULL</code>, the value
-     *         <code>null</code> is returned.
+     * @param i the first parameter is 1, the second is 2, and so on
+     * @return the parameter value as a <code>Ref</code> object in the Java
+     * programming language. If the value was SQL <code>NULL</code>, the value
+     * <code>null</code> is returned.
      * @throws java.sql.SQLException if a database access error occurs
      * @since 1.2
      */
@@ -381,9 +365,9 @@
      * {@link java.sql.Blob} object in the Java programming language.
      *
      * @param i the first parameter is 1, the second is 2, and so on
-     * @return the parameter value as a <code>Blob</code> object in the
-     *         Java programming language.  If the value was SQL <code>NULL</code>, the value
-     *         <code>null</code> is returned.
+     * @return the parameter value as a <code>Blob</code> object in the Java
+     * programming language. If the value was SQL <code>NULL</code>, the value
+     * <code>null</code> is returned.
      * @throws java.sql.SQLException if a database access error occurs
      * @since 1.2
      */
@@ -395,11 +379,10 @@
      * Retrieves the value of the designated JDBC <code>CLOB</code> parameter as a
      * <code>Clob</code> object in the Java programming language.
      *
-     * @param i the first parameter is 1, the second is 2, and
-     *          so on
-     * @return the parameter value as a <code>Clob</code> object in the
-     *         Java programming language.  If the value was SQL <code>NULL</code>, the
-     *         value <code>null</code> is returned.
+     * @param i the first parameter is 1, the second is 2, and so on
+     * @return the parameter value as a <code>Clob</code> object in the Java
+     * programming language. If the value was SQL <code>NULL</code>, the value
+     * <code>null</code> is returned.
      * @throws java.sql.SQLException if a database access error occurs
      * @since 1.2
      */
@@ -411,11 +394,10 @@
      * Retrieves the value of the designated JDBC <code>ARRAY</code> parameter as an
      * {@link java.sql.Array} object in the Java programming language.
      *
-     * @param i the first parameter is 1, the second is 2, and
-     *          so on
-     * @return the parameter value as an <code>Array</code> object in
-     *         the Java programming language.  If the value was SQL <code>NULL</code>, the
-     *         value <code>null</code> is returned.
+     * @param i the first parameter is 1, the second is 2, and so on
+     * @return the parameter value as an <code>Array</code> object in the Java
+     * programming language. If the value was SQL <code>NULL</code>, the value
+     * <code>null</code> is returned.
      * @throws java.sql.SQLException if a database access error occurs
      * @since 1.2
      */
@@ -425,20 +407,17 @@
 
     /**
      * Retrieves the value of the designated JDBC <code>DATE</code> parameter as a
-     * <code>java.sql.Date</code> object, using
-     * the given <code>Calendar</code> object
-     * to construct the date.
-     * With a <code>Calendar</code> object, the driver
-     * can calculate the date taking into account a custom timezone and locale.
-     * If no <code>Calendar</code> object is specified, the driver uses the
-     * default timezone and locale.
+     * <code>java.sql.Date</code> object, using the given <code>Calendar</code>
+     * object to construct the date. With a <code>Calendar</code> object, the driver
+     * can calculate the date taking into account a custom timezone and locale. If
+     * no <code>Calendar</code> object is specified, the driver uses the default
+     * timezone and locale.
      *
-     * @param parameterIndex the first parameter is 1, the second is 2,
-     *                       and so on
-     * @param cal            the <code>Calendar</code> object the driver will use
-     *                       to construct the date
-     * @return the parameter value.  If the value is SQL <code>NULL</code>, the result
-     *         is <code>null</code>.
+     * @param parameterIndex the first parameter is 1, the second is 2, and so on
+     * @param cal the <code>Calendar</code> object the driver will use to construct
+     * the date
+     * @return the parameter value. If the value is SQL <code>NULL</code>, the
+     * result is <code>null</code>.
      * @throws java.sql.SQLException if a database access error occurs
      * @see #setDate
      * @since 1.2
@@ -449,20 +428,17 @@
 
     /**
      * Retrieves the value of the designated JDBC <code>TIME</code> parameter as a
-     * <code>java.sql.Time</code> object, using
-     * the given <code>Calendar</code> object
-     * to construct the time.
-     * With a <code>Calendar</code> object, the driver
-     * can calculate the time taking into account a custom timezone and locale.
-     * If no <code>Calendar</code> object is specified, the driver uses the
-     * default timezone and locale.
+     * <code>java.sql.Time</code> object, using the given <code>Calendar</code>
+     * object to construct the time. With a <code>Calendar</code> object, the driver
+     * can calculate the time taking into account a custom timezone and locale. If
+     * no <code>Calendar</code> object is specified, the driver uses the default
+     * timezone and locale.
      *
-     * @param parameterIndex the first parameter is 1, the second is 2,
-     *                       and so on
-     * @param cal            the <code>Calendar</code> object the driver will use
-     *                       to construct the time
-     * @return the parameter value; if the value is SQL <code>NULL</code>, the result
-     *         is <code>null</code>.
+     * @param parameterIndex the first parameter is 1, the second is 2, and so on
+     * @param cal the <code>Calendar</code> object the driver will use to construct
+     * the time
+     * @return the parameter value; if the value is SQL <code>NULL</code>, the
+     * result is <code>null</code>.
      * @throws java.sql.SQLException if a database access error occurs
      * @see #setTime
      * @since 1.2
@@ -472,21 +448,18 @@
     }
 
     /**
-     * Retrieves the value of the designated JDBC <code>TIMESTAMP</code> parameter as a
-     * <code>java.sql.Timestamp</code> object, using
-     * the given <code>Calendar</code> object to construct
-     * the <code>Timestamp</code> object.
-     * With a <code>Calendar</code> object, the driver
-     * can calculate the timestamp taking into account a custom timezone and locale.
-     * If no <code>Calendar</code> object is specified, the driver uses the
-     * default timezone and locale.
+     * Retrieves the value of the designated JDBC <code>TIMESTAMP</code> parameter
+     * as a <code>java.sql.Timestamp</code> object, using the given
+     * <code>Calendar</code> object to construct the <code>Timestamp</code> object.
+     * With a <code>Calendar</code> object, the driver can calculate the timestamp
+     * taking into account a custom timezone and locale. If no <code>Calendar</code>
+     * object is specified, the driver uses the default timezone and locale.
      *
-     * @param parameterIndex the first parameter is 1, the second is 2,
-     *                       and so on
-     * @param cal            the <code>Calendar</code> object the driver will use
-     *                       to construct the timestamp
-     * @return the parameter value.  If the value is SQL <code>NULL</code>, the result
-     *         is <code>null</code>.
+     * @param parameterIndex the first parameter is 1, the second is 2, and so on
+     * @param cal the <code>Calendar</code> object the driver will use to construct
+     * the timestamp
+     * @return the parameter value. If the value is SQL <code>NULL</code>, the
+     * result is <code>null</code>.
      * @throws java.sql.SQLException if a database access error occurs
      * @see #setTimestamp
      * @since 1.2
@@ -496,35 +469,35 @@
     }
 
     /**
-     * Registers the designated output parameter.  This version of
-     * the method <code>registerOutParameter</code>
-     * should be used for a user-defined or <code>REF</code> output parameter.  Examples
-     * of user-defined types include: <code>STRUCT</code>, <code>DISTINCT</code>,
-     * <code>JAVA_OBJECT</code>, and named array types.
+     * Registers the designated output parameter. This version of the method
+     * <code>registerOutParameter</code> should be used for a user-defined or
+     * <code>REF</code> output parameter. Examples of user-defined types include:
+     * <code>STRUCT</code>, <code>DISTINCT</code>, <code>JAVA_OBJECT</code>, and
+     * named array types.
      * <p/>
-     * Before executing a stored procedure call, you must explicitly
-     * call <code>registerOutParameter</code> to register the type from
-     * <code>java.sql.Types</code> for each
-     * OUT parameter.  For a user-defined parameter, the fully-qualified SQL
-     * type name of the parameter should also be given, while a <code>REF</code>
-     * parameter requires that the fully-qualified type name of the
-     * referenced type be given.  A JDBC driver that does not need the
-     * type code and type name information may ignore it.   To be portable,
-     * however, applications should always provide these values for
-     * user-defined and <code>REF</code> parameters.
+     * Before executing a stored procedure call, you must explicitly call
+     * <code>registerOutParameter</code> to register the type from
+     * <code>java.sql.Types</code> for each OUT parameter. For a user-defined
+     * parameter, the fully-qualified SQL type name of the parameter should also be
+     * given, while a <code>REF</code> parameter requires that the fully-qualified
+     * type name of the referenced type be given. A JDBC driver that does not need
+     * the type code and type name information may ignore it. To be portable,
+     * however, applications should always provide these values for user-defined and
+     * <code>REF</code> parameters.
      * <p/>
      * Although it is intended for user-defined and <code>REF</code> parameters,
-     * this method may be used to register a parameter of any JDBC type.
-     * If the parameter does not have a user-defined or <code>REF</code> type, the
+     * this method may be used to register a parameter of any JDBC type. If the
+     * parameter does not have a user-defined or <code>REF</code> type, the
      * <i>typeName</i> parameter is ignored.
      * <p/>
-     * <P><B>Note:</B> When reading the value of an out parameter, you
-     * must use the getter method whose Java type corresponds to the
-     * parameter's registered SQL type.
+     * <P>
+     * <B>Note:</B> When reading the value of an out parameter, you must use the
+     * getter method whose Java type corresponds to the parameter's registered SQL
+     * type.
      *
      * @param paramIndex the first parameter is 1, the second is 2,...
-     * @param sqlType    a value from {@link java.sql.Types}
-     * @param typeName   the fully-qualified name of an SQL structured type
+     * @param sqlType a value from {@link java.sql.Types}
+     * @param typeName the fully-qualified name of an SQL structured type
      * @throws java.sql.SQLException if a database access error occurs
      * @see java.sql.Types
      * @since 1.2
@@ -534,26 +507,24 @@
     }
 
     /**
-     * Registers the OUT parameter named
-     * <code>parameterName</code> to the JDBC type
-     * <code>sqlType</code>.  All OUT parameters must be registered
-     * before a stored procedure is executed.
+     * Registers the OUT parameter named <code>parameterName</code> to the JDBC type
+     * <code>sqlType</code>. All OUT parameters must be registered before a stored
+     * procedure is executed.
      * <p/>
-     * The JDBC type specified by <code>sqlType</code> for an OUT
-     * parameter determines the Java type that must be used
-     * in the <code>get</code> method to read the value of that parameter.
+     * The JDBC type specified by <code>sqlType</code> for an OUT parameter
+     * determines the Java type that must be used in the <code>get</code> method to
+     * read the value of that parameter.
      * <p/>
-     * If the JDBC type expected to be returned to this output parameter
-     * is specific to this particular database, <code>sqlType</code>
-     * should be <code>java.sql.Types.OTHER</code>.  The method
-     * {@link #getObject} retrieves the value.
+     * If the JDBC type expected to be returned to this output parameter is specific
+     * to this particular database, <code>sqlType</code> should be
+     * <code>java.sql.Types.OTHER</code>. The method {@link #getObject} retrieves
+     * the value.
      *
      * @param parameterName the name of the parameter
-     * @param sqlType       the JDBC type code defined by <code>java.sql.Types</code>.
-     *                      If the parameter is of JDBC type <code>NUMERIC</code>
-     *                      or <code>DECIMAL</code>, the version of
-     *                      <code>registerOutParameter</code> that accepts a scale value
-     *                      should be used.
+     * @param sqlType the JDBC type code defined by <code>java.sql.Types</code>. If
+     * the parameter is of JDBC type <code>NUMERIC</code> or <code>DECIMAL</code>,
+     * the version of <code>registerOutParameter</code> that accepts a scale value
+     * should be used.
      * @throws java.sql.SQLException if a database access error occurs
      * @see java.sql.Types
      * @since 1.4
@@ -563,23 +534,21 @@
     }
 
     /**
-     * Registers the parameter named
-     * <code>parameterName</code> to be of JDBC type
-     * <code>sqlType</code>.  This method must be called
-     * before a stored procedure is executed.
+     * Registers the parameter named <code>parameterName</code> to be of JDBC type
+     * <code>sqlType</code>. This method must be called before a stored procedure is
+     * executed.
      * <p/>
-     * The JDBC type specified by <code>sqlType</code> for an OUT
-     * parameter determines the Java type that must be used
-     * in the <code>get</code> method to read the value of that parameter.
+     * The JDBC type specified by <code>sqlType</code> for an OUT parameter
+     * determines the Java type that must be used in the <code>get</code> method to
+     * read the value of that parameter.
      * <p/>
-     * This version of <code>registerOutParameter</code> should be
-     * used when the parameter is of JDBC type <code>NUMERIC</code>
-     * or <code>DECIMAL</code>.
+     * This version of <code>registerOutParameter</code> should be used when the
+     * parameter is of JDBC type <code>NUMERIC</code> or <code>DECIMAL</code>.
      *
      * @param parameterName the name of the parameter
-     * @param sqlType       SQL type code defined by <code>java.sql.Types</code>.
-     * @param scale         the desired number of digits to the right of the
-     *                      decimal point.  It must be greater than or equal to zero.
+     * @param sqlType SQL type code defined by <code>java.sql.Types</code>.
+     * @param scale the desired number of digits to the right of the decimal point.
+     * It must be greater than or equal to zero.
      * @throws java.sql.SQLException if a database access error occurs
      * @see java.sql.Types
      * @since 1.4
@@ -589,35 +558,33 @@
     }
 
     /**
-     * Registers the designated output parameter.  This version of
-     * the method <code>registerOutParameter</code>
-     * should be used for a user-named or REF output parameter.  Examples
-     * of user-named types include: STRUCT, DISTINCT, JAVA_OBJECT, and
-     * named array types.
+     * Registers the designated output parameter. This version of the method
+     * <code>registerOutParameter</code> should be used for a user-named or REF
+     * output parameter. Examples of user-named types include: STRUCT, DISTINCT,
+     * JAVA_OBJECT, and named array types.
      * <p/>
-     * Before executing a stored procedure call, you must explicitly
-     * call <code>registerOutParameter</code> to register the type from
-     * <code>java.sql.Types</code> for each
-     * OUT parameter.  For a user-named parameter the fully-qualified SQL
-     * type name of the parameter should also be given, while a REF
-     * parameter requires that the fully-qualified type name of the
-     * referenced type be given.  A JDBC driver that does not need the
-     * type code and type name information may ignore it.   To be portable,
-     * however, applications should always provide these values for
-     * user-named and REF parameters.
+     * Before executing a stored procedure call, you must explicitly call
+     * <code>registerOutParameter</code> to register the type from
+     * <code>java.sql.Types</code> for each OUT parameter. For a user-named
+     * parameter the fully-qualified SQL type name of the parameter should also be
+     * given, while a REF parameter requires that the fully-qualified type name of
+     * the referenced type be given. A JDBC driver that does not need the type code
+     * and type name information may ignore it. To be portable, however,
+     * applications should always provide these values for user-named and REF
+     * parameters.
      * <p/>
-     * Although it is intended for user-named and REF parameters,
-     * this method may be used to register a parameter of any JDBC type.
-     * If the parameter does not have a user-named or REF type, the
-     * typeName parameter is ignored.
+     * Although it is intended for user-named and REF parameters, this method may be
+     * used to register a parameter of any JDBC type. If the parameter does not have
+     * a user-named or REF type, the typeName parameter is ignored.
      * <p/>
-     * <P><B>Note:</B> When reading the value of an out parameter, you
-     * must use the <code>getXXX</code> method whose Java type XXX corresponds to the
-     * parameter's registered SQL type.
+     * <P>
+     * <B>Note:</B> When reading the value of an out parameter, you must use the
+     * <code>getXXX</code> method whose Java type XXX corresponds to the parameter's
+     * registered SQL type.
      *
      * @param parameterName the name of the parameter
-     * @param sqlType       a value from {@link java.sql.Types}
-     * @param typeName      the fully-qualified name of an SQL structured type
+     * @param sqlType a value from {@link java.sql.Types}
+     * @param typeName the fully-qualified name of an SQL structured type
      * @throws java.sql.SQLException if a database access error occurs
      * @see java.sql.Types
      * @since 1.4
@@ -627,16 +594,14 @@
     }
 
     /**
-     * Retrieves the value of the designated JDBC <code>DATALINK</code> parameter as a
-     * <code>java.net.URL</code> object.
+     * Retrieves the value of the designated JDBC <code>DATALINK</code> parameter as
+     * a <code>java.net.URL</code> object.
      *
      * @param parameterIndex the first parameter is 1, the second is 2,...
-     * @return a <code>java.net.URL</code> object that represents the
-     *         JDBC <code>DATALINK</code> value used as the designated
-     *         parameter
-     * @throws java.sql.SQLException if a database access error occurs,
-     *                               or if the URL being returned is
-     *                               not a valid URL on the Java platform
+     * @return a <code>java.net.URL</code> object that represents the JDBC
+     * <code>DATALINK</code> value used as the designated parameter
+     * @throws java.sql.SQLException if a database access error occurs, or if the
+     * URL being returned is not a valid URL on the Java platform
      * @see #setURL
      * @since 1.4
      */
@@ -646,13 +611,13 @@
 
     /**
      * Sets the designated parameter to the given <code>java.net.URL</code> object.
-     * The driver converts this to an SQL <code>DATALINK</code> value when
-     * it sends it to the database.
+     * The driver converts this to an SQL <code>DATALINK</code> value when it sends
+     * it to the database.
      *
      * @param parameterName the name of the parameter
-     * @param val           the parameter value
-     * @throws java.sql.SQLException if a database access error occurs,
-     *                               or if a URL is malformed
+     * @param val the parameter value
+     * @throws java.sql.SQLException if a database access error occurs, or if a URL
+     * is malformed
      * @see #getURL
      * @since 1.4
      */
@@ -663,10 +628,11 @@
     /**
      * Sets the designated parameter to SQL <code>NULL</code>.
      * <p/>
-     * <P><B>Note:</B> You must specify the parameter's SQL type.
+     * <P>
+     * <B>Note:</B> You must specify the parameter's SQL type.
      *
      * @param parameterName the name of the parameter
-     * @param sqlType       the SQL type code defined in <code>java.sql.Types</code>
+     * @param sqlType the SQL type code defined in <code>java.sql.Types</code>
      * @throws java.sql.SQLException if a database access error occurs
      * @since 1.4
      */
@@ -676,11 +642,11 @@
 
     /**
      * Sets the designated parameter to the given Java <code>boolean</code> value.
-     * The driver converts this
-     * to an SQL <code>BIT</code> value when it sends it to the database.
+     * The driver converts this to an SQL <code>BIT</code> value when it sends it to
+     * the database.
      *
      * @param parameterName the name of the parameter
-     * @param x             the parameter value
+     * @param x the parameter value
      * @throws java.sql.SQLException if a database access error occurs
      * @see #getBoolean
      * @since 1.4
@@ -690,12 +656,12 @@
     }
 
     /**
-     * Sets the designated parameter to the given Java <code>byte</code> value.
-     * The driver converts this
-     * to an SQL <code>TINYINT</code> value when it sends it to the database.
+     * Sets the designated parameter to the given Java <code>byte</code> value. The
+     * driver converts this to an SQL <code>TINYINT</code> value when it sends it to
+     * the database.
      *
      * @param parameterName the name of the parameter
-     * @param x             the parameter value
+     * @param x the parameter value
      * @throws java.sql.SQLException if a database access error occurs
      * @see #getByte
      * @since 1.4
@@ -705,12 +671,12 @@
     }
 
     /**
-     * Sets the designated parameter to the given Java <code>short</code> value.
-     * The driver converts this
-     * to an SQL <code>SMALLINT</code> value when it sends it to the database.
+     * Sets the designated parameter to the given Java <code>short</code> value. The
+     * driver converts this to an SQL <code>SMALLINT</code> value when it sends it
+     * to the database.
      *
      * @param parameterName the name of the parameter
-     * @param x             the parameter value
+     * @param x the parameter value
      * @throws java.sql.SQLException if a database access error occurs
      * @see #getShort
      * @since 1.4
@@ -720,12 +686,12 @@
     }
 
     /**
-     * Sets the designated parameter to the given Java <code>int</code> value.
-     * The driver converts this
-     * to an SQL <code>INTEGER</code> value when it sends it to the database.
+     * Sets the designated parameter to the given Java <code>int</code> value. The
+     * driver converts this to an SQL <code>INTEGER</code> value when it sends it to
+     * the database.
      *
      * @param parameterName the name of the parameter
-     * @param x             the parameter value
+     * @param x the parameter value
      * @throws java.sql.SQLException if a database access error occurs
      * @see #getInt
      * @since 1.4
@@ -735,12 +701,12 @@
     }
 
     /**
-     * Sets the designated parameter to the given Java <code>long</code> value.
-     * The driver converts this
-     * to an SQL <code>BIGINT</code> value when it sends it to the database.
+     * Sets the designated parameter to the given Java <code>long</code> value. The
+     * driver converts this to an SQL <code>BIGINT</code> value when it sends it to
+     * the database.
      *
      * @param parameterName the name of the parameter
-     * @param x             the parameter value
+     * @param x the parameter value
      * @throws java.sql.SQLException if a database access error occurs
      * @see #getLong
      * @since 1.4
@@ -750,12 +716,12 @@
     }
 
     /**
-     * Sets the designated parameter to the given Java <code>float</code> value.
-     * The driver converts this
-     * to an SQL <code>FLOAT</code> value when it sends it to the database.
+     * Sets the designated parameter to the given Java <code>float</code> value. The
+     * driver converts this to an SQL <code>FLOAT</code> value when it sends it to
+     * the database.
      *
      * @param parameterName the name of the parameter
-     * @param x             the parameter value
+     * @param x the parameter value
      * @throws java.sql.SQLException if a database access error occurs
      * @see #getFloat
      * @since 1.4
@@ -766,11 +732,11 @@
 
     /**
      * Sets the designated parameter to the given Java <code>double</code> value.
-     * The driver converts this
-     * to an SQL <code>DOUBLE</code> value when it sends it to the database.
+     * The driver converts this to an SQL <code>DOUBLE</code> value when it sends it
+     * to the database.
      *
      * @param parameterName the name of the parameter
-     * @param x             the parameter value
+     * @param x the parameter value
      * @throws java.sql.SQLException if a database access error occurs
      * @see #getDouble
      * @since 1.4
@@ -780,13 +746,12 @@
     }
 
     /**
-     * Sets the designated parameter to the given
-     * <code>java.math.BigDecimal</code> value.
-     * The driver converts this to an SQL <code>NUMERIC</code> value when
-     * it sends it to the database.
+     * Sets the designated parameter to the given <code>java.math.BigDecimal</code>
+     * value. The driver converts this to an SQL <code>NUMERIC</code> value when it
+     * sends it to the database.
      *
      * @param parameterName the name of the parameter
-     * @param x             the parameter value
+     * @param x the parameter value
      * @throws java.sql.SQLException if a database access error occurs
      * @see #getBigDecimal
      * @since 1.4
@@ -797,14 +762,13 @@
 
     /**
      * Sets the designated parameter to the given Java <code>String</code> value.
-     * The driver converts this
-     * to an SQL <code>VARCHAR</code> or <code>LONGVARCHAR</code> value
-     * (depending on the argument's
-     * size relative to the driver's limits on <code>VARCHAR</code> values)
-     * when it sends it to the database.
+     * The driver converts this to an SQL <code>VARCHAR</code> or
+     * <code>LONGVARCHAR</code> value (depending on the argument's size relative to
+     * the driver's limits on <code>VARCHAR</code> values) when it sends it to the
+     * database.
      *
      * @param parameterName the name of the parameter
-     * @param x             the parameter value
+     * @param x the parameter value
      * @throws java.sql.SQLException if a database access error occurs
      * @see #getString
      * @since 1.4
@@ -814,14 +778,13 @@
     }
 
     /**
-     * Sets the designated parameter to the given Java array of bytes.
-     * The driver converts this to an SQL <code>VARBINARY</code> or
-     * <code>LONGVARBINARY</code> (depending on the argument's size relative
-     * to the driver's limits on <code>VARBINARY</code> values) when it sends
-     * it to the database.
+     * Sets the designated parameter to the given Java array of bytes. The driver
+     * converts this to an SQL <code>VARBINARY</code> or <code>LONGVARBINARY</code>
+     * (depending on the argument's size relative to the driver's limits on
+     * <code>VARBINARY</code> values) when it sends it to the database.
      *
      * @param parameterName the name of the parameter
-     * @param x             the parameter value
+     * @param x the parameter value
      * @throws java.sql.SQLException if a database access error occurs
      * @see #getBytes
      * @since 1.4
@@ -832,11 +795,11 @@
 
     /**
      * Sets the designated parameter to the given <code>java.sql.Date</code> value.
-     * The driver converts this
-     * to an SQL <code>DATE</code> value when it sends it to the database.
+     * The driver converts this to an SQL <code>DATE</code> value when it sends it
+     * to the database.
      *
      * @param parameterName the name of the parameter
-     * @param x             the parameter value
+     * @param x the parameter value
      * @throws java.sql.SQLException if a database access error occurs
      * @see #getDate
      * @since 1.4
@@ -847,11 +810,11 @@
 
     /**
      * Sets the designated parameter to the given <code>java.sql.Time</code> value.
-     * The driver converts this
-     * to an SQL <code>TIME</code> value when it sends it to the database.
+     * The driver converts this to an SQL <code>TIME</code> value when it sends it
+     * to the database.
      *
      * @param parameterName the name of the parameter
-     * @param x             the parameter value
+     * @param x the parameter value
      * @throws java.sql.SQLException if a database access error occurs
      * @see #getTime
      * @since 1.4
@@ -861,13 +824,12 @@
     }
 
     /**
-     * Sets the designated parameter to the given <code>java.sql.Timestamp</code> value.
-     * The driver
-     * converts this to an SQL <code>TIMESTAMP</code> value when it sends it to the
-     * database.
+     * Sets the designated parameter to the given <code>java.sql.Timestamp</code>
+     * value. The driver converts this to an SQL <code>TIMESTAMP</code> value when
+     * it sends it to the database.
      *
      * @param parameterName the name of the parameter
-     * @param x             the parameter value
+     * @param x the parameter value
      * @throws java.sql.SQLException if a database access error occurs
      * @see #getTimestamp
      * @since 1.4
@@ -877,21 +839,20 @@
     }
 
     /**
-     * Sets the designated parameter to the given input stream, which will have
-     * the specified number of bytes.
-     * When a very large ASCII value is input to a <code>LONGVARCHAR</code>
-     * parameter, it may be more practical to send it via a
-     * <code>java.io.InputStream</code>. Data will be read from the stream
-     * as needed until end-of-file is reached.  The JDBC driver will
-     * do any necessary conversion from ASCII to the database char format.
+     * Sets the designated parameter to the given input stream, which will have the
+     * specified number of bytes. When a very large ASCII value is input to a
+     * <code>LONGVARCHAR</code> parameter, it may be more practical to send it via a
+     * <code>java.io.InputStream</code>. Data will be read from the stream as needed
+     * until end-of-file is reached. The JDBC driver will do any necessary
+     * conversion from ASCII to the database char format.
      * <p/>
-     * <P><B>Note:</B> This stream object can either be a standard
-     * Java stream object or your own subclass that implements the
-     * standard interface.
+     * <P>
+     * <B>Note:</B> This stream object can either be a standard Java stream object
+     * or your own subclass that implements the standard interface.
      *
      * @param parameterName the name of the parameter
-     * @param x             the Java input stream that contains the ASCII parameter value
-     * @param length        the number of bytes in the stream
+     * @param x the Java input stream that contains the ASCII parameter value
+     * @param length the number of bytes in the stream
      * @throws java.sql.SQLException if a database access error occurs
      * @since 1.4
      */
@@ -900,20 +861,19 @@
     }
 
     /**
-     * Sets the designated parameter to the given input stream, which will have
-     * the specified number of bytes.
-     * When a very large binary value is input to a <code>LONGVARBINARY</code>
-     * parameter, it may be more practical to send it via a
-     * <code>java.io.InputStream</code> object. The data will be read from the stream
-     * as needed until end-of-file is reached.
+     * Sets the designated parameter to the given input stream, which will have the
+     * specified number of bytes. When a very large binary value is input to a
+     * <code>LONGVARBINARY</code> parameter, it may be more practical to send it via
+     * a <code>java.io.InputStream</code> object. The data will be read from the
+     * stream as needed until end-of-file is reached.
      * <p/>
-     * <P><B>Note:</B> This stream object can either be a standard
-     * Java stream object or your own subclass that implements the
-     * standard interface.
+     * <P>
+     * <B>Note:</B> This stream object can either be a standard Java stream object
+     * or your own subclass that implements the standard interface.
      *
      * @param parameterName the name of the parameter
-     * @param x             the java input stream which contains the binary parameter value
-     * @param length        the number of bytes in the stream
+     * @param x the java input stream which contains the binary parameter value
+     * @param length the number of bytes in the stream
      * @throws java.sql.SQLException if a database access error occurs
      * @since 1.4
      */
@@ -926,28 +886,28 @@
      * argument must be an object type; for integral values, the
      * <code>java.lang</code> equivalent objects should be used.
      * <p/>
-     * <p>The given Java object will be converted to the given targetSqlType
-     * before being sent to the database.
+     * <p>
+     * The given Java object will be converted to the given targetSqlType before
+     * being sent to the database.
      * <p/>
-     * If the object has a custom mapping (is of a class implementing the
-     * interface <code>SQLData</code>),
-     * the JDBC driver should call the method <code>SQLData.writeSQL</code> to write it
-     * to the SQL data stream.
-     * If, on the other hand, the object is of a class implementing
-     * <code>Ref</code>, <code>Blob</code>, <code>Clob</code>, <code>Struct</code>,
-     * or <code>Array</code>, the driver should pass it to the database as a
-     * value of the corresponding SQL type.
+     * If the object has a custom mapping (is of a class implementing the interface
+     * <code>SQLData</code>), the JDBC driver should call the method
+     * <code>SQLData.writeSQL</code> to write it to the SQL data stream. If, on the
+     * other hand, the object is of a class implementing <code>Ref</code>,
+     * <code>Blob</code>, <code>Clob</code>, <code>Struct</code>, or
+     * <code>Array</code>, the driver should pass it to the database as a value of
+     * the corresponding SQL type.
      * <p/>
-     * Note that this method may be used to pass datatabase-
-     * specific abstract data types.
+     * Note that this method may be used to pass datatabase- specific abstract data
+     * types.
      *
      * @param parameterName the name of the parameter
-     * @param x             the object containing the input parameter value
-     * @param targetSqlType the SQL type (as defined in java.sql.Types) to be
-     *                      sent to the database. The scale argument may further qualify this type.
-     * @param scale         for java.sql.Types.DECIMAL or java.sql.Types.NUMERIC types,
-     *                      this is the number of digits after the decimal point.  For all other
-     *                      types, this value will be ignored.
+     * @param x the object containing the input parameter value
+     * @param targetSqlType the SQL type (as defined in java.sql.Types) to be sent
+     * to the database. The scale argument may further qualify this type.
+     * @param scale for java.sql.Types.DECIMAL or java.sql.Types.NUMERIC types, this
+     * is the number of digits after the decimal point. For all other types, this
+     * value will be ignored.
      * @throws java.sql.SQLException if a database access error occurs
      * @see java.sql.Types
      * @see #getObject
@@ -958,14 +918,14 @@
     }
 
     /**
-     * Sets the value of the designated parameter with the given object.
-     * This method is like the method <code>setObject</code>
-     * above, except that it assumes a scale of zero.
+     * Sets the value of the designated parameter with the given object. This method
+     * is like the method <code>setObject</code> above, except that it assumes a
+     * scale of zero.
      *
      * @param parameterName the name of the parameter
-     * @param x             the object containing the input parameter value
-     * @param targetSqlType the SQL type (as defined in java.sql.Types) to be
-     *                      sent to the database
+     * @param x the object containing the input parameter value
+     * @param targetSqlType the SQL type (as defined in java.sql.Types) to be sent
+     * to the database
      * @throws java.sql.SQLException if a database access error occurs
      * @see #getObject
      * @since 1.4
@@ -975,34 +935,34 @@
     }
 
     /**
-     * Sets the value of the designated parameter with the given object.
-     * The second parameter must be of type <code>Object</code>; therefore, the
+     * Sets the value of the designated parameter with the given object. The second
+     * parameter must be of type <code>Object</code>; therefore, the
      * <code>java.lang</code> equivalent objects should be used for built-in types.
      * <p/>
-     * <p>The JDBC specification specifies a standard mapping from
-     * Java <code>Object</code> types to SQL types.  The given argument
-     * will be converted to the corresponding SQL type before being
-     * sent to the database.
+     * <p>
+     * The JDBC specification specifies a standard mapping from Java
+     * <code>Object</code> types to SQL types. The given argument will be converted
+     * to the corresponding SQL type before being sent to the database.
      * <p/>
-     * <p>Note that this method may be used to pass datatabase-
-     * specific abstract data types, by using a driver-specific Java
-     * type.
+     * <p>
+     * Note that this method may be used to pass datatabase- specific abstract data
+     * types, by using a driver-specific Java type.
      * <p/>
      * If the object is of a class implementing the interface <code>SQLData</code>,
-     * the JDBC driver should call the method <code>SQLData.writeSQL</code>
-     * to write it to the SQL data stream.
-     * If, on the other hand, the object is of a class implementing
-     * <code>Ref</code>, <code>Blob</code>, <code>Clob</code>, <code>Struct</code>,
-     * or <code>Array</code>, the driver should pass it to the database as a
-     * value of the corresponding SQL type.
+     * the JDBC driver should call the method <code>SQLData.writeSQL</code> to write
+     * it to the SQL data stream. If, on the other hand, the object is of a class
+     * implementing <code>Ref</code>, <code>Blob</code>, <code>Clob</code>,
+     * <code>Struct</code>, or <code>Array</code>, the driver should pass it to the
+     * database as a value of the corresponding SQL type.
      * <p/>
      * This method throws an exception if there is an ambiguity, for example, if the
-     * object is of a class implementing more than one of the interfaces named above.
+     * object is of a class implementing more than one of the interfaces named
+     * above.
      *
      * @param parameterName the name of the parameter
-     * @param x             the object containing the input parameter value
-     * @throws java.sql.SQLException if a database access error occurs or if the given
-     *                               <code>Object</code> parameter is ambiguous
+     * @param x the object containing the input parameter value
+     * @throws java.sql.SQLException if a database access error occurs or if the
+     * given <code>Object</code> parameter is ambiguous
      * @see #getObject
      * @since 1.4
      */
@@ -1011,22 +971,21 @@
     }
 
     /**
-     * Sets the designated parameter to the given <code>Reader</code>
-     * object, which is the given number of characters long.
-     * When a very large UNICODE value is input to a <code>LONGVARCHAR</code>
-     * parameter, it may be more practical to send it via a
-     * <code>java.io.Reader</code> object. The data will be read from the stream
-     * as needed until end-of-file is reached.  The JDBC driver will
-     * do any necessary conversion from UNICODE to the database char format.
+     * Sets the designated parameter to the given <code>Reader</code> object, which
+     * is the given number of characters long. When a very large UNICODE value is
+     * input to a <code>LONGVARCHAR</code> parameter, it may be more practical to
+     * send it via a <code>java.io.Reader</code> object. The data will be read from
+     * the stream as needed until end-of-file is reached. The JDBC driver will do
+     * any necessary conversion from UNICODE to the database char format.
      * <p/>
-     * <P><B>Note:</B> This stream object can either be a standard
-     * Java stream object or your own subclass that implements the
-     * standard interface.
+     * <P>
+     * <B>Note:</B> This stream object can either be a standard Java stream object
+     * or your own subclass that implements the standard interface.
      *
      * @param parameterName the name of the parameter
-     * @param reader        the <code>java.io.Reader</code> object that
-     *                      contains the UNICODE data used as the designated parameter
-     * @param length        the number of characters in the stream
+     * @param reader the <code>java.io.Reader</code> object that contains the
+     * UNICODE data used as the designated parameter
+     * @param length the number of characters in the stream
      * @throws java.sql.SQLException if a database access error occurs
      * @since 1.4
      */
@@ -1036,18 +995,18 @@
 
     /**
      * Sets the designated parameter to the given <code>java.sql.Date</code> value,
-     * using the given <code>Calendar</code> object.  The driver uses
-     * the <code>Calendar</code> object to construct an SQL <code>DATE</code> value,
-     * which the driver then sends to the database.  With a
-     * a <code>Calendar</code> object, the driver can calculate the date
-     * taking into account a custom timezone.  If no
-     * <code>Calendar</code> object is specified, the driver uses the default
-     * timezone, which is that of the virtual machine running the application.
+     * using the given <code>Calendar</code> object. The driver uses the
+     * <code>Calendar</code> object to construct an SQL <code>DATE</code> value,
+     * which the driver then sends to the database. With a a <code>Calendar</code>
+     * object, the driver can calculate the date taking into account a custom
+     * timezone. If no <code>Calendar</code> object is specified, the driver uses
+     * the default timezone, which is that of the virtual machine running the
+     * application.
      *
      * @param parameterName the name of the parameter
-     * @param x             the parameter value
-     * @param cal           the <code>Calendar</code> object the driver will use
-     *                      to construct the date
+     * @param x the parameter value
+     * @param cal the <code>Calendar</code> object the driver will use to construct
+     * the date
      * @throws java.sql.SQLException if a database access error occurs
      * @see #getDate
      * @since 1.4
@@ -1058,18 +1017,18 @@
 
     /**
      * Sets the designated parameter to the given <code>java.sql.Time</code> value,
-     * using the given <code>Calendar</code> object.  The driver uses
-     * the <code>Calendar</code> object to construct an SQL <code>TIME</code> value,
-     * which the driver then sends to the database.  With a
-     * a <code>Calendar</code> object, the driver can calculate the time
-     * taking into account a custom timezone.  If no
-     * <code>Calendar</code> object is specified, the driver uses the default
-     * timezone, which is that of the virtual machine running the application.
+     * using the given <code>Calendar</code> object. The driver uses the
+     * <code>Calendar</code> object to construct an SQL <code>TIME</code> value,
+     * which the driver then sends to the database. With a a <code>Calendar</code>
+     * object, the driver can calculate the time taking into account a custom
+     * timezone. If no <code>Calendar</code> object is specified, the driver uses
+     * the default timezone, which is that of the virtual machine running the
+     * application.
      *
      * @param parameterName the name of the parameter
-     * @param x             the parameter value
-     * @param cal           the <code>Calendar</code> object the driver will use
-     *                      to construct the time
+     * @param x the parameter value
+     * @param cal the <code>Calendar</code> object the driver will use to construct
+     * the time
      * @throws java.sql.SQLException if a database access error occurs
      * @see #getTime
      * @since 1.4
@@ -1079,19 +1038,19 @@
     }
 
     /**
-     * Sets the designated parameter to the given <code>java.sql.Timestamp</code> value,
-     * using the given <code>Calendar</code> object.  The driver uses
-     * the <code>Calendar</code> object to construct an SQL <code>TIMESTAMP</code> value,
-     * which the driver then sends to the database.  With a
-     * a <code>Calendar</code> object, the driver can calculate the timestamp
-     * taking into account a custom timezone.  If no
-     * <code>Calendar</code> object is specified, the driver uses the default
-     * timezone, which is that of the virtual machine running the application.
+     * Sets the designated parameter to the given <code>java.sql.Timestamp</code>
+     * value, using the given <code>Calendar</code> object. The driver uses the
+     * <code>Calendar</code> object to construct an SQL <code>TIMESTAMP</code>
+     * value, which the driver then sends to the database. With a a
+     * <code>Calendar</code> object, the driver can calculate the timestamp taking
+     * into account a custom timezone. If no <code>Calendar</code> object is
+     * specified, the driver uses the default timezone, which is that of the virtual
+     * machine running the application.
      *
      * @param parameterName the name of the parameter
-     * @param x             the parameter value
-     * @param cal           the <code>Calendar</code> object the driver will use
-     *                      to construct the timestamp
+     * @param x the parameter value
+     * @param cal the <code>Calendar</code> object the driver will use to construct
+     * the timestamp
      * @throws java.sql.SQLException if a database access error occurs
      * @see #getTimestamp
      * @since 1.4
@@ -1101,30 +1060,27 @@
     }
 
     /**
-     * Sets the designated parameter to SQL <code>NULL</code>.
-     * This version of the method <code>setNull</code> should
-     * be used for user-defined types and REF type parameters.  Examples
-     * of user-defined types include: STRUCT, DISTINCT, JAVA_OBJECT, and
-     * named array types.
+     * Sets the designated parameter to SQL <code>NULL</code>. This version of the
+     * method <code>setNull</code> should be used for user-defined types and REF
+     * type parameters. Examples of user-defined types include: STRUCT, DISTINCT,
+     * JAVA_OBJECT, and named array types.
      * <p/>
-     * <P><B>Note:</B> To be portable, applications must give the
-     * SQL type code and the fully-qualified SQL type name when specifying
-     * a NULL user-defined or REF parameter.  In the case of a user-defined type
-     * the name is the type name of the parameter itself.  For a REF
-     * parameter, the name is the type name of the referenced type.  If
-     * a JDBC driver does not need the type code or type name information,
-     * it may ignore it.
+     * <P>
+     * <B>Note:</B> To be portable, applications must give the SQL type code and the
+     * fully-qualified SQL type name when specifying a NULL user-defined or REF
+     * parameter. In the case of a user-defined type the name is the type name of
+     * the parameter itself. For a REF parameter, the name is the type name of the
+     * referenced type. If a JDBC driver does not need the type code or type name
+     * information, it may ignore it.
      * <p/>
-     * Although it is intended for user-defined and Ref parameters,
-     * this method may be used to set a null parameter of any JDBC type.
-     * If the parameter does not have a user-defined or REF type, the given
-     * typeName is ignored.
+     * Although it is intended for user-defined and Ref parameters, this method may
+     * be used to set a null parameter of any JDBC type. If the parameter does not
+     * have a user-defined or REF type, the given typeName is ignored.
      *
      * @param parameterName the name of the parameter
-     * @param sqlType       a value from <code>java.sql.Types</code>
-     * @param typeName      the fully-qualified name of an SQL user-defined type;
-     *                      ignored if the parameter is not a user-defined type or
-     *                      SQL <code>REF</code> value
+     * @param sqlType a value from <code>java.sql.Types</code>
+     * @param typeName the fully-qualified name of an SQL user-defined type; ignored
+     * if the parameter is not a user-defined type or SQL <code>REF</code> value
      * @throws java.sql.SQLException if a database access error occurs
      * @since 1.4
      */
@@ -1133,19 +1089,17 @@
     }
 
     /**
-     * Retrieves the value of a JDBC <code>CHAR</code>, <code>VARCHAR</code>,
-     * or <code>LONGVARCHAR</code> parameter as a <code>String</code> in
-     * the Java programming language.
+     * Retrieves the value of a JDBC <code>CHAR</code>, <code>VARCHAR</code>, or
+     * <code>LONGVARCHAR</code> parameter as a <code>String</code> in the Java
+     * programming language.
      * <p/>
-     * For the fixed-length type JDBC <code>CHAR</code>,
-     * the <code>String</code> object
-     * returned has exactly the same value the JDBC
-     * <code>CHAR</code> value had in the
-     * database, including any padding added by the database.
+     * For the fixed-length type JDBC <code>CHAR</code>, the <code>String</code>
+     * object returned has exactly the same value the JDBC <code>CHAR</code> value
+     * had in the database, including any padding added by the database.
      *
      * @param parameterName the name of the parameter
-     * @return the parameter value. If the value is SQL <code>NULL</code>, the result
-     *         is <code>null</code>.
+     * @return the parameter value. If the value is SQL <code>NULL</code>, the
+     * result is <code>null</code>.
      * @throws java.sql.SQLException if a database access error occurs
      * @see #setString
      * @since 1.4
@@ -1159,8 +1113,8 @@
      * <code>boolean</code> in the Java programming language.
      *
      * @param parameterName the name of the parameter
-     * @return the parameter value.  If the value is SQL <code>NULL</code>, the result
-     *         is <code>false</code>.
+     * @return the parameter value. If the value is SQL <code>NULL</code>, the
+     * result is <code>false</code>.
      * @throws java.sql.SQLException if a database access error occurs
      * @see #setBoolean
      * @since 1.4
@@ -1170,12 +1124,12 @@
     }
 
     /**
-     * Retrieves the value of a JDBC <code>TINYINT</code> parameter as a <code>byte</code>
-     * in the Java programming language.
+     * Retrieves the value of a JDBC <code>TINYINT</code> parameter as a
+     * <code>byte</code> in the Java programming language.
      *
      * @param parameterName the name of the parameter
-     * @return the parameter value.  If the value is SQL <code>NULL</code>, the result
-     *         is <code>0</code>.
+     * @return the parameter value. If the value is SQL <code>NULL</code>, the
+     * result is <code>0</code>.
      * @throws java.sql.SQLException if a database access error occurs
      * @see #setByte
      * @since 1.4
@@ -1185,12 +1139,12 @@
     }
 
     /**
-     * Retrieves the value of a JDBC <code>SMALLINT</code> parameter as a <code>short</code>
-     * in the Java programming language.
+     * Retrieves the value of a JDBC <code>SMALLINT</code> parameter as a
+     * <code>short</code> in the Java programming language.
      *
      * @param parameterName the name of the parameter
-     * @return the parameter value.  If the value is SQL <code>NULL</code>, the result
-     *         is <code>0</code>.
+     * @return the parameter value. If the value is SQL <code>NULL</code>, the
+     * result is <code>0</code>.
      * @throws java.sql.SQLException if a database access error occurs
      * @see #setShort
      * @since 1.4
@@ -1200,12 +1154,12 @@
     }
 
     /**
-     * Retrieves the value of a JDBC <code>INTEGER</code> parameter as an <code>int</code>
-     * in the Java programming language.
+     * Retrieves the value of a JDBC <code>INTEGER</code> parameter as an
+     * <code>int</code> in the Java programming language.
      *
      * @param parameterName the name of the parameter
-     * @return the parameter value.  If the value is SQL <code>NULL</code>,
-     *         the result is <code>0</code>.
+     * @return the parameter value. If the value is SQL <code>NULL</code>, the
+     * result is <code>0</code>.
      * @throws java.sql.SQLException if a database access error occurs
      * @see #setInt
      * @since 1.4
@@ -1215,12 +1169,12 @@
     }
 
     /**
-     * Retrieves the value of a JDBC <code>BIGINT</code> parameter as a <code>long</code>
-     * in the Java programming language.
+     * Retrieves the value of a JDBC <code>BIGINT</code> parameter as a
+     * <code>long</code> in the Java programming language.
      *
      * @param parameterName the name of the parameter
-     * @return the parameter value.  If the value is SQL <code>NULL</code>,
-     *         the result is <code>0</code>.
+     * @return the parameter value. If the value is SQL <code>NULL</code>, the
+     * result is <code>0</code>.
      * @throws java.sql.SQLException if a database access error occurs
      * @see #setLong
      * @since 1.4
@@ -1230,12 +1184,12 @@
     }
 
     /**
-     * Retrieves the value of a JDBC <code>FLOAT</code> parameter as a <code>float</code>
-     * in the Java programming language.
+     * Retrieves the value of a JDBC <code>FLOAT</code> parameter as a
+     * <code>float</code> in the Java programming language.
      *
      * @param parameterName the name of the parameter
-     * @return the parameter value.  If the value is SQL <code>NULL</code>,
-     *         the result is <code>0</code>.
+     * @return the parameter value. If the value is SQL <code>NULL</code>, the
+     * result is <code>0</code>.
      * @throws java.sql.SQLException if a database access error occurs
      * @see #setFloat
      * @since 1.4
@@ -1245,12 +1199,12 @@
     }
 
     /**
-     * Retrieves the value of a JDBC <code>DOUBLE</code> parameter as a <code>double</code>
-     * in the Java programming language.
+     * Retrieves the value of a JDBC <code>DOUBLE</code> parameter as a
+     * <code>double</code> in the Java programming language.
      *
      * @param parameterName the name of the parameter
-     * @return the parameter value.  If the value is SQL <code>NULL</code>,
-     *         the result is <code>0</code>.
+     * @return the parameter value. If the value is SQL <code>NULL</code>, the
+     * result is <code>0</code>.
      * @throws java.sql.SQLException if a database access error occurs
      * @see #setDouble
      * @since 1.4
@@ -1261,12 +1215,12 @@
 
     /**
      * Retrieves the value of a JDBC <code>BINARY</code> or <code>VARBINARY</code>
-     * parameter as an array of <code>byte</code> values in the Java
-     * programming language.
+     * parameter as an array of <code>byte</code> values in the Java programming
+     * language.
      *
      * @param parameterName the name of the parameter
-     * @return the parameter value.  If the value is SQL <code>NULL</code>, the result is
-     *         <code>null</code>.
+     * @return the parameter value. If the value is SQL <code>NULL</code>, the
+     * result is <code>null</code>.
      * @throws java.sql.SQLException if a database access error occurs
      * @see #setBytes
      * @since 1.4
@@ -1280,8 +1234,8 @@
      * <code>java.sql.Date</code> object.
      *
      * @param parameterName the name of the parameter
-     * @return the parameter value.  If the value is SQL <code>NULL</code>, the result
-     *         is <code>null</code>.
+     * @return the parameter value. If the value is SQL <code>NULL</code>, the
+     * result is <code>null</code>.
      * @throws java.sql.SQLException if a database access error occurs
      * @see #setDate
      * @since 1.4
@@ -1295,8 +1249,8 @@
      * <code>java.sql.Time</code> object.
      *
      * @param parameterName the name of the parameter
-     * @return the parameter value.  If the value is SQL <code>NULL</code>, the result
-     *         is <code>null</code>.
+     * @return the parameter value. If the value is SQL <code>NULL</code>, the
+     * result is <code>null</code>.
      * @throws java.sql.SQLException if a database access error occurs
      * @see #setTime
      * @since 1.4
@@ -1310,8 +1264,8 @@
      * <code>java.sql.Timestamp</code> object.
      *
      * @param parameterName the name of the parameter
-     * @return the parameter value.  If the value is SQL <code>NULL</code>, the result
-     *         is <code>null</code>.
+     * @return the parameter value. If the value is SQL <code>NULL</code>, the
+     * result is <code>null</code>.
      * @throws java.sql.SQLException if a database access error occurs
      * @see #setTimestamp
      * @since 1.4
@@ -1322,14 +1276,14 @@
 
     /**
      * Retrieves the value of a parameter as an <code>Object</code> in the Java
-     * programming language. If the value is an SQL <code>NULL</code>, the
-     * driver returns a Java <code>null</code>.
+     * programming language. If the value is an SQL <code>NULL</code>, the driver
+     * returns a Java <code>null</code>.
      * <p/>
-     * This method returns a Java object whose type corresponds to the JDBC
-     * type that was registered for this parameter using the method
-     * <code>registerOutParameter</code>.  By registering the target JDBC
-     * type as <code>java.sql.Types.OTHER</code>, this method can be used
-     * to read database-specific abstract data types.
+     * This method returns a Java object whose type corresponds to the JDBC type
+     * that was registered for this parameter using the method
+     * <code>registerOutParameter</code>. By registering the target JDBC type as
+     * <code>java.sql.Types.OTHER</code>, this method can be used to read
+     * database-specific abstract data types.
      *
      * @param parameterName the name of the parameter
      * @return A <code>java.lang.Object</code> holding the OUT parameter value.
@@ -1344,12 +1298,12 @@
 
     /**
      * Retrieves the value of a JDBC <code>NUMERIC</code> parameter as a
-     * <code>java.math.BigDecimal</code> object with as many digits to the
-     * right of the decimal point as the value contains.
+     * <code>java.math.BigDecimal</code> object with as many digits to the right of
+     * the decimal point as the value contains.
      *
      * @param parameterName the name of the parameter
-     * @return the parameter value in full precision.  If the value is
-     *         SQL <code>NULL</code>, the result is <code>null</code>.
+     * @return the parameter value in full precision. If the value is SQL
+     * <code>NULL</code>, the result is <code>null</code>.
      * @throws java.sql.SQLException if a database access error occurs
      * @see #setBigDecimal
      * @since 1.4
@@ -1363,9 +1317,9 @@
      * parameter as a {@link java.sql.Ref} object in the Java programming language.
      *
      * @param parameterName the name of the parameter
-     * @return the parameter value as a <code>Ref</code> object in the
-     *         Java programming language.  If the value was SQL <code>NULL</code>,
-     *         the value <code>null</code> is returned.
+     * @return the parameter value as a <code>Ref</code> object in the Java
+     * programming language. If the value was SQL <code>NULL</code>, the value
+     * <code>null</code> is returned.
      * @throws java.sql.SQLException if a database access error occurs
      * @since 1.4
      */
@@ -1378,9 +1332,9 @@
      * {@link java.sql.Blob} object in the Java programming language.
      *
      * @param parameterName the name of the parameter
-     * @return the parameter value as a <code>Blob</code> object in the
-     *         Java programming language.  If the value was SQL <code>NULL</code>,
-     *         the value <code>null</code> is returned.
+     * @return the parameter value as a <code>Blob</code> object in the Java
+     * programming language. If the value was SQL <code>NULL</code>, the value
+     * <code>null</code> is returned.
      * @throws java.sql.SQLException if a database access error occurs
      * @since 1.4
      */
@@ -1393,9 +1347,9 @@
      * <code>Clob</code> object in the Java programming language.
      *
      * @param parameterName the name of the parameter
-     * @return the parameter value as a <code>Clob</code> object in the
-     *         Java programming language.  If the value was SQL <code>NULL</code>,
-     *         the value <code>null</code> is returned.
+     * @return the parameter value as a <code>Clob</code> object in the Java
+     * programming language. If the value was SQL <code>NULL</code>, the value
+     * <code>null</code> is returned.
      * @throws java.sql.SQLException if a database access error occurs
      * @since 1.4
      */
@@ -1408,9 +1362,9 @@
      * {@link java.sql.Array} object in the Java programming language.
      *
      * @param parameterName the name of the parameter
-     * @return the parameter value as an <code>Array</code> object in
-     *         Java programming language.  If the value was SQL <code>NULL</code>,
-     *         the value <code>null</code> is returned.
+     * @return the parameter value as an <code>Array</code> object in Java
+     * programming language. If the value was SQL <code>NULL</code>, the value
+     * <code>null</code> is returned.
      * @throws java.sql.SQLException if a database access error occurs
      * @since 1.4
      */
@@ -1420,19 +1374,17 @@
 
     /**
      * Retrieves the value of a JDBC <code>DATE</code> parameter as a
-     * <code>java.sql.Date</code> object, using
-     * the given <code>Calendar</code> object
-     * to construct the date.
-     * With a <code>Calendar</code> object, the driver
-     * can calculate the date taking into account a custom timezone and locale.
-     * If no <code>Calendar</code> object is specified, the driver uses the
-     * default timezone and locale.
+     * <code>java.sql.Date</code> object, using the given <code>Calendar</code>
+     * object to construct the date. With a <code>Calendar</code> object, the driver
+     * can calculate the date taking into account a custom timezone and locale. If
+     * no <code>Calendar</code> object is specified, the driver uses the default
+     * timezone and locale.
      *
      * @param parameterName the name of the parameter
-     * @param cal           the <code>Calendar</code> object the driver will use
-     *                      to construct the date
-     * @return the parameter value.  If the value is SQL <code>NULL</code>,
-     *         the result is <code>null</code>.
+     * @param cal the <code>Calendar</code> object the driver will use to construct
+     * the date
+     * @return the parameter value. If the value is SQL <code>NULL</code>, the
+     * result is <code>null</code>.
      * @throws java.sql.SQLException if a database access error occurs
      * @see #setDate
      * @since 1.4
@@ -1443,19 +1395,17 @@
 
     /**
      * Retrieves the value of a JDBC <code>TIME</code> parameter as a
-     * <code>java.sql.Time</code> object, using
-     * the given <code>Calendar</code> object
-     * to construct the time.
-     * With a <code>Calendar</code> object, the driver
-     * can calculate the time taking into account a custom timezone and locale.
-     * If no <code>Calendar</code> object is specified, the driver uses the
-     * default timezone and locale.
+     * <code>java.sql.Time</code> object, using the given <code>Calendar</code>
+     * object to construct the time. With a <code>Calendar</code> object, the driver
+     * can calculate the time taking into account a custom timezone and locale. If
+     * no <code>Calendar</code> object is specified, the driver uses the default
+     * timezone and locale.
      *
      * @param parameterName the name of the parameter
-     * @param cal           the <code>Calendar</code> object the driver will use
-     *                      to construct the time
-     * @return the parameter value; if the value is SQL <code>NULL</code>, the result is
-     *         <code>null</code>.
+     * @param cal the <code>Calendar</code> object the driver will use to construct
+     * the time
+     * @return the parameter value; if the value is SQL <code>NULL</code>, the
+     * result is <code>null</code>.
      * @throws java.sql.SQLException if a database access error occurs
      * @see #setTime
      * @since 1.4
@@ -1466,19 +1416,17 @@
 
     /**
      * Retrieves the value of a JDBC <code>TIMESTAMP</code> parameter as a
-     * <code>java.sql.Timestamp</code> object, using
-     * the given <code>Calendar</code> object to construct
-     * the <code>Timestamp</code> object.
-     * With a <code>Calendar</code> object, the driver
-     * can calculate the timestamp taking into account a custom timezone and locale.
-     * If no <code>Calendar</code> object is specified, the driver uses the
-     * default timezone and locale.
+     * <code>java.sql.Timestamp</code> object, using the given <code>Calendar</code>
+     * object to construct the <code>Timestamp</code> object. With a
+     * <code>Calendar</code> object, the driver can calculate the timestamp taking
+     * into account a custom timezone and locale. If no <code>Calendar</code> object
+     * is specified, the driver uses the default timezone and locale.
      *
      * @param parameterName the name of the parameter
-     * @param cal           the <code>Calendar</code> object the driver will use
-     *                      to construct the timestamp
-     * @return the parameter value.  If the value is SQL <code>NULL</code>, the result is
-     *         <code>null</code>.
+     * @param cal the <code>Calendar</code> object the driver will use to construct
+     * the timestamp
+     * @return the parameter value. If the value is SQL <code>NULL</code>, the
+     * result is <code>null</code>.
      * @throws java.sql.SQLException if a database access error occurs
      * @see #setTimestamp
      * @since 1.4
@@ -1492,11 +1440,11 @@
      * <code>java.net.URL</code> object.
      *
      * @param parameterName the name of the parameter
-     * @return the parameter value as a <code>java.net.URL</code> object in the
-     *         Java programming language.  If the value was SQL <code>NULL</code>, the
-     *         value <code>null</code> is returned.
-     * @throws java.sql.SQLException if a database access error occurs,
-     *                               or if there is a problem with the URL
+     * @return the parameter value as a <code>java.net.URL</code> object in the Java
+     * programming language. If the value was SQL <code>NULL</code>, the value
+     * <code>null</code> is returned.
+     * @throws java.sql.SQLException if a database access error occurs, or if there
+     * is a problem with the URL
      * @see #setURL
      * @since 1.4
      */
@@ -1505,17 +1453,16 @@
     }
 
     /**
-     * Returns an object representing the value of OUT parameter
-     * <code>i</code> and uses <code>map</code> for the custom
-     * mapping of the parameter value.
+     * Returns an object representing the value of OUT parameter <code>i</code> and
+     * uses <code>map</code> for the custom mapping of the parameter value.
      * <p/>
-     * This method returns a Java object whose type corresponds to the
-     * JDBC type that was registered for this parameter using the method
-     * <code>registerOutParameter</code>.  By registering the target
-     * JDBC type as <code>java.sql.Types.OTHER</code>, this method can
-     * be used to read database-specific abstract data types.
+     * This method returns a Java object whose type corresponds to the JDBC type
+     * that was registered for this parameter using the method
+     * <code>registerOutParameter</code>. By registering the target JDBC type as
+     * <code>java.sql.Types.OTHER</code>, this method can be used to read
+     * database-specific abstract data types.
      *
-     * @param i   the first parameter is 1, the second is 2, and so on
+     * @param i the first parameter is 1, the second is 2, and so on
      * @param map the mapping from SQL type names to Java classes
      * @return a <code>java.lang.Object</code> holding the OUT parameter value
      * @throws java.sql.SQLException if a database access error occurs
@@ -1527,18 +1474,17 @@
     }
 
     /**
-     * Returns an object representing the value of OUT parameter
-     * <code>i</code> and uses <code>map</code> for the custom
-     * mapping of the parameter value.
+     * Returns an object representing the value of OUT parameter <code>i</code> and
+     * uses <code>map</code> for the custom mapping of the parameter value.
      * <p/>
-     * This method returns a Java object whose type corresponds to the
-     * JDBC type that was registered for this parameter using the method
-     * <code>registerOutParameter</code>.  By registering the target
-     * JDBC type as <code>java.sql.Types.OTHER</code>, this method can
-     * be used to read database-specific abstract data types.
+     * This method returns a Java object whose type corresponds to the JDBC type
+     * that was registered for this parameter using the method
+     * <code>registerOutParameter</code>. By registering the target JDBC type as
+     * <code>java.sql.Types.OTHER</code>, this method can be used to read
+     * database-specific abstract data types.
      *
      * @param parameterName the name of the parameter
-     * @param map           the mapping from SQL type names to Java classes
+     * @param map the mapping from SQL type names to Java classes
      * @return a <code>java.lang.Object</code> holding the OUT parameter value
      * @throws java.sql.SQLException if a database access error occurs
      * @see #setObject
diff --git a/appserver/jdbc/jdbc-ra/jdbc-core/src/main/java/com/sun/gjc/spi/base/ConnectionHolder.java b/appserver/jdbc/jdbc-ra/jdbc-core/src/main/java/com/sun/gjc/spi/base/ConnectionHolder.java
index 1c81834..f110bab 100644
--- a/appserver/jdbc/jdbc-ra/jdbc-core/src/main/java/com/sun/gjc/spi/base/ConnectionHolder.java
+++ b/appserver/jdbc/jdbc-ra/jdbc-core/src/main/java/com/sun/gjc/spi/base/ConnectionHolder.java
@@ -16,6 +16,18 @@
 
 package com.sun.gjc.spi.base;
 
+import java.sql.CallableStatement;
+import java.sql.Connection;
+import java.sql.DatabaseMetaData;
+import java.sql.PreparedStatement;
+import java.sql.SQLException;
+import java.sql.SQLWarning;
+import java.sql.Savepoint;
+import java.sql.Statement;
+import java.util.Map;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
 import com.sun.enterprise.util.i18n.StringManager;
 import com.sun.gjc.common.DataSourceObjectBuilder;
 import com.sun.gjc.spi.ManagedConnectionImpl;
@@ -23,48 +35,41 @@
 import com.sun.logging.LogDomains;
 
 import jakarta.resource.ResourceException;
-import java.sql.*;
-import java.util.Map;
-import java.util.logging.Level;
-import java.util.logging.Logger;
+import jakarta.resource.spi.ConnectionRequestInfo;
+import jakarta.resource.spi.LazyAssociatableConnectionManager;
+import jakarta.resource.spi.LazyEnlistableConnectionManager;
+import jakarta.resource.spi.ManagedConnectionFactory;
 
 /**
- * Holds the java.sql.Connection object, which is to be
- * passed to the application program.
+ * Holds the java.sql.Connection object, which is to be passed to the
+ * application program.
  *
  * @author Binod P.G
  * @version 1.0, 02/07/23
  */
 public abstract class ConnectionHolder implements Connection {
 
-    protected Connection con;
+    protected final static Logger _logger = LogDomains.getLogger(ManagedConnectionImpl.class, LogDomains.RSR_LOGGER);
+    protected final static StringManager sm = StringManager.getManager(DataSourceObjectBuilder.class);
 
-    protected ManagedConnectionImpl mc;
+    protected Connection connection;
+    protected ManagedConnectionImpl managedConnectionImpl;
 
-    protected boolean wrappedAlready = false;
-
-    protected boolean isClosed = false;
-
+    protected boolean wrappedAlready;
+    protected boolean isClosed;
     protected boolean valid = true;
+    protected boolean active;
 
-    protected boolean active = false;
+    private LazyAssociatableConnectionManager lazyAssocCm_;
+    private LazyEnlistableConnectionManager lazyEnlistCm_;
 
-    private jakarta.resource.spi.LazyAssociatableConnectionManager lazyAssocCm_;
-    private jakarta.resource.spi.LazyEnlistableConnectionManager lazyEnlistCm_;
-
-    private jakarta.resource.spi.ConnectionRequestInfo cxReqInfo_;
-
-    private jakarta.resource.spi.ManagedConnectionFactory mcf_;
+    private ConnectionRequestInfo connectionRequestInfo;
+    private ManagedConnectionFactory managedConnectionFactory;
 
     protected int statementTimeout;
     protected boolean statementTimeoutEnabled;
 
-    protected final static Logger _logger;
-
-    static {
-        _logger = LogDomains.getLogger(ManagedConnectionImpl.class, LogDomains.RSR_LOGGER);
-    }
-    private MethodExecutor executor = null;
+    private MethodExecutor executor;
 
     public static enum ConnectionType {
         LAZY_ENLISTABLE, LAZY_ASSOCIATABLE, STANDARD
@@ -73,18 +78,14 @@
     private ConnectionType myType_ = ConnectionType.STANDARD;
 
     /**
-     * The active flag is false when the connection handle is
-     * created. When a method is invoked on this object, it asks
-     * the ManagedConnection if it can be the active connection
-     * handle out of the multiple connection handles. If the
-     * ManagedConnection reports that this connection handle
-     * can be active by setting this flag to true via the setActive
-     * function, the above method invocation succeeds; otherwise
-     * an exception is thrown.
+     * The active flag is false when the connection handle is created. When a method
+     * is invoked on this object, it asks the ManagedConnection if it can be the
+     * active connection handle out of the multiple connection handles. If the
+     * ManagedConnection reports that this connection handle can be active by
+     * setting this flag to true via the setActive function, the above method
+     * invocation succeeds; otherwise an exception is thrown.
      */
 
-    protected final static StringManager sm = StringManager.getManager(
-            DataSourceObjectBuilder.class);
 
 
     /**
@@ -92,12 +93,11 @@
      *
      * @param con <code>java.sql.Connection</code> object.
      */
-    public ConnectionHolder(Connection con, ManagedConnectionImpl mc,
-                            jakarta.resource.spi.ConnectionRequestInfo cxRequestInfo) {
-        this.con = con;
-        this.mc = mc;
-        mcf_ = mc.getMcf();
-        cxReqInfo_ = cxRequestInfo;
+    public ConnectionHolder(Connection con, ManagedConnectionImpl mc, ConnectionRequestInfo cxRequestInfo) {
+        this.connection = con;
+        this.managedConnectionImpl = mc;
+        managedConnectionFactory = mc.getMcf();
+        connectionRequestInfo = cxRequestInfo;
         statementTimeout = mc.getStatementTimeout();
         executor = new MethodExecutor();
         if (statementTimeout > 0) {
@@ -111,7 +111,7 @@
      * @return Connection object.
      */
     public Connection getConnection() {
-        return con;
+        return connection;
     }
 
     /**
@@ -133,13 +133,13 @@
     }
 
     /**
-     * Returns the <code>ManagedConnection</code> instance responsible
-     * for this connection.
+     * Returns the <code>ManagedConnection</code> instance responsible for this
+     * connection.
      *
      * @return <code>ManagedConnection</code> instance.
      */
     public ManagedConnectionImpl getManagedConnection() {
-        return mc;
+        return managedConnectionImpl;
     }
 
     /**
@@ -147,30 +147,30 @@
      * supplied. Also replace <code>ManagedConnection</code> link.
      *
      * @param con <code>Connection</code> object.
-     * @param mc  <code> ManagedConnection</code> object.
+     * @param mc <code> ManagedConnection</code> object.
      */
     public void associateConnection(Connection con, ManagedConnectionImpl mc) {
-        this.mc = mc;
-        this.con = con;
+        this.managedConnectionImpl = mc;
+        this.connection = con;
     }
 
     /**
-     * Dis-associate ManagedConnection and actual-connection from this user connection.
-     * Used when lazy-connection-association is ON.
+     * Dis-associate ManagedConnection and actual-connection from this user
+     * connection. Used when lazy-connection-association is ON.
      */
     public void dissociateConnection() {
-        this.mc = null;
-        this.con = null;
+        this.managedConnectionImpl = null;
+        this.connection = null;
     }
 
     /**
-     * Clears all warnings reported for the underlying connection  object.
+     * Clears all warnings reported for the underlying connection object.
      *
      * @throws SQLException In case of a database error.
      */
     public void clearWarnings() throws SQLException {
         checkValidity();
-        con.clearWarnings();
+        connection.clearWarnings();
     }
 
     /**
@@ -187,10 +187,10 @@
         }
 
         isClosed = true;
-        if (mc != null) {
-            //mc might be null if this is a lazyAssociatable connection
-            //and has not been associated yet or has been disassociated
-            mc.connectionClosed(null, this);
+        if (managedConnectionImpl != null) {
+            // mc might be null if this is a lazyAssociatable connection
+            // and has not been associated yet or has been disassociated
+            managedConnectionImpl.connectionClosed(null, this);
         }
     }
 
@@ -207,7 +207,7 @@
      * @throws SQLException In case of a database error.
      */
     void actualClose() throws SQLException {
-        con.close();
+        connection.close();
     }
 
     /**
@@ -217,7 +217,7 @@
      */
     public void commit() throws SQLException {
         checkValidity();
-        con.commit();
+        connection.commit();
     }
 
     /**
@@ -229,21 +229,23 @@
     public Statement createStatement() throws SQLException {
         checkValidity();
         jdbcPreInvoke();
-        Statement stmt = con.createStatement();
+
+        Statement statement = connection.createStatement();
         if (statementTimeoutEnabled) {
             try {
-                stmt.setQueryTimeout(statementTimeout);
+                statement.setQueryTimeout(statementTimeout);
             } catch (SQLException ex) {
-                stmt.close();
+                statement.close();
             }
         }
-        return stmt;
+
+        return statement;
     }
 
     /**
      * Creates a statement from the underlying Connection.
      *
-     * @param resultSetType        Type of the ResultSet
+     * @param resultSetType Type of the ResultSet
      * @param resultSetConcurrency ResultSet Concurrency.
      * @return <code>Statement</code> object.
      * @throws SQLException In case of a database error.
@@ -251,51 +253,54 @@
     public Statement createStatement(int resultSetType, int resultSetConcurrency) throws SQLException {
         checkValidity();
         jdbcPreInvoke();
-        Statement stmt = con.createStatement(resultSetType, resultSetConcurrency);
+
+        Statement statement = connection.createStatement(resultSetType, resultSetConcurrency);
         if (statementTimeoutEnabled) {
             try {
-                stmt.setQueryTimeout(statementTimeout);
+                statement.setQueryTimeout(statementTimeout);
             } catch (SQLException ex) {
-                stmt.close();
+                statement.close();
             }
         }
-        return stmt;
+
+        return statement;
     }
 
     /**
      * Creates a statement from the underlying Connection.
      *
-     * @param resultSetType        Type of the ResultSet
+     * @param resultSetType Type of the ResultSet
      * @param resultSetConcurrency ResultSet Concurrency.
      * @param resultSetHoldability ResultSet Holdability.
      * @return <code>Statement</code> object.
      * @throws SQLException In case of a database error.
      */
-    public Statement createStatement(int resultSetType, int resultSetConcurrency,
-                                     int resultSetHoldability) throws SQLException {
+    public Statement createStatement(int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException {
         checkValidity();
         jdbcPreInvoke();
-        Statement stmt = con.createStatement(resultSetType, resultSetConcurrency,
-                resultSetHoldability);
+
+        Statement statement = connection.createStatement(resultSetType, resultSetConcurrency, resultSetHoldability);
         if (statementTimeoutEnabled) {
             try {
-                stmt.setQueryTimeout(statementTimeout);
+                statement.setQueryTimeout(statementTimeout);
             } catch (SQLException ex) {
-                stmt.close();
+                statement.close();
             }
         }
-        return stmt;
+
+        return statement;
     }
 
     /**
-     * Retrieves the current auto-commit mode for the underlying <code> Connection</code>.
+     * Retrieves the current auto-commit mode for the underlying
+     * <code> Connection</code>.
      *
      * @return The current state of connection's auto-commit mode.
      * @throws SQLException In case of a database error.
      */
     public boolean getAutoCommit() throws SQLException {
         checkValidity();
-        return con.getAutoCommit();
+        return connection.getAutoCommit();
     }
 
     /**
@@ -306,7 +311,7 @@
      */
     public String getCatalog() throws SQLException {
         checkValidity();
-        return con.getCatalog();
+        return connection.getCatalog();
     }
 
     /**
@@ -318,7 +323,7 @@
      */
     public int getHoldability() throws SQLException {
         checkValidity();
-        return con.getHoldability();
+        return connection.getHoldability();
     }
 
     /**
@@ -330,18 +335,19 @@
      */
     public DatabaseMetaData getMetaData() throws SQLException {
         checkValidity();
-        return con.getMetaData();
+        return connection.getMetaData();
     }
 
     /**
-     * Retrieves this <code>Connection</code> object's current transaction isolation level.
+     * Retrieves this <code>Connection</code> object's current transaction isolation
+     * level.
      *
      * @return Transaction level
      * @throws SQLException In case of a database error.
      */
     public int getTransactionIsolation() throws SQLException {
         checkValidity();
-        return con.getTransactionIsolation();
+        return connection.getTransactionIsolation();
     }
 
     /**
@@ -353,7 +359,7 @@
      */
     public Map<String, Class<?>> getTypeMap() throws SQLException {
         checkValidity();
-        return con.getTypeMap();
+        return connection.getTypeMap();
     }
 
     /**
@@ -365,14 +371,14 @@
      */
     public SQLWarning getWarnings() throws SQLException {
         checkValidity();
-        return con.getWarnings();
+        return connection.getWarnings();
     }
 
     /**
      * Retrieves whether underlying <code>Connection</code> object is closed.
      *
-     * @return true if <code>Connection</code> object is closed, false
-     *         if it is closed.
+     * @return true if <code>Connection</code> object is closed, false if it is
+     * closed.
      * @throws SQLException In case of a database error.
      */
     public boolean isClosed() throws SQLException {
@@ -383,8 +389,8 @@
      * Set the isClosed flag based on whether the underlying <code>Connection</code>
      * object is closed.
      *
-     * @param flag true if <code>Connection</code> object is closed, false if
-     * its not closed.
+     * @param flag true if <code>Connection</code> object is closed, false if its
+     * not closed.
      */
     public void setClosed(boolean flag) {
         isClosed = flag;
@@ -398,7 +404,7 @@
      */
     public boolean isReadOnly() throws SQLException {
         checkValidity();
-        return con.isReadOnly();
+        return connection.isReadOnly();
     }
 
     /**
@@ -410,12 +416,12 @@
      */
     public String nativeSQL(String sql) throws SQLException {
         checkValidity();
-        return con.nativeSQL(sql);
+        return connection.nativeSQL(sql);
     }
 
     /**
-     * Creates a <code> CallableStatement </code> object for calling database
-     * stored procedures.
+     * Creates a <code> CallableStatement </code> object for calling database stored
+     * procedures.
      *
      * @param sql SQL Statement
      * @return <code> CallableStatement</code> object.
@@ -424,7 +430,7 @@
     public CallableStatement prepareCall(String sql) throws SQLException {
         checkValidity();
         jdbcPreInvoke();
-        CallableStatement stmt = con.prepareCall(sql);
+        CallableStatement stmt = connection.prepareCall(sql);
         if (statementTimeoutEnabled) {
             stmt.setQueryTimeout(statementTimeout);
         }
@@ -432,53 +438,53 @@
     }
 
     /**
-     * Creates a <code> CallableStatement </code> object for calling database
-     * stored procedures.
+     * Creates a <code> CallableStatement </code> object for calling database stored
+     * procedures.
      *
-     * @param sql                  SQL Statement
-     * @param resultSetType        Type of the ResultSet
+     * @param sql SQL Statement
+     * @param resultSetType Type of the ResultSet
      * @param resultSetConcurrency ResultSet Concurrency.
      * @return <code> CallableStatement</code> object.
      * @throws SQLException In case of a database error.
      */
-    public CallableStatement prepareCall(String sql, int resultSetType,
-                                         int resultSetConcurrency) throws SQLException {
+    public CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency) throws SQLException {
         checkValidity();
         jdbcPreInvoke();
-        CallableStatement stmt = con.prepareCall(sql, resultSetType, resultSetConcurrency);
+
+        CallableStatement callableStatement = connection.prepareCall(sql, resultSetType, resultSetConcurrency);
         if (statementTimeoutEnabled) {
-            stmt.setQueryTimeout(statementTimeout);
+            callableStatement.setQueryTimeout(statementTimeout);
         }
-        return stmt;
+
+        return callableStatement;
     }
 
     /**
-     * Creates a <code> CallableStatement </code> object for calling database
-     * stored procedures.
+     * Creates a <code> CallableStatement </code> object for calling database stored
+     * procedures.
      *
-     * @param sql                  SQL Statement
-     * @param resultSetType        Type of the ResultSet
+     * @param sql SQL Statement
+     * @param resultSetType Type of the ResultSet
      * @param resultSetConcurrency ResultSet Concurrency.
      * @param resultSetHoldability ResultSet Holdability.
      * @return <code> CallableStatement</code> object.
      * @throws SQLException In case of a database error.
      */
-    public CallableStatement prepareCall(String sql, int resultSetType,
-                                         int resultSetConcurrency,
-                                         int resultSetHoldability) throws SQLException {
+    public CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException {
         checkValidity();
         jdbcPreInvoke();
-        CallableStatement stmt = con.prepareCall(sql, resultSetType, resultSetConcurrency,
-                resultSetHoldability);
+
+        CallableStatement callableStatement = connection.prepareCall(sql, resultSetType, resultSetConcurrency, resultSetHoldability);
         if (statementTimeoutEnabled) {
-            stmt.setQueryTimeout(statementTimeout);
+            callableStatement.setQueryTimeout(statementTimeout);
         }
-        return stmt;
+
+        return callableStatement;
     }
 
     /**
-     * Creates a <code> PreparedStatement </code> object for sending
-     * paramterized SQL statements to database
+     * Creates a <code> PreparedStatement </code> object for sending paramterized
+     * SQL statements to database
      *
      * @param sql SQL Statement
      * @return <code> PreparedStatement</code> object.
@@ -487,122 +493,129 @@
     public PreparedStatement prepareStatement(final String sql) throws SQLException {
         checkValidity();
         jdbcPreInvoke();
-        PreparedStatement stmt = con.prepareStatement(sql);
+
+        PreparedStatement preparedStatement = connection.prepareStatement(sql);
         if (statementTimeoutEnabled) {
             try {
-                stmt.setQueryTimeout(statementTimeout);
+                preparedStatement.setQueryTimeout(statementTimeout);
             } catch (SQLException ex) {
-                stmt.close();
+                preparedStatement.close();
             }
         }
-        return stmt;
+
+        return preparedStatement;
     }
 
     /**
-     * Creates a <code> PreparedStatement </code> object for sending
-     * paramterized SQL statements to database
+     * Creates a <code> PreparedStatement </code> object for sending paramterized
+     * SQL statements to database
      *
-     * @param sql               SQL Statement
-     * @param autoGeneratedKeys a flag indicating AutoGeneratedKeys need to be returned.
+     * @param sql SQL Statement
+     * @param autoGeneratedKeys a flag indicating AutoGeneratedKeys need to be
+     * returned.
      * @return <code> PreparedStatement</code> object.
      * @throws SQLException In case of a database error.
      */
     public PreparedStatement prepareStatement(final String sql, int autoGeneratedKeys) throws SQLException {
         checkValidity();
         jdbcPreInvoke();
-        PreparedStatement stmt = con.prepareStatement(sql, autoGeneratedKeys);
+
+        PreparedStatement preparedStatement = connection.prepareStatement(sql, autoGeneratedKeys);
         if (statementTimeoutEnabled) {
             try {
-                stmt.setQueryTimeout(statementTimeout);
+                preparedStatement.setQueryTimeout(statementTimeout);
             } catch (SQLException ex) {
-                stmt.close();
+                preparedStatement.close();
             }
         }
-        return stmt;
+
+        return preparedStatement;
     }
 
     /**
-     * Creates a <code> PreparedStatement </code> object for sending
-     * paramterized SQL statements to database
+     * Creates a <code> PreparedStatement </code> object for sending paramterized
+     * SQL statements to database
      *
-     * @param sql           SQL Statement
-     * @param columnIndexes an array of column indexes indicating the columns that should be
-     *                      returned from the inserted row or rows.
+     * @param sql SQL Statement
+     * @param columnIndexes an array of column indexes indicating the columns that
+     * should be returned from the inserted row or rows.
      * @return <code> PreparedStatement</code> object.
      * @throws SQLException In case of a database error.
      */
     public PreparedStatement prepareStatement(final String sql, int[] columnIndexes) throws SQLException {
         checkValidity();
         jdbcPreInvoke();
-        PreparedStatement stmt = con.prepareStatement(sql, columnIndexes);
+
+        PreparedStatement preparedStatement = connection.prepareStatement(sql, columnIndexes);
         if (statementTimeoutEnabled) {
             try {
-                stmt.setQueryTimeout(statementTimeout);
+                preparedStatement.setQueryTimeout(statementTimeout);
             } catch (SQLException ex) {
-                stmt.close();
+                preparedStatement.close();
             }
         }
-        return stmt;
+
+        return preparedStatement;
     }
 
     /**
-     * Creates a <code> PreparedStatement </code> object for sending
-     * paramterized SQL statements to database
+     * Creates a <code> PreparedStatement </code> object for sending paramterized
+     * SQL statements to database
      *
-     * @param sql                  SQL Statement
-     * @param resultSetType        Type of the ResultSet
+     * @param sql SQL Statement
+     * @param resultSetType Type of the ResultSet
      * @param resultSetConcurrency ResultSet Concurrency.
      * @return <code> PreparedStatement</code> object.
      * @throws SQLException In case of a database error.
      */
-    public PreparedStatement prepareStatement(final String sql, int resultSetType,
-                                              int resultSetConcurrency) throws SQLException {
+    public PreparedStatement prepareStatement(final String sql, int resultSetType, int resultSetConcurrency) throws SQLException {
         checkValidity();
         jdbcPreInvoke();
-        PreparedStatement stmt = con.prepareStatement(sql, resultSetType, resultSetConcurrency);
+
+        PreparedStatement preparedStatement = connection.prepareStatement(sql, resultSetType, resultSetConcurrency);
         if (statementTimeoutEnabled) {
             try {
-                stmt.setQueryTimeout(statementTimeout);
+                preparedStatement.setQueryTimeout(statementTimeout);
             } catch (SQLException ex) {
-                stmt.close();
+                preparedStatement.close();
             }
         }
-        return stmt;
+
+        return preparedStatement;
     }
 
     /**
-     * Creates a <code> PreparedStatement </code> object for sending
-     * paramterized SQL statements to database
+     * Creates a <code> PreparedStatement </code> object for sending paramterized
+     * SQL statements to database
      *
-     * @param sql                  SQL Statement
-     * @param resultSetType        Type of the ResultSet
+     * @param sql SQL Statement
+     * @param resultSetType Type of the ResultSet
      * @param resultSetConcurrency ResultSet Concurrency.
      * @param resultSetHoldability ResultSet Holdability.
      * @return <code> PreparedStatement</code> object.
      * @throws SQLException In case of a database error.
      */
-    public PreparedStatement prepareStatement(final String sql, int resultSetType,
-                                              int resultSetConcurrency,
-                                              int resultSetHoldability) throws SQLException {
+    public PreparedStatement prepareStatement(final String sql, int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException {
         checkValidity();
         jdbcPreInvoke();
-        PreparedStatement stmt = con.prepareStatement(sql, resultSetType,
-                resultSetConcurrency, resultSetHoldability);
+
+        PreparedStatement preparedStatement = connection.prepareStatement(sql, resultSetType, resultSetConcurrency, resultSetHoldability);
         if (statementTimeoutEnabled) {
             try {
-                stmt.setQueryTimeout(statementTimeout);
+                preparedStatement.setQueryTimeout(statementTimeout);
             } catch (SQLException ex) {
-                stmt.close();
+                preparedStatement.close();
             }
         }
-        return stmt;
+
+        return preparedStatement;
     }
 
     /**
-     * Creates a <code> PreparedStatement </code> object for sending
-     * paramterized SQL statements to database
+     * Creates a <code> PreparedStatement </code> object for sending paramterized
+     * SQL statements to database
      *
-     * @param sql         SQL Statement
+     * @param sql SQL Statement
      * @param columnNames Name of bound columns.
      * @return <code> PreparedStatement</code> object.
      * @throws SQLException In case of a database error.
@@ -610,15 +623,17 @@
     public PreparedStatement prepareStatement(final String sql, String[] columnNames) throws SQLException {
         checkValidity();
         jdbcPreInvoke();
-        PreparedStatement stmt = con.prepareStatement(sql, columnNames);
+
+        PreparedStatement preparedStatement = connection.prepareStatement(sql, columnNames);
         if (statementTimeoutEnabled) {
             try {
-                stmt.setQueryTimeout(statementTimeout);
+                preparedStatement.setQueryTimeout(statementTimeout);
             } catch (SQLException ex) {
-                stmt.close();
+                preparedStatement.close();
             }
         }
-        return stmt;
+
+        return preparedStatement;
     }
 
     /**
@@ -629,7 +644,7 @@
      */
     public void releaseSavepoint(Savepoint savepoint) throws SQLException {
         checkValidity();
-        con.releaseSavepoint(savepoint);
+        connection.releaseSavepoint(savepoint);
     }
 
     /**
@@ -639,7 +654,7 @@
      */
     public void rollback() throws SQLException {
         checkValidity();
-        con.rollback();
+        connection.rollback();
     }
 
     /**
@@ -649,7 +664,7 @@
      */
     public void rollback(Savepoint savepoint) throws SQLException {
         checkValidity();
-        con.rollback(savepoint);
+        connection.rollback(savepoint);
     }
 
     /**
@@ -660,8 +675,8 @@
      */
     public void setAutoCommit(boolean autoCommit) throws SQLException {
         checkValidity();
-        con.setAutoCommit(autoCommit);
-        mc.setLastAutoCommitValue(autoCommit);
+        connection.setAutoCommit(autoCommit);
+        managedConnectionImpl.setLastAutoCommitValue(autoCommit);
     }
 
     /**
@@ -672,31 +687,31 @@
      */
     public void setCatalog(String catalog) throws SQLException {
         checkValidity();
-        con.setCatalog(catalog);
+        connection.setCatalog(catalog);
     }
 
     /**
-     * Sets the holdability of <code>ResultSet</code> objects created
-     * using this <code>Connection</code> object.
+     * Sets the holdability of <code>ResultSet</code> objects created using this
+     * <code>Connection</code> object.
      *
      * @param holdability A <code>ResultSet</code> holdability constant
      * @throws SQLException In case of a database error.
      */
     public void setHoldability(int holdability) throws SQLException {
         checkValidity();
-        con.setHoldability(holdability);
+        connection.setHoldability(holdability);
     }
 
     /**
-     * Puts the connection in read-only mode as a hint to the driver to
-     * perform database optimizations.
+     * Puts the connection in read-only mode as a hint to the driver to perform
+     * database optimizations.
      *
      * @param readOnly true enables read-only mode, false disables it.
      * @throws SQLException In case of a database error.
      */
     public void setReadOnly(boolean readOnly) throws SQLException {
         checkValidity();
-        con.setReadOnly(readOnly);
+        connection.setReadOnly(readOnly);
     }
 
     /**
@@ -707,11 +722,12 @@
      */
     public Savepoint setSavepoint() throws SQLException {
         checkValidity();
-        return con.setSavepoint();
+        return connection.setSavepoint();
     }
 
     /**
-     * Creates a savepoint with the name and returns an object corresponding to that.
+     * Creates a savepoint with the name and returns an object corresponding to
+     * that.
      *
      * @param name Name of the savepoint.
      * @return <code>Savepoint</code> object.
@@ -719,7 +735,7 @@
      */
     public Savepoint setSavepoint(String name) throws SQLException {
         checkValidity();
-        return con.setSavepoint(name);
+        return connection.setSavepoint(name);
     }
 
     /**
@@ -730,19 +746,24 @@
      */
     public void setTransactionIsolation(int level) throws SQLException {
         checkValidity();
-        con.setTransactionIsolation(level);
-        mc.setLastTransactionIsolationLevel(level);
+        connection.setTransactionIsolation(level);
+        managedConnectionImpl.setLastTransactionIsolationLevel(level);
     }
 
-
     /**
      * Checks the validity of this object
      */
     protected void checkValidity() throws SQLException {
-        if (isClosed) throw new SQLException("Connection closed");
-        if (!valid) throw new SQLException("Invalid Connection");
+        if (isClosed) {
+            throw new SQLException("Connection closed");
+        }
+
+        if (!valid) {
+            throw new SQLException("Invalid Connection");
+        }
+
         if (active == false) {
-            mc.checkIfActive(this);
+            managedConnectionImpl.checkIfActive(this);
         }
     }
 
@@ -756,8 +777,8 @@
     }
 
     /*
-     * Here this is a no-op. In the LazyEnlistableConnectionHolder, it will
-     * actually fire the lazyEnlist method of LazyEnlistableManagedConnection
+     * Here this is a no-op. In the LazyEnlistableConnectionHolder, it will actually
+     * fire the lazyEnlist method of LazyEnlistableManagedConnection
      */
     protected void jdbcPreInvoke() throws SQLException {
         if (myType_ == ConnectionType.LAZY_ASSOCIATABLE) {
@@ -770,13 +791,11 @@
 
     protected void performLazyEnlistment() throws SQLException {
         try {
-            if(lazyEnlistCm_ != null) {
-                lazyEnlistCm_.lazyEnlist(mc);
+            if (lazyEnlistCm_ != null) {
+                lazyEnlistCm_.lazyEnlist(managedConnectionImpl);
             }
         } catch (ResourceException re) {
-            String msg = sm.getString(
-                    "jdbc.cannot_enlist", re.getMessage() +
-                    " Cannnot Enlist ManagedConnection");
+            String msg = sm.getString("jdbc.cannot_enlist", re.getMessage() + " Cannnot Enlist ManagedConnection");
 
             SQLException sqle = new SQLException(msg);
             sqle.initCause(re);
@@ -786,15 +805,14 @@
     }
 
     protected void performLazyAssociation() throws SQLException {
-        if (mc == null) {
+        if (managedConnectionImpl == null) {
             try {
-                if(lazyAssocCm_ != null) {
-                    lazyAssocCm_.associateConnection(this, mcf_, cxReqInfo_);
+                if (lazyAssocCm_ != null) {
+                    lazyAssocCm_.associateConnection(this, managedConnectionFactory, connectionRequestInfo);
                 }
             } catch (ResourceException re) {
-                String msg = sm.getString(
-                        "jdbc.cannot_assoc", re.getMessage() +
-                        " Cannnot Associate ManagedConnection");
+                String msg = sm.getString("jdbc.cannot_assoc",
+                        re.getMessage() + " Cannnot Associate ManagedConnection");
 
                 SQLException sqle = new SQLException(msg);
                 sqle.initCause(re);
@@ -811,24 +829,14 @@
         return myType_;
     }
 
-    public void setLazyAssociatableConnectionManager(
-            jakarta.resource.spi.LazyAssociatableConnectionManager cm) {
-
+    public void setLazyAssociatableConnectionManager(jakarta.resource.spi.LazyAssociatableConnectionManager cm) {
         lazyAssocCm_ = cm;
     }
 
-    public void setLazyEnlistableConnectionManager(
-            jakarta.resource.spi.LazyEnlistableConnectionManager cm) {
-
+    public void setLazyEnlistableConnectionManager(jakarta.resource.spi.LazyEnlistableConnectionManager cm) {
         lazyEnlistCm_ = cm;
     }
 
-/*
-    public void setManagedConnection(ManagedConnection con) {
-        this.mc = con;
-    }
-*/
-
     /**
      * Installs the given <code>Map</code> object as the tyoe map for this
      * <code> Connection </code> object.
@@ -838,7 +846,7 @@
      */
     public void setTypeMap(java.util.Map<String, Class<?>> map) throws SQLException {
         checkValidity();
-        con.setTypeMap(map);
+        connection.setTypeMap(map);
     }
 
     protected MethodExecutor getMethodExecutor() {
diff --git a/appserver/jdbc/jdbc-ra/jdbc-core/src/main/java/com/sun/gjc/spi/base/ConnectionWrapper.java b/appserver/jdbc/jdbc-ra/jdbc-core/src/main/java/com/sun/gjc/spi/base/ConnectionWrapper.java
index 155eca2..8e8f3e9 100644
--- a/appserver/jdbc/jdbc-ra/jdbc-core/src/main/java/com/sun/gjc/spi/base/ConnectionWrapper.java
+++ b/appserver/jdbc/jdbc-ra/jdbc-core/src/main/java/com/sun/gjc/spi/base/ConnectionWrapper.java
@@ -16,7 +16,6 @@
 
 package com.sun.gjc.spi.base;
 
-
 import java.sql.SQLException;
 
 /**
@@ -24,26 +23,17 @@
  * @author Shalini M
  */
 public interface ConnectionWrapper {
-    PreparedStatementWrapper prepareCachedStatement(String sql, int resultSetType,
-            int resultSetConcurrency, boolean enableCaching) throws SQLException;
+    PreparedStatementWrapper prepareCachedStatement(String sql, int resultSetType, int resultSetConcurrency, boolean enableCaching) throws SQLException;
 
-    PreparedStatementWrapper prepareCachedStatement(String sql, int resultSetType,
-            int resultSetConcurrency, int resultSetHoldability,
-            boolean enableCaching) throws SQLException;
+    PreparedStatementWrapper prepareCachedStatement(String sql, int resultSetType, int resultSetConcurrency, int resultSetHoldability, boolean enableCaching) throws SQLException;
 
-    PreparedStatementWrapper prepareCachedStatement(String sql,
-              String[] columnNames, boolean enableCaching) throws SQLException;
+    PreparedStatementWrapper prepareCachedStatement(String sql, String[] columnNames, boolean enableCaching) throws SQLException;
 
-    PreparedStatementWrapper prepareCachedStatement(String sql,
-              int[] columnIndexes, boolean enableCaching) throws SQLException;
+    PreparedStatementWrapper prepareCachedStatement(String sql, int[] columnIndexes, boolean enableCaching) throws SQLException;
 
-    PreparedStatementWrapper prepareCachedStatement(String sql,
-              int autoGeneratedKeys, boolean enableCaching) throws SQLException;
+    PreparedStatementWrapper prepareCachedStatement(String sql, int autoGeneratedKeys, boolean enableCaching) throws SQLException;
 
-    CallableStatementWrapper callableCachedStatement(String sql, int resultSetType,
-            int resultSetConcurrency, boolean enableCaching) throws SQLException;
+    CallableStatementWrapper callableCachedStatement(String sql, int resultSetType, int resultSetConcurrency, boolean enableCaching) throws SQLException;
 
-    CallableStatementWrapper callableCachedStatement(String sql, int resultSetType,
-            int resultSetConcurrency, int resultSetHoldability,
-            boolean enableCaching) throws SQLException;
+    CallableStatementWrapper callableCachedStatement(String sql, int resultSetType, int resultSetConcurrency, int resultSetHoldability, boolean enableCaching) throws SQLException;
 }
diff --git a/appserver/jdbc/jdbc-ra/jdbc-core/src/main/java/com/sun/gjc/spi/base/DatabaseMetaDataWrapper.java b/appserver/jdbc/jdbc-ra/jdbc-core/src/main/java/com/sun/gjc/spi/base/DatabaseMetaDataWrapper.java
index 7fcea7b..f9f56fe 100644
--- a/appserver/jdbc/jdbc-ra/jdbc-core/src/main/java/com/sun/gjc/spi/base/DatabaseMetaDataWrapper.java
+++ b/appserver/jdbc/jdbc-ra/jdbc-core/src/main/java/com/sun/gjc/spi/base/DatabaseMetaDataWrapper.java
@@ -16,32 +16,30 @@
 
 package com.sun.gjc.spi.base;
 
-import com.sun.gjc.util.MethodExecutor;
-import com.sun.logging.LogDomains;
 import java.sql.Connection;
 import java.sql.DatabaseMetaData;
 import java.sql.ResultSet;
 import java.sql.SQLException;
 import java.util.logging.Logger;
 
+import com.sun.gjc.util.MethodExecutor;
+import com.sun.logging.LogDomains;
+
 /**
  * Abstract class for wrapping DatabaseMetaData<br>
  */
 public abstract class DatabaseMetaDataWrapper implements DatabaseMetaData {
 
-    protected DatabaseMetaData databaseMetaData = null;
-    protected Connection connection = null;
-    private MethodExecutor executor = null;
-    protected final static Logger _logger;
+    protected final static Logger _logger = LogDomains.getLogger(MethodExecutor.class, LogDomains.RSR_LOGGER);
 
-    static {
-        _logger = LogDomains.getLogger(MethodExecutor.class, LogDomains.RSR_LOGGER);
-    }
+    protected DatabaseMetaData databaseMetaData;
+    protected Connection connection;
+    private MethodExecutor executor;
 
     /**
      * Abstract class for wrapping DatabaseMetaData
      *
-     * @param con      Connection that is wrapped.<br>
+     * @param con Connection that is wrapped.<br>
      * @param metaData DatabaseMetaData that is wrapped <br>
      */
     public DatabaseMetaDataWrapper(Connection con, DatabaseMetaData metaData) {
@@ -51,8 +49,8 @@
     }
 
     /**
-     * Retrieves whether the current user can call all the procedures
-     * returned by the method <code>getProcedures</code>.
+     * Retrieves whether the current user can call all the procedures returned by
+     * the method <code>getProcedures</code>.
      *
      * @return <code>true</code> if so; <code>false</code> otherwise
      * @throws java.sql.SQLException if a database access error occurs
@@ -62,9 +60,8 @@
     }
 
     /**
-     * Retrieves whether the current user can use all the tables returned
-     * by the method <code>getTables</code> in a <code>SELECT</code>
-     * statement.
+     * Retrieves whether the current user can use all the tables returned by the
+     * method <code>getTables</code> in a <code>SELECT</code> statement.
      *
      * @return <code>true</code> if so; <code>false</code> otherwise
      * @throws java.sql.SQLException if a database access error occurs
@@ -76,8 +73,7 @@
     /**
      * Retrieves the URL for this DBMS.
      *
-     * @return the URL for this DBMS or <code>null</code> if it cannot be
-     *         generated
+     * @return the URL for this DBMS or <code>null</code> if it cannot be generated
      * @throws java.sql.SQLException if a database access error occurs
      */
     public String getURL() throws SQLException {
@@ -105,11 +101,10 @@
     }
 
     /**
-     * Retrieves whether <code>NULL</code> values are sorted high.
-     * Sorted high means that <code>NULL</code> values
-     * sort higher than any other value in a domain.  In an ascending order,
-     * if this method returns <code>true</code>,  <code>NULL</code> values
-     * will appear at the end. By contrast, the method
+     * Retrieves whether <code>NULL</code> values are sorted high. Sorted high means
+     * that <code>NULL</code> values sort higher than any other value in a domain.
+     * In an ascending order, if this method returns <code>true</code>,
+     * <code>NULL</code> values will appear at the end. By contrast, the method
      * <code>nullsAreSortedAtEnd</code> indicates whether <code>NULL</code> values
      * are sorted at the end regardless of sort order.
      *
@@ -121,13 +116,12 @@
     }
 
     /**
-     * Retrieves whether <code>NULL</code> values are sorted low.
-     * Sorted low means that <code>NULL</code> values
-     * sort lower than any other value in a domain.  In an ascending order,
-     * if this method returns <code>true</code>,  <code>NULL</code> values
-     * will appear at the beginning. By contrast, the method
-     * <code>nullsAreSortedAtStart</code> indicates whether <code>NULL</code> values
-     * are sorted at the beginning regardless of sort order.
+     * Retrieves whether <code>NULL</code> values are sorted low. Sorted low means
+     * that <code>NULL</code> values sort lower than any other value in a domain. In
+     * an ascending order, if this method returns <code>true</code>,
+     * <code>NULL</code> values will appear at the beginning. By contrast, the
+     * method <code>nullsAreSortedAtStart</code> indicates whether <code>NULL</code>
+     * values are sorted at the beginning regardless of sort order.
      *
      * @return <code>true</code> if so; <code>false</code> otherwise
      * @throws java.sql.SQLException if a database access error occurs
@@ -148,8 +142,8 @@
     }
 
     /**
-     * Retrieves whether <code>NULL</code> values are sorted at the end regardless of
-     * sort order.
+     * Retrieves whether <code>NULL</code> values are sorted at the end regardless
+     * of sort order.
      *
      * @return <code>true</code> if so; <code>false</code> otherwise
      * @throws java.sql.SQLException if a database access error occurs
@@ -230,7 +224,7 @@
      * Retrieves whether this database uses a file for each table.
      *
      * @return <code>true</code> if this database uses a local file for each table;
-     *         <code>false</code> otherwise
+     * <code>false</code> otherwise
      * @throws java.sql.SQLException if a database access error occurs
      */
     public boolean usesLocalFilePerTable() throws SQLException {
@@ -326,8 +320,8 @@
     }
 
     /**
-     * Retrieves the string used to quote SQL identifiers.
-     * This method returns a space " " if identifier quoting is not supported.
+     * Retrieves the string used to quote SQL identifiers. This method returns a
+     * space " " if identifier quoting is not supported.
      *
      * @return the quoting string or a space if quoting is not supported
      * @throws java.sql.SQLException if a database access error occurs
@@ -337,11 +331,10 @@
     }
 
     /**
-     * Retrieves a comma-separated list of all of this database's SQL keywords
-     * that are NOT also SQL92 keywords.
+     * Retrieves a comma-separated list of all of this database's SQL keywords that
+     * are NOT also SQL92 keywords.
      *
-     * @return the list of this database's keywords that are not also
-     *         SQL92 keywords
+     * @return the list of this database's keywords that are not also SQL92 keywords
      * @throws java.sql.SQLException if a database access error occurs
      */
     public String getSQLKeywords() throws SQLException {
@@ -349,9 +342,9 @@
     }
 
     /**
-     * Retrieves a comma-separated list of math functions available with
-     * this database.  These are the Open /Open CLI math function names used in
-     * the JDBC function escape clause.
+     * Retrieves a comma-separated list of math functions available with this
+     * database. These are the Open /Open CLI math function names used in the JDBC
+     * function escape clause.
      *
      * @return the list of math functions supported by this database
      * @throws java.sql.SQLException if a database access error occurs
@@ -361,9 +354,9 @@
     }
 
     /**
-     * Retrieves a comma-separated list of string functions available with
-     * this database.  These are the  Open Group CLI string function names used
-     * in the JDBC function escape clause.
+     * Retrieves a comma-separated list of string functions available with this
+     * database. These are the Open Group CLI string function names used in the JDBC
+     * function escape clause.
      *
      * @return the list of string functions supported by this database
      * @throws java.sql.SQLException if a database access error occurs
@@ -373,9 +366,9 @@
     }
 
     /**
-     * Retrieves a comma-separated list of system functions available with
-     * this database.  These are the  Open Group CLI system function names used
-     * in the JDBC function escape clause.
+     * Retrieves a comma-separated list of system functions available with this
+     * database. These are the Open Group CLI system function names used in the JDBC
+     * function escape clause.
      *
      * @return a list of system functions supported by this database
      * @throws java.sql.SQLException if a database access error occurs
@@ -396,14 +389,14 @@
     }
 
     /**
-     * Retrieves the string that can be used to escape wildcard characters.
-     * This is the string that can be used to escape '_' or '%' in
-     * the catalog search parameters that are a pattern (and therefore use one
-     * of the wildcard characters).
+     * Retrieves the string that can be used to escape wildcard characters. This is
+     * the string that can be used to escape '_' or '%' in the catalog search
+     * parameters that are a pattern (and therefore use one of the wildcard
+     * characters).
      * <p/>
-     * <P>The '_' character represents any single character;
-     * the '%' character represents any sequence of zero or
-     * more characters.
+     * <P>
+     * The '_' character represents any single character; the '%' character
+     * represents any sequence of zero or more characters.
      *
      * @return the string used to escape wildcard characters
      * @throws java.sql.SQLException if a database access error occurs
@@ -413,8 +406,8 @@
     }
 
     /**
-     * Retrieves all the "extra" characters that can be used in unquoted
-     * identifier names (those beyond a-z, A-Z, 0-9 and _).
+     * Retrieves all the "extra" characters that can be used in unquoted identifier
+     * names (those beyond a-z, A-Z, 0-9 and _).
      *
      * @return the string containing the extra characters
      * @throws java.sql.SQLException if a database access error occurs
@@ -424,8 +417,8 @@
     }
 
     /**
-     * Retrieves whether this database supports <code>ALTER TABLE</code>
-     * with add column.
+     * Retrieves whether this database supports <code>ALTER TABLE</code> with add
+     * column.
      *
      * @return <code>true</code> if so; <code>false</code> otherwise
      * @throws java.sql.SQLException if a database access error occurs
@@ -435,8 +428,8 @@
     }
 
     /**
-     * Retrieves whether this database supports <code>ALTER TABLE</code>
-     * with drop column.
+     * Retrieves whether this database supports <code>ALTER TABLE</code> with drop
+     * column.
      *
      * @return <code>true</code> if so; <code>false</code> otherwise
      * @throws java.sql.SQLException if a database access error occurs
@@ -448,9 +441,9 @@
     /**
      * Retrieves whether this database supports column aliasing.
      * <p/>
-     * <P>If so, the SQL AS clause can be used to provide names for
-     * computed columns or to provide alias names for columns as
-     * required.
+     * <P>
+     * If so, the SQL AS clause can be used to provide names for computed columns or
+     * to provide alias names for columns as required.
      *
      * @return <code>true</code> if so; <code>false</code> otherwise
      * @throws java.sql.SQLException if a database access error occurs
@@ -461,8 +454,7 @@
 
     /**
      * Retrieves whether this database supports concatenations between
-     * <code>NULL</code> and non-<code>NULL</code> values being
-     * <code>NULL</code>.
+     * <code>NULL</code> and non-<code>NULL</code> values being <code>NULL</code>.
      *
      * @return <code>true</code> if so; <code>false</code> otherwise
      * @throws java.sql.SQLException if a database access error occurs
@@ -472,8 +464,8 @@
     }
 
     /**
-     * Retrieves whether this database supports the <code>CONVERT</code>
-     * function between SQL types.
+     * Retrieves whether this database supports the <code>CONVERT</code> function
+     * between SQL types.
      *
      * @return <code>true</code> if so; <code>false</code> otherwise
      * @throws java.sql.SQLException if a database access error occurs
@@ -483,13 +475,13 @@
     }
 
     /**
-     * Retrieves whether this database supports the <code>CONVERT</code>
-     * for two given SQL types.
+     * Retrieves whether this database supports the <code>CONVERT</code> for two
+     * given SQL types.
      *
-     * @param fromType the type to convert from; one of the type codes from
-     *                 the class <code>java.sql.Types</code>
-     * @param toType   the type to convert to; one of the type codes from
-     *                 the class <code>java.sql.Types</code>
+     * @param fromType the type to convert from; one of the type codes from the
+     * class <code>java.sql.Types</code>
+     * @param toType the type to convert to; one of the type codes from the class
+     * <code>java.sql.Types</code>
      * @return <code>true</code> if so; <code>false</code> otherwise
      * @throws java.sql.SQLException if a database access error occurs
      * @see java.sql.Types
@@ -509,8 +501,8 @@
     }
 
     /**
-     * Retrieves whether, when table correlation names are supported, they
-     * are restricted to being different from the names of the tables.
+     * Retrieves whether, when table correlation names are supported, they are
+     * restricted to being different from the names of the tables.
      *
      * @return <code>true</code> if so; <code>false</code> otherwise
      * @throws java.sql.SQLException if a database access error occurs
@@ -520,8 +512,8 @@
     }
 
     /**
-     * Retrieves whether this database supports expressions in
-     * <code>ORDER BY</code> lists.
+     * Retrieves whether this database supports expressions in <code>ORDER BY</code>
+     * lists.
      *
      * @return <code>true</code> if so; <code>false</code> otherwise
      * @throws java.sql.SQLException if a database access error occurs
@@ -531,9 +523,8 @@
     }
 
     /**
-     * Retrieves whether this database supports using a column that is
-     * not in the <code>SELECT</code> statement in an
-     * <code>ORDER BY</code> clause.
+     * Retrieves whether this database supports using a column that is not in the
+     * <code>SELECT</code> statement in an <code>ORDER BY</code> clause.
      *
      * @return <code>true</code> if so; <code>false</code> otherwise
      * @throws java.sql.SQLException if a database access error occurs
@@ -543,8 +534,8 @@
     }
 
     /**
-     * Retrieves whether this database supports some form of
-     * <code>GROUP BY</code> clause.
+     * Retrieves whether this database supports some form of <code>GROUP BY</code>
+     * clause.
      *
      * @return <code>true</code> if so; <code>false</code> otherwise
      * @throws java.sql.SQLException if a database access error occurs
@@ -554,9 +545,8 @@
     }
 
     /**
-     * Retrieves whether this database supports using a column that is
-     * not in the <code>SELECT</code> statement in a
-     * <code>GROUP BY</code> clause.
+     * Retrieves whether this database supports using a column that is not in the
+     * <code>SELECT</code> statement in a <code>GROUP BY</code> clause.
      *
      * @return <code>true</code> if so; <code>false</code> otherwise
      * @throws java.sql.SQLException if a database access error occurs
@@ -566,10 +556,10 @@
     }
 
     /**
-     * Retrieves whether this database supports using columns not included in
-     * the <code>SELECT</code> statement in a <code>GROUP BY</code> clause
-     * provided that all of the columns in the <code>SELECT</code> statement
-     * are included in the <code>GROUP BY</code> clause.
+     * Retrieves whether this database supports using columns not included in the
+     * <code>SELECT</code> statement in a <code>GROUP BY</code> clause provided that
+     * all of the columns in the <code>SELECT</code> statement are included in the
+     * <code>GROUP BY</code> clause.
      *
      * @return <code>true</code> if so; <code>false</code> otherwise
      * @throws java.sql.SQLException if a database access error occurs
@@ -579,8 +569,8 @@
     }
 
     /**
-     * Retrieves whether this database supports specifying a
-     * <code>LIKE</code> escape clause.
+     * Retrieves whether this database supports specifying a <code>LIKE</code>
+     * escape clause.
      *
      * @return <code>true</code> if so; <code>false</code> otherwise
      * @throws java.sql.SQLException if a database access error occurs
@@ -591,8 +581,8 @@
 
     /**
      * Retrieves whether this database supports getting multiple
-     * <code>ResultSet</code> objects from a single call to the
-     * method <code>execute</code>.
+     * <code>ResultSet</code> objects from a single call to the method
+     * <code>execute</code>.
      *
      * @return <code>true</code> if so; <code>false</code> otherwise
      * @throws java.sql.SQLException if a database access error occurs
@@ -602,8 +592,8 @@
     }
 
     /**
-     * Retrieves whether this database allows having multiple
-     * transactions open at once (on different connections).
+     * Retrieves whether this database allows having multiple transactions open at
+     * once (on different connections).
      *
      * @return <code>true</code> if so; <code>false</code> otherwise
      * @throws java.sql.SQLException if a database access error occurs
@@ -653,8 +643,7 @@
     }
 
     /**
-     * Retrieves whether this database supports the ANSI92 entry level SQL
-     * grammar.
+     * Retrieves whether this database supports the ANSI92 entry level SQL grammar.
      *
      * @return <code>true</code> if so; <code>false</code> otherwise
      * @throws java.sql.SQLException if a database access error occurs
@@ -664,7 +653,8 @@
     }
 
     /**
-     * Retrieves whether this database supports the ANSI92 intermediate SQL grammar supported.
+     * Retrieves whether this database supports the ANSI92 intermediate SQL grammar
+     * supported.
      *
      * @return <code>true</code> if so; <code>false</code> otherwise
      * @throws java.sql.SQLException if a database access error occurs
@@ -674,7 +664,8 @@
     }
 
     /**
-     * Retrieves whether this database supports the ANSI92 full SQL grammar supported.
+     * Retrieves whether this database supports the ANSI92 full SQL grammar
+     * supported.
      *
      * @return <code>true</code> if so; <code>false</code> otherwise
      * @throws java.sql.SQLException if a database access error occurs
@@ -684,8 +675,8 @@
     }
 
     /**
-     * Retrieves whether this database supports the SQL Integrity
-     * Enhancement Facility.
+     * Retrieves whether this database supports the SQL Integrity Enhancement
+     * Facility.
      *
      * @return <code>true</code> if so; <code>false</code> otherwise
      * @throws java.sql.SQLException if a database access error occurs
@@ -715,8 +706,8 @@
     }
 
     /**
-     * Retrieves whether this database provides limited support for outer
-     * joins.  (This will be <code>true</code> if the method
+     * Retrieves whether this database provides limited support for outer joins.
+     * (This will be <code>true</code> if the method
      * <code>supportsFullOuterJoins</code> returns <code>true</code>).
      *
      * @return <code>true</code> if so; <code>false</code> otherwise
@@ -757,11 +748,11 @@
     }
 
     /**
-     * Retrieves whether a catalog appears at the start of a fully qualified
-     * table name.  If not, the catalog appears at the end.
+     * Retrieves whether a catalog appears at the start of a fully qualified table
+     * name. If not, the catalog appears at the end.
      *
-     * @return <code>true</code> if the catalog name appears at the beginning
-     *         of a fully qualified table name; <code>false</code> otherwise
+     * @return <code>true</code> if the catalog name appears at the beginning of a
+     * fully qualified table name; <code>false</code> otherwise
      * @throws java.sql.SQLException if a database access error occurs
      */
     public boolean isCatalogAtStart() throws SQLException {
@@ -769,8 +760,8 @@
     }
 
     /**
-     * Retrieves the <code>String</code> that this database uses as the
-     * separator between a catalog and table name.
+     * Retrieves the <code>String</code> that this database uses as the separator
+     * between a catalog and table name.
      *
      * @return the separator string
      * @throws java.sql.SQLException if a database access error occurs
@@ -820,7 +811,8 @@
     }
 
     /**
-     * Retrieves whether a schema name can be used in a privilege definition statement.
+     * Retrieves whether a schema name can be used in a privilege definition
+     * statement.
      *
      * @return <code>true</code> if so; <code>false</code> otherwise
      * @throws java.sql.SQLException if a database access error occurs
@@ -830,7 +822,8 @@
     }
 
     /**
-     * Retrieves whether a catalog name can be used in a data manipulation statement.
+     * Retrieves whether a catalog name can be used in a data manipulation
+     * statement.
      *
      * @return <code>true</code> if so; <code>false</code> otherwise
      * @throws java.sql.SQLException if a database access error occurs
@@ -860,7 +853,8 @@
     }
 
     /**
-     * Retrieves whether a catalog name can be used in an index definition statement.
+     * Retrieves whether a catalog name can be used in an index definition
+     * statement.
      *
      * @return <code>true</code> if so; <code>false</code> otherwise
      * @throws java.sql.SQLException if a database access error occurs
@@ -870,7 +864,8 @@
     }
 
     /**
-     * Retrieves whether a catalog name can be used in a privilege definition statement.
+     * Retrieves whether a catalog name can be used in a privilege definition
+     * statement.
      *
      * @return <code>true</code> if so; <code>false</code> otherwise
      * @throws java.sql.SQLException if a database access error occurs
@@ -913,8 +908,8 @@
     }
 
     /**
-     * Retrieves whether this database supports stored procedure calls
-     * that use the stored procedure escape syntax.
+     * Retrieves whether this database supports stored procedure calls that use the
+     * stored procedure escape syntax.
      *
      * @return <code>true</code> if so; <code>false</code> otherwise
      * @throws java.sql.SQLException if a database access error occurs
@@ -935,8 +930,8 @@
     }
 
     /**
-     * Retrieves whether this database supports subqueries in
-     * <code>EXISTS</code> expressions.
+     * Retrieves whether this database supports subqueries in <code>EXISTS</code>
+     * expressions.
      *
      * @return <code>true</code> if so; <code>false</code> otherwise
      * @throws java.sql.SQLException if a database access error occurs
@@ -946,8 +941,8 @@
     }
 
     /**
-     * Retrieves whether this database supports subqueries in
-     * <code>IN</code> statements.
+     * Retrieves whether this database supports subqueries in <code>IN</code>
+     * statements.
      *
      * @return <code>true</code> if so; <code>false</code> otherwise
      * @throws java.sql.SQLException if a database access error occurs
@@ -998,11 +993,10 @@
     }
 
     /**
-     * Retrieves whether this database supports keeping cursors open
-     * across commits.
+     * Retrieves whether this database supports keeping cursors open across commits.
      *
-     * @return <code>true</code> if cursors always remain open;
-     *         <code>false</code> if they might not remain open
+     * @return <code>true</code> if cursors always remain open; <code>false</code>
+     * if they might not remain open
      * @throws java.sql.SQLException if a database access error occurs
      */
     public boolean supportsOpenCursorsAcrossCommit() throws SQLException {
@@ -1010,11 +1004,11 @@
     }
 
     /**
-     * Retrieves whether this database supports keeping cursors open
-     * across rollbacks.
+     * Retrieves whether this database supports keeping cursors open across
+     * rollbacks.
      *
-     * @return <code>true</code> if cursors always remain open;
-     *         <code>false</code> if they might not remain open
+     * @return <code>true</code> if cursors always remain open; <code>false</code>
+     * if they might not remain open
      * @throws java.sql.SQLException if a database access error occurs
      */
     public boolean supportsOpenCursorsAcrossRollback() throws SQLException {
@@ -1022,11 +1016,11 @@
     }
 
     /**
-     * Retrieves whether this database supports keeping statements open
-     * across commits.
+     * Retrieves whether this database supports keeping statements open across
+     * commits.
      *
      * @return <code>true</code> if statements always remain open;
-     *         <code>false</code> if they might not remain open
+     * <code>false</code> if they might not remain open
      * @throws java.sql.SQLException if a database access error occurs
      */
     public boolean supportsOpenStatementsAcrossCommit() throws SQLException {
@@ -1034,11 +1028,11 @@
     }
 
     /**
-     * Retrieves whether this database supports keeping statements open
-     * across rollbacks.
+     * Retrieves whether this database supports keeping statements open across
+     * rollbacks.
      *
      * @return <code>true</code> if statements always remain open;
-     *         <code>false</code> if they might not remain open
+     * <code>false</code> if they might not remain open
      * @throws java.sql.SQLException if a database access error occurs
      */
     public boolean supportsOpenStatementsAcrossRollback() throws SQLException {
@@ -1049,9 +1043,8 @@
      * Retrieves the maximum number of hex characters this database allows in an
      * inline binary literal.
      *
-     * @return max the maximum length (in hex characters) for a binary literal;
-     *         a result of zero means that there is no limit or the limit
-     *         is not known
+     * @return max the maximum length (in hex characters) for a binary literal; a
+     * result of zero means that there is no limit or the limit is not known
      * @throws java.sql.SQLException if a database access error occurs
      */
     public int getMaxBinaryLiteralLength() throws SQLException {
@@ -1059,12 +1052,11 @@
     }
 
     /**
-     * Retrieves the maximum number of characters this database allows
-     * for a character literal.
+     * Retrieves the maximum number of characters this database allows for a
+     * character literal.
      *
-     * @return the maximum number of characters allowed for a character literal;
-     *         a result of zero means that there is no limit or the limit is
-     *         not known
+     * @return the maximum number of characters allowed for a character literal; a
+     * result of zero means that there is no limit or the limit is not known
      * @throws java.sql.SQLException if a database access error occurs
      */
     public int getMaxCharLiteralLength() throws SQLException {
@@ -1072,12 +1064,11 @@
     }
 
     /**
-     * Retrieves the maximum number of characters this database allows
-     * for a column name.
+     * Retrieves the maximum number of characters this database allows for a column
+     * name.
      *
-     * @return the maximum number of characters allowed for a column name;
-     *         a result of zero means that there is no limit or the limit
-     *         is not known
+     * @return the maximum number of characters allowed for a column name; a result
+     * of zero means that there is no limit or the limit is not known
      * @throws java.sql.SQLException if a database access error occurs
      */
     public int getMaxColumnNameLength() throws SQLException {
@@ -1088,9 +1079,8 @@
      * Retrieves the maximum number of columns this database allows in a
      * <code>GROUP BY</code> clause.
      *
-     * @return the maximum number of columns allowed;
-     *         a result of zero means that there is no limit or the limit
-     *         is not known
+     * @return the maximum number of columns allowed; a result of zero means that
+     * there is no limit or the limit is not known
      * @throws java.sql.SQLException if a database access error occurs
      */
     public int getMaxColumnsInGroupBy() throws SQLException {
@@ -1100,9 +1090,8 @@
     /**
      * Retrieves the maximum number of columns this database allows in an index.
      *
-     * @return the maximum number of columns allowed;
-     *         a result of zero means that there is no limit or the limit
-     *         is not known
+     * @return the maximum number of columns allowed; a result of zero means that
+     * there is no limit or the limit is not known
      * @throws java.sql.SQLException if a database access error occurs
      */
     public int getMaxColumnsInIndex() throws SQLException {
@@ -1113,9 +1102,8 @@
      * Retrieves the maximum number of columns this database allows in an
      * <code>ORDER BY</code> clause.
      *
-     * @return the maximum number of columns allowed;
-     *         a result of zero means that there is no limit or the limit
-     *         is not known
+     * @return the maximum number of columns allowed; a result of zero means that
+     * there is no limit or the limit is not known
      * @throws java.sql.SQLException if a database access error occurs
      */
     public int getMaxColumnsInOrderBy() throws SQLException {
@@ -1126,9 +1114,8 @@
      * Retrieves the maximum number of columns this database allows in a
      * <code>SELECT</code> list.
      *
-     * @return the maximum number of columns allowed;
-     *         a result of zero means that there is no limit or the limit
-     *         is not known
+     * @return the maximum number of columns allowed; a result of zero means that
+     * there is no limit or the limit is not known
      * @throws java.sql.SQLException if a database access error occurs
      */
     public int getMaxColumnsInSelect() throws SQLException {
@@ -1138,9 +1125,8 @@
     /**
      * Retrieves the maximum number of columns this database allows in a table.
      *
-     * @return the maximum number of columns allowed;
-     *         a result of zero means that there is no limit or the limit
-     *         is not known
+     * @return the maximum number of columns allowed; a result of zero means that
+     * there is no limit or the limit is not known
      * @throws java.sql.SQLException if a database access error occurs
      */
     public int getMaxColumnsInTable() throws SQLException {
@@ -1148,12 +1134,11 @@
     }
 
     /**
-     * Retrieves the maximum number of concurrent connections to this
-     * database that are possible.
+     * Retrieves the maximum number of concurrent connections to this database that
+     * are possible.
      *
-     * @return the maximum number of active connections possible at one time;
-     *         a result of zero means that there is no limit or the limit
-     *         is not known
+     * @return the maximum number of active connections possible at one time; a
+     * result of zero means that there is no limit or the limit is not known
      * @throws java.sql.SQLException if a database access error occurs
      */
     public int getMaxConnections() throws SQLException {
@@ -1164,9 +1149,8 @@
      * Retrieves the maximum number of characters that this database allows in a
      * cursor name.
      *
-     * @return the maximum number of characters allowed in a cursor name;
-     *         a result of zero means that there is no limit or the limit
-     *         is not known
+     * @return the maximum number of characters allowed in a cursor name; a result
+     * of zero means that there is no limit or the limit is not known
      * @throws java.sql.SQLException if a database access error occurs
      */
     public int getMaxCursorNameLength() throws SQLException {
@@ -1174,13 +1158,12 @@
     }
 
     /**
-     * Retrieves the maximum number of bytes this database allows for an
-     * index, including all of the parts of the index.
+     * Retrieves the maximum number of bytes this database allows for an index,
+     * including all of the parts of the index.
      *
      * @return the maximum number of bytes allowed; this limit includes the
-     *         composite of all the constituent parts of the index;
-     *         a result of zero means that there is no limit or the limit
-     *         is not known
+     * composite of all the constituent parts of the index; a result of zero means
+     * that there is no limit or the limit is not known
      * @throws java.sql.SQLException if a database access error occurs
      */
     public int getMaxIndexLength() throws SQLException {
@@ -1191,9 +1174,8 @@
      * Retrieves the maximum number of characters that this database allows in a
      * schema name.
      *
-     * @return the maximum number of characters allowed in a schema name;
-     *         a result of zero means that there is no limit or the limit
-     *         is not known
+     * @return the maximum number of characters allowed in a schema name; a result
+     * of zero means that there is no limit or the limit is not known
      * @throws java.sql.SQLException if a database access error occurs
      */
     public int getMaxSchemaNameLength() throws SQLException {
@@ -1204,9 +1186,8 @@
      * Retrieves the maximum number of characters that this database allows in a
      * procedure name.
      *
-     * @return the maximum number of characters allowed in a procedure name;
-     *         a result of zero means that there is no limit or the limit
-     *         is not known
+     * @return the maximum number of characters allowed in a procedure name; a
+     * result of zero means that there is no limit or the limit is not known
      * @throws java.sql.SQLException if a database access error occurs
      */
     public int getMaxProcedureNameLength() throws SQLException {
@@ -1217,9 +1198,8 @@
      * Retrieves the maximum number of characters that this database allows in a
      * catalog name.
      *
-     * @return the maximum number of characters allowed in a catalog name;
-     *         a result of zero means that there is no limit or the limit
-     *         is not known
+     * @return the maximum number of characters allowed in a catalog name; a result
+     * of zero means that there is no limit or the limit is not known
      * @throws java.sql.SQLException if a database access error occurs
      */
     public int getMaxCatalogNameLength() throws SQLException {
@@ -1227,11 +1207,10 @@
     }
 
     /**
-     * Retrieves the maximum number of bytes this database allows in
-     * a single row.
+     * Retrieves the maximum number of bytes this database allows in a single row.
      *
-     * @return the maximum number of bytes allowed for a row; a result of
-     *         zero means that there is no limit or the limit is not known
+     * @return the maximum number of bytes allowed for a row; a result of zero means
+     * that there is no limit or the limit is not known
      * @throws java.sql.SQLException if a database access error occurs
      */
     public int getMaxRowSize() throws SQLException {
@@ -1239,9 +1218,9 @@
     }
 
     /**
-     * Retrieves whether the return value for the method
-     * <code>getMaxRowSize</code> includes the SQL data types
-     * <code>LONGVARCHAR</code> and <code>LONGVARBINARY</code>.
+     * Retrieves whether the return value for the method <code>getMaxRowSize</code>
+     * includes the SQL data types <code>LONGVARCHAR</code> and
+     * <code>LONGVARBINARY</code>.
      *
      * @return <code>true</code> if so; <code>false</code> otherwise
      * @throws java.sql.SQLException if a database access error occurs
@@ -1251,12 +1230,11 @@
     }
 
     /**
-     * Retrieves the maximum number of characters this database allows in
-     * an SQL statement.
+     * Retrieves the maximum number of characters this database allows in an SQL
+     * statement.
      *
-     * @return the maximum number of characters allowed for an SQL statement;
-     *         a result of zero means that there is no limit or the limit
-     *         is not known
+     * @return the maximum number of characters allowed for an SQL statement; a
+     * result of zero means that there is no limit or the limit is not known
      * @throws java.sql.SQLException if a database access error occurs
      */
     public int getMaxStatementLength() throws SQLException {
@@ -1264,12 +1242,11 @@
     }
 
     /**
-     * Retrieves the maximum number of active statements to this database
-     * that can be open at the same time.
+     * Retrieves the maximum number of active statements to this database that can
+     * be open at the same time.
      *
-     * @return the maximum number of statements that can be open at one time;
-     *         a result of zero means that there is no limit or the limit
-     *         is not known
+     * @return the maximum number of statements that can be open at one time; a
+     * result of zero means that there is no limit or the limit is not known
      * @throws java.sql.SQLException if a database access error occurs
      */
     public int getMaxStatements() throws SQLException {
@@ -1277,12 +1254,11 @@
     }
 
     /**
-     * Retrieves the maximum number of characters this database allows in
-     * a table name.
+     * Retrieves the maximum number of characters this database allows in a table
+     * name.
      *
-     * @return the maximum number of characters allowed for a table name;
-     *         a result of zero means that there is no limit or the limit
-     *         is not known
+     * @return the maximum number of characters allowed for a table name; a result
+     * of zero means that there is no limit or the limit is not known
      * @throws java.sql.SQLException if a database access error occurs
      */
     public int getMaxTableNameLength() throws SQLException {
@@ -1294,8 +1270,8 @@
      * <code>SELECT</code> statement.
      *
      * @return the maximum number of tables allowed in a <code>SELECT</code>
-     *         statement; a result of zero means that there is no limit or
-     *         the limit is not known
+     * statement; a result of zero means that there is no limit or the limit is not
+     * known
      * @throws java.sql.SQLException if a database access error occurs
      */
     public int getMaxTablesInSelect() throws SQLException {
@@ -1303,12 +1279,11 @@
     }
 
     /**
-     * Retrieves the maximum number of characters this database allows in
-     * a user name.
+     * Retrieves the maximum number of characters this database allows in a user
+     * name.
      *
-     * @return the maximum number of characters allowed for a user name;
-     *         a result of zero means that there is no limit or the limit
-     *         is not known
+     * @return the maximum number of characters allowed for a user name; a result of
+     * zero means that there is no limit or the limit is not known
      * @throws java.sql.SQLException if a database access error occurs
      */
     public int getMaxUserNameLength() throws SQLException {
@@ -1316,8 +1291,8 @@
     }
 
     /**
-     * Retrieves this database's default transaction isolation level.  The
-     * possible values are defined in <code>java.sql.Connection</code>.
+     * Retrieves this database's default transaction isolation level. The possible
+     * values are defined in <code>java.sql.Connection</code>.
      *
      * @return the default isolation level
      * @throws java.sql.SQLException if a database access error occurs
@@ -1332,8 +1307,8 @@
      * method <code>commit</code> is a noop, and the isolation level is
      * <code>TRANSACTION_NONE</code>.
      *
-     * @return <code>true</code> if transactions are supported;
-     *         <code>false</code> otherwise
+     * @return <code>true</code> if transactions are supported; <code>false</code>
+     * otherwise
      * @throws java.sql.SQLException if a database access error occurs
      */
     public boolean supportsTransactions() throws SQLException {
@@ -1341,10 +1316,11 @@
     }
 
     /**
-     * Retrieves whether this database supports the given transaction isolation level.
+     * Retrieves whether this database supports the given transaction isolation
+     * level.
      *
      * @param level one of the transaction isolation levels defined in
-     *              <code>java.sql.Connection</code>
+     * <code>java.sql.Connection</code>
      * @return <code>true</code> if so; <code>false</code> otherwise
      * @throws java.sql.SQLException if a database access error occurs
      * @see java.sql.Connection
@@ -1354,8 +1330,8 @@
     }
 
     /**
-     * Retrieves whether this database supports both data definition and
-     * data manipulation statements within a transaction.
+     * Retrieves whether this database supports both data definition and data
+     * manipulation statements within a transaction.
      *
      * @return <code>true</code> if so; <code>false</code> otherwise
      * @throws java.sql.SQLException if a database access error occurs
@@ -1365,8 +1341,8 @@
     }
 
     /**
-     * Retrieves whether this database supports only data manipulation
-     * statements within a transaction.
+     * Retrieves whether this database supports only data manipulation statements
+     * within a transaction.
      *
      * @return <code>true</code> if so; <code>false</code> otherwise
      * @throws java.sql.SQLException if a database access error occurs
@@ -1376,8 +1352,8 @@
     }
 
     /**
-     * Retrieves whether a data definition statement within a transaction forces
-     * the transaction to commit.
+     * Retrieves whether a data definition statement within a transaction forces the
+     * transaction to commit.
      *
      * @return <code>true</code> if so; <code>false</code> otherwise
      * @throws java.sql.SQLException if a database access error occurs
@@ -1387,8 +1363,8 @@
     }
 
     /**
-     * Retrieves whether this database ignores a data definition statement
-     * within a transaction.
+     * Retrieves whether this database ignores a data definition statement within a
+     * transaction.
      *
      * @return <code>true</code> if so; <code>false</code> otherwise
      * @throws java.sql.SQLException if a database access error occurs
@@ -1401,119 +1377,122 @@
      * Retrieves a description of the stored procedures available in the given
      * catalog.
      * <p/>
-     * Only procedure descriptions matching the schema and
-     * procedure name criteria are returned.  They are ordered by
-     * <code>PROCEDURE_SCHEM</code> and <code>PROCEDURE_NAME</code>.
+     * Only procedure descriptions matching the schema and procedure name criteria
+     * are returned. They are ordered by <code>PROCEDURE_SCHEM</code> and
+     * <code>PROCEDURE_NAME</code>.
      * <p/>
-     * <P>Each procedure description has the the following columns:
+     * <P>
+     * Each procedure description has the the following columns:
      * <OL>
-     * <LI><B>PROCEDURE_CAT</B> String => procedure catalog (may be <code>null</code>)
-     * <LI><B>PROCEDURE_SCHEM</B> String => procedure schema (may be <code>null</code>)
+     * <LI><B>PROCEDURE_CAT</B> String => procedure catalog (may be
+     * <code>null</code>)
+     * <LI><B>PROCEDURE_SCHEM</B> String => procedure schema (may be
+     * <code>null</code>)
      * <LI><B>PROCEDURE_NAME</B> String => procedure name
-     * <LI> reserved for future use
-     * <LI> reserved for future use
-     * <LI> reserved for future use
+     * <LI>reserved for future use
+     * <LI>reserved for future use
+     * <LI>reserved for future use
      * <LI><B>REMARKS</B> String => explanatory comment on the procedure
      * <LI><B>PROCEDURE_TYPE</B> short => kind of procedure:
      * <UL>
-     * <LI> procedureResultUnknown - May return a result
-     * <LI> procedureNoResult - Does not return a result
-     * <LI> procedureReturnsResult - Returns a result
+     * <LI>procedureResultUnknown - May return a result
+     * <LI>procedureNoResult - Does not return a result
+     * <LI>procedureReturnsResult - Returns a result
      * </UL>
      * </OL>
      *
-     * @param catalog              a catalog name; must match the catalog name as it
-     *                             is stored in the database; "" retrieves those without a catalog;
-     *                             <code>null</code> means that the catalog name should not be used to narrow
-     *                             the search
-     * @param schemaPattern        a schema name pattern; must match the schema name
-     *                             as it is stored in the database; "" retrieves those without a schema;
-     *                             <code>null</code> means that the schema name should not be used to narrow
-     *                             the search
+     * @param catalog a catalog name; must match the catalog name as it is stored in
+     * the database; "" retrieves those without a catalog; <code>null</code> means
+     * that the catalog name should not be used to narrow the search
+     * @param schemaPattern a schema name pattern; must match the schema name as it
+     * is stored in the database; "" retrieves those without a schema;
+     * <code>null</code> means that the schema name should not be used to narrow the
+     * search
      * @param procedureNamePattern a procedure name pattern; must match the
-     *                             procedure name as it is stored in the database
+     * procedure name as it is stored in the database
      * @return <code>ResultSet</code> - each row is a procedure description
      * @throws java.sql.SQLException if a database access error occurs
      * @see #getSearchStringEscape
      */
-    public ResultSet getProcedures(String catalog, String schemaPattern,
-                                   String procedureNamePattern) throws SQLException {
+    public ResultSet getProcedures(String catalog, String schemaPattern, String procedureNamePattern)
+            throws SQLException {
         return databaseMetaData.getProcedures(catalog, schemaPattern, procedureNamePattern);
     }
 
     /**
-     * Retrieves a description of the given catalog's stored procedure parameter
-     * and result columns.
+     * Retrieves a description of the given catalog's stored procedure parameter and
+     * result columns.
      * <p/>
-     * <P>Only descriptions matching the schema, procedure and
-     * parameter name criteria are returned.  They are ordered by
-     * PROCEDURE_SCHEM and PROCEDURE_NAME. Within this, the return value,
-     * if any, is first. Next are the parameter descriptions in call
-     * order. The column descriptions follow in column number order.
+     * <P>
+     * Only descriptions matching the schema, procedure and parameter name criteria
+     * are returned. They are ordered by PROCEDURE_SCHEM and PROCEDURE_NAME. Within
+     * this, the return value, if any, is first. Next are the parameter descriptions
+     * in call order. The column descriptions follow in column number order.
      * <p/>
-     * <P>Each row in the <code>ResultSet</code> is a parameter description or
-     * column description with the following fields:
+     * <P>
+     * Each row in the <code>ResultSet</code> is a parameter description or column
+     * description with the following fields:
      * <OL>
-     * <LI><B>PROCEDURE_CAT</B> String => procedure catalog (may be <code>null</code>)
-     * <LI><B>PROCEDURE_SCHEM</B> String => procedure schema (may be <code>null</code>)
+     * <LI><B>PROCEDURE_CAT</B> String => procedure catalog (may be
+     * <code>null</code>)
+     * <LI><B>PROCEDURE_SCHEM</B> String => procedure schema (may be
+     * <code>null</code>)
      * <LI><B>PROCEDURE_NAME</B> String => procedure name
      * <LI><B>COLUMN_NAME</B> String => column/parameter name
      * <LI><B>COLUMN_TYPE</B> Short => kind of column/parameter:
      * <UL>
-     * <LI> procedureColumnUnknown - nobody knows
-     * <LI> procedureColumnIn - IN parameter
-     * <LI> procedureColumnInOut - INOUT parameter
-     * <LI> procedureColumnOut - OUT parameter
-     * <LI> procedureColumnReturn - procedure return value
-     * <LI> procedureColumnResult - result column in <code>ResultSet</code>
+     * <LI>procedureColumnUnknown - nobody knows
+     * <LI>procedureColumnIn - IN parameter
+     * <LI>procedureColumnInOut - INOUT parameter
+     * <LI>procedureColumnOut - OUT parameter
+     * <LI>procedureColumnReturn - procedure return value
+     * <LI>procedureColumnResult - result column in <code>ResultSet</code>
      * </UL>
      * <LI><B>DATA_TYPE</B> int => SQL type from java.sql.Types
-     * <LI><B>TYPE_NAME</B> String => SQL type name, for a UDT type the
-     * type name is fully qualified
+     * <LI><B>TYPE_NAME</B> String => SQL type name, for a UDT type the type name is
+     * fully qualified
      * <LI><B>PRECISION</B> int => precision
      * <LI><B>LENGTH</B> int => length in bytes of data
      * <LI><B>SCALE</B> short => scale
      * <LI><B>RADIX</B> short => radix
      * <LI><B>NULLABLE</B> short => can it contain NULL.
      * <UL>
-     * <LI> procedureNoNulls - does not allow NULL values
-     * <LI> procedureNullable - allows NULL values
-     * <LI> procedureNullableUnknown - nullability unknown
+     * <LI>procedureNoNulls - does not allow NULL values
+     * <LI>procedureNullable - allows NULL values
+     * <LI>procedureNullableUnknown - nullability unknown
      * </UL>
      * <LI><B>REMARKS</B> String => comment describing parameter/column
      * </OL>
      * <p/>
-     * <P><B>Note:</B> Some databases may not return the column
-     * descriptions for a procedure. Additional columns beyond
-     * REMARKS can be defined by the database.
+     * <P>
+     * <B>Note:</B> Some databases may not return the column descriptions for a
+     * procedure. Additional columns beyond REMARKS can be defined by the database.
      *
-     * @param catalog              a catalog name; must match the catalog name as it
-     *                             is stored in the database; "" retrieves those without a catalog;
-     *                             <code>null</code> means that the catalog name should not be used to narrow
-     *                             the search
-     * @param schemaPattern        a schema name pattern; must match the schema name
-     *                             as it is stored in the database; "" retrieves those without a schema;
-     *                             <code>null</code> means that the schema name should not be used to narrow
-     *                             the search
+     * @param catalog a catalog name; must match the catalog name as it is stored in
+     * the database; "" retrieves those without a catalog; <code>null</code> means
+     * that the catalog name should not be used to narrow the search
+     * @param schemaPattern a schema name pattern; must match the schema name as it
+     * is stored in the database; "" retrieves those without a schema;
+     * <code>null</code> means that the schema name should not be used to narrow the
+     * search
      * @param procedureNamePattern a procedure name pattern; must match the
-     *                             procedure name as it is stored in the database
-     * @param columnNamePattern    a column name pattern; must match the column name
-     *                             as it is stored in the database
-     * @return <code>ResultSet</code> - each row describes a stored procedure parameter or
-     *         column
+     * procedure name as it is stored in the database
+     * @param columnNamePattern a column name pattern; must match the column name as
+     * it is stored in the database
+     * @return <code>ResultSet</code> - each row describes a stored procedure
+     * parameter or column
      * @throws java.sql.SQLException if a database access error occurs
      * @see #getSearchStringEscape
      */
     public ResultSet getProcedureColumns(String catalog, String schemaPattern, String procedureNamePattern,
-                                         String columnNamePattern) throws SQLException {
+            String columnNamePattern) throws SQLException {
         return databaseMetaData.getProcedureColumns(catalog, schemaPattern, procedureNamePattern, columnNamePattern);
     }
 
     /**
-     * Retrieves a description of the tables available in the given catalog.
-     * Only table descriptions matching the catalog, schema, table
-     * name and type criteria are returned.  They are ordered by
-     * TABLE_TYPE, TABLE_SCHEM and TABLE_NAME.
+     * Retrieves a description of the tables available in the given catalog. Only
+     * table descriptions matching the catalog, schema, table name and type criteria
+     * are returned. They are ordered by TABLE_TYPE, TABLE_SCHEM and TABLE_NAME.
      * <p/>
      * Each table description has the following columns:
      * <OL>
@@ -1521,7 +1500,8 @@
      * <LI><B>TABLE_SCHEM</B> String => table schema (may be <code>null</code>)
      * <LI><B>TABLE_NAME</B> String => table name
      * <LI><B>TABLE_TYPE</B> String => table type. Typical types are "TABLE",
-     * "VIEW", "SYSTEM TABLE", "GLOBAL TEMPORARY", "LOCAL TEMPORARY", "ALIAS", "SYNONYM".
+     * "VIEW", "SYSTEM TABLE", "GLOBAL TEMPORARY", "LOCAL TEMPORARY", "ALIAS",
+     * "SYNONYM".
      * <LI><B>REMARKS</B> String => explanatory comment on the table
      * <LI><B>TYPE_CAT</B> String => the types catalog (may be <code>null</code>)
      * <LI><B>TYPE_SCHEM</B> String => the types schema (may be <code>null</code>)
@@ -1529,45 +1509,46 @@
      * <LI><B>SELF_REFERENCING_COL_NAME</B> String => name of the designated
      * "identifier" column of a typed table (may be <code>null</code>)
      * <LI><B>REF_GENERATION</B> String => specifies how values in
-     * SELF_REFERENCING_COL_NAME are created. Values are
-     * "SYSTEM", "USER", "DERIVED". (may be <code>null</code>)
+     * SELF_REFERENCING_COL_NAME are created. Values are "SYSTEM", "USER",
+     * "DERIVED". (may be <code>null</code>)
      * </OL>
      * <p/>
-     * <P><B>Note:</B> Some databases may not return information for
-     * all tables.
+     * <P>
+     * <B>Note:</B> Some databases may not return information for all tables.
      *
-     * @param catalog          a catalog name; must match the catalog name as it
-     *                         is stored in the database; "" retrieves those without a catalog;
-     *                         <code>null</code> means that the catalog name should not be used to narrow
-     *                         the search
-     * @param schemaPattern    a schema name pattern; must match the schema name
-     *                         as it is stored in the database; "" retrieves those without a schema;
-     *                         <code>null</code> means that the schema name should not be used to narrow
-     *                         the search
-     * @param tableNamePattern a table name pattern; must match the
-     *                         table name as it is stored in the database
-     * @param types            a list of table types to include; <code>null</code> returns all types
+     * @param catalog a catalog name; must match the catalog name as it is stored in
+     * the database; "" retrieves those without a catalog; <code>null</code> means
+     * that the catalog name should not be used to narrow the search
+     * @param schemaPattern a schema name pattern; must match the schema name as it
+     * is stored in the database; "" retrieves those without a schema;
+     * <code>null</code> means that the schema name should not be used to narrow the
+     * search
+     * @param tableNamePattern a table name pattern; must match the table name as it
+     * is stored in the database
+     * @param types a list of table types to include; <code>null</code> returns all
+     * types
      * @return <code>ResultSet</code> - each row is a table description
      * @throws java.sql.SQLException if a database access error occurs
      * @see #getSearchStringEscape
      */
-    public ResultSet getTables(String catalog, String schemaPattern, String tableNamePattern,
-                               String types[]) throws SQLException {
+    public ResultSet getTables(String catalog, String schemaPattern, String tableNamePattern, String types[])
+            throws SQLException {
         return databaseMetaData.getTables(catalog, schemaPattern, tableNamePattern, types);
     }
 
     /**
-     * Retrieves the schema names available in this database.  The results
-     * are ordered by schema name.
+     * Retrieves the schema names available in this database. The results are
+     * ordered by schema name.
      * <p/>
-     * <P>The schema column is:
+     * <P>
+     * The schema column is:
      * <OL>
      * <LI><B>TABLE_SCHEM</B> String => schema name
      * <LI><B>TABLE_CATALOG</B> String => catalog name (may be <code>null</code>)
      * </OL>
      *
-     * @return a <code>ResultSet</code> object in which each row is a
-     *         schema decription
+     * @return a <code>ResultSet</code> object in which each row is a schema
+     * decription
      * @throws java.sql.SQLException if a database access error occurs
      */
     public ResultSet getSchemas() throws SQLException {
@@ -1575,16 +1556,17 @@
     }
 
     /**
-     * Retrieves the catalog names available in this database.  The results
-     * are ordered by catalog name.
+     * Retrieves the catalog names available in this database. The results are
+     * ordered by catalog name.
      * <p/>
-     * <P>The catalog column is:
+     * <P>
+     * The catalog column is:
      * <OL>
      * <LI><B>TABLE_CAT</B> String => catalog name
      * </OL>
      *
-     * @return a <code>ResultSet</code> object in which each row has a
-     *         single <code>String</code> column that is a catalog name
+     * @return a <code>ResultSet</code> object in which each row has a single
+     * <code>String</code> column that is a catalog name
      * @throws java.sql.SQLException if a database access error occurs
      */
     public ResultSet getCatalogs() throws SQLException {
@@ -1592,18 +1574,19 @@
     }
 
     /**
-     * Retrieves the table types available in this database.  The results
-     * are ordered by table type.
+     * Retrieves the table types available in this database. The results are ordered
+     * by table type.
      * <p/>
-     * <P>The table type is:
+     * <P>
+     * The table type is:
      * <OL>
-     * <LI><B>TABLE_TYPE</B> String => table type.  Typical types are "TABLE",
-     * "VIEW", "SYSTEM TABLE", "GLOBAL TEMPORARY",
-     * "LOCAL TEMPORARY", "ALIAS", "SYNONYM".
+     * <LI><B>TABLE_TYPE</B> String => table type. Typical types are "TABLE",
+     * "VIEW", "SYSTEM TABLE", "GLOBAL TEMPORARY", "LOCAL TEMPORARY", "ALIAS",
+     * "SYNONYM".
      * </OL>
      *
-     * @return a <code>ResultSet</code> object in which each row has a
-     *         single <code>String</code> column that is a table type
+     * @return a <code>ResultSet</code> object in which each row has a single
+     * <code>String</code> column that is a table type
      * @throws java.sql.SQLException if a database access error occurs
      */
     public ResultSet getTableTypes() throws SQLException {
@@ -1611,85 +1594,85 @@
     }
 
     /**
-     * Retrieves a description of table columns available in
-     * the specified catalog.
+     * Retrieves a description of table columns available in the specified catalog.
      * <p/>
-     * <P>Only column descriptions matching the catalog, schema, table
-     * and column name criteria are returned.  They are ordered by
-     * <code>TABLE_SCHEM</code>, <code>TABLE_NAME</code>, and
-     * <code>ORDINAL_POSITION</code>.
+     * <P>
+     * Only column descriptions matching the catalog, schema, table and column name
+     * criteria are returned. They are ordered by <code>TABLE_SCHEM</code>,
+     * <code>TABLE_NAME</code>, and <code>ORDINAL_POSITION</code>.
      * <p/>
-     * <P>Each column description has the following columns:
+     * <P>
+     * Each column description has the following columns:
      * <OL>
      * <LI><B>TABLE_CAT</B> String => table catalog (may be <code>null</code>)
      * <LI><B>TABLE_SCHEM</B> String => table schema (may be <code>null</code>)
      * <LI><B>TABLE_NAME</B> String => table name
      * <LI><B>COLUMN_NAME</B> String => column name
      * <LI><B>DATA_TYPE</B> int => SQL type from java.sql.Types
-     * <LI><B>TYPE_NAME</B> String => Data source dependent type name,
-     * for a UDT the type name is fully qualified
-     * <LI><B>COLUMN_SIZE</B> int => column size.  For char or date
-     * types this is the maximum number of characters, for numeric or
-     * decimal types this is precision.
+     * <LI><B>TYPE_NAME</B> String => Data source dependent type name, for a UDT the
+     * type name is fully qualified
+     * <LI><B>COLUMN_SIZE</B> int => column size. For char or date types this is the
+     * maximum number of characters, for numeric or decimal types this is precision.
      * <LI><B>BUFFER_LENGTH</B> is not used.
      * <LI><B>DECIMAL_DIGITS</B> int => the number of fractional digits
      * <LI><B>NUM_PREC_RADIX</B> int => Radix (typically either 10 or 2)
      * <LI><B>NULLABLE</B> int => is NULL allowed.
      * <UL>
-     * <LI> columnNoNulls - might not allow <code>NULL</code> values
-     * <LI> columnNullable - definitely allows <code>NULL</code> values
-     * <LI> columnNullableUnknown - nullability unknown
+     * <LI>columnNoNulls - might not allow <code>NULL</code> values
+     * <LI>columnNullable - definitely allows <code>NULL</code> values
+     * <LI>columnNullableUnknown - nullability unknown
      * </UL>
-     * <LI><B>REMARKS</B> String => comment describing column (may be <code>null</code>)
+     * <LI><B>REMARKS</B> String => comment describing column (may be
+     * <code>null</code>)
      * <LI><B>COLUMN_DEF</B> String => default value (may be <code>null</code>)
      * <LI><B>SQL_DATA_TYPE</B> int => unused
      * <LI><B>SQL_DATETIME_SUB</B> int => unused
-     * <LI><B>CHAR_OCTET_LENGTH</B> int => for char types the
-     * maximum number of bytes in the column
-     * <LI><B>ORDINAL_POSITION</B> int    => index of column in table
-     * (starting at 1)
-     * <LI><B>IS_NULLABLE</B> String => "NO" means column definitely
-     * does not allow NULL values; "YES" means the column might
-     * allow NULL values.  An empty string means nobody knows.
-     * <LI><B>SCOPE_CATLOG</B> String => catalog of table that is the scope
-     * of a reference attribute (<code>null</code> if DATA_TYPE isn't REF)
-     * <LI><B>SCOPE_SCHEMA</B> String => schema of table that is the scope
-     * of a reference attribute (<code>null</code> if the DATA_TYPE isn't REF)
-     * <LI><B>SCOPE_TABLE</B> String => table name that this the scope
-     * of a reference attribure (<code>null</code> if the DATA_TYPE isn't REF)
-     * <LI><B>SOURCE_DATA_TYPE</B> short => source type of a distinct type or user-generated
-     * Ref type, SQL type from java.sql.Types (<code>null</code> if DATA_TYPE
-     * isn't DISTINCT or user-generated REF)
+     * <LI><B>CHAR_OCTET_LENGTH</B> int => for char types the maximum number of
+     * bytes in the column
+     * <LI><B>ORDINAL_POSITION</B> int => index of column in table (starting at 1)
+     * <LI><B>IS_NULLABLE</B> String => "NO" means column definitely does not allow
+     * NULL values; "YES" means the column might allow NULL values. An empty string
+     * means nobody knows.
+     * <LI><B>SCOPE_CATLOG</B> String => catalog of table that is the scope of a
+     * reference attribute (<code>null</code> if DATA_TYPE isn't REF)
+     * <LI><B>SCOPE_SCHEMA</B> String => schema of table that is the scope of a
+     * reference attribute (<code>null</code> if the DATA_TYPE isn't REF)
+     * <LI><B>SCOPE_TABLE</B> String => table name that this the scope of a
+     * reference attribure (<code>null</code> if the DATA_TYPE isn't REF)
+     * <LI><B>SOURCE_DATA_TYPE</B> short => source type of a distinct type or
+     * user-generated Ref type, SQL type from java.sql.Types (<code>null</code> if
+     * DATA_TYPE isn't DISTINCT or user-generated REF)
      * </OL>
      *
-     * @param catalog           a catalog name; must match the catalog name as it
-     *                          is stored in the database; "" retrieves those without a catalog;
-     *                          <code>null</code> means that the catalog name should not be used to narrow
-     *                          the search
-     * @param schemaPattern     a schema name pattern; must match the schema name
-     *                          as it is stored in the database; "" retrieves those without a schema;
-     *                          <code>null</code> means that the schema name should not be used to narrow
-     *                          the search
-     * @param tableNamePattern  a table name pattern; must match the
-     *                          table name as it is stored in the database
-     * @param columnNamePattern a column name pattern; must match the column
-     *                          name as it is stored in the database
+     * @param catalog a catalog name; must match the catalog name as it is stored in
+     * the database; "" retrieves those without a catalog; <code>null</code> means
+     * that the catalog name should not be used to narrow the search
+     * @param schemaPattern a schema name pattern; must match the schema name as it
+     * is stored in the database; "" retrieves those without a schema;
+     * <code>null</code> means that the schema name should not be used to narrow the
+     * search
+     * @param tableNamePattern a table name pattern; must match the table name as it
+     * is stored in the database
+     * @param columnNamePattern a column name pattern; must match the column name as
+     * it is stored in the database
      * @return <code>ResultSet</code> - each row is a column description
      * @throws java.sql.SQLException if a database access error occurs
      * @see #getSearchStringEscape
      */
-    public ResultSet getColumns(String catalog, String schemaPattern, String tableNamePattern,
-                                String columnNamePattern) throws SQLException {
+    public ResultSet getColumns(String catalog, String schemaPattern, String tableNamePattern, String columnNamePattern)
+            throws SQLException {
         return databaseMetaData.getColumns(catalog, schemaPattern, tableNamePattern, columnNamePattern);
     }
 
     /**
      * Retrieves a description of the access rights for a table's columns.
      * <p/>
-     * <P>Only privileges matching the column name criteria are
-     * returned.  They are ordered by COLUMN_NAME and PRIVILEGE.
+     * <P>
+     * Only privileges matching the column name criteria are returned. They are
+     * ordered by COLUMN_NAME and PRIVILEGE.
      * <p/>
-     * <P>Each privilige description has the following columns:
+     * <P>
+     * Each privilige description has the following columns:
      * <OL>
      * <LI><B>TABLE_CAT</B> String => table catalog (may be <code>null</code>)
      * <LI><B>TABLE_SCHEM</B> String => table schema (may be <code>null</code>)
@@ -1697,130 +1680,126 @@
      * <LI><B>COLUMN_NAME</B> String => column name
      * <LI><B>GRANTOR</B> => grantor of access (may be <code>null</code>)
      * <LI><B>GRANTEE</B> String => grantee of access
-     * <LI><B>PRIVILEGE</B> String => name of access (SELECT,
-     * INSERT, UPDATE, REFRENCES, ...)
-     * <LI><B>IS_GRANTABLE</B> String => "YES" if grantee is permitted
-     * to grant to others; "NO" if not; <code>null</code> if unknown
+     * <LI><B>PRIVILEGE</B> String => name of access (SELECT, INSERT, UPDATE,
+     * REFRENCES, ...)
+     * <LI><B>IS_GRANTABLE</B> String => "YES" if grantee is permitted to grant to
+     * others; "NO" if not; <code>null</code> if unknown
      * </OL>
      *
-     * @param catalog           a catalog name; must match the catalog name as it
-     *                          is stored in the database; "" retrieves those without a catalog;
-     *                          <code>null</code> means that the catalog name should not be used to narrow
-     *                          the search
-     * @param schema            a schema name; must match the schema name as it is
-     *                          stored in the database; "" retrieves those without a schema;
-     *                          <code>null</code> means that the schema name should not be used to narrow
-     *                          the search
-     * @param table             a table name; must match the table name as it is
-     *                          stored in the database
-     * @param columnNamePattern a column name pattern; must match the column
-     *                          name as it is stored in the database
+     * @param catalog a catalog name; must match the catalog name as it is stored in
+     * the database; "" retrieves those without a catalog; <code>null</code> means
+     * that the catalog name should not be used to narrow the search
+     * @param schema a schema name; must match the schema name as it is stored in
+     * the database; "" retrieves those without a schema; <code>null</code> means
+     * that the schema name should not be used to narrow the search
+     * @param table a table name; must match the table name as it is stored in the
+     * database
+     * @param columnNamePattern a column name pattern; must match the column name as
+     * it is stored in the database
      * @return <code>ResultSet</code> - each row is a column privilege description
      * @throws java.sql.SQLException if a database access error occurs
      * @see #getSearchStringEscape
      */
-    public ResultSet getColumnPrivileges(String catalog, String schema, String table,
-                                         String columnNamePattern) throws SQLException {
+    public ResultSet getColumnPrivileges(String catalog, String schema, String table, String columnNamePattern)
+            throws SQLException {
         return databaseMetaData.getColumnPrivileges(catalog, schema, table, columnNamePattern);
     }
 
     /**
-     * Retrieves a description of the access rights for each table available
-     * in a catalog. Note that a table privilege applies to one or
-     * more columns in the table. It would be wrong to assume that
-     * this privilege applies to all columns (this may be true for
-     * some systems but is not true for all.)
+     * Retrieves a description of the access rights for each table available in a
+     * catalog. Note that a table privilege applies to one or more columns in the
+     * table. It would be wrong to assume that this privilege applies to all columns
+     * (this may be true for some systems but is not true for all.)
      * <p/>
-     * <P>Only privileges matching the schema and table name
-     * criteria are returned.  They are ordered by TABLE_SCHEM,
-     * TABLE_NAME, and PRIVILEGE.
+     * <P>
+     * Only privileges matching the schema and table name criteria are returned.
+     * They are ordered by TABLE_SCHEM, TABLE_NAME, and PRIVILEGE.
      * <p/>
-     * <P>Each privilige description has the following columns:
+     * <P>
+     * Each privilige description has the following columns:
      * <OL>
      * <LI><B>TABLE_CAT</B> String => table catalog (may be <code>null</code>)
      * <LI><B>TABLE_SCHEM</B> String => table schema (may be <code>null</code>)
      * <LI><B>TABLE_NAME</B> String => table name
      * <LI><B>GRANTOR</B> => grantor of access (may be <code>null</code>)
      * <LI><B>GRANTEE</B> String => grantee of access
-     * <LI><B>PRIVILEGE</B> String => name of access (SELECT,
-     * INSERT, UPDATE, REFRENCES, ...)
-     * <LI><B>IS_GRANTABLE</B> String => "YES" if grantee is permitted
-     * to grant to others; "NO" if not; <code>null</code> if unknown
+     * <LI><B>PRIVILEGE</B> String => name of access (SELECT, INSERT, UPDATE,
+     * REFRENCES, ...)
+     * <LI><B>IS_GRANTABLE</B> String => "YES" if grantee is permitted to grant to
+     * others; "NO" if not; <code>null</code> if unknown
      * </OL>
      *
-     * @param catalog          a catalog name; must match the catalog name as it
-     *                         is stored in the database; "" retrieves those without a catalog;
-     *                         <code>null</code> means that the catalog name should not be used to narrow
-     *                         the search
-     * @param schemaPattern    a schema name pattern; must match the schema name
-     *                         as it is stored in the database; "" retrieves those without a schema;
-     *                         <code>null</code> means that the schema name should not be used to narrow
-     *                         the search
-     * @param tableNamePattern a table name pattern; must match the
-     *                         table name as it is stored in the database
+     * @param catalog a catalog name; must match the catalog name as it is stored in
+     * the database; "" retrieves those without a catalog; <code>null</code> means
+     * that the catalog name should not be used to narrow the search
+     * @param schemaPattern a schema name pattern; must match the schema name as it
+     * is stored in the database; "" retrieves those without a schema;
+     * <code>null</code> means that the schema name should not be used to narrow the
+     * search
+     * @param tableNamePattern a table name pattern; must match the table name as it
+     * is stored in the database
      * @return <code>ResultSet</code> - each row is a table privilege description
      * @throws java.sql.SQLException if a database access error occurs
      * @see #getSearchStringEscape
      */
-    public ResultSet getTablePrivileges(String catalog, String schemaPattern,
-                                        String tableNamePattern) throws SQLException {
+    public ResultSet getTablePrivileges(String catalog, String schemaPattern, String tableNamePattern)
+            throws SQLException {
         return databaseMetaData.getTablePrivileges(catalog, schemaPattern, tableNamePattern);
     }
 
     /**
-     * Retrieves a description of a table's optimal set of columns that
-     * uniquely identifies a row. They are ordered by SCOPE.
+     * Retrieves a description of a table's optimal set of columns that uniquely
+     * identifies a row. They are ordered by SCOPE.
      * <p/>
-     * <P>Each column description has the following columns:
+     * <P>
+     * Each column description has the following columns:
      * <OL>
      * <LI><B>SCOPE</B> short => actual scope of result
      * <UL>
-     * <LI> bestRowTemporary - very temporary, while using row
-     * <LI> bestRowTransaction - valid for remainder of current transaction
-     * <LI> bestRowSession - valid for remainder of current session
+     * <LI>bestRowTemporary - very temporary, while using row
+     * <LI>bestRowTransaction - valid for remainder of current transaction
+     * <LI>bestRowSession - valid for remainder of current session
      * </UL>
      * <LI><B>COLUMN_NAME</B> String => column name
      * <LI><B>DATA_TYPE</B> int => SQL data type from java.sql.Types
-     * <LI><B>TYPE_NAME</B> String => Data source dependent type name,
-     * for a UDT the type name is fully qualified
+     * <LI><B>TYPE_NAME</B> String => Data source dependent type name, for a UDT the
+     * type name is fully qualified
      * <LI><B>COLUMN_SIZE</B> int => precision
      * <LI><B>BUFFER_LENGTH</B> int => not used
-     * <LI><B>DECIMAL_DIGITS</B> short     => scale
-     * <LI><B>PSEUDO_COLUMN</B> short => is this a pseudo column
-     * like an Oracle ROWID
+     * <LI><B>DECIMAL_DIGITS</B> short => scale
+     * <LI><B>PSEUDO_COLUMN</B> short => is this a pseudo column like an Oracle
+     * ROWID
      * <UL>
-     * <LI> bestRowUnknown - may or may not be pseudo column
-     * <LI> bestRowNotPseudo - is NOT a pseudo column
-     * <LI> bestRowPseudo - is a pseudo column
+     * <LI>bestRowUnknown - may or may not be pseudo column
+     * <LI>bestRowNotPseudo - is NOT a pseudo column
+     * <LI>bestRowPseudo - is a pseudo column
      * </UL>
      * </OL>
      *
-     * @param catalog  a catalog name; must match the catalog name as it
-     *                 is stored in the database; "" retrieves those without a catalog;
-     *                 <code>null</code> means that the catalog name should not be used to narrow
-     *                 the search
-     * @param schema   a schema name; must match the schema name
-     *                 as it is stored in the database; "" retrieves those without a schema;
-     *                 <code>null</code> means that the schema name should not be used to narrow
-     *                 the search
-     * @param table    a table name; must match the table name as it is stored
-     *                 in the database
-     * @param scope    the scope of interest; use same values as SCOPE
+     * @param catalog a catalog name; must match the catalog name as it is stored in
+     * the database; "" retrieves those without a catalog; <code>null</code> means
+     * that the catalog name should not be used to narrow the search
+     * @param schema a schema name; must match the schema name as it is stored in
+     * the database; "" retrieves those without a schema; <code>null</code> means
+     * that the schema name should not be used to narrow the search
+     * @param table a table name; must match the table name as it is stored in the
+     * database
+     * @param scope the scope of interest; use same values as SCOPE
      * @param nullable include columns that are nullable.
      * @return <code>ResultSet</code> - each row is a column description
      * @throws java.sql.SQLException if a database access error occurs
      */
-    public ResultSet getBestRowIdentifier(String catalog, String schema, String table, int scope,
-                                          boolean nullable) throws SQLException {
+    public ResultSet getBestRowIdentifier(String catalog, String schema, String table, int scope, boolean nullable)
+            throws SQLException {
         return databaseMetaData.getBestRowIdentifier(catalog, schema, table, scope, nullable);
     }
 
     /**
-     * Retrieves a description of a table's columns that are automatically
-     * updated when any value in a row is updated.  They are
-     * unordered.
+     * Retrieves a description of a table's columns that are automatically updated
+     * when any value in a row is updated. They are unordered.
      * <p/>
-     * <P>Each column description has the following columns:
+     * <P>
+     * Each column description has the following columns:
      * <OL>
      * <LI><B>SCOPE</B> short => is not used
      * <LI><B>COLUMN_NAME</B> String => column name
@@ -1828,28 +1807,26 @@
      * <LI><B>TYPE_NAME</B> String => Data source-dependent type name
      * <LI><B>COLUMN_SIZE</B> int => precision
      * <LI><B>BUFFER_LENGTH</B> int => length of column value in bytes
-     * <LI><B>DECIMAL_DIGITS</B> short     => scale
-     * <LI><B>PSEUDO_COLUMN</B> short => whether this is pseudo column
-     * like an Oracle ROWID
+     * <LI><B>DECIMAL_DIGITS</B> short => scale
+     * <LI><B>PSEUDO_COLUMN</B> short => whether this is pseudo column like an
+     * Oracle ROWID
      * <UL>
-     * <LI> versionColumnUnknown - may or may not be pseudo column
-     * <LI> versionColumnNotPseudo - is NOT a pseudo column
-     * <LI> versionColumnPseudo - is a pseudo column
+     * <LI>versionColumnUnknown - may or may not be pseudo column
+     * <LI>versionColumnNotPseudo - is NOT a pseudo column
+     * <LI>versionColumnPseudo - is a pseudo column
      * </UL>
      * </OL>
      *
-     * @param catalog a catalog name; must match the catalog name as it
-     *                is stored in the database; "" retrieves those without a catalog;
-     *                <code>null</code> means that the catalog name should not be used to narrow
-     *                the search
-     * @param schema  a schema name; must match the schema name
-     *                as it is stored in the database; "" retrieves those without a schema;
-     *                <code>null</code> means that the schema name should not be used to narrow
-     *                the search
-     * @param table   a table name; must match the table name as it is stored
-     *                in the database
-     * @return a <code>ResultSet</code> object in which each row is a
-     *         column description
+     * @param catalog a catalog name; must match the catalog name as it is stored in
+     * the database; "" retrieves those without a catalog; <code>null</code> means
+     * that the catalog name should not be used to narrow the search
+     * @param schema a schema name; must match the schema name as it is stored in
+     * the database; "" retrieves those without a schema; <code>null</code> means
+     * that the schema name should not be used to narrow the search
+     * @param table a table name; must match the table name as it is stored in the
+     * database
+     * @return a <code>ResultSet</code> object in which each row is a column
+     * description
      * @throws java.sql.SQLException if a database access error occurs
      */
     public ResultSet getVersionColumns(String catalog, String schema, String table) throws SQLException {
@@ -1857,10 +1834,11 @@
     }
 
     /**
-     * Retrieves a description of the given table's primary key columns.  They
-     * are ordered by COLUMN_NAME.
+     * Retrieves a description of the given table's primary key columns. They are
+     * ordered by COLUMN_NAME.
      * <p/>
-     * <P>Each primary key column description has the following columns:
+     * <P>
+     * Each primary key column description has the following columns:
      * <OL>
      * <LI><B>TABLE_CAT</B> String => table catalog (may be <code>null</code>)
      * <LI><B>TABLE_SCHEM</B> String => table schema (may be <code>null</code>)
@@ -1870,16 +1848,14 @@
      * <LI><B>PK_NAME</B> String => primary key name (may be <code>null</code>)
      * </OL>
      *
-     * @param catalog a catalog name; must match the catalog name as it
-     *                is stored in the database; "" retrieves those without a catalog;
-     *                <code>null</code> means that the catalog name should not be used to narrow
-     *                the search
-     * @param schema  a schema name; must match the schema name
-     *                as it is stored in the database; "" retrieves those without a schema;
-     *                <code>null</code> means that the schema name should not be used to narrow
-     *                the search
-     * @param table   a table name; must match the table name as it is stored
-     *                in the database
+     * @param catalog a catalog name; must match the catalog name as it is stored in
+     * the database; "" retrieves those without a catalog; <code>null</code> means
+     * that the catalog name should not be used to narrow the search
+     * @param schema a schema name; must match the schema name as it is stored in
+     * the database; "" retrieves those without a schema; <code>null</code> means
+     * that the schema name should not be used to narrow the search
+     * @param table a table name; must match the table name as it is stored in the
+     * database
      * @return <code>ResultSet</code> - each row is a primary key column description
      * @throws java.sql.SQLException if a database access error occurs
      */
@@ -1888,74 +1864,71 @@
     }
 
     /**
-     * Retrieves a description of the primary key columns that are
-     * referenced by a table's foreign key columns (the primary keys
-     * imported by a table).  They are ordered by PKTABLE_CAT,
-     * PKTABLE_SCHEM, PKTABLE_NAME, and KEY_SEQ.
+     * Retrieves a description of the primary key columns that are referenced by a
+     * table's foreign key columns (the primary keys imported by a table). They are
+     * ordered by PKTABLE_CAT, PKTABLE_SCHEM, PKTABLE_NAME, and KEY_SEQ.
      * <p/>
-     * <P>Each primary key column description has the following columns:
+     * <P>
+     * Each primary key column description has the following columns:
      * <OL>
-     * <LI><B>PKTABLE_CAT</B> String => primary key table catalog
-     * being imported (may be <code>null</code>)
-     * <LI><B>PKTABLE_SCHEM</B> String => primary key table schema
-     * being imported (may be <code>null</code>)
-     * <LI><B>PKTABLE_NAME</B> String => primary key table name
-     * being imported
-     * <LI><B>PKCOLUMN_NAME</B> String => primary key column name
-     * being imported
-     * <LI><B>FKTABLE_CAT</B> String => foreign key table catalog (may be <code>null</code>)
-     * <LI><B>FKTABLE_SCHEM</B> String => foreign key table schema (may be <code>null</code>)
+     * <LI><B>PKTABLE_CAT</B> String => primary key table catalog being imported
+     * (may be <code>null</code>)
+     * <LI><B>PKTABLE_SCHEM</B> String => primary key table schema being imported
+     * (may be <code>null</code>)
+     * <LI><B>PKTABLE_NAME</B> String => primary key table name being imported
+     * <LI><B>PKCOLUMN_NAME</B> String => primary key column name being imported
+     * <LI><B>FKTABLE_CAT</B> String => foreign key table catalog (may be
+     * <code>null</code>)
+     * <LI><B>FKTABLE_SCHEM</B> String => foreign key table schema (may be
+     * <code>null</code>)
      * <LI><B>FKTABLE_NAME</B> String => foreign key table name
      * <LI><B>FKCOLUMN_NAME</B> String => foreign key column name
      * <LI><B>KEY_SEQ</B> short => sequence number within a foreign key
-     * <LI><B>UPDATE_RULE</B> short => What happens to a
-     * foreign key when the primary key is updated:
+     * <LI><B>UPDATE_RULE</B> short => What happens to a foreign key when the
+     * primary key is updated:
      * <UL>
-     * <LI> importedNoAction - do not allow update of primary
-     * key if it has been imported
-     * <LI> importedKeyCascade - change imported key to agree
-     * with primary key update
-     * <LI> importedKeySetNull - change imported key to <code>NULL</code>
-     * if its primary key has been updated
-     * <LI> importedKeySetDefault - change imported key to default values
-     * if its primary key has been updated
-     * <LI> importedKeyRestrict - same as importedKeyNoAction
-     * (for ODBC 2.x compatibility)
+     * <LI>importedNoAction - do not allow update of primary key if it has been
+     * imported
+     * <LI>importedKeyCascade - change imported key to agree with primary key update
+     * <LI>importedKeySetNull - change imported key to <code>NULL</code> if its
+     * primary key has been updated
+     * <LI>importedKeySetDefault - change imported key to default values if its
+     * primary key has been updated
+     * <LI>importedKeyRestrict - same as importedKeyNoAction (for ODBC 2.x
+     * compatibility)
      * </UL>
-     * <LI><B>DELETE_RULE</B> short => What happens to
-     * the foreign key when primary is deleted.
+     * <LI><B>DELETE_RULE</B> short => What happens to the foreign key when primary
+     * is deleted.
      * <UL>
-     * <LI> importedKeyNoAction - do not allow delete of primary
-     * key if it has been imported
-     * <LI> importedKeyCascade - delete rows that import a deleted key
-     * <LI> importedKeySetNull - change imported key to NULL if
-     * its primary key has been deleted
-     * <LI> importedKeyRestrict - same as importedKeyNoAction
-     * (for ODBC 2.x compatibility)
-     * <LI> importedKeySetDefault - change imported key to default if
-     * its primary key has been deleted
+     * <LI>importedKeyNoAction - do not allow delete of primary key if it has been
+     * imported
+     * <LI>importedKeyCascade - delete rows that import a deleted key
+     * <LI>importedKeySetNull - change imported key to NULL if its primary key has
+     * been deleted
+     * <LI>importedKeyRestrict - same as importedKeyNoAction (for ODBC 2.x
+     * compatibility)
+     * <LI>importedKeySetDefault - change imported key to default if its primary key
+     * has been deleted
      * </UL>
      * <LI><B>FK_NAME</B> String => foreign key name (may be <code>null</code>)
      * <LI><B>PK_NAME</B> String => primary key name (may be <code>null</code>)
      * <LI><B>DEFERRABILITY</B> short => can the evaluation of foreign key
      * constraints be deferred until commit
      * <UL>
-     * <LI> importedKeyInitiallyDeferred - see SQL92 for definition
-     * <LI> importedKeyInitiallyImmediate - see SQL92 for definition
-     * <LI> importedKeyNotDeferrable - see SQL92 for definition
+     * <LI>importedKeyInitiallyDeferred - see SQL92 for definition
+     * <LI>importedKeyInitiallyImmediate - see SQL92 for definition
+     * <LI>importedKeyNotDeferrable - see SQL92 for definition
      * </UL>
      * </OL>
      *
-     * @param catalog a catalog name; must match the catalog name as it
-     *                is stored in the database; "" retrieves those without a catalog;
-     *                <code>null</code> means that the catalog name should not be used to narrow
-     *                the search
-     * @param schema  a schema name; must match the schema name
-     *                as it is stored in the database; "" retrieves those without a schema;
-     *                <code>null</code> means that the schema name should not be used to narrow
-     *                the search
-     * @param table   a table name; must match the table name as it is stored
-     *                in the database
+     * @param catalog a catalog name; must match the catalog name as it is stored in
+     * the database; "" retrieves those without a catalog; <code>null</code> means
+     * that the catalog name should not be used to narrow the search
+     * @param schema a schema name; must match the schema name as it is stored in
+     * the database; "" retrieves those without a schema; <code>null</code> means
+     * that the schema name should not be used to narrow the search
+     * @param table a table name; must match the table name as it is stored in the
+     * database
      * @return <code>ResultSet</code> - each row is a primary key column description
      * @throws java.sql.SQLException if a database access error occurs
      * @see #getExportedKeys
@@ -1965,76 +1938,73 @@
     }
 
     /**
-     * Retrieves a description of the foreign key columns that reference the
-     * given table's primary key columns (the foreign keys exported by a
-     * table).  They are ordered by FKTABLE_CAT, FKTABLE_SCHEM,
-     * FKTABLE_NAME, and KEY_SEQ.
+     * Retrieves a description of the foreign key columns that reference the given
+     * table's primary key columns (the foreign keys exported by a table). They are
+     * ordered by FKTABLE_CAT, FKTABLE_SCHEM, FKTABLE_NAME, and KEY_SEQ.
      * <p/>
-     * <P>Each foreign key column description has the following columns:
+     * <P>
+     * Each foreign key column description has the following columns:
      * <OL>
-     * <LI><B>PKTABLE_CAT</B> String => primary key table catalog (may be <code>null</code>)
-     * <LI><B>PKTABLE_SCHEM</B> String => primary key table schema (may be <code>null</code>)
+     * <LI><B>PKTABLE_CAT</B> String => primary key table catalog (may be
+     * <code>null</code>)
+     * <LI><B>PKTABLE_SCHEM</B> String => primary key table schema (may be
+     * <code>null</code>)
      * <LI><B>PKTABLE_NAME</B> String => primary key table name
      * <LI><B>PKCOLUMN_NAME</B> String => primary key column name
-     * <LI><B>FKTABLE_CAT</B> String => foreign key table catalog (may be <code>null</code>)
-     * being exported (may be <code>null</code>)
-     * <LI><B>FKTABLE_SCHEM</B> String => foreign key table schema (may be <code>null</code>)
-     * being exported (may be <code>null</code>)
-     * <LI><B>FKTABLE_NAME</B> String => foreign key table name
-     * being exported
-     * <LI><B>FKCOLUMN_NAME</B> String => foreign key column name
-     * being exported
+     * <LI><B>FKTABLE_CAT</B> String => foreign key table catalog (may be
+     * <code>null</code>) being exported (may be <code>null</code>)
+     * <LI><B>FKTABLE_SCHEM</B> String => foreign key table schema (may be
+     * <code>null</code>) being exported (may be <code>null</code>)
+     * <LI><B>FKTABLE_NAME</B> String => foreign key table name being exported
+     * <LI><B>FKCOLUMN_NAME</B> String => foreign key column name being exported
      * <LI><B>KEY_SEQ</B> short => sequence number within foreign key
-     * <LI><B>UPDATE_RULE</B> short => What happens to
-     * foreign key when primary is updated:
+     * <LI><B>UPDATE_RULE</B> short => What happens to foreign key when primary is
+     * updated:
      * <UL>
-     * <LI> importedNoAction - do not allow update of primary
-     * key if it has been imported
-     * <LI> importedKeyCascade - change imported key to agree
-     * with primary key update
-     * <LI> importedKeySetNull - change imported key to <code>NULL</code> if
-     * its primary key has been updated
-     * <LI> importedKeySetDefault - change imported key to default values
-     * if its primary key has been updated
-     * <LI> importedKeyRestrict - same as importedKeyNoAction
-     * (for ODBC 2.x compatibility)
+     * <LI>importedNoAction - do not allow update of primary key if it has been
+     * imported
+     * <LI>importedKeyCascade - change imported key to agree with primary key update
+     * <LI>importedKeySetNull - change imported key to <code>NULL</code> if its
+     * primary key has been updated
+     * <LI>importedKeySetDefault - change imported key to default values if its
+     * primary key has been updated
+     * <LI>importedKeyRestrict - same as importedKeyNoAction (for ODBC 2.x
+     * compatibility)
      * </UL>
-     * <LI><B>DELETE_RULE</B> short => What happens to
-     * the foreign key when primary is deleted.
+     * <LI><B>DELETE_RULE</B> short => What happens to the foreign key when primary
+     * is deleted.
      * <UL>
-     * <LI> importedKeyNoAction - do not allow delete of primary
-     * key if it has been imported
-     * <LI> importedKeyCascade - delete rows that import a deleted key
-     * <LI> importedKeySetNull - change imported key to <code>NULL</code> if
-     * its primary key has been deleted
-     * <LI> importedKeyRestrict - same as importedKeyNoAction
-     * (for ODBC 2.x compatibility)
-     * <LI> importedKeySetDefault - change imported key to default if
-     * its primary key has been deleted
+     * <LI>importedKeyNoAction - do not allow delete of primary key if it has been
+     * imported
+     * <LI>importedKeyCascade - delete rows that import a deleted key
+     * <LI>importedKeySetNull - change imported key to <code>NULL</code> if its
+     * primary key has been deleted
+     * <LI>importedKeyRestrict - same as importedKeyNoAction (for ODBC 2.x
+     * compatibility)
+     * <LI>importedKeySetDefault - change imported key to default if its primary key
+     * has been deleted
      * </UL>
      * <LI><B>FK_NAME</B> String => foreign key name (may be <code>null</code>)
      * <LI><B>PK_NAME</B> String => primary key name (may be <code>null</code>)
      * <LI><B>DEFERRABILITY</B> short => can the evaluation of foreign key
      * constraints be deferred until commit
      * <UL>
-     * <LI> importedKeyInitiallyDeferred - see SQL92 for definition
-     * <LI> importedKeyInitiallyImmediate - see SQL92 for definition
-     * <LI> importedKeyNotDeferrable - see SQL92 for definition
+     * <LI>importedKeyInitiallyDeferred - see SQL92 for definition
+     * <LI>importedKeyInitiallyImmediate - see SQL92 for definition
+     * <LI>importedKeyNotDeferrable - see SQL92 for definition
      * </UL>
      * </OL>
      *
-     * @param catalog a catalog name; must match the catalog name as it
-     *                is stored in this database; "" retrieves those without a catalog;
-     *                <code>null</code> means that the catalog name should not be used to narrow
-     *                the search
-     * @param schema  a schema name; must match the schema name
-     *                as it is stored in the database; "" retrieves those without a schema;
-     *                <code>null</code> means that the schema name should not be used to narrow
-     *                the search
-     * @param table   a table name; must match the table name as it is stored
-     *                in this database
-     * @return a <code>ResultSet</code> object in which each row is a
-     *         foreign key column description
+     * @param catalog a catalog name; must match the catalog name as it is stored in
+     * this database; "" retrieves those without a catalog; <code>null</code> means
+     * that the catalog name should not be used to narrow the search
+     * @param schema a schema name; must match the schema name as it is stored in
+     * the database; "" retrieves those without a schema; <code>null</code> means
+     * that the schema name should not be used to narrow the search
+     * @param table a table name; must match the table name as it is stored in this
+     * database
+     * @return a <code>ResultSet</code> object in which each row is a foreign key
+     * column description
      * @throws java.sql.SQLException if a database access error occurs
      * @see #getImportedKeys
      */
@@ -2044,129 +2014,128 @@
 
     /**
      * Retrieves a description of the foreign key columns in the given foreign key
-     * table that reference the primary key columns of the given primary key
-     * table (describe how one table imports another's key). This
-     * should normally return a single foreign key/primary key pair because
-     * most tables import a foreign key from a table only once.  They
-     * are ordered by FKTABLE_CAT, FKTABLE_SCHEM, FKTABLE_NAME, and
-     * KEY_SEQ.
+     * table that reference the primary key columns of the given primary key table
+     * (describe how one table imports another's key). This should normally return a
+     * single foreign key/primary key pair because most tables import a foreign key
+     * from a table only once. They are ordered by FKTABLE_CAT, FKTABLE_SCHEM,
+     * FKTABLE_NAME, and KEY_SEQ.
      * <p/>
-     * <P>Each foreign key column description has the following columns:
+     * <P>
+     * Each foreign key column description has the following columns:
      * <OL>
-     * <LI><B>PKTABLE_CAT</B> String => primary key table catalog (may be <code>null</code>)
-     * <LI><B>PKTABLE_SCHEM</B> String => primary key table schema (may be <code>null</code>)
+     * <LI><B>PKTABLE_CAT</B> String => primary key table catalog (may be
+     * <code>null</code>)
+     * <LI><B>PKTABLE_SCHEM</B> String => primary key table schema (may be
+     * <code>null</code>)
      * <LI><B>PKTABLE_NAME</B> String => primary key table name
      * <LI><B>PKCOLUMN_NAME</B> String => primary key column name
-     * <LI><B>FKTABLE_CAT</B> String => foreign key table catalog (may be <code>null</code>)
-     * being exported (may be <code>null</code>)
-     * <LI><B>FKTABLE_SCHEM</B> String => foreign key table schema (may be <code>null</code>)
-     * being exported (may be <code>null</code>)
-     * <LI><B>FKTABLE_NAME</B> String => foreign key table name
-     * being exported
-     * <LI><B>FKCOLUMN_NAME</B> String => foreign key column name
-     * being exported
+     * <LI><B>FKTABLE_CAT</B> String => foreign key table catalog (may be
+     * <code>null</code>) being exported (may be <code>null</code>)
+     * <LI><B>FKTABLE_SCHEM</B> String => foreign key table schema (may be
+     * <code>null</code>) being exported (may be <code>null</code>)
+     * <LI><B>FKTABLE_NAME</B> String => foreign key table name being exported
+     * <LI><B>FKCOLUMN_NAME</B> String => foreign key column name being exported
      * <LI><B>KEY_SEQ</B> short => sequence number within foreign key
-     * <LI><B>UPDATE_RULE</B> short => What happens to
-     * foreign key when primary is updated:
+     * <LI><B>UPDATE_RULE</B> short => What happens to foreign key when primary is
+     * updated:
      * <UL>
-     * <LI> importedNoAction - do not allow update of primary
-     * key if it has been imported
-     * <LI> importedKeyCascade - change imported key to agree
-     * with primary key update
-     * <LI> importedKeySetNull - change imported key to <code>NULL</code> if
-     * its primary key has been updated
-     * <LI> importedKeySetDefault - change imported key to default values
-     * if its primary key has been updated
-     * <LI> importedKeyRestrict - same as importedKeyNoAction
-     * (for ODBC 2.x compatibility)
+     * <LI>importedNoAction - do not allow update of primary key if it has been
+     * imported
+     * <LI>importedKeyCascade - change imported key to agree with primary key update
+     * <LI>importedKeySetNull - change imported key to <code>NULL</code> if its
+     * primary key has been updated
+     * <LI>importedKeySetDefault - change imported key to default values if its
+     * primary key has been updated
+     * <LI>importedKeyRestrict - same as importedKeyNoAction (for ODBC 2.x
+     * compatibility)
      * </UL>
-     * <LI><B>DELETE_RULE</B> short => What happens to
-     * the foreign key when primary is deleted.
+     * <LI><B>DELETE_RULE</B> short => What happens to the foreign key when primary
+     * is deleted.
      * <UL>
-     * <LI> importedKeyNoAction - do not allow delete of primary
-     * key if it has been imported
-     * <LI> importedKeyCascade - delete rows that import a deleted key
-     * <LI> importedKeySetNull - change imported key to <code>NULL</code> if
-     * its primary key has been deleted
-     * <LI> importedKeyRestrict - same as importedKeyNoAction
-     * (for ODBC 2.x compatibility)
-     * <LI> importedKeySetDefault - change imported key to default if
-     * its primary key has been deleted
+     * <LI>importedKeyNoAction - do not allow delete of primary key if it has been
+     * imported
+     * <LI>importedKeyCascade - delete rows that import a deleted key
+     * <LI>importedKeySetNull - change imported key to <code>NULL</code> if its
+     * primary key has been deleted
+     * <LI>importedKeyRestrict - same as importedKeyNoAction (for ODBC 2.x
+     * compatibility)
+     * <LI>importedKeySetDefault - change imported key to default if its primary key
+     * has been deleted
      * </UL>
      * <LI><B>FK_NAME</B> String => foreign key name (may be <code>null</code>)
      * <LI><B>PK_NAME</B> String => primary key name (may be <code>null</code>)
      * <LI><B>DEFERRABILITY</B> short => can the evaluation of foreign key
      * constraints be deferred until commit
      * <UL>
-     * <LI> importedKeyInitiallyDeferred - see SQL92 for definition
-     * <LI> importedKeyInitiallyImmediate - see SQL92 for definition
-     * <LI> importedKeyNotDeferrable - see SQL92 for definition
+     * <LI>importedKeyInitiallyDeferred - see SQL92 for definition
+     * <LI>importedKeyInitiallyImmediate - see SQL92 for definition
+     * <LI>importedKeyNotDeferrable - see SQL92 for definition
      * </UL>
      * </OL>
      *
-     * @param primaryCatalog a catalog name; must match the catalog name
-     *                       as it is stored in the database; "" retrieves those without a
-     *                       catalog; <code>null</code> means drop catalog name from the selection criteria
-     * @param primarySchema  a schema name; must match the schema name as
-     *                       it is stored in the database; "" retrieves those without a schema;
-     *                       <code>null</code> means drop schema name from the selection criteria
-     * @param primaryTable   the name of the table that exports the key; must match
-     *                       the table name as it is stored in the database
-     * @param foreignCatalog a catalog name; must match the catalog name as
-     *                       it is stored in the database; "" retrieves those without a
-     *                       catalog; <code>null</code> means drop catalog name from the selection criteria
-     * @param foreignSchema  a schema name; must match the schema name as it
-     *                       is stored in the database; "" retrieves those without a schema;
-     *                       <code>null</code> means drop schema name from the selection criteria
-     * @param foreignTable   the name of the table that imports the key; must match
-     *                       the table name as it is stored in the database
+     * @param primaryCatalog a catalog name; must match the catalog name as it is
+     * stored in the database; "" retrieves those without a catalog;
+     * <code>null</code> means drop catalog name from the selection criteria
+     * @param primarySchema a schema name; must match the schema name as it is
+     * stored in the database; "" retrieves those without a schema;
+     * <code>null</code> means drop schema name from the selection criteria
+     * @param primaryTable the name of the table that exports the key; must match
+     * the table name as it is stored in the database
+     * @param foreignCatalog a catalog name; must match the catalog name as it is
+     * stored in the database; "" retrieves those without a catalog;
+     * <code>null</code> means drop catalog name from the selection criteria
+     * @param foreignSchema a schema name; must match the schema name as it is
+     * stored in the database; "" retrieves those without a schema;
+     * <code>null</code> means drop schema name from the selection criteria
+     * @param foreignTable the name of the table that imports the key; must match
+     * the table name as it is stored in the database
      * @return <code>ResultSet</code> - each row is a foreign key column description
      * @throws java.sql.SQLException if a database access error occurs
      * @see #getImportedKeys
      */
     public ResultSet getCrossReference(String primaryCatalog, String primarySchema, String primaryTable,
-                                       String foreignCatalog, String foreignSchema, String foreignTable)
-            throws SQLException {
-        return databaseMetaData.getCrossReference(primaryCatalog, primarySchema, primaryTable,
-                foreignCatalog, foreignSchema, foreignTable);
+            String foreignCatalog, String foreignSchema, String foreignTable) throws SQLException {
+        return databaseMetaData.getCrossReference(primaryCatalog, primarySchema, primaryTable, foreignCatalog,
+                foreignSchema, foreignTable);
     }
 
     /**
-     * Retrieves a description of all the standard SQL types supported by
-     * this database. They are ordered by DATA_TYPE and then by how
-     * closely the data type maps to the corresponding JDBC SQL type.
+     * Retrieves a description of all the standard SQL types supported by this
+     * database. They are ordered by DATA_TYPE and then by how closely the data type
+     * maps to the corresponding JDBC SQL type.
      * <p/>
-     * <P>Each type description has the following columns:
+     * <P>
+     * Each type description has the following columns:
      * <OL>
      * <LI><B>TYPE_NAME</B> String => Type name
      * <LI><B>DATA_TYPE</B> int => SQL data type from java.sql.Types
      * <LI><B>PRECISION</B> int => maximum precision
-     * <LI><B>LITERAL_PREFIX</B> String => prefix used to quote a literal
-     * (may be <code>null</code>)
-     * <LI><B>LITERAL_SUFFIX</B> String => suffix used to quote a literal
-     * (may be <code>null</code>)
-     * <LI><B>CREATE_PARAMS</B> String => parameters used in creating
-     * the type (may be <code>null</code>)
+     * <LI><B>LITERAL_PREFIX</B> String => prefix used to quote a literal (may be
+     * <code>null</code>)
+     * <LI><B>LITERAL_SUFFIX</B> String => suffix used to quote a literal (may be
+     * <code>null</code>)
+     * <LI><B>CREATE_PARAMS</B> String => parameters used in creating the type (may
+     * be <code>null</code>)
      * <LI><B>NULLABLE</B> short => can you use NULL for this type.
      * <UL>
-     * <LI> typeNoNulls - does not allow NULL values
-     * <LI> typeNullable - allows NULL values
-     * <LI> typeNullableUnknown - nullability unknown
+     * <LI>typeNoNulls - does not allow NULL values
+     * <LI>typeNullable - allows NULL values
+     * <LI>typeNullableUnknown - nullability unknown
      * </UL>
      * <LI><B>CASE_SENSITIVE</B> boolean=> is it case sensitive.
      * <LI><B>SEARCHABLE</B> short => can you use "WHERE" based on this type:
      * <UL>
-     * <LI> typePredNone - No support
-     * <LI> typePredChar - Only supported with WHERE .. LIKE
-     * <LI> typePredBasic - Supported except for WHERE .. LIKE
-     * <LI> typeSearchable - Supported for all WHERE ..
+     * <LI>typePredNone - No support
+     * <LI>typePredChar - Only supported with WHERE .. LIKE
+     * <LI>typePredBasic - Supported except for WHERE .. LIKE
+     * <LI>typeSearchable - Supported for all WHERE ..
      * </UL>
      * <LI><B>UNSIGNED_ATTRIBUTE</B> boolean => is it unsigned.
      * <LI><B>FIXED_PREC_SCALE</B> boolean => can it be a money value.
-     * <LI><B>AUTO_INCREMENT</B> boolean => can it be used for an
-     * auto-increment value.
-     * <LI><B>LOCAL_TYPE_NAME</B> String => localized version of type name
-     * (may be <code>null</code>)
+     * <LI><B>AUTO_INCREMENT</B> boolean => can it be used for an auto-increment
+     * value.
+     * <LI><B>LOCAL_TYPE_NAME</B> String => localized version of type name (may be
+     * <code>null</code>)
      * <LI><B>MINIMUM_SCALE</B> short => minimum scale supported
      * <LI><B>MAXIMUM_SCALE</B> short => maximum scale supported
      * <LI><B>SQL_DATA_TYPE</B> int => unused
@@ -2174,8 +2143,8 @@
      * <LI><B>NUM_PREC_RADIX</B> int => usually 2 or 10
      * </OL>
      *
-     * @return a <code>ResultSet</code> object in which each row is an SQL
-     *         type description
+     * @return a <code>ResultSet</code> object in which each row is an SQL type
+     * description
      * @throws java.sql.SQLException if a database access error occurs
      */
     public ResultSet getTypeInfo() throws SQLException {
@@ -2186,62 +2155,60 @@
      * Retrieves a description of the given table's indices and statistics. They are
      * ordered by NON_UNIQUE, TYPE, INDEX_NAME, and ORDINAL_POSITION.
      * <p/>
-     * <P>Each index column description has the following columns:
+     * <P>
+     * Each index column description has the following columns:
      * <OL>
      * <LI><B>TABLE_CAT</B> String => table catalog (may be <code>null</code>)
      * <LI><B>TABLE_SCHEM</B> String => table schema (may be <code>null</code>)
      * <LI><B>TABLE_NAME</B> String => table name
-     * <LI><B>NON_UNIQUE</B> boolean => Can index values be non-unique.
-     * false when TYPE is tableIndexStatistic
-     * <LI><B>INDEX_QUALIFIER</B> String => index catalog (may be <code>null</code>);
-     * <code>null</code> when TYPE is tableIndexStatistic
+     * <LI><B>NON_UNIQUE</B> boolean => Can index values be non-unique. false when
+     * TYPE is tableIndexStatistic
+     * <LI><B>INDEX_QUALIFIER</B> String => index catalog (may be
+     * <code>null</code>); <code>null</code> when TYPE is tableIndexStatistic
      * <LI><B>INDEX_NAME</B> String => index name; <code>null</code> when TYPE is
      * tableIndexStatistic
      * <LI><B>TYPE</B> short => index type:
      * <UL>
-     * <LI> tableIndexStatistic - this identifies table statistics that are
-     * returned in conjuction with a table's index descriptions
-     * <LI> tableIndexClustered - this is a clustered index
-     * <LI> tableIndexHashed - this is a hashed index
-     * <LI> tableIndexOther - this is some other style of index
+     * <LI>tableIndexStatistic - this identifies table statistics that are returned
+     * in conjuction with a table's index descriptions
+     * <LI>tableIndexClustered - this is a clustered index
+     * <LI>tableIndexHashed - this is a hashed index
+     * <LI>tableIndexOther - this is some other style of index
      * </UL>
-     * <LI><B>ORDINAL_POSITION</B> short => column sequence number
-     * within index; zero when TYPE is tableIndexStatistic
+     * <LI><B>ORDINAL_POSITION</B> short => column sequence number within index;
+     * zero when TYPE is tableIndexStatistic
      * <LI><B>COLUMN_NAME</B> String => column name; <code>null</code> when TYPE is
      * tableIndexStatistic
-     * <LI><B>ASC_OR_DESC</B> String => column sort sequence, "A" => ascending,
-     * "D" => descending, may be <code>null</code> if sort sequence is not supported;
+     * <LI><B>ASC_OR_DESC</B> String => column sort sequence, "A" => ascending, "D"
+     * => descending, may be <code>null</code> if sort sequence is not supported;
      * <code>null</code> when TYPE is tableIndexStatistic
-     * <LI><B>CARDINALITY</B> int => When TYPE is tableIndexStatistic, then
-     * this is the number of rows in the table; otherwise, it is the
-     * number of unique values in the index.
-     * <LI><B>PAGES</B> int => When TYPE is  tableIndexStatisic then
-     * this is the number of pages used for the table, otherwise it
-     * is the number of pages used for the current index.
-     * <LI><B>FILTER_CONDITION</B> String => Filter condition, if any.
-     * (may be <code>null</code>)
+     * <LI><B>CARDINALITY</B> int => When TYPE is tableIndexStatistic, then this is
+     * the number of rows in the table; otherwise, it is the number of unique values
+     * in the index.
+     * <LI><B>PAGES</B> int => When TYPE is tableIndexStatisic then this is the
+     * number of pages used for the table, otherwise it is the number of pages used
+     * for the current index.
+     * <LI><B>FILTER_CONDITION</B> String => Filter condition, if any. (may be
+     * <code>null</code>)
      * </OL>
      *
-     * @param catalog     a catalog name; must match the catalog name as it
-     *                    is stored in this database; "" retrieves those without a catalog;
-     *                    <code>null</code> means that the catalog name should not be used to narrow
-     *                    the search
-     * @param schema      a schema name; must match the schema name
-     *                    as it is stored in this database; "" retrieves those without a schema;
-     *                    <code>null</code> means that the schema name should not be used to narrow
-     *                    the search
-     * @param table       a table name; must match the table name as it is stored
-     *                    in this database
-     * @param unique      when true, return only indices for unique values;
-     *                    when false, return indices regardless of whether unique or not
-     * @param approximate when true, result is allowed to reflect approximate
-     *                    or out of data values; when false, results are requested to be
-     *                    accurate
+     * @param catalog a catalog name; must match the catalog name as it is stored in
+     * this database; "" retrieves those without a catalog; <code>null</code> means
+     * that the catalog name should not be used to narrow the search
+     * @param schema a schema name; must match the schema name as it is stored in
+     * this database; "" retrieves those without a schema; <code>null</code> means
+     * that the schema name should not be used to narrow the search
+     * @param table a table name; must match the table name as it is stored in this
+     * database
+     * @param unique when true, return only indices for unique values; when false,
+     * return indices regardless of whether unique or not
+     * @param approximate when true, result is allowed to reflect approximate or out
+     * of data values; when false, results are requested to be accurate
      * @return <code>ResultSet</code> - each row is an index column description
      * @throws java.sql.SQLException if a database access error occurs
      */
-    public ResultSet getIndexInfo(String catalog, String schema, String table, boolean unique,
-                                  boolean approximate) throws SQLException {
+    public ResultSet getIndexInfo(String catalog, String schema, String table, boolean unique, boolean approximate)
+            throws SQLException {
         return databaseMetaData.getIndexInfo(catalog, schema, table, unique, approximate);
     }
 
@@ -2259,10 +2226,10 @@
     }
 
     /**
-     * Retrieves whether this database supports the given concurrency type
-     * in combination with the given result set type.
+     * Retrieves whether this database supports the given concurrency type in
+     * combination with the given result set type.
      *
-     * @param type        defined in <code>java.sql.ResultSet</code>
+     * @param type defined in <code>java.sql.ResultSet</code>
      * @param concurrency type defined in <code>java.sql.ResultSet</code>
      * @return <code>true</code> if so; <code>false</code> otherwise
      * @throws java.sql.SQLException if a database access error occurs
@@ -2274,15 +2241,15 @@
     }
 
     /**
-     * Retrieves whether for the given type of <code>ResultSet</code> object,
-     * the result set's own updates are visible.
+     * Retrieves whether for the given type of <code>ResultSet</code> object, the
+     * result set's own updates are visible.
      *
      * @param type the <code>ResultSet</code> type; one of
-     *             <code>ResultSet.TYPE_FORWARD_ONLY</code>,
-     *             <code>ResultSet.TYPE_SCROLL_INSENSITIVE</code>, or
-     *             <code>ResultSet.TYPE_SCROLL_SENSITIVE</code>
-     * @return <code>true</code> if updates are visible for the given result set type;
-     *         <code>false</code> otherwise
+     * <code>ResultSet.TYPE_FORWARD_ONLY</code>,
+     * <code>ResultSet.TYPE_SCROLL_INSENSITIVE</code>, or
+     * <code>ResultSet.TYPE_SCROLL_SENSITIVE</code>
+     * @return <code>true</code> if updates are visible for the given result set
+     * type; <code>false</code> otherwise
      * @throws java.sql.SQLException if a database access error occurs
      * @since 1.2
      */
@@ -2294,11 +2261,11 @@
      * Retrieves whether a result set's own deletes are visible.
      *
      * @param type the <code>ResultSet</code> type; one of
-     *             <code>ResultSet.TYPE_FORWARD_ONLY</code>,
-     *             <code>ResultSet.TYPE_SCROLL_INSENSITIVE</code>, or
-     *             <code>ResultSet.TYPE_SCROLL_SENSITIVE</code>
-     * @return <code>true</code> if deletes are visible for the given result set type;
-     *         <code>false</code> otherwise
+     * <code>ResultSet.TYPE_FORWARD_ONLY</code>,
+     * <code>ResultSet.TYPE_SCROLL_INSENSITIVE</code>, or
+     * <code>ResultSet.TYPE_SCROLL_SENSITIVE</code>
+     * @return <code>true</code> if deletes are visible for the given result set
+     * type; <code>false</code> otherwise
      * @throws java.sql.SQLException if a database access error occurs
      * @since 1.2
      */
@@ -2310,11 +2277,11 @@
      * Retrieves whether a result set's own inserts are visible.
      *
      * @param type the <code>ResultSet</code> type; one of
-     *             <code>ResultSet.TYPE_FORWARD_ONLY</code>,
-     *             <code>ResultSet.TYPE_SCROLL_INSENSITIVE</code>, or
-     *             <code>ResultSet.TYPE_SCROLL_SENSITIVE</code>
-     * @return <code>true</code> if inserts are visible for the given result set type;
-     *         <code>false</code> otherwise
+     * <code>ResultSet.TYPE_FORWARD_ONLY</code>,
+     * <code>ResultSet.TYPE_SCROLL_INSENSITIVE</code>, or
+     * <code>ResultSet.TYPE_SCROLL_SENSITIVE</code>
+     * @return <code>true</code> if inserts are visible for the given result set
+     * type; <code>false</code> otherwise
      * @throws java.sql.SQLException if a database access error occurs
      * @since 1.2
      */
@@ -2326,12 +2293,11 @@
      * Retrieves whether updates made by others are visible.
      *
      * @param type the <code>ResultSet</code> type; one of
-     *             <code>ResultSet.TYPE_FORWARD_ONLY</code>,
-     *             <code>ResultSet.TYPE_SCROLL_INSENSITIVE</code>, or
-     *             <code>ResultSet.TYPE_SCROLL_SENSITIVE</code>
-     * @return <code>true</code> if updates made by others
-     *         are visible for the given result set type;
-     *         <code>false</code> otherwise
+     * <code>ResultSet.TYPE_FORWARD_ONLY</code>,
+     * <code>ResultSet.TYPE_SCROLL_INSENSITIVE</code>, or
+     * <code>ResultSet.TYPE_SCROLL_SENSITIVE</code>
+     * @return <code>true</code> if updates made by others are visible for the given
+     * result set type; <code>false</code> otherwise
      * @throws java.sql.SQLException if a database access error occurs
      * @since 1.2
      */
@@ -2343,12 +2309,11 @@
      * Retrieves whether deletes made by others are visible.
      *
      * @param type the <code>ResultSet</code> type; one of
-     *             <code>ResultSet.TYPE_FORWARD_ONLY</code>,
-     *             <code>ResultSet.TYPE_SCROLL_INSENSITIVE</code>, or
-     *             <code>ResultSet.TYPE_SCROLL_SENSITIVE</code>
-     * @return <code>true</code> if deletes made by others
-     *         are visible for the given result set type;
-     *         <code>false</code> otherwise
+     * <code>ResultSet.TYPE_FORWARD_ONLY</code>,
+     * <code>ResultSet.TYPE_SCROLL_INSENSITIVE</code>, or
+     * <code>ResultSet.TYPE_SCROLL_SENSITIVE</code>
+     * @return <code>true</code> if deletes made by others are visible for the given
+     * result set type; <code>false</code> otherwise
      * @throws java.sql.SQLException if a database access error occurs
      * @since 1.2
      */
@@ -2360,12 +2325,11 @@
      * Retrieves whether inserts made by others are visible.
      *
      * @param type the <code>ResultSet</code> type; one of
-     *             <code>ResultSet.TYPE_FORWARD_ONLY</code>,
-     *             <code>ResultSet.TYPE_SCROLL_INSENSITIVE</code>, or
-     *             <code>ResultSet.TYPE_SCROLL_SENSITIVE</code>
-     * @return <code>true</code> if inserts made by others
-     *         are visible for the given result set type;
-     *         <code>false</code> otherwise
+     * <code>ResultSet.TYPE_FORWARD_ONLY</code>,
+     * <code>ResultSet.TYPE_SCROLL_INSENSITIVE</code>, or
+     * <code>ResultSet.TYPE_SCROLL_SENSITIVE</code>
+     * @return <code>true</code> if inserts made by others are visible for the given
+     * result set type; <code>false</code> otherwise
      * @throws java.sql.SQLException if a database access error occurs
      * @since 1.2
      */
@@ -2374,15 +2338,15 @@
     }
 
     /**
-     * Retrieves whether or not a visible row update can be detected by
-     * calling the method <code>ResultSet.rowUpdated</code>.
+     * Retrieves whether or not a visible row update can be detected by calling the
+     * method <code>ResultSet.rowUpdated</code>.
      *
      * @param type the <code>ResultSet</code> type; one of
-     *             <code>ResultSet.TYPE_FORWARD_ONLY</code>,
-     *             <code>ResultSet.TYPE_SCROLL_INSENSITIVE</code>, or
-     *             <code>ResultSet.TYPE_SCROLL_SENSITIVE</code>
+     * <code>ResultSet.TYPE_FORWARD_ONLY</code>,
+     * <code>ResultSet.TYPE_SCROLL_INSENSITIVE</code>, or
+     * <code>ResultSet.TYPE_SCROLL_SENSITIVE</code>
      * @return <code>true</code> if changes are detected by the result set type;
-     *         <code>false</code> otherwise
+     * <code>false</code> otherwise
      * @throws java.sql.SQLException if a database access error occurs
      * @since 1.2
      */
@@ -2391,17 +2355,17 @@
     }
 
     /**
-     * Retrieves whether or not a visible row delete can be detected by
-     * calling the method <code>ResultSet.rowDeleted</code>.  If the method
+     * Retrieves whether or not a visible row delete can be detected by calling the
+     * method <code>ResultSet.rowDeleted</code>. If the method
      * <code>deletesAreDetected</code> returns <code>false</code>, it means that
      * deleted rows are removed from the result set.
      *
      * @param type the <code>ResultSet</code> type; one of
-     *             <code>ResultSet.TYPE_FORWARD_ONLY</code>,
-     *             <code>ResultSet.TYPE_SCROLL_INSENSITIVE</code>, or
-     *             <code>ResultSet.TYPE_SCROLL_SENSITIVE</code>
-     * @return <code>true</code> if deletes are detected by the given result set type;
-     *         <code>false</code> otherwise
+     * <code>ResultSet.TYPE_FORWARD_ONLY</code>,
+     * <code>ResultSet.TYPE_SCROLL_INSENSITIVE</code>, or
+     * <code>ResultSet.TYPE_SCROLL_SENSITIVE</code>
+     * @return <code>true</code> if deletes are detected by the given result set
+     * type; <code>false</code> otherwise
      * @throws java.sql.SQLException if a database access error occurs
      * @since 1.2
      */
@@ -2410,15 +2374,15 @@
     }
 
     /**
-     * Retrieves whether or not a visible row insert can be detected
-     * by calling the method <code>ResultSet.rowInserted</code>.
+     * Retrieves whether or not a visible row insert can be detected by calling the
+     * method <code>ResultSet.rowInserted</code>.
      *
      * @param type the <code>ResultSet</code> type; one of
-     *             <code>ResultSet.TYPE_FORWARD_ONLY</code>,
-     *             <code>ResultSet.TYPE_SCROLL_INSENSITIVE</code>, or
-     *             <code>ResultSet.TYPE_SCROLL_SENSITIVE</code>
-     * @return <code>true</code> if changes are detected by the specified result
-     *         set type; <code>false</code> otherwise
+     * <code>ResultSet.TYPE_FORWARD_ONLY</code>,
+     * <code>ResultSet.TYPE_SCROLL_INSENSITIVE</code>, or
+     * <code>ResultSet.TYPE_SCROLL_SENSITIVE</code>
+     * @return <code>true</code> if changes are detected by the specified result set
+     * type; <code>false</code> otherwise
      * @throws java.sql.SQLException if a database access error occurs
      * @since 1.2
      */
@@ -2430,7 +2394,7 @@
      * Retrieves whether this database supports batch updates.
      *
      * @return <code>true</code> if this database supports batch upcates;
-     *         <code>false</code> otherwise
+     * <code>false</code> otherwise
      * @throws java.sql.SQLException if a database access error occurs
      * @since 1.2
      */
@@ -2439,53 +2403,54 @@
     }
 
     /**
-     * Retrieves a description of the user-defined types (UDTs) defined
-     * in a particular schema.  Schema-specific UDTs may have type
-     * <code>JAVA_OBJECT</code>, <code>STRUCT</code>,
-     * or <code>DISTINCT</code>.
+     * Retrieves a description of the user-defined types (UDTs) defined in a
+     * particular schema. Schema-specific UDTs may have type
+     * <code>JAVA_OBJECT</code>, <code>STRUCT</code>, or <code>DISTINCT</code>.
      * <p/>
-     * <P>Only types matching the catalog, schema, type name and type
-     * criteria are returned.  They are ordered by DATA_TYPE, TYPE_SCHEM
-     * and TYPE_NAME.  The type name parameter may be a fully-qualified
-     * name.  In this case, the catalog and schemaPattern parameters are
-     * ignored.
+     * <P>
+     * Only types matching the catalog, schema, type name and type criteria are
+     * returned. They are ordered by DATA_TYPE, TYPE_SCHEM and TYPE_NAME. The type
+     * name parameter may be a fully-qualified name. In this case, the catalog and
+     * schemaPattern parameters are ignored.
      * <p/>
-     * <P>Each type description has the following columns:
+     * <P>
+     * Each type description has the following columns:
      * <OL>
      * <LI><B>TYPE_CAT</B> String => the type's catalog (may be <code>null</code>)
      * <LI><B>TYPE_SCHEM</B> String => type's schema (may be <code>null</code>)
      * <LI><B>TYPE_NAME</B> String => type name
      * <LI><B>CLASS_NAME</B> String => Java class name
-     * <LI><B>DATA_TYPE</B> int => type value defined in java.sql.Types.
-     * One of JAVA_OBJECT, STRUCT, or DISTINCT
+     * <LI><B>DATA_TYPE</B> int => type value defined in java.sql.Types. One of
+     * JAVA_OBJECT, STRUCT, or DISTINCT
      * <LI><B>REMARKS</B> String => explanatory comment on the type
-     * <LI><B>BASE_TYPE</B> short => type code of the source type of a
-     * DISTINCT type or the type that implements the user-generated
-     * reference type of the SELF_REFERENCING_COLUMN of a structured
-     * type as defined in java.sql.Types (<code>null</code> if DATA_TYPE is not
-     * DISTINCT or not STRUCT with REFERENCE_GENERATION = USER_DEFINED)
+     * <LI><B>BASE_TYPE</B> short => type code of the source type of a DISTINCT type
+     * or the type that implements the user-generated reference type of the
+     * SELF_REFERENCING_COLUMN of a structured type as defined in java.sql.Types
+     * (<code>null</code> if DATA_TYPE is not DISTINCT or not STRUCT with
+     * REFERENCE_GENERATION = USER_DEFINED)
      * </OL>
      * <p/>
-     * <P><B>Note:</B> If the driver does not support UDTs, an empty
-     * result set is returned.
+     * <P>
+     * <B>Note:</B> If the driver does not support UDTs, an empty result set is
+     * returned.
      *
-     * @param catalog         a catalog name; must match the catalog name as it
-     *                        is stored in the database; "" retrieves those without a catalog;
-     *                        <code>null</code> means that the catalog name should not be used to narrow
-     *                        the search
-     * @param schemaPattern   a schema pattern name; must match the schema name
-     *                        as it is stored in the database; "" retrieves those without a schema;
-     *                        <code>null</code> means that the schema name should not be used to narrow
-     *                        the search
-     * @param typeNamePattern a type name pattern; must match the type name
-     *                        as it is stored in the database; may be a fully qualified name
-     * @param types           a list of user-defined types (JAVA_OBJECT,
-     *                        STRUCT, or DISTINCT) to include; <code>null</code> returns all types
+     * @param catalog a catalog name; must match the catalog name as it is stored in
+     * the database; "" retrieves those without a catalog; <code>null</code> means
+     * that the catalog name should not be used to narrow the search
+     * @param schemaPattern a schema pattern name; must match the schema name as it
+     * is stored in the database; "" retrieves those without a schema;
+     * <code>null</code> means that the schema name should not be used to narrow the
+     * search
+     * @param typeNamePattern a type name pattern; must match the type name as it is
+     * stored in the database; may be a fully qualified name
+     * @param types a list of user-defined types (JAVA_OBJECT, STRUCT, or DISTINCT)
+     * to include; <code>null</code> returns all types
      * @return <code>ResultSet</code> object in which each row describes a UDT
      * @throws java.sql.SQLException if a database access error occurs
      * @since 1.2
      */
-    public ResultSet getUDTs(String catalog, String schemaPattern, String typeNamePattern, int[] types) throws SQLException {
+    public ResultSet getUDTs(String catalog, String schemaPattern, String typeNamePattern, int[] types)
+            throws SQLException {
         return databaseMetaData.getUDTs(catalog, schemaPattern, typeNamePattern, types);
     }
 
@@ -2514,8 +2479,8 @@
     /**
      * Retrieves whether this database supports savepoints.
      *
-     * @return <code>true</code> if savepoints are supported;
-     *         <code>false</code> otherwise
+     * @return <code>true</code> if savepoints are supported; <code>false</code>
+     * otherwise
      * @throws java.sql.SQLException if a database access error occurs
      * @since 1.4
      */
@@ -2528,7 +2493,7 @@
      * statements.
      *
      * @return <code>true</code> if named parameters are supported;
-     *         <code>false</code> otherwise
+     * <code>false</code> otherwise
      * @throws java.sql.SQLException if a database access error occurs
      * @since 1.4
      */
@@ -2537,13 +2502,12 @@
     }
 
     /**
-     * Retrieves whether it is possible to have multiple <code>ResultSet</code> objects
-     * returned from a <code>CallableStatement</code> object
-     * simultaneously.
+     * Retrieves whether it is possible to have multiple <code>ResultSet</code>
+     * objects returned from a <code>CallableStatement</code> object simultaneously.
      *
-     * @return <code>true</code> if a <code>CallableStatement</code> object
-     *         can return multiple <code>ResultSet</code> objects
-     *         simultaneously; <code>false</code> otherwise
+     * @return <code>true</code> if a <code>CallableStatement</code> object can
+     * return multiple <code>ResultSet</code> objects simultaneously;
+     * <code>false</code> otherwise
      * @throws java.sql.SQLException if a datanase access error occurs
      * @since 1.4
      */
@@ -2552,11 +2516,11 @@
     }
 
     /**
-     * Retrieves whether auto-generated keys can be retrieved after
-     * a statement has been executed.
+     * Retrieves whether auto-generated keys can be retrieved after a statement has
+     * been executed.
      *
-     * @return <code>true</code> if auto-generated keys can be retrieved
-     *         after a statement has executed; <code>false</code> otherwise
+     * @return <code>true</code> if auto-generated keys can be retrieved after a
+     * statement has executed; <code>false</code> otherwise
      * @throws java.sql.SQLException if a database access error occurs
      * @since 1.4
      */
@@ -2565,42 +2529,40 @@
     }
 
     /**
-     * Retrieves a description of the user-defined type (UDT) hierarchies defined in a
-     * particular schema in this database. Only the immediate super type/
-     * sub type relationship is modeled.
+     * Retrieves a description of the user-defined type (UDT) hierarchies defined in
+     * a particular schema in this database. Only the immediate super type/ sub type
+     * relationship is modeled.
      * <p/>
-     * Only supertype information for UDTs matching the catalog,
-     * schema, and type name is returned. The type name parameter
-     * may be a fully-qualified name. When the UDT name supplied is a
-     * fully-qualified name, the catalog and schemaPattern parameters are
-     * ignored.
+     * Only supertype information for UDTs matching the catalog, schema, and type
+     * name is returned. The type name parameter may be a fully-qualified name. When
+     * the UDT name supplied is a fully-qualified name, the catalog and
+     * schemaPattern parameters are ignored.
      * <p/>
-     * If a UDT does not have a direct super type, it is not listed here.
-     * A row of the <code>ResultSet</code> object returned by this method
-     * describes the designated UDT and a direct supertype. A row has the following
-     * columns:
+     * If a UDT does not have a direct super type, it is not listed here. A row of
+     * the <code>ResultSet</code> object returned by this method describes the
+     * designated UDT and a direct supertype. A row has the following columns:
      * <OL>
      * <LI><B>TYPE_CAT</B> String => the UDT's catalog (may be <code>null</code>)
      * <LI><B>TYPE_SCHEM</B> String => UDT's schema (may be <code>null</code>)
      * <LI><B>TYPE_NAME</B> String => type name of the UDT
-     * <LI><B>SUPERTYPE_CAT</B> String => the direct super type's catalog
-     * (may be <code>null</code>)
-     * <LI><B>SUPERTYPE_SCHEM</B> String => the direct super type's schema
-     * (may be <code>null</code>)
+     * <LI><B>SUPERTYPE_CAT</B> String => the direct super type's catalog (may be
+     * <code>null</code>)
+     * <LI><B>SUPERTYPE_SCHEM</B> String => the direct super type's schema (may be
+     * <code>null</code>)
      * <LI><B>SUPERTYPE_NAME</B> String => the direct super type's name
      * </OL>
      * <p/>
-     * <P><B>Note:</B> If the driver does not support type hierarchies, an
-     * empty result set is returned.
+     * <P>
+     * <B>Note:</B> If the driver does not support type hierarchies, an empty result
+     * set is returned.
      *
-     * @param catalog         a catalog name; "" retrieves those without a catalog;
-     *                        <code>null</code> means drop catalog name from the selection criteria
-     * @param schemaPattern   a schema name pattern; "" retrieves those
-     *                        without a schema
-     * @param typeNamePattern a UDT name pattern; may be a fully-qualified
-     *                        name
+     * @param catalog a catalog name; "" retrieves those without a catalog;
+     * <code>null</code> means drop catalog name from the selection criteria
+     * @param schemaPattern a schema name pattern; "" retrieves those without a
+     * schema
+     * @param typeNamePattern a UDT name pattern; may be a fully-qualified name
      * @return a <code>ResultSet</code> object in which a row gives information
-     *         about the designated UDT
+     * about the designated UDT
      * @throws java.sql.SQLException if a database access error occurs
      * @since 1.4
      */
@@ -2612,15 +2574,17 @@
      * Retrieves a description of the table hierarchies defined in a particular
      * schema in this database.
      * <p/>
-     * <P>Only supertable information for tables matching the catalog, schema
-     * and table name are returned. The table name parameter may be a fully-
-     * qualified name, in which case, the catalog and schemaPattern parameters
-     * are ignored. If a table does not have a super table, it is not listed here.
-     * Supertables have to be defined in the same catalog and schema as the
-     * sub tables. Therefore, the type description does not need to include
-     * this information for the supertable.
+     * <P>
+     * Only supertable information for tables matching the catalog, schema and table
+     * name are returned. The table name parameter may be a fully- qualified name,
+     * in which case, the catalog and schemaPattern parameters are ignored. If a
+     * table does not have a super table, it is not listed here. Supertables have to
+     * be defined in the same catalog and schema as the sub tables. Therefore, the
+     * type description does not need to include this information for the
+     * supertable.
      * <p/>
-     * <P>Each type description has the following columns:
+     * <P>
+     * Each type description has the following columns:
      * <OL>
      * <LI><B>TABLE_CAT</B> String => the type's catalog (may be <code>null</code>)
      * <LI><B>TABLE_SCHEM</B> String => type's schema (may be <code>null</code>)
@@ -2628,16 +2592,17 @@
      * <LI><B>SUPERTABLE_NAME</B> String => the direct super type's name
      * </OL>
      * <p/>
-     * <P><B>Note:</B> If the driver does not support type hierarchies, an
-     * empty result set is returned.
+     * <P>
+     * <B>Note:</B> If the driver does not support type hierarchies, an empty result
+     * set is returned.
      *
-     * @param catalog          a catalog name; "" retrieves those without a catalog;
-     *                         <code>null</code> means drop catalog name from the selection criteria
-     * @param schemaPattern    a schema name pattern; "" retrieves those
-     *                         without a schema
-     * @param tableNamePattern a table name pattern; may be a fully-qualified
-     *                         name
-     * @return a <code>ResultSet</code> object in which each row is a type description
+     * @param catalog a catalog name; "" retrieves those without a catalog;
+     * <code>null</code> means drop catalog name from the selection criteria
+     * @param schemaPattern a schema name pattern; "" retrieves those without a
+     * schema
+     * @param tableNamePattern a table name pattern; may be a fully-qualified name
+     * @return a <code>ResultSet</code> object in which each row is a type
+     * description
      * @throws java.sql.SQLException if a database access error occurs
      * @since 1.4
      */
@@ -2646,78 +2611,74 @@
     }
 
     /**
-     * Retrieves a description of the given attribute of the given type
-     * for a user-defined type (UDT) that is available in the given schema
-     * and catalog.
+     * Retrieves a description of the given attribute of the given type for a
+     * user-defined type (UDT) that is available in the given schema and catalog.
      * <p/>
-     * Descriptions are returned only for attributes of UDTs matching the
-     * catalog, schema, type, and attribute name criteria. They are ordered by
-     * TYPE_SCHEM, TYPE_NAME and ORDINAL_POSITION. This description
-     * does not contain inherited attributes.
+     * Descriptions are returned only for attributes of UDTs matching the catalog,
+     * schema, type, and attribute name criteria. They are ordered by TYPE_SCHEM,
+     * TYPE_NAME and ORDINAL_POSITION. This description does not contain inherited
+     * attributes.
      * <p/>
-     * The <code>ResultSet</code> object that is returned has the following
-     * columns:
+     * The <code>ResultSet</code> object that is returned has the following columns:
      * <OL>
      * <LI><B>TYPE_CAT</B> String => type catalog (may be <code>null</code>)
      * <LI><B>TYPE_SCHEM</B> String => type schema (may be <code>null</code>)
      * <LI><B>TYPE_NAME</B> String => type name
      * <LI><B>ATTR_NAME</B> String => attribute name
      * <LI><B>DATA_TYPE</B> int => attribute type SQL type from java.sql.Types
-     * <LI><B>ATTR_TYPE_NAME</B> String => Data source dependent type name.
-     * For a UDT, the type name is fully qualified. For a REF, the type name is
-     * fully qualified and represents the target type of the reference type.
-     * <LI><B>ATTR_SIZE</B> int => column size.  For char or date
-     * types this is the maximum number of characters; for numeric or
-     * decimal types this is precision.
+     * <LI><B>ATTR_TYPE_NAME</B> String => Data source dependent type name. For a
+     * UDT, the type name is fully qualified. For a REF, the type name is fully
+     * qualified and represents the target type of the reference type.
+     * <LI><B>ATTR_SIZE</B> int => column size. For char or date types this is the
+     * maximum number of characters; for numeric or decimal types this is precision.
      * <LI><B>DECIMAL_DIGITS</B> int => the number of fractional digits
      * <LI><B>NUM_PREC_RADIX</B> int => Radix (typically either 10 or 2)
      * <LI><B>NULLABLE</B> int => whether NULL is allowed
      * <UL>
-     * <LI> attributeNoNulls - might not allow NULL values
-     * <LI> attributeNullable - definitely allows NULL values
-     * <LI> attributeNullableUnknown - nullability unknown
+     * <LI>attributeNoNulls - might not allow NULL values
+     * <LI>attributeNullable - definitely allows NULL values
+     * <LI>attributeNullableUnknown - nullability unknown
      * </UL>
-     * <LI><B>REMARKS</B> String => comment describing column (may be <code>null</code>)
+     * <LI><B>REMARKS</B> String => comment describing column (may be
+     * <code>null</code>)
      * <LI><B>ATTR_DEF</B> String => default value (may be <code>null</code>)
      * <LI><B>SQL_DATA_TYPE</B> int => unused
      * <LI><B>SQL_DATETIME_SUB</B> int => unused
-     * <LI><B>CHAR_OCTET_LENGTH</B> int => for char types the
-     * maximum number of bytes in the column
-     * <LI><B>ORDINAL_POSITION</B> int    => index of column in table
-     * (starting at 1)
-     * <LI><B>IS_NULLABLE</B> String => "NO" means column definitely
-     * does not allow NULL values; "YES" means the column might
-     * allow NULL values.  An empty string means unknown.
-     * <LI><B>SCOPE_CATALOG</B> String => catalog of table that is the
-     * scope of a reference attribute (<code>null</code> if DATA_TYPE isn't REF)
-     * <LI><B>SCOPE_SCHEMA</B> String => schema of table that is the
-     * scope of a reference attribute (<code>null</code> if DATA_TYPE isn't REF)
-     * <LI><B>SCOPE_TABLE</B> String => table name that is the scope of a
-     * reference attribute (<code>null</code> if the DATA_TYPE isn't REF)
-     * <LI><B>SOURCE_DATA_TYPE</B> short => source type of a distinct type or user-generated
-     * Ref type,SQL type from java.sql.Types (<code>null</code> if DATA_TYPE
-     * isn't DISTINCT or user-generated REF)
+     * <LI><B>CHAR_OCTET_LENGTH</B> int => for char types the maximum number of
+     * bytes in the column
+     * <LI><B>ORDINAL_POSITION</B> int => index of column in table (starting at 1)
+     * <LI><B>IS_NULLABLE</B> String => "NO" means column definitely does not allow
+     * NULL values; "YES" means the column might allow NULL values. An empty string
+     * means unknown.
+     * <LI><B>SCOPE_CATALOG</B> String => catalog of table that is the scope of a
+     * reference attribute (<code>null</code> if DATA_TYPE isn't REF)
+     * <LI><B>SCOPE_SCHEMA</B> String => schema of table that is the scope of a
+     * reference attribute (<code>null</code> if DATA_TYPE isn't REF)
+     * <LI><B>SCOPE_TABLE</B> String => table name that is the scope of a reference
+     * attribute (<code>null</code> if the DATA_TYPE isn't REF)
+     * <LI><B>SOURCE_DATA_TYPE</B> short => source type of a distinct type or
+     * user-generated Ref type,SQL type from java.sql.Types (<code>null</code> if
+     * DATA_TYPE isn't DISTINCT or user-generated REF)
      * </OL>
      *
-     * @param catalog              a catalog name; must match the catalog name as it
-     *                             is stored in the database; "" retrieves those without a catalog;
-     *                             <code>null</code> means that the catalog name should not be used to narrow
-     *                             the search
-     * @param schemaPattern        a schema name pattern; must match the schema name
-     *                             as it is stored in the database; "" retrieves those without a schema;
-     *                             <code>null</code> means that the schema name should not be used to narrow
-     *                             the search
-     * @param typeNamePattern      a type name pattern; must match the
-     *                             type name as it is stored in the database
-     * @param attributeNamePattern an attribute name pattern; must match the attribute
-     *                             name as it is declared in the database
-     * @return a <code>ResultSet</code> object in which each row is an
-     *         attribute description
+     * @param catalog a catalog name; must match the catalog name as it is stored in
+     * the database; "" retrieves those without a catalog; <code>null</code> means
+     * that the catalog name should not be used to narrow the search
+     * @param schemaPattern a schema name pattern; must match the schema name as it
+     * is stored in the database; "" retrieves those without a schema;
+     * <code>null</code> means that the schema name should not be used to narrow the
+     * search
+     * @param typeNamePattern a type name pattern; must match the type name as it is
+     * stored in the database
+     * @param attributeNamePattern an attribute name pattern; must match the
+     * attribute name as it is declared in the database
+     * @return a <code>ResultSet</code> object in which each row is an attribute
+     * description
      * @throws java.sql.SQLException if a database access error occurs
      * @since 1.4
      */
     public ResultSet getAttributes(String catalog, String schemaPattern, String typeNamePattern,
-                                   String attributeNamePattern) throws SQLException {
+            String attributeNamePattern) throws SQLException {
         return databaseMetaData.getAttributes(catalog, schemaPattern, typeNamePattern, attributeNamePattern);
     }
 
@@ -2725,9 +2686,9 @@
      * Retrieves whether this database supports the given result set holdability.
      *
      * @param holdability one of the following constants:
-     *                    <code>ResultSet.HOLD_CURSORS_OVER_COMMIT</code> or
-     *                    <code>ResultSet.CLOSE_CURSORS_AT_COMMIT<code>
-     * @return <code>true</code> if so; <code>false</code> otherwise
+     * <code>ResultSet.HOLD_CURSORS_OVER_COMMIT</code> or
+     * <code>ResultSet.CLOSE_CURSORS_AT_COMMIT<code>
+     * &#64;return <code>true</code> if so; <code>false</code> otherwise
      * @throws java.sql.SQLException if a database access error occurs
      * @see java.sql.Connection
      * @since 1.4
@@ -2737,12 +2698,11 @@
     }
 
     /**
-     * Retrieves the default holdability of this <code>ResultSet</code>
-     * object.
+     * Retrieves the default holdability of this <code>ResultSet</code> object.
      *
      * @return the default holdability; either
-     *         <code>ResultSet.HOLD_CURSORS_OVER_COMMIT</code> or
-     *         <code>ResultSet.CLOSE_CURSORS_AT_COMMIT</code>
+     * <code>ResultSet.HOLD_CURSORS_OVER_COMMIT</code> or
+     * <code>ResultSet.CLOSE_CURSORS_AT_COMMIT</code>
      * @throws java.sql.SQLException if a database access error occurs
      * @since 1.4
      */
@@ -2773,8 +2733,7 @@
     }
 
     /**
-     * Retrieves the major JDBC version number for this
-     * driver.
+     * Retrieves the major JDBC version number for this driver.
      *
      * @return JDBC version major number
      * @throws java.sql.SQLException if a database access error occurs
@@ -2785,8 +2744,7 @@
     }
 
     /**
-     * Retrieves the minor JDBC version number for this
-     * driver.
+     * Retrieves the minor JDBC version number for this driver.
      *
      * @return JDBC version minor number
      * @throws java.sql.SQLException if a database access error occurs
@@ -2797,12 +2755,11 @@
     }
 
     /**
-     * Indicates whether the SQLSTATE returned by <code>SQLException.getSQLState</code>
-     * is X/Open (now known as Open Group) SQL CLI or SQL99.
+     * Indicates whether the SQLSTATE returned by
+     * <code>SQLException.getSQLState</code> is X/Open (now known as Open Group) SQL
+     * CLI or SQL99.
      *
-     * @return the type of SQLSTATE; one of:
-     *         sqlStateXOpen or
-     *         sqlStateSQL99
+     * @return the type of SQLSTATE; one of: sqlStateXOpen or sqlStateSQL99
      * @throws java.sql.SQLException if a database access error occurs
      * @since 1.4
      */
@@ -2811,11 +2768,11 @@
     }
 
     /**
-     * Indicates whether updates made to a LOB are made on a copy or directly
-     * to the LOB.
+     * Indicates whether updates made to a LOB are made on a copy or directly to the
+     * LOB.
      *
      * @return <code>true</code> if updates are made to a copy of the LOB;
-     *         <code>false</code> if updates are made directly to the LOB
+     * <code>false</code> if updates are made directly to the LOB
      * @throws java.sql.SQLException if a database access error occurs
      * @since 1.4
      */
diff --git a/appserver/jdbc/jdbc-ra/jdbc-core/src/main/java/com/sun/gjc/spi/base/PreparedStatementWrapper.java b/appserver/jdbc/jdbc-ra/jdbc-core/src/main/java/com/sun/gjc/spi/base/PreparedStatementWrapper.java
index 5763f4c..40ad3d1 100644
--- a/appserver/jdbc/jdbc-ra/jdbc-core/src/main/java/com/sun/gjc/spi/base/PreparedStatementWrapper.java
+++ b/appserver/jdbc/jdbc-ra/jdbc-core/src/main/java/com/sun/gjc/spi/base/PreparedStatementWrapper.java
@@ -16,25 +16,38 @@
 
 package com.sun.gjc.spi.base;
 
-import com.sun.gjc.common.DataSourceObjectBuilder;
-import com.sun.gjc.util.ResultSetClosedEventListener;
+import static com.sun.gjc.common.DataSourceObjectBuilder.isJDBC41;
 
 import java.io.InputStream;
 import java.io.Reader;
 import java.math.BigDecimal;
 import java.net.URL;
-import java.sql.*;
+import java.sql.Array;
+import java.sql.Blob;
+import java.sql.Clob;
+import java.sql.Connection;
+import java.sql.Date;
+import java.sql.ParameterMetaData;
+import java.sql.PreparedStatement;
+import java.sql.Ref;
+import java.sql.ResultSetMetaData;
+import java.sql.SQLException;
+import java.sql.Time;
+import java.sql.Timestamp;
 import java.util.Calendar;
 import java.util.logging.Level;
 
+import com.sun.gjc.common.DataSourceObjectBuilder;
+import com.sun.gjc.util.ResultSetClosedEventListener;
+
 /**
  * Abstract class for wrapping PreparedStatement<br>
  */
-public abstract class PreparedStatementWrapper extends StatementWrapper implements
-        PreparedStatement, ResultSetClosedEventListener {
-    protected PreparedStatement preparedStatement = null;
-    private boolean busy = false;
-    private boolean cached = false;
+public abstract class PreparedStatementWrapper extends StatementWrapper implements PreparedStatement, ResultSetClosedEventListener {
+
+    protected PreparedStatement preparedStatement;
+    private boolean busy;
+    private boolean cached;
     private int defaultMaxFieldSize;
     private int defaultMaxRows;
     private int defaultQueryTimeout;
@@ -50,13 +63,12 @@
     /**
      * Abstract class for wrapping PreparedStatement <br>
      *
-     * @param con       Connection Wrapper <br>
+     * @param con Connection Wrapper <br>
      * @param statement PreparedStatement that is to be wrapped.<br>
      * @param cachingEnabled boolean that enabled/ disables caching <br>
      * @throws SQLException Exception thrown from underlying statement<br>
-    */
-    public PreparedStatementWrapper(Connection con,
-                                    PreparedStatement statement, boolean cachingEnabled) throws SQLException {
+     */
+    public PreparedStatementWrapper(Connection con, PreparedStatement statement, boolean cachingEnabled) throws SQLException {
         super(con, statement);
         preparedStatement = statement;
         cached = cachingEnabled;
@@ -64,7 +76,6 @@
         leakDetector = wrappedCon.getManagedConnection().getLeakDetector();
 
         if (cached) {
-
             defaultQueryTimeout = preparedStatement.getQueryTimeout();
             defaultMaxFieldSize = preparedStatement.getMaxFieldSize();
             defaultFetchSize = preparedStatement.getFetchSize();
@@ -78,8 +89,8 @@
             currentFetchDirection = defaultFetchDirection;
 
         } else {
-            //Start Statement leak detection
-            if(leakDetector != null) {
+            // Start Statement leak detection
+            if (leakDetector != null) {
                 leakDetector.startStatementLeakTracing(preparedStatement, this);
             }
         }
@@ -88,14 +99,14 @@
     /**
      * Executes the SQL statement in this <code>PreparedStatement</code> object,
      * which must be an SQL <code>INSERT</code>, <code>UPDATE</code> or
-     * <code>DELETE</code> statement; or an SQL statement that returns nothing,
-     * such as a DDL statement.
+     * <code>DELETE</code> statement; or an SQL statement that returns nothing, such
+     * as a DDL statement.
      *
-     * @return either (1) the row count for <code>INSERT</code>, <code>UPDATE</code>,
-     *         or <code>DELETE</code> statements
-     *         or (2) 0 for SQL statements that return nothing
+     * @return either (1) the row count for <code>INSERT</code>,
+     * <code>UPDATE</code>, or <code>DELETE</code> statements or (2) 0 for SQL
+     * statements that return nothing
      * @throws java.sql.SQLException if a database access error occurs or the SQL
-     *                               statement returns a <code>ResultSet</code> object
+     * statement returns a <code>ResultSet</code> object
      */
     public int executeUpdate() throws SQLException {
         return preparedStatement.executeUpdate();
@@ -104,10 +115,11 @@
     /**
      * Sets the designated parameter to SQL <code>NULL</code>.
      * <p/>
-     * <P><B>Note:</B> You must specify the parameter's SQL type.
+     * <P>
+     * <B>Note:</B> You must specify the parameter's SQL type.
      *
      * @param parameterIndex the first parameter is 1, the second is 2, ...
-     * @param sqlType        the SQL type code defined in <code>java.sql.Types</code>
+     * @param sqlType the SQL type code defined in <code>java.sql.Types</code>
      * @throws java.sql.SQLException if a database access error occurs
      */
     public void setNull(int parameterIndex, int sqlType) throws SQLException {
@@ -116,11 +128,11 @@
 
     /**
      * Sets the designated parameter to the given Java <code>boolean</code> value.
-     * The driver converts this
-     * to an SQL <code>BIT</code> value when it sends it to the database.
+     * The driver converts this to an SQL <code>BIT</code> value when it sends it to
+     * the database.
      *
      * @param parameterIndex the first parameter is 1, the second is 2, ...
-     * @param x              the parameter value
+     * @param x the parameter value
      * @throws java.sql.SQLException if a database access error occurs
      */
     public void setBoolean(int parameterIndex, boolean x) throws SQLException {
@@ -128,12 +140,12 @@
     }
 
     /**
-     * Sets the designated parameter to the given Java <code>byte</code> value.
-     * The driver converts this
-     * to an SQL <code>TINYINT</code> value when it sends it to the database.
+     * Sets the designated parameter to the given Java <code>byte</code> value. The
+     * driver converts this to an SQL <code>TINYINT</code> value when it sends it to
+     * the database.
      *
      * @param parameterIndex the first parameter is 1, the second is 2, ...
-     * @param x              the parameter value
+     * @param x the parameter value
      * @throws java.sql.SQLException if a database access error occurs
      */
     public void setByte(int parameterIndex, byte x) throws SQLException {
@@ -141,12 +153,12 @@
     }
 
     /**
-     * Sets the designated parameter to the given Java <code>short</code> value.
-     * The driver converts this
-     * to an SQL <code>SMALLINT</code> value when it sends it to the database.
+     * Sets the designated parameter to the given Java <code>short</code> value. The
+     * driver converts this to an SQL <code>SMALLINT</code> value when it sends it
+     * to the database.
      *
      * @param parameterIndex the first parameter is 1, the second is 2, ...
-     * @param x              the parameter value
+     * @param x the parameter value
      * @throws java.sql.SQLException if a database access error occurs
      */
     public void setShort(int parameterIndex, short x) throws SQLException {
@@ -154,12 +166,12 @@
     }
 
     /**
-     * Sets the designated parameter to the given Java <code>int</code> value.
-     * The driver converts this
-     * to an SQL <code>INTEGER</code> value when it sends it to the database.
+     * Sets the designated parameter to the given Java <code>int</code> value. The
+     * driver converts this to an SQL <code>INTEGER</code> value when it sends it to
+     * the database.
      *
      * @param parameterIndex the first parameter is 1, the second is 2, ...
-     * @param x              the parameter value
+     * @param x the parameter value
      * @throws java.sql.SQLException if a database access error occurs
      */
     public void setInt(int parameterIndex, int x) throws SQLException {
@@ -167,12 +179,12 @@
     }
 
     /**
-     * Sets the designated parameter to the given Java <code>long</code> value.
-     * The driver converts this
-     * to an SQL <code>BIGINT</code> value when it sends it to the database.
+     * Sets the designated parameter to the given Java <code>long</code> value. The
+     * driver converts this to an SQL <code>BIGINT</code> value when it sends it to
+     * the database.
      *
      * @param parameterIndex the first parameter is 1, the second is 2, ...
-     * @param x              the parameter value
+     * @param x the parameter value
      * @throws java.sql.SQLException if a database access error occurs
      */
     public void setLong(int parameterIndex, long x) throws SQLException {
@@ -180,12 +192,12 @@
     }
 
     /**
-     * Sets the designated parameter to the given Java <code>float</code> value.
-     * The driver converts this
-     * to an SQL <code>FLOAT</code> value when it sends it to the database.
+     * Sets the designated parameter to the given Java <code>float</code> value. The
+     * driver converts this to an SQL <code>FLOAT</code> value when it sends it to
+     * the database.
      *
      * @param parameterIndex the first parameter is 1, the second is 2, ...
-     * @param x              the parameter value
+     * @param x the parameter value
      * @throws java.sql.SQLException if a database access error occurs
      */
     public void setFloat(int parameterIndex, float x) throws SQLException {
@@ -194,11 +206,11 @@
 
     /**
      * Sets the designated parameter to the given Java <code>double</code> value.
-     * The driver converts this
-     * to an SQL <code>DOUBLE</code> value when it sends it to the database.
+     * The driver converts this to an SQL <code>DOUBLE</code> value when it sends it
+     * to the database.
      *
      * @param parameterIndex the first parameter is 1, the second is 2, ...
-     * @param x              the parameter value
+     * @param x the parameter value
      * @throws java.sql.SQLException if a database access error occurs
      */
     public void setDouble(int parameterIndex, double x) throws SQLException {
@@ -206,12 +218,12 @@
     }
 
     /**
-     * Sets the designated parameter to the given <code>java.math.BigDecimal</code> value.
-     * The driver converts this to an SQL <code>NUMERIC</code> value when
-     * it sends it to the database.
+     * Sets the designated parameter to the given <code>java.math.BigDecimal</code>
+     * value. The driver converts this to an SQL <code>NUMERIC</code> value when it
+     * sends it to the database.
      *
      * @param parameterIndex the first parameter is 1, the second is 2, ...
-     * @param x              the parameter value
+     * @param x the parameter value
      * @throws java.sql.SQLException if a database access error occurs
      */
     public void setBigDecimal(int parameterIndex, BigDecimal x) throws SQLException {
@@ -220,14 +232,13 @@
 
     /**
      * Sets the designated parameter to the given Java <code>String</code> value.
-     * The driver converts this
-     * to an SQL <code>VARCHAR</code> or <code>LONGVARCHAR</code> value
-     * (depending on the argument's
-     * size relative to the driver's limits on <code>VARCHAR</code> values)
-     * when it sends it to the database.
+     * The driver converts this to an SQL <code>VARCHAR</code> or
+     * <code>LONGVARCHAR</code> value (depending on the argument's size relative to
+     * the driver's limits on <code>VARCHAR</code> values) when it sends it to the
+     * database.
      *
      * @param parameterIndex the first parameter is 1, the second is 2, ...
-     * @param x              the parameter value
+     * @param x the parameter value
      * @throws java.sql.SQLException if a database access error occurs
      */
     public void setString(int parameterIndex, String x) throws SQLException {
@@ -235,13 +246,13 @@
     }
 
     /**
-     * Sets the designated parameter to the given Java array of bytes.  The driver converts
-     * this to an SQL <code>VARBINARY</code> or <code>LONGVARBINARY</code>
+     * Sets the designated parameter to the given Java array of bytes. The driver
+     * converts this to an SQL <code>VARBINARY</code> or <code>LONGVARBINARY</code>
      * (depending on the argument's size relative to the driver's limits on
      * <code>VARBINARY</code> values) when it sends it to the database.
      *
      * @param parameterIndex the first parameter is 1, the second is 2, ...
-     * @param x              the parameter value
+     * @param x the parameter value
      * @throws java.sql.SQLException if a database access error occurs
      */
     public void setBytes(int parameterIndex, byte x[]) throws SQLException {
@@ -250,11 +261,11 @@
 
     /**
      * Sets the designated parameter to the given <code>java.sql.Date</code> value.
-     * The driver converts this
-     * to an SQL <code>DATE</code> value when it sends it to the database.
+     * The driver converts this to an SQL <code>DATE</code> value when it sends it
+     * to the database.
      *
      * @param parameterIndex the first parameter is 1, the second is 2, ...
-     * @param x              the parameter value
+     * @param x the parameter value
      * @throws java.sql.SQLException if a database access error occurs
      */
     public void setDate(int parameterIndex, Date x) throws SQLException {
@@ -263,11 +274,11 @@
 
     /**
      * Sets the designated parameter to the given <code>java.sql.Time</code> value.
-     * The driver converts this
-     * to an SQL <code>TIME</code> value when it sends it to the database.
+     * The driver converts this to an SQL <code>TIME</code> value when it sends it
+     * to the database.
      *
      * @param parameterIndex the first parameter is 1, the second is 2, ...
-     * @param x              the parameter value
+     * @param x the parameter value
      * @throws java.sql.SQLException if a database access error occurs
      */
     public void setTime(int parameterIndex, Time x) throws SQLException {
@@ -275,13 +286,12 @@
     }
 
     /**
-     * Sets the designated parameter to the given <code>java.sql.Timestamp</code> value.
-     * The driver
-     * converts this to an SQL <code>TIMESTAMP</code> value when it sends it to the
-     * database.
+     * Sets the designated parameter to the given <code>java.sql.Timestamp</code>
+     * value. The driver converts this to an SQL <code>TIMESTAMP</code> value when
+     * it sends it to the database.
      *
      * @param parameterIndex the first parameter is 1, the second is 2, ...
-     * @param x              the parameter value
+     * @param x the parameter value
      * @throws java.sql.SQLException if a database access error occurs
      */
     public void setTimestamp(int parameterIndex, Timestamp x) throws SQLException {
@@ -289,21 +299,20 @@
     }
 
     /**
-     * Sets the designated parameter to the given input stream, which will have
-     * the specified number of bytes.
-     * When a very large ASCII value is input to a <code>LONGVARCHAR</code>
-     * parameter, it may be more practical to send it via a
-     * <code>java.io.InputStream</code>. Data will be read from the stream
-     * as needed until end-of-file is reached.  The JDBC driver will
-     * do any necessary conversion from ASCII to the database char format.
+     * Sets the designated parameter to the given input stream, which will have the
+     * specified number of bytes. When a very large ASCII value is input to a
+     * <code>LONGVARCHAR</code> parameter, it may be more practical to send it via a
+     * <code>java.io.InputStream</code>. Data will be read from the stream as needed
+     * until end-of-file is reached. The JDBC driver will do any necessary
+     * conversion from ASCII to the database char format.
      * <p/>
-     * <P><B>Note:</B> This stream object can either be a standard
-     * Java stream object or your own subclass that implements the
-     * standard interface.
+     * <P>
+     * <B>Note:</B> This stream object can either be a standard Java stream object
+     * or your own subclass that implements the standard interface.
      *
      * @param parameterIndex the first parameter is 1, the second is 2, ...
-     * @param x              the Java input stream that contains the ASCII parameter value
-     * @param length         the number of bytes in the stream
+     * @param x the Java input stream that contains the ASCII parameter value
+     * @param length the number of bytes in the stream
      * @throws java.sql.SQLException if a database access error occurs
      */
     public void setAsciiStream(int parameterIndex, InputStream x, int length) throws SQLException {
@@ -311,25 +320,24 @@
     }
 
     /**
-     * Sets the designated parameter to the given input stream, which
-     * will have the specified number of bytes. A Unicode character has
-     * two bytes, with the first byte being the high byte, and the second
-     * being the low byte.
+     * Sets the designated parameter to the given input stream, which will have the
+     * specified number of bytes. A Unicode character has two bytes, with the first
+     * byte being the high byte, and the second being the low byte.
      * <p/>
      * When a very large Unicode value is input to a <code>LONGVARCHAR</code>
      * parameter, it may be more practical to send it via a
      * <code>java.io.InputStream</code> object. The data will be read from the
-     * stream as needed until end-of-file is reached.  The JDBC driver will
-     * do any necessary conversion from Unicode to the database char format.
+     * stream as needed until end-of-file is reached. The JDBC driver will do any
+     * necessary conversion from Unicode to the database char format.
      * <p/>
-     * <P><B>Note:</B> This stream object can either be a standard
-     * Java stream object or your own subclass that implements the
-     * standard interface.
+     * <P>
+     * <B>Note:</B> This stream object can either be a standard Java stream object
+     * or your own subclass that implements the standard interface.
      *
      * @param parameterIndex the first parameter is 1, the second is 2, ...
-     * @param x              a <code>java.io.InputStream</code> object that contains the
-     *                       Unicode parameter value as two-byte Unicode characters
-     * @param length         the number of bytes in the stream
+     * @param x a <code>java.io.InputStream</code> object that contains the Unicode
+     * parameter value as two-byte Unicode characters
+     * @param length the number of bytes in the stream
      * @throws java.sql.SQLException if a database access error occurs
      * @deprecated
      */
@@ -339,20 +347,19 @@
     }
 
     /**
-     * Sets the designated parameter to the given input stream, which will have
-     * the specified number of bytes.
-     * When a very large binary value is input to a <code>LONGVARBINARY</code>
-     * parameter, it may be more practical to send it via a
-     * <code>java.io.InputStream</code> object. The data will be read from the
+     * Sets the designated parameter to the given input stream, which will have the
+     * specified number of bytes. When a very large binary value is input to a
+     * <code>LONGVARBINARY</code> parameter, it may be more practical to send it via
+     * a <code>java.io.InputStream</code> object. The data will be read from the
      * stream as needed until end-of-file is reached.
      * <p/>
-     * <P><B>Note:</B> This stream object can either be a standard
-     * Java stream object or your own subclass that implements the
-     * standard interface.
+     * <P>
+     * <B>Note:</B> This stream object can either be a standard Java stream object
+     * or your own subclass that implements the standard interface.
      *
      * @param parameterIndex the first parameter is 1, the second is 2, ...
-     * @param x              the java input stream which contains the binary parameter value
-     * @param length         the number of bytes in the stream
+     * @param x the java input stream which contains the binary parameter value
+     * @param length the number of bytes in the stream
      * @throws java.sql.SQLException if a database access error occurs
      */
     public void setBinaryStream(int parameterIndex, InputStream x, int length) throws SQLException {
@@ -361,11 +368,12 @@
 
     /**
      * Clears the current parameter values immediately.
-     * <P>In general, parameter values remain in force for repeated use of a
-     * statement. Setting a parameter value automatically clears its
-     * previous value.  However, in some cases it is useful to immediately
-     * release the resources used by the current parameter values; this can
-     * be done by calling the method <code>clearParameters</code>.
+     * <P>
+     * In general, parameter values remain in force for repeated use of a statement.
+     * Setting a parameter value automatically clears its previous value. However,
+     * in some cases it is useful to immediately release the resources used by the
+     * current parameter values; this can be done by calling the method
+     * <code>clearParameters</code>.
      *
      * @throws java.sql.SQLException if a database access error occurs
      */
@@ -374,32 +382,34 @@
     }
 
     /**
-     * <p>Sets the value of the designated parameter with the given object. The second
+     * <p>
+     * Sets the value of the designated parameter with the given object. The second
      * argument must be an object type; for integral values, the
      * <code>java.lang</code> equivalent objects should be used.
      * <p/>
-     * <p>The given Java object will be converted to the given targetSqlType
-     * before being sent to the database.
+     * <p>
+     * The given Java object will be converted to the given targetSqlType before
+     * being sent to the database.
      * <p/>
-     * If the object has a custom mapping (is of a class implementing the
-     * interface <code>SQLData</code>),
-     * the JDBC driver should call the method <code>SQLData.writeSQL</code> to
-     * write it to the SQL data stream.
-     * If, on the other hand, the object is of a class implementing
-     * <code>Ref</code>, <code>Blob</code>, <code>Clob</code>, <code>Struct</code>,
-     * or <code>Array</code>, the driver should pass it to the database as a
-     * value of the corresponding SQL type.
+     * If the object has a custom mapping (is of a class implementing the interface
+     * <code>SQLData</code>), the JDBC driver should call the method
+     * <code>SQLData.writeSQL</code> to write it to the SQL data stream. If, on the
+     * other hand, the object is of a class implementing <code>Ref</code>,
+     * <code>Blob</code>, <code>Clob</code>, <code>Struct</code>, or
+     * <code>Array</code>, the driver should pass it to the database as a value of
+     * the corresponding SQL type.
      * <p/>
-     * <p>Note that this method may be used to pass database-specific
-     * abstract data types.
+     * <p>
+     * Note that this method may be used to pass database-specific abstract data
+     * types.
      *
      * @param parameterIndex the first parameter is 1, the second is 2, ...
-     * @param x              the object containing the input parameter value
-     * @param targetSqlType  the SQL type (as defined in java.sql.Types) to be
-     *                       sent to the database. The scale argument may further qualify this type.
-     * @param scale          for java.sql.Types.DECIMAL or java.sql.Types.NUMERIC types,
-     *                       this is the number of digits after the decimal point.  For all other
-     *                       types, this value will be ignored.
+     * @param x the object containing the input parameter value
+     * @param targetSqlType the SQL type (as defined in java.sql.Types) to be sent
+     * to the database. The scale argument may further qualify this type.
+     * @param scale for java.sql.Types.DECIMAL or java.sql.Types.NUMERIC types, this
+     * is the number of digits after the decimal point. For all other types, this
+     * value will be ignored.
      * @throws java.sql.SQLException if a database access error occurs
      * @see java.sql.Types
      */
@@ -408,14 +418,14 @@
     }
 
     /**
-     * Sets the value of the designated parameter with the given object.
-     * This method is like the method <code>setObject</code>
-     * above, except that it assumes a scale of zero.
+     * Sets the value of the designated parameter with the given object. This method
+     * is like the method <code>setObject</code> above, except that it assumes a
+     * scale of zero.
      *
      * @param parameterIndex the first parameter is 1, the second is 2, ...
-     * @param x              the object containing the input parameter value
-     * @param targetSqlType  the SQL type (as defined in java.sql.Types) to be
-     *                       sent to the database
+     * @param x the object containing the input parameter value
+     * @param targetSqlType the SQL type (as defined in java.sql.Types) to be sent
+     * to the database
      * @throws java.sql.SQLException if a database access error occurs
      */
     public void setObject(int parameterIndex, Object x, int targetSqlType) throws SQLException {
@@ -423,34 +433,35 @@
     }
 
     /**
-     * <p>Sets the value of the designated parameter using the given object.
-     * The second parameter must be of type <code>Object</code>; therefore, the
+     * <p>
+     * Sets the value of the designated parameter using the given object. The second
+     * parameter must be of type <code>Object</code>; therefore, the
      * <code>java.lang</code> equivalent objects should be used for built-in types.
      * <p/>
-     * <p>The JDBC specification specifies a standard mapping from
-     * Java <code>Object</code> types to SQL types.  The given argument
-     * will be converted to the corresponding SQL type before being
-     * sent to the database.
+     * <p>
+     * The JDBC specification specifies a standard mapping from Java
+     * <code>Object</code> types to SQL types. The given argument will be converted
+     * to the corresponding SQL type before being sent to the database.
      * <p/>
-     * <p>Note that this method may be used to pass datatabase-
-     * specific abstract data types, by using a driver-specific Java
-     * type.
+     * <p>
+     * Note that this method may be used to pass datatabase- specific abstract data
+     * types, by using a driver-specific Java type.
      * <p/>
      * If the object is of a class implementing the interface <code>SQLData</code>,
-     * the JDBC driver should call the method <code>SQLData.writeSQL</code>
-     * to write it to the SQL data stream.
-     * If, on the other hand, the object is of a class implementing
-     * <code>Ref</code>, <code>Blob</code>, <code>Clob</code>, <code>Struct</code>,
-     * or <code>Array</code>, the driver should pass it to the database as a
-     * value of the corresponding SQL type.
+     * the JDBC driver should call the method <code>SQLData.writeSQL</code> to write
+     * it to the SQL data stream. If, on the other hand, the object is of a class
+     * implementing <code>Ref</code>, <code>Blob</code>, <code>Clob</code>,
+     * <code>Struct</code>, or <code>Array</code>, the driver should pass it to the
+     * database as a value of the corresponding SQL type.
      * <p/>
      * This method throws an exception if there is an ambiguity, for example, if the
-     * object is of a class implementing more than one of the interfaces named above.
+     * object is of a class implementing more than one of the interfaces named
+     * above.
      *
      * @param parameterIndex the first parameter is 1, the second is 2, ...
-     * @param x              the object containing the input parameter value
+     * @param x the object containing the input parameter value
      * @throws java.sql.SQLException if a database access error occurs or the type
-     *                               of the given object is ambiguous
+     * of the given object is ambiguous
      */
     public void setObject(int parameterIndex, Object x) throws SQLException {
         preparedStatement.setObject(parameterIndex, x);
@@ -458,23 +469,22 @@
 
     /**
      * Executes the SQL statement in this <code>PreparedStatement</code> object,
-     * which may be any kind of SQL statement.
-     * Some prepared statements return multiple results; the <code>execute</code>
-     * method handles these complex statements as well as the simpler
-     * form of statements handled by the methods <code>executeQuery</code>
-     * and <code>executeUpdate</code>.
+     * which may be any kind of SQL statement. Some prepared statements return
+     * multiple results; the <code>execute</code> method handles these complex
+     * statements as well as the simpler form of statements handled by the methods
+     * <code>executeQuery</code> and <code>executeUpdate</code>.
      * <p/>
-     * The <code>execute</code> method returns a <code>boolean</code> to
-     * indicate the form of the first result.  You must call either the method
-     * <code>getResultSet</code> or <code>getUpdateCount</code>
-     * to retrieve the result; you must call <code>getMoreResults</code> to
-     * move to any subsequent result(s).
+     * The <code>execute</code> method returns a <code>boolean</code> to indicate
+     * the form of the first result. You must call either the method
+     * <code>getResultSet</code> or <code>getUpdateCount</code> to retrieve the
+     * result; you must call <code>getMoreResults</code> to move to any subsequent
+     * result(s).
      *
      * @return <code>true</code> if the first result is a <code>ResultSet</code>
-     *         object; <code>false</code> if the first result is an update
-     *         count or there is no result
-     * @throws java.sql.SQLException if a database access error occurs or an argument
-     *                               is supplied to this method
+     * object; <code>false</code> if the first result is an update count or there is
+     * no result
+     * @throws java.sql.SQLException if a database access error occurs or an
+     * argument is supplied to this method
      * @see java.sql.Statement#execute
      * @see java.sql.Statement#getResultSet
      * @see java.sql.Statement#getUpdateCount
@@ -485,8 +495,8 @@
     }
 
     /**
-     * Adds a set of parameters to this <code>PreparedStatement</code>
-     * object's batch of commands.
+     * Adds a set of parameters to this <code>PreparedStatement</code> object's
+     * batch of commands.
      *
      * @throws java.sql.SQLException if a database access error occurs
      * @see java.sql.Statement#addBatch
@@ -497,22 +507,21 @@
     }
 
     /**
-     * Sets the designated parameter to the given <code>Reader</code>
-     * object, which is the given number of characters long.
-     * When a very large UNICODE value is input to a <code>LONGVARCHAR</code>
-     * parameter, it may be more practical to send it via a
-     * <code>java.io.Reader</code> object. The data will be read from the stream
-     * as needed until end-of-file is reached.  The JDBC driver will
-     * do any necessary conversion from UNICODE to the database char format.
+     * Sets the designated parameter to the given <code>Reader</code> object, which
+     * is the given number of characters long. When a very large UNICODE value is
+     * input to a <code>LONGVARCHAR</code> parameter, it may be more practical to
+     * send it via a <code>java.io.Reader</code> object. The data will be read from
+     * the stream as needed until end-of-file is reached. The JDBC driver will do
+     * any necessary conversion from UNICODE to the database char format.
      * <p/>
-     * <P><B>Note:</B> This stream object can either be a standard
-     * Java stream object or your own subclass that implements the
-     * standard interface.
+     * <P>
+     * <B>Note:</B> This stream object can either be a standard Java stream object
+     * or your own subclass that implements the standard interface.
      *
      * @param parameterIndex the first parameter is 1, the second is 2, ...
-     * @param reader         the <code>java.io.Reader</code> object that contains the
-     *                       Unicode data
-     * @param length         the number of characters in the stream
+     * @param reader the <code>java.io.Reader</code> object that contains the
+     * Unicode data
+     * @param length the number of characters in the stream
      * @throws java.sql.SQLException if a database access error occurs
      * @since 1.2
      */
@@ -522,9 +531,8 @@
 
     /**
      * Sets the designated parameter to the given
-     * <code>REF(&lt;structured-type&gt;)</code> value.
-     * The driver converts this to an SQL <code>REF</code> value when it
-     * sends it to the database.
+     * <code>REF(&lt;structured-type&gt;)</code> value. The driver converts this to
+     * an SQL <code>REF</code> value when it sends it to the database.
      *
      * @param i the first parameter is 1, the second is 2, ...
      * @param x an SQL <code>REF</code> value
@@ -536,9 +544,9 @@
     }
 
     /**
-     * Sets the designated parameter to the given <code>Blob</code> object.
-     * The driver converts this to an SQL <code>BLOB</code> value when it
-     * sends it to the database.
+     * Sets the designated parameter to the given <code>Blob</code> object. The
+     * driver converts this to an SQL <code>BLOB</code> value when it sends it to
+     * the database.
      *
      * @param i the first parameter is 1, the second is 2, ...
      * @param x a <code>Blob</code> object that maps an SQL <code>BLOB</code> value
@@ -550,9 +558,9 @@
     }
 
     /**
-     * Sets the designated parameter to the given <code>Clob</code> object.
-     * The driver converts this to an SQL <code>CLOB</code> value when it
-     * sends it to the database.
+     * Sets the designated parameter to the given <code>Clob</code> object. The
+     * driver converts this to an SQL <code>CLOB</code> value when it sends it to
+     * the database.
      *
      * @param i the first parameter is 1, the second is 2, ...
      * @param x a <code>Clob</code> object that maps an SQL <code>CLOB</code> value
@@ -564,12 +572,13 @@
     }
 
     /**
-     * Sets the designated parameter to the given <code>Array</code> object.
-     * The driver converts this to an SQL <code>ARRAY</code> value when it
-     * sends it to the database.
+     * Sets the designated parameter to the given <code>Array</code> object. The
+     * driver converts this to an SQL <code>ARRAY</code> value when it sends it to
+     * the database.
      *
      * @param i the first parameter is 1, the second is 2, ...
-     * @param x an <code>Array</code> object that maps an SQL <code>ARRAY</code> value
+     * @param x an <code>Array</code> object that maps an SQL <code>ARRAY</code>
+     * value
      * @throws java.sql.SQLException if a database access error occurs
      * @since 1.2
      */
@@ -578,25 +587,24 @@
     }
 
     /**
-     * Retrieves a <code>ResultSetMetaData</code> object that contains
-     * information about the columns of the <code>ResultSet</code> object
-     * that will be returned when this <code>PreparedStatement</code> object
-     * is executed.
+     * Retrieves a <code>ResultSetMetaData</code> object that contains information
+     * about the columns of the <code>ResultSet</code> object that will be returned
+     * when this <code>PreparedStatement</code> object is executed.
      * <p/>
      * Because a <code>PreparedStatement</code> object is precompiled, it is
-     * possible to know about the <code>ResultSet</code> object that it will
-     * return without having to execute it.  Consequently, it is possible
-     * to invoke the method <code>getMetaData</code> on a
-     * <code>PreparedStatement</code> object rather than waiting to execute
-     * it and then invoking the <code>ResultSet.getMetaData</code> method
-     * on the <code>ResultSet</code> object that is returned.
+     * possible to know about the <code>ResultSet</code> object that it will return
+     * without having to execute it. Consequently, it is possible to invoke the
+     * method <code>getMetaData</code> on a <code>PreparedStatement</code> object
+     * rather than waiting to execute it and then invoking the
+     * <code>ResultSet.getMetaData</code> method on the <code>ResultSet</code>
+     * object that is returned.
      * <p/>
-     * <B>NOTE:</B> Using this method may be expensive for some drivers due
-     * to the lack of underlying DBMS support.
+     * <B>NOTE:</B> Using this method may be expensive for some drivers due to the
+     * lack of underlying DBMS support.
      *
      * @return the description of a <code>ResultSet</code> object's columns or
-     *         <code>null</code> if the driver cannot return a
-     *         <code>ResultSetMetaData</code> object
+     * <code>null</code> if the driver cannot return a
+     * <code>ResultSetMetaData</code> object
      * @throws java.sql.SQLException if a database access error occurs
      * @since 1.2
      */
@@ -606,18 +614,18 @@
 
     /**
      * Sets the designated parameter to the given <code>java.sql.Date</code> value,
-     * using the given <code>Calendar</code> object.  The driver uses
-     * the <code>Calendar</code> object to construct an SQL <code>DATE</code> value,
-     * which the driver then sends to the database.  With
-     * a <code>Calendar</code> object, the driver can calculate the date
-     * taking into account a custom timezone.  If no
-     * <code>Calendar</code> object is specified, the driver uses the default
-     * timezone, which is that of the virtual machine running the application.
+     * using the given <code>Calendar</code> object. The driver uses the
+     * <code>Calendar</code> object to construct an SQL <code>DATE</code> value,
+     * which the driver then sends to the database. With a <code>Calendar</code>
+     * object, the driver can calculate the date taking into account a custom
+     * timezone. If no <code>Calendar</code> object is specified, the driver uses
+     * the default timezone, which is that of the virtual machine running the
+     * application.
      *
      * @param parameterIndex the first parameter is 1, the second is 2, ...
-     * @param x              the parameter value
-     * @param cal            the <code>Calendar</code> object the driver will use
-     *                       to construct the date
+     * @param x the parameter value
+     * @param cal the <code>Calendar</code> object the driver will use to construct
+     * the date
      * @throws java.sql.SQLException if a database access error occurs
      * @since 1.2
      */
@@ -627,18 +635,18 @@
 
     /**
      * Sets the designated parameter to the given <code>java.sql.Time</code> value,
-     * using the given <code>Calendar</code> object.  The driver uses
-     * the <code>Calendar</code> object to construct an SQL <code>TIME</code> value,
-     * which the driver then sends to the database.  With
-     * a <code>Calendar</code> object, the driver can calculate the time
-     * taking into account a custom timezone.  If no
-     * <code>Calendar</code> object is specified, the driver uses the default
-     * timezone, which is that of the virtual machine running the application.
+     * using the given <code>Calendar</code> object. The driver uses the
+     * <code>Calendar</code> object to construct an SQL <code>TIME</code> value,
+     * which the driver then sends to the database. With a <code>Calendar</code>
+     * object, the driver can calculate the time taking into account a custom
+     * timezone. If no <code>Calendar</code> object is specified, the driver uses
+     * the default timezone, which is that of the virtual machine running the
+     * application.
      *
      * @param parameterIndex the first parameter is 1, the second is 2, ...
-     * @param x              the parameter value
-     * @param cal            the <code>Calendar</code> object the driver will use
-     *                       to construct the time
+     * @param x the parameter value
+     * @param cal the <code>Calendar</code> object the driver will use to construct
+     * the time
      * @throws java.sql.SQLException if a database access error occurs
      * @since 1.2
      */
@@ -647,19 +655,19 @@
     }
 
     /**
-     * Sets the designated parameter to the given <code>java.sql.Timestamp</code> value,
-     * using the given <code>Calendar</code> object.  The driver uses
-     * the <code>Calendar</code> object to construct an SQL <code>TIMESTAMP</code> value,
-     * which the driver then sends to the database.  With a
-     * <code>Calendar</code> object, the driver can calculate the timestamp
-     * taking into account a custom timezone.  If no
-     * <code>Calendar</code> object is specified, the driver uses the default
-     * timezone, which is that of the virtual machine running the application.
+     * Sets the designated parameter to the given <code>java.sql.Timestamp</code>
+     * value, using the given <code>Calendar</code> object. The driver uses the
+     * <code>Calendar</code> object to construct an SQL <code>TIMESTAMP</code>
+     * value, which the driver then sends to the database. With a
+     * <code>Calendar</code> object, the driver can calculate the timestamp taking
+     * into account a custom timezone. If no <code>Calendar</code> object is
+     * specified, the driver uses the default timezone, which is that of the virtual
+     * machine running the application.
      *
      * @param parameterIndex the first parameter is 1, the second is 2, ...
-     * @param x              the parameter value
-     * @param cal            the <code>Calendar</code> object the driver will use
-     *                       to construct the timestamp
+     * @param x the parameter value
+     * @param cal the <code>Calendar</code> object the driver will use to construct
+     * the timestamp
      * @throws java.sql.SQLException if a database access error occurs
      * @since 1.2
      */
@@ -668,29 +676,27 @@
     }
 
     /**
-     * Sets the designated parameter to SQL <code>NULL</code>.
-     * This version of the method <code>setNull</code> should
-     * be used for user-defined types and REF type parameters.  Examples
-     * of user-defined types include: STRUCT, DISTINCT, JAVA_OBJECT, and
-     * named array types.
+     * Sets the designated parameter to SQL <code>NULL</code>. This version of the
+     * method <code>setNull</code> should be used for user-defined types and REF
+     * type parameters. Examples of user-defined types include: STRUCT, DISTINCT,
+     * JAVA_OBJECT, and named array types.
      * <p/>
-     * <P><B>Note:</B> To be portable, applications must give the
-     * SQL type code and the fully-qualified SQL type name when specifying
-     * a NULL user-defined or REF parameter.  In the case of a user-defined type
-     * the name is the type name of the parameter itself.  For a REF
-     * parameter, the name is the type name of the referenced type.  If
-     * a JDBC driver does not need the type code or type name information,
-     * it may ignore it.
+     * <P>
+     * <B>Note:</B> To be portable, applications must give the SQL type code and the
+     * fully-qualified SQL type name when specifying a NULL user-defined or REF
+     * parameter. In the case of a user-defined type the name is the type name of
+     * the parameter itself. For a REF parameter, the name is the type name of the
+     * referenced type. If a JDBC driver does not need the type code or type name
+     * information, it may ignore it.
      * <p/>
-     * Although it is intended for user-defined and Ref parameters,
-     * this method may be used to set a null parameter of any JDBC type.
-     * If the parameter does not have a user-defined or REF type, the given
-     * typeName is ignored.
+     * Although it is intended for user-defined and Ref parameters, this method may
+     * be used to set a null parameter of any JDBC type. If the parameter does not
+     * have a user-defined or REF type, the given typeName is ignored.
      *
      * @param paramIndex the first parameter is 1, the second is 2, ...
-     * @param sqlType    a value from <code>java.sql.Types</code>
-     * @param typeName   the fully-qualified name of an SQL user-defined type;
-     *                   ignored if the parameter is not a user-defined type or REF
+     * @param sqlType a value from <code>java.sql.Types</code>
+     * @param typeName the fully-qualified name of an SQL user-defined type; ignored
+     * if the parameter is not a user-defined type or REF
      * @throws java.sql.SQLException if a database access error occurs
      * @since 1.2
      */
@@ -700,11 +706,11 @@
 
     /**
      * Sets the designated parameter to the given <code>java.net.URL</code> value.
-     * The driver converts this to an SQL <code>DATALINK</code> value
-     * when it sends it to the database.
+     * The driver converts this to an SQL <code>DATALINK</code> value when it sends
+     * it to the database.
      *
      * @param parameterIndex the first parameter is 1, the second is 2, ...
-     * @param x              the <code>java.net.URL</code> object to be set
+     * @param x the <code>java.net.URL</code> object to be set
      * @throws java.sql.SQLException if a database access error occurs
      * @since 1.4
      */
@@ -717,8 +723,8 @@
      * <code>PreparedStatement</code> object's parameters.
      *
      * @return a <code>ParameterMetaData</code> object that contains information
-     *         about the number, types and properties of this
-     *         <code>PreparedStatement</code> object's parameters
+     * about the number, types and properties of this <code>PreparedStatement</code>
+     * object's parameters
      * @throws java.sql.SQLException if a database access error occurs
      * @see java.sql.ParameterMetaData
      * @since 1.4
@@ -740,11 +746,11 @@
         } else {
             if (leakDetector != null) {
                 leakDetector.stopStatementLeakTracing(preparedStatement, this);
-                if(cached && isMarkedForReclaim()) {
-                    //When caching is on and is marked for reclaim, the statement
-                    //would still remain in cache. Hence mark it as invalid and
-                    //let the client that uses the statement, detect and purge
-                    //it if found as invalid
+                if (cached && isMarkedForReclaim()) {
+                    // When caching is on and is marked for reclaim, the statement
+                    // would still remain in cache. Hence mark it as invalid and
+                    // let the client that uses the statement, detect and purge
+                    // it if found as invalid
                     setValid(false);
                 }
             }
@@ -757,13 +763,14 @@
 
     public void close() throws SQLException {
         if (!cached) {
-            //Stop leak tracing
-            if(leakDetector != null) {
+            // Stop leak tracing
+            if (leakDetector != null) {
                 leakDetector.stopStatementLeakTracing(preparedStatement, this);
             }
             preparedStatement.close();
         } else {
-            //TODO-SC what if Exception is thrown in this block, should there be a way to indicate the
+            // TODO-SC what if Exception is thrown in this block, should there be a way to
+            // indicate the
             // con. not to use this statement any more ?
             clearParameters();
 
@@ -795,8 +802,9 @@
 
     public void closeOnCompletion() throws SQLException {
         if (DataSourceObjectBuilder.isJDBC41()) {
-            if(!cached) {
-                //If statement caching is not turned on, call the driver implementation directly
+            if (!cached) {
+                // If statement caching is not turned on, call the driver implementation
+                // directly
                 if (leakDetector != null) {
                     _logger.log(Level.INFO, "jdbc.invalid_operation.close_on_completion");
                     throw new UnsupportedOperationException("Not supported yet.");
@@ -810,7 +818,7 @@
 
     public boolean isCloseOnCompletion() throws SQLException {
         if (DataSourceObjectBuilder.isJDBC41()) {
-            if(cached) {
+            if (cached) {
                 return getCloseOnCompletion();
             }
         }
@@ -847,8 +855,8 @@
             currentFetchSize = rows;
     }
 
-    public void setCached(boolean cached){
-        this.cached =  cached;
+    public void setCached(boolean cached) {
+        this.cached = cached;
     }
 
     public boolean isValid() {
@@ -860,14 +868,14 @@
     }
 
     public void incrementResultSetReferenceCount() {
-        //Update resultSetCount to be used in case of jdbc41 closeOnCompletion
-        if (DataSourceObjectBuilder.isJDBC41() && getCached()) {
+        // Update resultSetCount to be used in case of jdbc41 closeOnCompletion
+        if (isJDBC41() && getCached()) {
             incrementResultSetCount();
         }
     }
 
     public void resultSetClosed() throws SQLException {
-        if (DataSourceObjectBuilder.isJDBC41() && getCached()) {
+        if (isJDBC41() && getCached()) {
             decrementResultSetCount();
             if (getCloseOnCompletion() && getResultSetCount() == 0) {
                 ConnectionHolder wrappedCon = (ConnectionHolder) getConnection();
diff --git a/appserver/jdbc/jdbc-ra/jdbc-core/src/main/java/com/sun/gjc/spi/base/ResultSetWrapper.java b/appserver/jdbc/jdbc-ra/jdbc-core/src/main/java/com/sun/gjc/spi/base/ResultSetWrapper.java
index d640969..23c0e31 100644
--- a/appserver/jdbc/jdbc-ra/jdbc-core/src/main/java/com/sun/gjc/spi/base/ResultSetWrapper.java
+++ b/appserver/jdbc/jdbc-ra/jdbc-core/src/main/java/com/sun/gjc/spi/base/ResultSetWrapper.java
@@ -16,63 +16,71 @@
 
 package com.sun.gjc.spi.base;
 
-import com.sun.gjc.util.MethodExecutor;
-import com.sun.gjc.util.ResultSetClosedEventListener;
-import com.sun.logging.LogDomains;
 import java.io.InputStream;
 import java.io.Reader;
 import java.math.BigDecimal;
 import java.net.URL;
-import java.sql.*;
+import java.sql.Array;
+import java.sql.Blob;
+import java.sql.Clob;
+import java.sql.Date;
+import java.sql.Ref;
+import java.sql.ResultSet;
+import java.sql.ResultSetMetaData;
+import java.sql.SQLException;
+import java.sql.SQLWarning;
+import java.sql.Statement;
+import java.sql.Time;
+import java.sql.Timestamp;
 import java.util.Calendar;
 import java.util.Map;
 import java.util.logging.Logger;
 
+import com.sun.gjc.util.MethodExecutor;
+import com.sun.gjc.util.ResultSetClosedEventListener;
+import com.sun.logging.LogDomains;
 
 /**
  * Abstract class for ResultSet Wrapper <br>
  */
 public abstract class ResultSetWrapper implements ResultSet {
 
-    protected ResultSet resultSet = null;
-    protected Statement statement = null;
-    private MethodExecutor executor = null;
-    protected final static Logger _logger;
-    private ResultSetClosedEventListener eventListener = null;
+    protected final static Logger _logger = LogDomains.getLogger(MethodExecutor.class, LogDomains.RSR_LOGGER);
 
-    static {
-        _logger = LogDomains.getLogger(MethodExecutor.class, LogDomains.RSR_LOGGER);
-    }
+    protected ResultSet resultSet;
+    protected Statement statement;
+    private MethodExecutor executor;
+
+    private ResultSetClosedEventListener eventListener;
 
     /**
      * Abstract class for wrapping Statement<br>
      *
      * @param stmt Statement that is to be wrapped<br>
-     * @param rs   ResultSet that is to be wraped<br>
+     * @param rs ResultSet that is to be wraped<br>
      */
     public ResultSetWrapper(Statement stmt, ResultSet rs) {
         resultSet = rs;
         statement = stmt;
         executor = new MethodExecutor();
-        if(stmt instanceof ResultSetClosedEventListener) {
+        if (stmt instanceof ResultSetClosedEventListener) {
             eventListener = (ResultSetClosedEventListener) stmt;
         }
     }
 
     /**
-     * Moves the cursor down one row from its current position.
-     * A <code>ResultSet</code> cursor is initially positioned
-     * before the first row; the first call to the method
-     * <code>next</code> makes the first row the current row; the
-     * second call makes the second row the current row, and so on.
+     * Moves the cursor down one row from its current position. A
+     * <code>ResultSet</code> cursor is initially positioned before the first row;
+     * the first call to the method <code>next</code> makes the first row the
+     * current row; the second call makes the second row the current row, and so on.
      * <p/>
-     * <P>If an input stream is open for the current row, a call
-     * to the method <code>next</code> will
-     * implicitly close it. A <code>ResultSet</code> object's
+     * <P>
+     * If an input stream is open for the current row, a call to the method
+     * <code>next</code> will implicitly close it. A <code>ResultSet</code> object's
      * warning chain is cleared when a new row is read.
      *
-     * @return <code>true</code> if the new current row is valid;
-     *         <code>false</code> if there are no more rows
+     * @return <code>true</code> if the new current row is valid; <code>false</code>
+     * if there are no more rows
      * @throws java.sql.SQLException if a database access error occurs
      */
     public boolean next() throws SQLException {
@@ -80,17 +88,16 @@
     }
 
     /**
-     * Releases this <code>ResultSet</code> object's database and
-     * JDBC resources immediately instead of waiting for
-     * this to happen when it is automatically closed.
+     * Releases this <code>ResultSet</code> object's database and JDBC resources
+     * immediately instead of waiting for this to happen when it is automatically
+     * closed.
      * <p/>
-     * <P><B>Note:</B> A <code>ResultSet</code> object
-     * is automatically closed by the
-     * <code>Statement</code> object that generated it when
-     * that <code>Statement</code> object is closed,
-     * re-executed, or is used to retrieve the next result from a
-     * sequence of multiple results. A <code>ResultSet</code> object
-     * is also automatically closed when it is garbage collected.
+     * <P>
+     * <B>Note:</B> A <code>ResultSet</code> object is automatically closed by the
+     * <code>Statement</code> object that generated it when that
+     * <code>Statement</code> object is closed, re-executed, or is used to retrieve
+     * the next result from a sequence of multiple results. A <code>ResultSet</code>
+     * object is also automatically closed when it is garbage collected.
      *
      * @throws java.sql.SQLException if a database access error occurs
      */
@@ -102,15 +109,13 @@
     }
 
     /**
-     * Reports whether
-     * the last column read had a value of SQL <code>NULL</code>.
-     * Note that you must first call one of the getter methods
-     * on a column to try to read its value and then call
-     * the method <code>wasNull</code> to see if the value read was
-     * SQL <code>NULL</code>.
+     * Reports whether the last column read had a value of SQL <code>NULL</code>.
+     * Note that you must first call one of the getter methods on a column to try to
+     * read its value and then call the method <code>wasNull</code> to see if the
+     * value read was SQL <code>NULL</code>.
      *
      * @return <code>true</code> if the last column value read was SQL
-     *         <code>NULL</code> and <code>false</code> otherwise
+     * <code>NULL</code> and <code>false</code> otherwise
      * @throws java.sql.SQLException if a database access error occurs
      */
     public boolean wasNull() throws SQLException {
@@ -118,13 +123,13 @@
     }
 
     /**
-     * Retrieves the value of the designated column in the current row
-     * of this <code>ResultSet</code> object as
-     * a <code>String</code> in the Java programming language.
+     * Retrieves the value of the designated column in the current row of this
+     * <code>ResultSet</code> object as a <code>String</code> in the Java
+     * programming language.
      *
      * @param columnIndex the first column is 1, the second is 2, ...
-     * @return the column value; if the value is SQL <code>NULL</code>, the
-     *         value returned is <code>null</code>
+     * @return the column value; if the value is SQL <code>NULL</code>, the value
+     * returned is <code>null</code>
      * @throws java.sql.SQLException if a database access error occurs
      */
     public String getString(int columnIndex) throws SQLException {
@@ -132,13 +137,13 @@
     }
 
     /**
-     * Retrieves the value of the designated column in the current row
-     * of this <code>ResultSet</code> object as
-     * a <code>boolean</code> in the Java programming language.
+     * Retrieves the value of the designated column in the current row of this
+     * <code>ResultSet</code> object as a <code>boolean</code> in the Java
+     * programming language.
      *
      * @param columnIndex the first column is 1, the second is 2, ...
-     * @return the column value; if the value is SQL <code>NULL</code>, the
-     *         value returned is <code>false</code>
+     * @return the column value; if the value is SQL <code>NULL</code>, the value
+     * returned is <code>false</code>
      * @throws java.sql.SQLException if a database access error occurs
      */
     public boolean getBoolean(int columnIndex) throws SQLException {
@@ -146,13 +151,13 @@
     }
 
     /**
-     * Retrieves the value of the designated column in the current row
-     * of this <code>ResultSet</code> object as
-     * a <code>byte</code> in the Java programming language.
+     * Retrieves the value of the designated column in the current row of this
+     * <code>ResultSet</code> object as a <code>byte</code> in the Java programming
+     * language.
      *
      * @param columnIndex the first column is 1, the second is 2, ...
-     * @return the column value; if the value is SQL <code>NULL</code>, the
-     *         value returned is <code>0</code>
+     * @return the column value; if the value is SQL <code>NULL</code>, the value
+     * returned is <code>0</code>
      * @throws java.sql.SQLException if a database access error occurs
      */
     public byte getByte(int columnIndex) throws SQLException {
@@ -160,13 +165,13 @@
     }
 
     /**
-     * Retrieves the value of the designated column in the current row
-     * of this <code>ResultSet</code> object as
-     * a <code>short</code> in the Java programming language.
+     * Retrieves the value of the designated column in the current row of this
+     * <code>ResultSet</code> object as a <code>short</code> in the Java programming
+     * language.
      *
      * @param columnIndex the first column is 1, the second is 2, ...
-     * @return the column value; if the value is SQL <code>NULL</code>, the
-     *         value returned is <code>0</code>
+     * @return the column value; if the value is SQL <code>NULL</code>, the value
+     * returned is <code>0</code>
      * @throws java.sql.SQLException if a database access error occurs
      */
     public short getShort(int columnIndex) throws SQLException {
@@ -174,13 +179,13 @@
     }
 
     /**
-     * Retrieves the value of the designated column in the current row
-     * of this <code>ResultSet</code> object as
-     * an <code>int</code> in the Java programming language.
+     * Retrieves the value of the designated column in the current row of this
+     * <code>ResultSet</code> object as an <code>int</code> in the Java programming
+     * language.
      *
      * @param columnIndex the first column is 1, the second is 2, ...
-     * @return the column value; if the value is SQL <code>NULL</code>, the
-     *         value returned is <code>0</code>
+     * @return the column value; if the value is SQL <code>NULL</code>, the value
+     * returned is <code>0</code>
      * @throws java.sql.SQLException if a database access error occurs
      */
     public int getInt(int columnIndex) throws SQLException {
@@ -188,13 +193,13 @@
     }
 
     /**
-     * Retrieves the value of the designated column in the current row
-     * of this <code>ResultSet</code> object as
-     * a <code>long</code> in the Java programming language.
+     * Retrieves the value of the designated column in the current row of this
+     * <code>ResultSet</code> object as a <code>long</code> in the Java programming
+     * language.
      *
      * @param columnIndex the first column is 1, the second is 2, ...
-     * @return the column value; if the value is SQL <code>NULL</code>, the
-     *         value returned is <code>0</code>
+     * @return the column value; if the value is SQL <code>NULL</code>, the value
+     * returned is <code>0</code>
      * @throws java.sql.SQLException if a database access error occurs
      */
     public long getLong(int columnIndex) throws SQLException {
@@ -202,13 +207,13 @@
     }
 
     /**
-     * Retrieves the value of the designated column in the current row
-     * of this <code>ResultSet</code> object as
-     * a <code>float</code> in the Java programming language.
+     * Retrieves the value of the designated column in the current row of this
+     * <code>ResultSet</code> object as a <code>float</code> in the Java programming
+     * language.
      *
      * @param columnIndex the first column is 1, the second is 2, ...
-     * @return the column value; if the value is SQL <code>NULL</code>, the
-     *         value returned is <code>0</code>
+     * @return the column value; if the value is SQL <code>NULL</code>, the value
+     * returned is <code>0</code>
      * @throws java.sql.SQLException if a database access error occurs
      */
     public float getFloat(int columnIndex) throws SQLException {
@@ -216,13 +221,13 @@
     }
 
     /**
-     * Retrieves the value of the designated column in the current row
-     * of this <code>ResultSet</code> object as
-     * a <code>double</code> in the Java programming language.
+     * Retrieves the value of the designated column in the current row of this
+     * <code>ResultSet</code> object as a <code>double</code> in the Java
+     * programming language.
      *
      * @param columnIndex the first column is 1, the second is 2, ...
-     * @return the column value; if the value is SQL <code>NULL</code>, the
-     *         value returned is <code>0</code>
+     * @return the column value; if the value is SQL <code>NULL</code>, the value
+     * returned is <code>0</code>
      * @throws java.sql.SQLException if a database access error occurs
      */
     public double getDouble(int columnIndex) throws SQLException {
@@ -230,14 +235,14 @@
     }
 
     /**
-     * Retrieves the value of the designated column in the current row
-     * of this <code>ResultSet</code> object as
-     * a <code>java.sql.BigDecimal</code> in the Java programming language.
+     * Retrieves the value of the designated column in the current row of this
+     * <code>ResultSet</code> object as a <code>java.sql.BigDecimal</code> in the
+     * Java programming language.
      *
      * @param columnIndex the first column is 1, the second is 2, ...
-     * @param scale       the number of digits to the right of the decimal point
-     * @return the column value; if the value is SQL <code>NULL</code>, the
-     *         value returned is <code>null</code>
+     * @param scale the number of digits to the right of the decimal point
+     * @return the column value; if the value is SQL <code>NULL</code>, the value
+     * returned is <code>null</code>
      * @throws java.sql.SQLException if a database access error occurs
      * @deprecated
      */
@@ -247,14 +252,14 @@
     }
 
     /**
-     * Retrieves the value of the designated column in the current row
-     * of this <code>ResultSet</code> object as
-     * a <code>byte</code> array in the Java programming language.
-     * The bytes represent the raw values returned by the driver.
+     * Retrieves the value of the designated column in the current row of this
+     * <code>ResultSet</code> object as a <code>byte</code> array in the Java
+     * programming language. The bytes represent the raw values returned by the
+     * driver.
      *
      * @param columnIndex the first column is 1, the second is 2, ...
-     * @return the column value; if the value is SQL <code>NULL</code>, the
-     *         value returned is <code>null</code>
+     * @return the column value; if the value is SQL <code>NULL</code>, the value
+     * returned is <code>null</code>
      * @throws java.sql.SQLException if a database access error occurs
      */
     public byte[] getBytes(int columnIndex) throws SQLException {
@@ -262,13 +267,13 @@
     }
 
     /**
-     * Retrieves the value of the designated column in the current row
-     * of this <code>ResultSet</code> object as
-     * a <code>java.sql.Date</code> object in the Java programming language.
+     * Retrieves the value of the designated column in the current row of this
+     * <code>ResultSet</code> object as a <code>java.sql.Date</code> object in the
+     * Java programming language.
      *
      * @param columnIndex the first column is 1, the second is 2, ...
-     * @return the column value; if the value is SQL <code>NULL</code>, the
-     *         value returned is <code>null</code>
+     * @return the column value; if the value is SQL <code>NULL</code>, the value
+     * returned is <code>null</code>
      * @throws java.sql.SQLException if a database access error occurs
      */
     public Date getDate(int columnIndex) throws SQLException {
@@ -276,13 +281,13 @@
     }
 
     /**
-     * Retrieves the value of the designated column in the current row
-     * of this <code>ResultSet</code> object as
-     * a <code>java.sql.Time</code> object in the Java programming language.
+     * Retrieves the value of the designated column in the current row of this
+     * <code>ResultSet</code> object as a <code>java.sql.Time</code> object in the
+     * Java programming language.
      *
      * @param columnIndex the first column is 1, the second is 2, ...
-     * @return the column value; if the value is SQL <code>NULL</code>, the
-     *         value returned is <code>null</code>
+     * @return the column value; if the value is SQL <code>NULL</code>, the value
+     * returned is <code>null</code>
      * @throws java.sql.SQLException if a database access error occurs
      */
     public Time getTime(int columnIndex) throws SQLException {
@@ -290,13 +295,13 @@
     }
 
     /**
-     * Retrieves the value of the designated column in the current row
-     * of this <code>ResultSet</code> object as
-     * a <code>java.sql.Timestamp</code> object in the Java programming language.
+     * Retrieves the value of the designated column in the current row of this
+     * <code>ResultSet</code> object as a <code>java.sql.Timestamp</code> object in
+     * the Java programming language.
      *
      * @param columnIndex the first column is 1, the second is 2, ...
-     * @return the column value; if the value is SQL <code>NULL</code>, the
-     *         value returned is <code>null</code>
+     * @return the column value; if the value is SQL <code>NULL</code>, the value
+     * returned is <code>null</code>
      * @throws java.sql.SQLException if a database access error occurs
      */
     public Timestamp getTimestamp(int columnIndex) throws SQLException {
@@ -304,26 +309,23 @@
     }
 
     /**
-     * Retrieves the value of the designated column in the current row
-     * of this <code>ResultSet</code> object as
-     * a stream of ASCII characters. The value can then be read in chunks from the
-     * stream. This method is particularly
-     * suitable for retrieving large <char>LONGVARCHAR</char> values.
-     * The JDBC driver will
-     * do any necessary conversion from the database format into ASCII.
+     * Retrieves the value of the designated column in the current row of this
+     * <code>ResultSet</code> object as a stream of ASCII characters. The value can
+     * then be read in chunks from the stream. This method is particularly suitable
+     * for retrieving large <char>LONGVARCHAR</char> values. The JDBC driver will do
+     * any necessary conversion from the database format into ASCII.
      * <p/>
-     * <P><B>Note:</B> All the data in the returned stream must be
-     * read prior to getting the value of any other column. The next
-     * call to a getter method implicitly closes the stream.  Also, a
-     * stream may return <code>0</code> when the method
-     * <code>InputStream.available</code>
-     * is called whether there is data available or not.
+     * <P>
+     * <B>Note:</B> All the data in the returned stream must be read prior to
+     * getting the value of any other column. The next call to a getter method
+     * implicitly closes the stream. Also, a stream may return <code>0</code> when
+     * the method <code>InputStream.available</code> is called whether there is data
+     * available or not.
      *
      * @param columnIndex the first column is 1, the second is 2, ...
-     * @return a Java input stream that delivers the database column value
-     *         as a stream of one-byte ASCII characters;
-     *         if the value is SQL <code>NULL</code>, the
-     *         value returned is <code>null</code>
+     * @return a Java input stream that delivers the database column value as a
+     * stream of one-byte ASCII characters; if the value is SQL <code>NULL</code>,
+     * the value returned is <code>null</code>
      * @throws java.sql.SQLException if a database access error occurs
      */
     public InputStream getAsciiStream(int columnIndex) throws SQLException {
@@ -331,32 +333,29 @@
     }
 
     /**
-     * Retrieves the value of the designated column in the current row
-     * of this <code>ResultSet</code> object as
-     * as a stream of two-byte Unicode characters. The first byte is
-     * the high byte; the second byte is the low byte.
+     * Retrieves the value of the designated column in the current row of this
+     * <code>ResultSet</code> object as as a stream of two-byte Unicode characters.
+     * The first byte is the high byte; the second byte is the low byte.
      * <p/>
-     * The value can then be read in chunks from the
-     * stream. This method is particularly
-     * suitable for retrieving large <code>LONGVARCHAR</code>values.  The
-     * JDBC driver will do any necessary conversion from the database
-     * format into Unicode.
+     * The value can then be read in chunks from the stream. This method is
+     * particularly suitable for retrieving large <code>LONGVARCHAR</code>values.
+     * The JDBC driver will do any necessary conversion from the database format
+     * into Unicode.
      * <p/>
-     * <P><B>Note:</B> All the data in the returned stream must be
-     * read prior to getting the value of any other column. The next
-     * call to a getter method implicitly closes the stream.
-     * Also, a stream may return <code>0</code> when the method
-     * <code>InputStream.available</code>
-     * is called, whether there is data available or not.
+     * <P>
+     * <B>Note:</B> All the data in the returned stream must be read prior to
+     * getting the value of any other column. The next call to a getter method
+     * implicitly closes the stream. Also, a stream may return <code>0</code> when
+     * the method <code>InputStream.available</code> is called, whether there is
+     * data available or not.
      *
      * @param columnIndex the first column is 1, the second is 2, ...
-     * @return a Java input stream that delivers the database column value
-     *         as a stream of two-byte Unicode characters;
-     *         if the value is SQL <code>NULL</code>, the value returned is
-     *         <code>null</code>
+     * @return a Java input stream that delivers the database column value as a
+     * stream of two-byte Unicode characters; if the value is SQL <code>NULL</code>,
+     * the value returned is <code>null</code>
      * @throws java.sql.SQLException if a database access error occurs
      * @deprecated use <code>getCharacterStream</code> in place of
-     *             <code>getUnicodeStream</code>
+     * <code>getUnicodeStream</code>
      */
     @Deprecated
     public InputStream getUnicodeStream(int columnIndex) throws SQLException {
@@ -364,24 +363,22 @@
     }
 
     /**
-     * Retrieves the value of the designated column in the current row
-     * of this <code>ResultSet</code> object as a binary stream of
-     * uninterpreted bytes. The value can then be read in chunks from the
-     * stream. This method is particularly
+     * Retrieves the value of the designated column in the current row of this
+     * <code>ResultSet</code> object as a binary stream of uninterpreted bytes. The
+     * value can then be read in chunks from the stream. This method is particularly
      * suitable for retrieving large <code>LONGVARBINARY</code> values.
      * <p/>
-     * <P><B>Note:</B> All the data in the returned stream must be
-     * read prior to getting the value of any other column. The next
-     * call to a getter method implicitly closes the stream.  Also, a
-     * stream may return <code>0</code> when the method
-     * <code>InputStream.available</code>
-     * is called whether there is data available or not.
+     * <P>
+     * <B>Note:</B> All the data in the returned stream must be read prior to
+     * getting the value of any other column. The next call to a getter method
+     * implicitly closes the stream. Also, a stream may return <code>0</code> when
+     * the method <code>InputStream.available</code> is called whether there is data
+     * available or not.
      *
      * @param columnIndex the first column is 1, the second is 2, ...
-     * @return a Java input stream that delivers the database column value
-     *         as a stream of uninterpreted bytes;
-     *         if the value is SQL <code>NULL</code>, the value returned is
-     *         <code>null</code>
+     * @return a Java input stream that delivers the database column value as a
+     * stream of uninterpreted bytes; if the value is SQL <code>NULL</code>, the
+     * value returned is <code>null</code>
      * @throws java.sql.SQLException if a database access error occurs
      */
     public InputStream getBinaryStream(int columnIndex) throws SQLException {
@@ -389,13 +386,13 @@
     }
 
     /**
-     * Retrieves the value of the designated column in the current row
-     * of this <code>ResultSet</code> object as
-     * a <code>String</code> in the Java programming language.
+     * Retrieves the value of the designated column in the current row of this
+     * <code>ResultSet</code> object as a <code>String</code> in the Java
+     * programming language.
      *
      * @param columnName the SQL name of the column
-     * @return the column value; if the value is SQL <code>NULL</code>, the
-     *         value returned is <code>null</code>
+     * @return the column value; if the value is SQL <code>NULL</code>, the value
+     * returned is <code>null</code>
      * @throws java.sql.SQLException if a database access error occurs
      */
     public String getString(String columnName) throws SQLException {
@@ -403,13 +400,13 @@
     }
 
     /**
-     * Retrieves the value of the designated column in the current row
-     * of this <code>ResultSet</code> object as
-     * a <code>boolean</code> in the Java programming language.
+     * Retrieves the value of the designated column in the current row of this
+     * <code>ResultSet</code> object as a <code>boolean</code> in the Java
+     * programming language.
      *
      * @param columnName the SQL name of the column
-     * @return the column value; if the value is SQL <code>NULL</code>, the
-     *         value returned is <code>false</code>
+     * @return the column value; if the value is SQL <code>NULL</code>, the value
+     * returned is <code>false</code>
      * @throws java.sql.SQLException if a database access error occurs
      */
     public boolean getBoolean(String columnName) throws SQLException {
@@ -417,13 +414,13 @@
     }
 
     /**
-     * Retrieves the value of the designated column in the current row
-     * of this <code>ResultSet</code> object as
-     * a <code>byte</code> in the Java programming language.
+     * Retrieves the value of the designated column in the current row of this
+     * <code>ResultSet</code> object as a <code>byte</code> in the Java programming
+     * language.
      *
      * @param columnName the SQL name of the column
-     * @return the column value; if the value is SQL <code>NULL</code>, the
-     *         value returned is <code>0</code>
+     * @return the column value; if the value is SQL <code>NULL</code>, the value
+     * returned is <code>0</code>
      * @throws java.sql.SQLException if a database access error occurs
      */
     public byte getByte(String columnName) throws SQLException {
@@ -431,13 +428,13 @@
     }
 
     /**
-     * Retrieves the value of the designated column in the current row
-     * of this <code>ResultSet</code> object as
-     * a <code>short</code> in the Java programming language.
+     * Retrieves the value of the designated column in the current row of this
+     * <code>ResultSet</code> object as a <code>short</code> in the Java programming
+     * language.
      *
      * @param columnName the SQL name of the column
-     * @return the column value; if the value is SQL <code>NULL</code>, the
-     *         value returned is <code>0</code>
+     * @return the column value; if the value is SQL <code>NULL</code>, the value
+     * returned is <code>0</code>
      * @throws java.sql.SQLException if a database access error occurs
      */
     public short getShort(String columnName) throws SQLException {
@@ -445,13 +442,13 @@
     }
 
     /**
-     * Retrieves the value of the designated column in the current row
-     * of this <code>ResultSet</code> object as
-     * an <code>int</code> in the Java programming language.
+     * Retrieves the value of the designated column in the current row of this
+     * <code>ResultSet</code> object as an <code>int</code> in the Java programming
+     * language.
      *
      * @param columnName the SQL name of the column
-     * @return the column value; if the value is SQL <code>NULL</code>, the
-     *         value returned is <code>0</code>
+     * @return the column value; if the value is SQL <code>NULL</code>, the value
+     * returned is <code>0</code>
      * @throws java.sql.SQLException if a database access error occurs
      */
     public int getInt(String columnName) throws SQLException {
@@ -459,13 +456,13 @@
     }
 
     /**
-     * Retrieves the value of the designated column in the current row
-     * of this <code>ResultSet</code> object as
-     * a <code>long</code> in the Java programming language.
+     * Retrieves the value of the designated column in the current row of this
+     * <code>ResultSet</code> object as a <code>long</code> in the Java programming
+     * language.
      *
      * @param columnName the SQL name of the column
-     * @return the column value; if the value is SQL <code>NULL</code>, the
-     *         value returned is <code>0</code>
+     * @return the column value; if the value is SQL <code>NULL</code>, the value
+     * returned is <code>0</code>
      * @throws java.sql.SQLException if a database access error occurs
      */
     public long getLong(String columnName) throws SQLException {
@@ -473,13 +470,13 @@
     }
 
     /**
-     * Retrieves the value of the designated column in the current row
-     * of this <code>ResultSet</code> object as
-     * a <code>float</code> in the Java programming language.
+     * Retrieves the value of the designated column in the current row of this
+     * <code>ResultSet</code> object as a <code>float</code> in the Java programming
+     * language.
      *
      * @param columnName the SQL name of the column
-     * @return the column value; if the value is SQL <code>NULL</code>, the
-     *         value returned is <code>0</code>
+     * @return the column value; if the value is SQL <code>NULL</code>, the value
+     * returned is <code>0</code>
      * @throws java.sql.SQLException if a database access error occurs
      */
     public float getFloat(String columnName) throws SQLException {
@@ -487,13 +484,13 @@
     }
 
     /**
-     * Retrieves the value of the designated column in the current row
-     * of this <code>ResultSet</code> object as
-     * a <code>double</code> in the Java programming language.
+     * Retrieves the value of the designated column in the current row of this
+     * <code>ResultSet</code> object as a <code>double</code> in the Java
+     * programming language.
      *
      * @param columnName the SQL name of the column
-     * @return the column value; if the value is SQL <code>NULL</code>, the
-     *         value returned is <code>0</code>
+     * @return the column value; if the value is SQL <code>NULL</code>, the value
+     * returned is <code>0</code>
      * @throws java.sql.SQLException if a database access error occurs
      */
     public double getDouble(String columnName) throws SQLException {
@@ -501,14 +498,14 @@
     }
 
     /**
-     * Retrieves the value of the designated column in the current row
-     * of this <code>ResultSet</code> object as
-     * a <code>java.math.BigDecimal</code> in the Java programming language.
+     * Retrieves the value of the designated column in the current row of this
+     * <code>ResultSet</code> object as a <code>java.math.BigDecimal</code> in the
+     * Java programming language.
      *
      * @param columnName the SQL name of the column
-     * @param scale      the number of digits to the right of the decimal point
-     * @return the column value; if the value is SQL <code>NULL</code>, the
-     *         value returned is <code>null</code>
+     * @param scale the number of digits to the right of the decimal point
+     * @return the column value; if the value is SQL <code>NULL</code>, the value
+     * returned is <code>null</code>
      * @throws java.sql.SQLException if a database access error occurs
      * @deprecated
      */
@@ -518,14 +515,14 @@
     }
 
     /**
-     * Retrieves the value of the designated column in the current row
-     * of this <code>ResultSet</code> object as
-     * a <code>byte</code> array in the Java programming language.
-     * The bytes represent the raw values returned by the driver.
+     * Retrieves the value of the designated column in the current row of this
+     * <code>ResultSet</code> object as a <code>byte</code> array in the Java
+     * programming language. The bytes represent the raw values returned by the
+     * driver.
      *
      * @param columnName the SQL name of the column
-     * @return the column value; if the value is SQL <code>NULL</code>, the
-     *         value returned is <code>null</code>
+     * @return the column value; if the value is SQL <code>NULL</code>, the value
+     * returned is <code>null</code>
      * @throws java.sql.SQLException if a database access error occurs
      */
     public byte[] getBytes(String columnName) throws SQLException {
@@ -533,13 +530,13 @@
     }
 
     /**
-     * Retrieves the value of the designated column in the current row
-     * of this <code>ResultSet</code> object as
-     * a <code>java.sql.Date</code> object in the Java programming language.
+     * Retrieves the value of the designated column in the current row of this
+     * <code>ResultSet</code> object as a <code>java.sql.Date</code> object in the
+     * Java programming language.
      *
      * @param columnName the SQL name of the column
-     * @return the column value; if the value is SQL <code>NULL</code>, the
-     *         value returned is <code>null</code>
+     * @return the column value; if the value is SQL <code>NULL</code>, the value
+     * returned is <code>null</code>
      * @throws java.sql.SQLException if a database access error occurs
      */
     public Date getDate(String columnName) throws SQLException {
@@ -547,14 +544,13 @@
     }
 
     /**
-     * Retrieves the value of the designated column in the current row
-     * of this <code>ResultSet</code> object as
-     * a <code>java.sql.Time</code> object in the Java programming language.
+     * Retrieves the value of the designated column in the current row of this
+     * <code>ResultSet</code> object as a <code>java.sql.Time</code> object in the
+     * Java programming language.
      *
      * @param columnName the SQL name of the column
-     * @return the column value;
-     *         if the value is SQL <code>NULL</code>,
-     *         the value returned is <code>null</code>
+     * @return the column value; if the value is SQL <code>NULL</code>, the value
+     * returned is <code>null</code>
      * @throws java.sql.SQLException if a database access error occurs
      */
     public Time getTime(String columnName) throws SQLException {
@@ -562,13 +558,12 @@
     }
 
     /**
-     * Retrieves the value of the designated column in the current row
-     * of this <code>ResultSet</code> object as
-     * a <code>java.sql.Timestamp</code> object.
+     * Retrieves the value of the designated column in the current row of this
+     * <code>ResultSet</code> object as a <code>java.sql.Timestamp</code> object.
      *
      * @param columnName the SQL name of the column
-     * @return the column value; if the value is SQL <code>NULL</code>, the
-     *         value returned is <code>null</code>
+     * @return the column value; if the value is SQL <code>NULL</code>, the value
+     * returned is <code>null</code>
      * @throws java.sql.SQLException if a database access error occurs
      */
     public Timestamp getTimestamp(String columnName) throws SQLException {
@@ -576,25 +571,23 @@
     }
 
     /**
-     * Retrieves the value of the designated column in the current row
-     * of this <code>ResultSet</code> object as a stream of
-     * ASCII characters. The value can then be read in chunks from the
-     * stream. This method is particularly
-     * suitable for retrieving large <code>LONGVARCHAR</code> values.
-     * The JDBC driver will
-     * do any necessary conversion from the database format into ASCII.
+     * Retrieves the value of the designated column in the current row of this
+     * <code>ResultSet</code> object as a stream of ASCII characters. The value can
+     * then be read in chunks from the stream. This method is particularly suitable
+     * for retrieving large <code>LONGVARCHAR</code> values. The JDBC driver will do
+     * any necessary conversion from the database format into ASCII.
      * <p/>
-     * <P><B>Note:</B> All the data in the returned stream must be
-     * read prior to getting the value of any other column. The next
-     * call to a getter method implicitly closes the stream. Also, a
-     * stream may return <code>0</code> when the method <code>available</code>
-     * is called whether there is data available or not.
+     * <P>
+     * <B>Note:</B> All the data in the returned stream must be read prior to
+     * getting the value of any other column. The next call to a getter method
+     * implicitly closes the stream. Also, a stream may return <code>0</code> when
+     * the method <code>available</code> is called whether there is data available
+     * or not.
      *
      * @param columnName the SQL name of the column
-     * @return a Java input stream that delivers the database column value
-     *         as a stream of one-byte ASCII characters.
-     *         If the value is SQL <code>NULL</code>,
-     *         the value returned is <code>null</code>.
+     * @return a Java input stream that delivers the database column value as a
+     * stream of one-byte ASCII characters. If the value is SQL <code>NULL</code>,
+     * the value returned is <code>null</code>.
      * @throws java.sql.SQLException if a database access error occurs
      */
     public InputStream getAsciiStream(String columnName) throws SQLException {
@@ -602,29 +595,26 @@
     }
 
     /**
-     * Retrieves the value of the designated column in the current row
-     * of this <code>ResultSet</code> object as a stream of two-byte
-     * Unicode characters. The first byte is the high byte; the second
-     * byte is the low byte.
+     * Retrieves the value of the designated column in the current row of this
+     * <code>ResultSet</code> object as a stream of two-byte Unicode characters. The
+     * first byte is the high byte; the second byte is the low byte.
      * <p/>
-     * The value can then be read in chunks from the
-     * stream. This method is particularly
-     * suitable for retrieving large <code>LONGVARCHAR</code> values.
-     * The JDBC technology-enabled driver will
-     * do any necessary conversion from the database format into Unicode.
+     * The value can then be read in chunks from the stream. This method is
+     * particularly suitable for retrieving large <code>LONGVARCHAR</code> values.
+     * The JDBC technology-enabled driver will do any necessary conversion from the
+     * database format into Unicode.
      * <p/>
-     * <P><B>Note:</B> All the data in the returned stream must be
-     * read prior to getting the value of any other column. The next
-     * call to a getter method implicitly closes the stream.
-     * Also, a stream may return <code>0</code> when the method
-     * <code>InputStream.available</code> is called, whether there
-     * is data available or not.
+     * <P>
+     * <B>Note:</B> All the data in the returned stream must be read prior to
+     * getting the value of any other column. The next call to a getter method
+     * implicitly closes the stream. Also, a stream may return <code>0</code> when
+     * the method <code>InputStream.available</code> is called, whether there is
+     * data available or not.
      *
      * @param columnName the SQL name of the column
-     * @return a Java input stream that delivers the database column value
-     *         as a stream of two-byte Unicode characters.
-     *         If the value is SQL <code>NULL</code>, the value returned
-     *         is <code>null</code>.
+     * @return a Java input stream that delivers the database column value as a
+     * stream of two-byte Unicode characters. If the value is SQL <code>NULL</code>,
+     * the value returned is <code>null</code>.
      * @throws java.sql.SQLException if a database access error occurs
      * @deprecated use <code>getCharacterStream</code> instead
      */
@@ -634,24 +624,23 @@
     }
 
     /**
-     * Retrieves the value of the designated column in the current row
-     * of this <code>ResultSet</code> object as a stream of uninterpreted
-     * <code>byte</code>s.
-     * The value can then be read in chunks from the
-     * stream. This method is particularly
-     * suitable for retrieving large <code>LONGVARBINARY</code>
-     * values.
+     * Retrieves the value of the designated column in the current row of this
+     * <code>ResultSet</code> object as a stream of uninterpreted
+     * <code>byte</code>s. The value can then be read in chunks from the stream.
+     * This method is particularly suitable for retrieving large
+     * <code>LONGVARBINARY</code> values.
      * <p/>
-     * <P><B>Note:</B> All the data in the returned stream must be
-     * read prior to getting the value of any other column. The next
-     * call to a getter method implicitly closes the stream. Also, a
-     * stream may return <code>0</code> when the method <code>available</code>
-     * is called whether there is data available or not.
+     * <P>
+     * <B>Note:</B> All the data in the returned stream must be read prior to
+     * getting the value of any other column. The next call to a getter method
+     * implicitly closes the stream. Also, a stream may return <code>0</code> when
+     * the method <code>available</code> is called whether there is data available
+     * or not.
      *
      * @param columnName the SQL name of the column
-     * @return a Java input stream that delivers the database column value
-     *         as a stream of uninterpreted bytes;
-     *         if the value is SQL <code>NULL</code>, the result is <code>null</code>
+     * @return a Java input stream that delivers the database column value as a
+     * stream of uninterpreted bytes; if the value is SQL <code>NULL</code>, the
+     * result is <code>null</code>
      * @throws java.sql.SQLException if a database access error occurs
      */
     public InputStream getBinaryStream(String columnName) throws SQLException {
@@ -659,37 +648,34 @@
     }
 
     /**
-     * Retrieves the first warning reported by calls on this
-     * <code>ResultSet</code> object.
-     * Subsequent warnings on this <code>ResultSet</code> object
-     * will be chained to the <code>SQLWarning</code> object that
-     * this method returns.
+     * Retrieves the first warning reported by calls on this <code>ResultSet</code>
+     * object. Subsequent warnings on this <code>ResultSet</code> object will be
+     * chained to the <code>SQLWarning</code> object that this method returns.
      * <p/>
-     * <P>The warning chain is automatically cleared each time a new
-     * row is read.  This method may not be called on a <code>ResultSet</code>
-     * object that has been closed; doing so will cause an
-     * <code>SQLException</code> to be thrown.
+     * <P>
+     * The warning chain is automatically cleared each time a new row is read. This
+     * method may not be called on a <code>ResultSet</code> object that has been
+     * closed; doing so will cause an <code>SQLException</code> to be thrown.
      * <p/>
-     * <B>Note:</B> This warning chain only covers warnings caused
-     * by <code>ResultSet</code> methods.  Any warning caused by
-     * <code>Statement</code> methods
-     * (such as reading OUT parameters) will be chained on the
+     * <B>Note:</B> This warning chain only covers warnings caused by
+     * <code>ResultSet</code> methods. Any warning caused by <code>Statement</code>
+     * methods (such as reading OUT parameters) will be chained on the
      * <code>Statement</code> object.
      *
      * @return the first <code>SQLWarning</code> object reported or
-     *         <code>null</code> if there are none
-     * @throws java.sql.SQLException if a database access error occurs or this method is
-     *                               called on a closed result set
+     * <code>null</code> if there are none
+     * @throws java.sql.SQLException if a database access error occurs or this
+     * method is called on a closed result set
      */
     public SQLWarning getWarnings() throws SQLException {
         return resultSet.getWarnings();
     }
 
     /**
-     * Clears all warnings reported on this <code>ResultSet</code> object.
-     * After this method is called, the method <code>getWarnings</code>
-     * returns <code>null</code> until a new warning is
-     * reported for this <code>ResultSet</code> object.
+     * Clears all warnings reported on this <code>ResultSet</code> object. After
+     * this method is called, the method <code>getWarnings</code> returns
+     * <code>null</code> until a new warning is reported for this
+     * <code>ResultSet</code> object.
      *
      * @throws java.sql.SQLException if a database access error occurs
      */
@@ -701,20 +687,22 @@
      * Retrieves the name of the SQL cursor used by this <code>ResultSet</code>
      * object.
      * <p/>
-     * <P>In SQL, a result table is retrieved through a cursor that is
-     * named. The current row of a result set can be updated or deleted
-     * using a positioned update/delete statement that references the
-     * cursor name. To insure that the cursor has the proper isolation
-     * level to support update, the cursor's <code>SELECT</code> statement
-     * should be of the form <code>SELECT FOR UPDATE</code>. If
-     * <code>FOR UPDATE</code> is omitted, the positioned updates may fail.
+     * <P>
+     * In SQL, a result table is retrieved through a cursor that is named. The
+     * current row of a result set can be updated or deleted using a positioned
+     * update/delete statement that references the cursor name. To insure that the
+     * cursor has the proper isolation level to support update, the cursor's
+     * <code>SELECT</code> statement should be of the form
+     * <code>SELECT FOR UPDATE</code>. If <code>FOR UPDATE</code> is omitted, the
+     * positioned updates may fail.
      * <p/>
-     * <P>The JDBC API supports this SQL feature by providing the name of the
-     * SQL cursor used by a <code>ResultSet</code> object.
-     * The current row of a <code>ResultSet</code> object
-     * is also the current row of this SQL cursor.
+     * <P>
+     * The JDBC API supports this SQL feature by providing the name of the SQL
+     * cursor used by a <code>ResultSet</code> object. The current row of a
+     * <code>ResultSet</code> object is also the current row of this SQL cursor.
      * <p/>
-     * <P><B>Note:</B> If positioned update is not supported, a
+     * <P>
+     * <B>Note:</B> If positioned update is not supported, a
      * <code>SQLException</code> is thrown.
      *
      * @return the SQL name for this <code>ResultSet</code> object's cursor
@@ -725,8 +713,8 @@
     }
 
     /**
-     * Retrieves the  number, types and properties of
-     * this <code>ResultSet</code> object's columns.
+     * Retrieves the number, types and properties of this <code>ResultSet</code>
+     * object's columns.
      *
      * @return the description of this <code>ResultSet</code> object's columns
      * @throws java.sql.SQLException if a database access error occurs
@@ -736,25 +724,25 @@
     }
 
     /**
-     * <p>Gets the value of the designated column in the current row
-     * of this <code>ResultSet</code> object as
-     * an <code>Object</code> in the Java programming language.
+     * <p>
+     * Gets the value of the designated column in the current row of this
+     * <code>ResultSet</code> object as an <code>Object</code> in the Java
+     * programming language.
      * <p/>
-     * <p>This method will return the value of the given column as a
-     * Java object.  The type of the Java object will be the default
-     * Java object type corresponding to the column's SQL type,
-     * following the mapping for built-in types specified in the JDBC
-     * specification. If the value is an SQL <code>NULL</code>,
-     * the driver returns a Java <code>null</code>.
+     * <p>
+     * This method will return the value of the given column as a Java object. The
+     * type of the Java object will be the default Java object type corresponding to
+     * the column's SQL type, following the mapping for built-in types specified in
+     * the JDBC specification. If the value is an SQL <code>NULL</code>, the driver
+     * returns a Java <code>null</code>.
      * <p/>
-     * <p>This method may also be used to read database-specific
-     * abstract data types.
+     * <p>
+     * This method may also be used to read database-specific abstract data types.
      * <p/>
-     * In the JDBC 2.0 API, the behavior of method
-     * <code>getObject</code> is extended to materialize
-     * data of SQL user-defined types.  When a column contains
-     * a structured or distinct value, the behavior of this method is as
-     * if it were a call to: <code>getObject(columnIndex,
+     * In the JDBC 2.0 API, the behavior of method <code>getObject</code> is
+     * extended to materialize data of SQL user-defined types. When a column
+     * contains a structured or distinct value, the behavior of this method is as if
+     * it were a call to: <code>getObject(columnIndex,
      * this.getStatement().getConnection().getTypeMap())</code>.
      *
      * @param columnIndex the first column is 1, the second is 2, ...
@@ -766,25 +754,24 @@
     }
 
     /**
-     * <p>Gets the value of the designated column in the current row
-     * of this <code>ResultSet</code> object as
-     * an <code>Object</code> in the Java programming language.
+     * <p>
+     * Gets the value of the designated column in the current row of this
+     * <code>ResultSet</code> object as an <code>Object</code> in the Java
+     * programming language.
      * <p/>
-     * <p>This method will return the value of the given column as a
-     * Java object.  The type of the Java object will be the default
-     * Java object type corresponding to the column's SQL type,
-     * following the mapping for built-in types specified in the JDBC
-     * specification. If the value is an SQL <code>NULL</code>,
-     * the driver returns a Java <code>null</code>.
+     * <p>
+     * This method will return the value of the given column as a Java object. The
+     * type of the Java object will be the default Java object type corresponding to
+     * the column's SQL type, following the mapping for built-in types specified in
+     * the JDBC specification. If the value is an SQL <code>NULL</code>, the driver
+     * returns a Java <code>null</code>.
      * <p/>
-     * This method may also be used to read database-specific
-     * abstract data types.
+     * This method may also be used to read database-specific abstract data types.
      * <p/>
-     * In the JDBC 2.0 API, the behavior of the method
-     * <code>getObject</code> is extended to materialize
-     * data of SQL user-defined types.  When a column contains
-     * a structured or distinct value, the behavior of this method is as
-     * if it were a call to: <code>getObject(columnIndex,
+     * In the JDBC 2.0 API, the behavior of the method <code>getObject</code> is
+     * extended to materialize data of SQL user-defined types. When a column
+     * contains a structured or distinct value, the behavior of this method is as if
+     * it were a call to: <code>getObject(columnIndex,
      * this.getStatement().getConnection().getTypeMap())</code>.
      *
      * @param columnName the SQL name of the column
@@ -801,22 +788,21 @@
      *
      * @param columnName the name of the column
      * @return the column index of the given column name
-     * @throws java.sql.SQLException if the <code>ResultSet</code> object
-     *                               does not contain <code>columnName</code> or a database access error occurs
+     * @throws java.sql.SQLException if the <code>ResultSet</code> object does not
+     * contain <code>columnName</code> or a database access error occurs
      */
     public int findColumn(String columnName) throws SQLException {
         return resultSet.findColumn(columnName);
     }
 
     /**
-     * Retrieves the value of the designated column in the current row
-     * of this <code>ResultSet</code> object as a
-     * <code>java.io.Reader</code> object.
+     * Retrieves the value of the designated column in the current row of this
+     * <code>ResultSet</code> object as a <code>java.io.Reader</code> object.
      *
      * @param columnIndex the first column is 1, the second is 2, ...
-     * @return a <code>java.io.Reader</code> object that contains the column
-     *         value; if the value is SQL <code>NULL</code>, the value returned is
-     *         <code>null</code> in the Java programming language.
+     * @return a <code>java.io.Reader</code> object that contains the column value;
+     * if the value is SQL <code>NULL</code>, the value returned is
+     * <code>null</code> in the Java programming language.
      * @throws java.sql.SQLException if a database access error occurs
      * @since 1.2
      */
@@ -825,14 +811,13 @@
     }
 
     /**
-     * Retrieves the value of the designated column in the current row
-     * of this <code>ResultSet</code> object as a
-     * <code>java.io.Reader</code> object.
+     * Retrieves the value of the designated column in the current row of this
+     * <code>ResultSet</code> object as a <code>java.io.Reader</code> object.
      *
      * @param columnName the name of the column
-     * @return a <code>java.io.Reader</code> object that contains the column
-     *         value; if the value is SQL <code>NULL</code>, the value returned is
-     *         <code>null</code> in the Java programming language
+     * @return a <code>java.io.Reader</code> object that contains the column value;
+     * if the value is SQL <code>NULL</code>, the value returned is
+     * <code>null</code> in the Java programming language
      * @throws java.sql.SQLException if a database access error occurs
      * @since 1.2
      */
@@ -841,14 +826,14 @@
     }
 
     /**
-     * Retrieves the value of the designated column in the current row
-     * of this <code>ResultSet</code> object as a
-     * <code>java.math.BigDecimal</code> with full precision.
+     * Retrieves the value of the designated column in the current row of this
+     * <code>ResultSet</code> object as a <code>java.math.BigDecimal</code> with
+     * full precision.
      *
      * @param columnIndex the first column is 1, the second is 2, ...
-     * @return the column value (full precision);
-     *         if the value is SQL <code>NULL</code>, the value returned is
-     *         <code>null</code> in the Java programming language.
+     * @return the column value (full precision); if the value is SQL
+     * <code>NULL</code>, the value returned is <code>null</code> in the Java
+     * programming language.
      * @throws java.sql.SQLException if a database access error occurs
      * @since 1.2
      */
@@ -857,14 +842,14 @@
     }
 
     /**
-     * Retrieves the value of the designated column in the current row
-     * of this <code>ResultSet</code> object as a
-     * <code>java.math.BigDecimal</code> with full precision.
+     * Retrieves the value of the designated column in the current row of this
+     * <code>ResultSet</code> object as a <code>java.math.BigDecimal</code> with
+     * full precision.
      *
      * @param columnName the column name
-     * @return the column value (full precision);
-     *         if the value is SQL <code>NULL</code>, the value returned is
-     *         <code>null</code> in the Java programming language.
+     * @return the column value (full precision); if the value is SQL
+     * <code>NULL</code>, the value returned is <code>null</code> in the Java
+     * programming language.
      * @throws java.sql.SQLException if a database access error occurs
      * @since 1.2
      */
@@ -873,12 +858,12 @@
     }
 
     /**
-     * Retrieves whether the cursor is before the first row in
-     * this <code>ResultSet</code> object.
+     * Retrieves whether the cursor is before the first row in this
+     * <code>ResultSet</code> object.
      *
      * @return <code>true</code> if the cursor is before the first row;
-     *         <code>false</code> if the cursor is at any other position or the
-     *         result set contains no rows
+     * <code>false</code> if the cursor is at any other position or the result set
+     * contains no rows
      * @throws java.sql.SQLException if a database access error occurs
      * @since 1.2
      */
@@ -887,12 +872,12 @@
     }
 
     /**
-     * Retrieves whether the cursor is after the last row in
-     * this <code>ResultSet</code> object.
+     * Retrieves whether the cursor is after the last row in this
+     * <code>ResultSet</code> object.
      *
      * @return <code>true</code> if the cursor is after the last row;
-     *         <code>false</code> if the cursor is at any other position or the
-     *         result set contains no rows
+     * <code>false</code> if the cursor is at any other position or the result set
+     * contains no rows
      * @throws java.sql.SQLException if a database access error occurs
      * @since 1.2
      */
@@ -901,11 +886,11 @@
     }
 
     /**
-     * Retrieves whether the cursor is on the first row of
-     * this <code>ResultSet</code> object.
+     * Retrieves whether the cursor is on the first row of this
+     * <code>ResultSet</code> object.
      *
      * @return <code>true</code> if the cursor is on the first row;
-     *         <code>false</code> otherwise
+     * <code>false</code> otherwise
      * @throws java.sql.SQLException if a database access error occurs
      * @since 1.2
      */
@@ -914,15 +899,13 @@
     }
 
     /**
-     * Retrieves whether the cursor is on the last row of
-     * this <code>ResultSet</code> object.
-     * Note: Calling the method <code>isLast</code> may be expensive
-     * because the JDBC driver
-     * might need to fetch ahead one row in order to determine
-     * whether the current row is the last row in the result set.
+     * Retrieves whether the cursor is on the last row of this
+     * <code>ResultSet</code> object. Note: Calling the method <code>isLast</code>
+     * may be expensive because the JDBC driver might need to fetch ahead one row in
+     * order to determine whether the current row is the last row in the result set.
      *
      * @return <code>true</code> if the cursor is on the last row;
-     *         <code>false</code> otherwise
+     * <code>false</code> otherwise
      * @throws java.sql.SQLException if a database access error occurs
      * @since 1.2
      */
@@ -931,12 +914,12 @@
     }
 
     /**
-     * Moves the cursor to the front of
-     * this <code>ResultSet</code> object, just before the
-     * first row. This method has no effect if the result set contains no rows.
+     * Moves the cursor to the front of this <code>ResultSet</code> object, just
+     * before the first row. This method has no effect if the result set contains no
+     * rows.
      *
-     * @throws java.sql.SQLException if a database access error
-     *                               occurs or the result set type is <code>TYPE_FORWARD_ONLY</code>
+     * @throws java.sql.SQLException if a database access error occurs or the result
+     * set type is <code>TYPE_FORWARD_ONLY</code>
      * @since 1.2
      */
     public void beforeFirst() throws SQLException {
@@ -944,12 +927,11 @@
     }
 
     /**
-     * Moves the cursor to the end of
-     * this <code>ResultSet</code> object, just after the
-     * last row. This method has no effect if the result set contains no rows.
+     * Moves the cursor to the end of this <code>ResultSet</code> object, just after
+     * the last row. This method has no effect if the result set contains no rows.
      *
-     * @throws java.sql.SQLException if a database access error
-     *                               occurs or the result set type is <code>TYPE_FORWARD_ONLY</code>
+     * @throws java.sql.SQLException if a database access error occurs or the result
+     * set type is <code>TYPE_FORWARD_ONLY</code>
      * @since 1.2
      */
     public void afterLast() throws SQLException {
@@ -957,13 +939,12 @@
     }
 
     /**
-     * Moves the cursor to the first row in
-     * this <code>ResultSet</code> object.
+     * Moves the cursor to the first row in this <code>ResultSet</code> object.
      *
-     * @return <code>true</code> if the cursor is on a valid row;
-     *         <code>false</code> if there are no rows in the result set
-     * @throws java.sql.SQLException if a database access error
-     *                               occurs or the result set type is <code>TYPE_FORWARD_ONLY</code>
+     * @return <code>true</code> if the cursor is on a valid row; <code>false</code>
+     * if there are no rows in the result set
+     * @throws java.sql.SQLException if a database access error occurs or the result
+     * set type is <code>TYPE_FORWARD_ONLY</code>
      * @since 1.2
      */
     public boolean first() throws SQLException {
@@ -971,13 +952,12 @@
     }
 
     /**
-     * Moves the cursor to the last row in
-     * this <code>ResultSet</code> object.
+     * Moves the cursor to the last row in this <code>ResultSet</code> object.
      *
-     * @return <code>true</code> if the cursor is on a valid row;
-     *         <code>false</code> if there are no rows in the result set
-     * @throws java.sql.SQLException if a database access error
-     *                               occurs or the result set type is <code>TYPE_FORWARD_ONLY</code>
+     * @return <code>true</code> if the cursor is on a valid row; <code>false</code>
+     * if there are no rows in the result set
+     * @throws java.sql.SQLException if a database access error occurs or the result
+     * set type is <code>TYPE_FORWARD_ONLY</code>
      * @since 1.2
      */
     public boolean last() throws SQLException {
@@ -985,8 +965,8 @@
     }
 
     /**
-     * Retrieves the current row number.  The first row is number 1, the
-     * second number 2, and so on.
+     * Retrieves the current row number. The first row is number 1, the second
+     * number 2, and so on.
      *
      * @return the current row number; <code>0</code> if there is no current row
      * @throws java.sql.SQLException if a database access error occurs
@@ -997,37 +977,38 @@
     }
 
     /**
-     * Moves the cursor to the given row number in
-     * this <code>ResultSet</code> object.
+     * Moves the cursor to the given row number in this <code>ResultSet</code>
+     * object.
      * <p/>
-     * <p>If the row number is positive, the cursor moves to
-     * the given row number with respect to the
-     * beginning of the result set.  The first row is row 1, the second
-     * is row 2, and so on.
+     * <p>
+     * If the row number is positive, the cursor moves to the given row number with
+     * respect to the beginning of the result set. The first row is row 1, the
+     * second is row 2, and so on.
      * <p/>
-     * <p>If the given row number is negative, the cursor moves to
-     * an absolute row position with respect to
-     * the end of the result set.  For example, calling the method
-     * <code>absolute(-1)</code> positions the
-     * cursor on the last row; calling the method <code>absolute(-2)</code>
-     * moves the cursor to the next-to-last row, and so on.
+     * <p>
+     * If the given row number is negative, the cursor moves to an absolute row
+     * position with respect to the end of the result set. For example, calling the
+     * method <code>absolute(-1)</code> positions the cursor on the last row;
+     * calling the method <code>absolute(-2)</code> moves the cursor to the
+     * next-to-last row, and so on.
      * <p/>
-     * <p>An attempt to position the cursor beyond the first/last row in
-     * the result set leaves the cursor before the first row or after
-     * the last row.
+     * <p>
+     * An attempt to position the cursor beyond the first/last row in the result set
+     * leaves the cursor before the first row or after the last row.
      * <p/>
-     * <p><B>Note:</B> Calling <code>absolute(1)</code> is the same
-     * as calling <code>first()</code>. Calling <code>absolute(-1)</code>
-     * is the same as calling <code>last()</code>.
+     * <p>
+     * <B>Note:</B> Calling <code>absolute(1)</code> is the same as calling
+     * <code>first()</code>. Calling <code>absolute(-1)</code> is the same as
+     * calling <code>last()</code>.
      *
-     * @param row the number of the row to which the cursor should move.
-     *            A positive number indicates the row number counting from the
-     *            beginning of the result set; a negative number indicates the
-     *            row number counting from the end of the result set
+     * @param row the number of the row to which the cursor should move. A positive
+     * number indicates the row number counting from the beginning of the result
+     * set; a negative number indicates the row number counting from the end of the
+     * result set
      * @return <code>true</code> if the cursor is on the result set;
-     *         <code>false</code> otherwise
-     * @throws java.sql.SQLException if a database access error
-     *                               occurs, or the result set type is <code>TYPE_FORWARD_ONLY</code>
+     * <code>false</code> otherwise
+     * @throws java.sql.SQLException if a database access error occurs, or the
+     * result set type is <code>TYPE_FORWARD_ONLY</code>
      * @since 1.2
      */
     public boolean absolute(int row) throws SQLException {
@@ -1036,24 +1017,22 @@
 
     /**
      * Moves the cursor a relative number of rows, either positive or negative.
-     * Attempting to move beyond the first/last row in the
-     * result set positions the cursor before/after the
-     * the first/last row. Calling <code>relative(0)</code> is valid, but does
-     * not change the cursor position.
+     * Attempting to move beyond the first/last row in the result set positions the
+     * cursor before/after the the first/last row. Calling <code>relative(0)</code>
+     * is valid, but does not change the cursor position.
      * <p/>
-     * <p>Note: Calling the method <code>relative(1)</code>
-     * is identical to calling the method <code>next()</code> and
-     * calling the method <code>relative(-1)</code> is identical
-     * to calling the method <code>previous()</code>.
+     * <p>
+     * Note: Calling the method <code>relative(1)</code> is identical to calling the
+     * method <code>next()</code> and calling the method <code>relative(-1)</code>
+     * is identical to calling the method <code>previous()</code>.
      *
-     * @param rows an <code>int</code> specifying the number of rows to
-     *             move from the current row; a positive number moves the cursor
-     *             forward; a negative number moves the cursor backward
-     * @return <code>true</code> if the cursor is on a row;
-     *         <code>false</code> otherwise
-     * @throws java.sql.SQLException if a database access error occurs,
-     *                               there is no current row, or the result set type is
-     *                               <code>TYPE_FORWARD_ONLY</code>
+     * @param rows an <code>int</code> specifying the number of rows to move from
+     * the current row; a positive number moves the cursor forward; a negative
+     * number moves the cursor backward
+     * @return <code>true</code> if the cursor is on a row; <code>false</code>
+     * otherwise
+     * @throws java.sql.SQLException if a database access error occurs, there is no
+     * current row, or the result set type is <code>TYPE_FORWARD_ONLY</code>
      * @since 1.2
      */
     public boolean relative(int rows) throws SQLException {
@@ -1061,13 +1040,12 @@
     }
 
     /**
-     * Moves the cursor to the previous row in this
-     * <code>ResultSet</code> object.
+     * Moves the cursor to the previous row in this <code>ResultSet</code> object.
      *
-     * @return <code>true</code> if the cursor is on a valid row;
-     *         <code>false</code> if it is off the result set
-     * @throws java.sql.SQLException if a database access error
-     *                               occurs or the result set type is <code>TYPE_FORWARD_ONLY</code>
+     * @return <code>true</code> if the cursor is on a valid row; <code>false</code>
+     * if it is off the result set
+     * @throws java.sql.SQLException if a database access error occurs or the result
+     * set type is <code>TYPE_FORWARD_ONLY</code>
      * @since 1.2
      */
     public boolean previous() throws SQLException {
@@ -1076,19 +1054,17 @@
 
     /**
      * Gives a hint as to the direction in which the rows in this
-     * <code>ResultSet</code> object will be processed.
-     * The initial value is determined by the
-     * <code>Statement</code> object
-     * that produced this <code>ResultSet</code> object.
-     * The fetch direction may be changed at any time.
+     * <code>ResultSet</code> object will be processed. The initial value is
+     * determined by the <code>Statement</code> object that produced this
+     * <code>ResultSet</code> object. The fetch direction may be changed at any
+     * time.
      *
-     * @param direction an <code>int</code> specifying the suggested
-     *                  fetch direction; one of <code>ResultSet.FETCH_FORWARD</code>,
-     *                  <code>ResultSet.FETCH_REVERSE</code>, or
-     *                  <code>ResultSet.FETCH_UNKNOWN</code>
-     * @throws java.sql.SQLException if a database access error occurs or
-     *                               the result set type is <code>TYPE_FORWARD_ONLY</code> and the fetch
-     *                               direction is not <code>FETCH_FORWARD</code>
+     * @param direction an <code>int</code> specifying the suggested fetch
+     * direction; one of <code>ResultSet.FETCH_FORWARD</code>,
+     * <code>ResultSet.FETCH_REVERSE</code>, or <code>ResultSet.FETCH_UNKNOWN</code>
+     * @throws java.sql.SQLException if a database access error occurs or the result
+     * set type is <code>TYPE_FORWARD_ONLY</code> and the fetch direction is not
+     * <code>FETCH_FORWARD</code>
      * @see java.sql.Statement#setFetchDirection
      * @see #getFetchDirection
      * @since 1.2
@@ -1098,8 +1074,7 @@
     }
 
     /**
-     * Retrieves the fetch direction for this
-     * <code>ResultSet</code> object.
+     * Retrieves the fetch direction for this <code>ResultSet</code> object.
      *
      * @return the current fetch direction for this <code>ResultSet</code> object
      * @throws java.sql.SQLException if a database access error occurs
@@ -1111,18 +1086,16 @@
     }
 
     /**
-     * Gives the JDBC driver a hint as to the number of rows that should
-     * be fetched from the database when more rows are needed for this
-     * <code>ResultSet</code> object.
-     * If the fetch size specified is zero, the JDBC driver
-     * ignores the value and is free to make its own best guess as to what
-     * the fetch size should be.  The default value is set by the
-     * <code>Statement</code> object
-     * that created the result set.  The fetch size may be changed at any time.
+     * Gives the JDBC driver a hint as to the number of rows that should be fetched
+     * from the database when more rows are needed for this <code>ResultSet</code>
+     * object. If the fetch size specified is zero, the JDBC driver ignores the
+     * value and is free to make its own best guess as to what the fetch size should
+     * be. The default value is set by the <code>Statement</code> object that
+     * created the result set. The fetch size may be changed at any time.
      *
      * @param rows the number of rows to fetch
      * @throws java.sql.SQLException if a database access error occurs or the
-     *                               condition <code>0 <= rows <= Statement.getMaxRows()</code> is not satisfied
+     * condition <code>0 <= rows <= Statement.getMaxRows()</code> is not satisfied
      * @see #getFetchSize
      * @since 1.2
      */
@@ -1131,8 +1104,7 @@
     }
 
     /**
-     * Retrieves the fetch size for this
-     * <code>ResultSet</code> object.
+     * Retrieves the fetch size for this <code>ResultSet</code> object.
      *
      * @return the current fetch size for this <code>ResultSet</code> object
      * @throws java.sql.SQLException if a database access error occurs
@@ -1144,13 +1116,12 @@
     }
 
     /**
-     * Retrieves the type of this <code>ResultSet</code> object.
-     * The type is determined by the <code>Statement</code> object
-     * that created the result set.
+     * Retrieves the type of this <code>ResultSet</code> object. The type is
+     * determined by the <code>Statement</code> object that created the result set.
      *
      * @return <code>ResultSet.TYPE_FORWARD_ONLY</code>,
-     *         <code>ResultSet.TYPE_SCROLL_INSENSITIVE</code>,
-     *         or <code>ResultSet.TYPE_SCROLL_SENSITIVE</code>
+     * <code>ResultSet.TYPE_SCROLL_INSENSITIVE</code>, or
+     * <code>ResultSet.TYPE_SCROLL_SENSITIVE</code>
      * @throws java.sql.SQLException if a database access error occurs
      * @since 1.2
      */
@@ -1159,13 +1130,12 @@
     }
 
     /**
-     * Retrieves the concurrency mode of this <code>ResultSet</code> object.
-     * The concurrency used is determined by the
-     * <code>Statement</code> object that created the result set.
+     * Retrieves the concurrency mode of this <code>ResultSet</code> object. The
+     * concurrency used is determined by the <code>Statement</code> object that
+     * created the result set.
      *
-     * @return the concurrency type, either
-     *         <code>ResultSet.CONCUR_READ_ONLY</code>
-     *         or <code>ResultSet.CONCUR_UPDATABLE</code>
+     * @return the concurrency type, either <code>ResultSet.CONCUR_READ_ONLY</code>
+     * or <code>ResultSet.CONCUR_UPDATABLE</code>
      * @throws java.sql.SQLException if a database access error occurs
      * @since 1.2
      */
@@ -1174,11 +1144,11 @@
     }
 
     /**
-     * Retrieves whether the current row has been updated.  The value returned
+     * Retrieves whether the current row has been updated. The value returned
      * depends on whether or not the result set can detect updates.
      *
-     * @return <code>true</code> if both (1) the row has been visibly updated
-     *         by the owner or another and (2) updates are detected
+     * @return <code>true</code> if both (1) the row has been visibly updated by the
+     * owner or another and (2) updates are detected
      * @throws java.sql.SQLException if a database access error occurs
      * @see java.sql.DatabaseMetaData#updatesAreDetected
      * @since 1.2
@@ -1188,12 +1158,12 @@
     }
 
     /**
-     * Retrieves whether the current row has had an insertion.
-     * The value returned depends on whether or not this
-     * <code>ResultSet</code> object can detect visible inserts.
+     * Retrieves whether the current row has had an insertion. The value returned
+     * depends on whether or not this <code>ResultSet</code> object can detect
+     * visible inserts.
      *
-     * @return <code>true</code> if a row has had an insertion
-     *         and insertions are detected; <code>false</code> otherwise
+     * @return <code>true</code> if a row has had an insertion and insertions are
+     * detected; <code>false</code> otherwise
      * @throws java.sql.SQLException if a database access error occurs
      * @see java.sql.DatabaseMetaData#insertsAreDetected
      * @since 1.2
@@ -1203,13 +1173,13 @@
     }
 
     /**
-     * Retrieves whether a row has been deleted.  A deleted row may leave
-     * a visible "hole" in a result set.  This method can be used to
-     * detect holes in a result set.  The value returned depends on whether
-     * or not this <code>ResultSet</code> object can detect deletions.
+     * Retrieves whether a row has been deleted. A deleted row may leave a visible
+     * "hole" in a result set. This method can be used to detect holes in a result
+     * set. The value returned depends on whether or not this <code>ResultSet</code>
+     * object can detect deletions.
      *
      * @return <code>true</code> if a row was deleted and deletions are detected;
-     *         <code>false</code> otherwise
+     * <code>false</code> otherwise
      * @throws java.sql.SQLException if a database access error occurs
      * @see java.sql.DatabaseMetaData#deletesAreDetected
      * @since 1.2
@@ -1221,10 +1191,10 @@
     /**
      * Gives a nullable column a null value.
      * <p/>
-     * The updater methods are used to update column values in the
-     * current row or the insert row.  The updater methods do not
-     * update the underlying database; instead the <code>updateRow</code>
-     * or <code>insertRow</code> methods are called to update the database.
+     * The updater methods are used to update column values in the current row or
+     * the insert row. The updater methods do not update the underlying database;
+     * instead the <code>updateRow</code> or <code>insertRow</code> methods are
+     * called to update the database.
      *
      * @param columnIndex the first column is 1, the second is 2, ...
      * @throws java.sql.SQLException if a database access error occurs
@@ -1235,14 +1205,14 @@
     }
 
     /**
-     * Updates the designated column with a <code>boolean</code> value.
-     * The updater methods are used to update column values in the
-     * current row or the insert row.  The updater methods do not
-     * update the underlying database; instead the <code>updateRow</code> or
-     * <code>insertRow</code> methods are called to update the database.
+     * Updates the designated column with a <code>boolean</code> value. The updater
+     * methods are used to update column values in the current row or the insert
+     * row. The updater methods do not update the underlying database; instead the
+     * <code>updateRow</code> or <code>insertRow</code> methods are called to update
+     * the database.
      *
      * @param columnIndex the first column is 1, the second is 2, ...
-     * @param x           the new column value
+     * @param x the new column value
      * @throws java.sql.SQLException if a database access error occurs
      * @since 1.2
      */
@@ -1251,14 +1221,14 @@
     }
 
     /**
-     * Updates the designated column with a <code>byte</code> value.
-     * The updater methods are used to update column values in the
-     * current row or the insert row.  The updater methods do not
-     * update the underlying database; instead the <code>updateRow</code> or
-     * <code>insertRow</code> methods are called to update the database.
+     * Updates the designated column with a <code>byte</code> value. The updater
+     * methods are used to update column values in the current row or the insert
+     * row. The updater methods do not update the underlying database; instead the
+     * <code>updateRow</code> or <code>insertRow</code> methods are called to update
+     * the database.
      *
      * @param columnIndex the first column is 1, the second is 2, ...
-     * @param x           the new column value
+     * @param x the new column value
      * @throws java.sql.SQLException if a database access error occurs
      * @since 1.2
      */
@@ -1267,14 +1237,14 @@
     }
 
     /**
-     * Updates the designated column with a <code>short</code> value.
-     * The updater methods are used to update column values in the
-     * current row or the insert row.  The updater methods do not
-     * update the underlying database; instead the <code>updateRow</code> or
-     * <code>insertRow</code> methods are called to update the database.
+     * Updates the designated column with a <code>short</code> value. The updater
+     * methods are used to update column values in the current row or the insert
+     * row. The updater methods do not update the underlying database; instead the
+     * <code>updateRow</code> or <code>insertRow</code> methods are called to update
+     * the database.
      *
      * @param columnIndex the first column is 1, the second is 2, ...
-     * @param x           the new column value
+     * @param x the new column value
      * @throws java.sql.SQLException if a database access error occurs
      * @since 1.2
      */
@@ -1283,14 +1253,14 @@
     }
 
     /**
-     * Updates the designated column with an <code>int</code> value.
-     * The updater methods are used to update column values in the
-     * current row or the insert row.  The updater methods do not
-     * update the underlying database; instead the <code>updateRow</code> or
-     * <code>insertRow</code> methods are called to update the database.
+     * Updates the designated column with an <code>int</code> value. The updater
+     * methods are used to update column values in the current row or the insert
+     * row. The updater methods do not update the underlying database; instead the
+     * <code>updateRow</code> or <code>insertRow</code> methods are called to update
+     * the database.
      *
      * @param columnIndex the first column is 1, the second is 2, ...
-     * @param x           the new column value
+     * @param x the new column value
      * @throws java.sql.SQLException if a database access error occurs
      * @since 1.2
      */
@@ -1299,14 +1269,14 @@
     }
 
     /**
-     * Updates the designated column with a <code>long</code> value.
-     * The updater methods are used to update column values in the
-     * current row or the insert row.  The updater methods do not
-     * update the underlying database; instead the <code>updateRow</code> or
-     * <code>insertRow</code> methods are called to update the database.
+     * Updates the designated column with a <code>long</code> value. The updater
+     * methods are used to update column values in the current row or the insert
+     * row. The updater methods do not update the underlying database; instead the
+     * <code>updateRow</code> or <code>insertRow</code> methods are called to update
+     * the database.
      *
      * @param columnIndex the first column is 1, the second is 2, ...
-     * @param x           the new column value
+     * @param x the new column value
      * @throws java.sql.SQLException if a database access error occurs
      * @since 1.2
      */
@@ -1315,14 +1285,14 @@
     }
 
     /**
-     * Updates the designated column with a <code>float</code> value.
-     * The updater methods are used to update column values in the
-     * current row or the insert row.  The updater methods do not
-     * update the underlying database; instead the <code>updateRow</code> or
-     * <code>insertRow</code> methods are called to update the database.
+     * Updates the designated column with a <code>float</code> value. The updater
+     * methods are used to update column values in the current row or the insert
+     * row. The updater methods do not update the underlying database; instead the
+     * <code>updateRow</code> or <code>insertRow</code> methods are called to update
+     * the database.
      *
      * @param columnIndex the first column is 1, the second is 2, ...
-     * @param x           the new column value
+     * @param x the new column value
      * @throws java.sql.SQLException if a database access error occurs
      * @since 1.2
      */
@@ -1331,14 +1301,14 @@
     }
 
     /**
-     * Updates the designated column with a <code>double</code> value.
-     * The updater methods are used to update column values in the
-     * current row or the insert row.  The updater methods do not
-     * update the underlying database; instead the <code>updateRow</code> or
-     * <code>insertRow</code> methods are called to update the database.
+     * Updates the designated column with a <code>double</code> value. The updater
+     * methods are used to update column values in the current row or the insert
+     * row. The updater methods do not update the underlying database; instead the
+     * <code>updateRow</code> or <code>insertRow</code> methods are called to update
+     * the database.
      *
      * @param columnIndex the first column is 1, the second is 2, ...
-     * @param x           the new column value
+     * @param x the new column value
      * @throws java.sql.SQLException if a database access error occurs
      * @since 1.2
      */
@@ -1347,15 +1317,14 @@
     }
 
     /**
-     * Updates the designated column with a <code>java.math.BigDecimal</code>
-     * value.
-     * The updater methods are used to update column values in the
-     * current row or the insert row.  The updater methods do not
-     * update the underlying database; instead the <code>updateRow</code> or
-     * <code>insertRow</code> methods are called to update the database.
+     * Updates the designated column with a <code>java.math.BigDecimal</code> value.
+     * The updater methods are used to update column values in the current row or
+     * the insert row. The updater methods do not update the underlying database;
+     * instead the <code>updateRow</code> or <code>insertRow</code> methods are
+     * called to update the database.
      *
      * @param columnIndex the first column is 1, the second is 2, ...
-     * @param x           the new column value
+     * @param x the new column value
      * @throws java.sql.SQLException if a database access error occurs
      * @since 1.2
      */
@@ -1364,14 +1333,14 @@
     }
 
     /**
-     * Updates the designated column with a <code>String</code> value.
-     * The updater methods are used to update column values in the
-     * current row or the insert row.  The updater methods do not
-     * update the underlying database; instead the <code>updateRow</code> or
-     * <code>insertRow</code> methods are called to update the database.
+     * Updates the designated column with a <code>String</code> value. The updater
+     * methods are used to update column values in the current row or the insert
+     * row. The updater methods do not update the underlying database; instead the
+     * <code>updateRow</code> or <code>insertRow</code> methods are called to update
+     * the database.
      *
      * @param columnIndex the first column is 1, the second is 2, ...
-     * @param x           the new column value
+     * @param x the new column value
      * @throws java.sql.SQLException if a database access error occurs
      * @since 1.2
      */
@@ -1380,14 +1349,14 @@
     }
 
     /**
-     * Updates the designated column with a <code>byte</code> array value.
-     * The updater methods are used to update column values in the
-     * current row or the insert row.  The updater methods do not
-     * update the underlying database; instead the <code>updateRow</code> or
-     * <code>insertRow</code> methods are called to update the database.
+     * Updates the designated column with a <code>byte</code> array value. The
+     * updater methods are used to update column values in the current row or the
+     * insert row. The updater methods do not update the underlying database;
+     * instead the <code>updateRow</code> or <code>insertRow</code> methods are
+     * called to update the database.
      *
      * @param columnIndex the first column is 1, the second is 2, ...
-     * @param x           the new column value
+     * @param x the new column value
      * @throws java.sql.SQLException if a database access error occurs
      * @since 1.2
      */
@@ -1396,14 +1365,14 @@
     }
 
     /**
-     * Updates the designated column with a <code>java.sql.Date</code> value.
-     * The updater methods are used to update column values in the
-     * current row or the insert row.  The updater methods do not
-     * update the underlying database; instead the <code>updateRow</code> or
-     * <code>insertRow</code> methods are called to update the database.
+     * Updates the designated column with a <code>java.sql.Date</code> value. The
+     * updater methods are used to update column values in the current row or the
+     * insert row. The updater methods do not update the underlying database;
+     * instead the <code>updateRow</code> or <code>insertRow</code> methods are
+     * called to update the database.
      *
      * @param columnIndex the first column is 1, the second is 2, ...
-     * @param x           the new column value
+     * @param x the new column value
      * @throws java.sql.SQLException if a database access error occurs
      * @since 1.2
      */
@@ -1412,14 +1381,14 @@
     }
 
     /**
-     * Updates the designated column with a <code>java.sql.Time</code> value.
-     * The updater methods are used to update column values in the
-     * current row or the insert row.  The updater methods do not
-     * update the underlying database; instead the <code>updateRow</code> or
-     * <code>insertRow</code> methods are called to update the database.
+     * Updates the designated column with a <code>java.sql.Time</code> value. The
+     * updater methods are used to update column values in the current row or the
+     * insert row. The updater methods do not update the underlying database;
+     * instead the <code>updateRow</code> or <code>insertRow</code> methods are
+     * called to update the database.
      *
      * @param columnIndex the first column is 1, the second is 2, ...
-     * @param x           the new column value
+     * @param x the new column value
      * @throws java.sql.SQLException if a database access error occurs
      * @since 1.2
      */
@@ -1428,15 +1397,14 @@
     }
 
     /**
-     * Updates the designated column with a <code>java.sql.Timestamp</code>
-     * value.
-     * The updater methods are used to update column values in the
-     * current row or the insert row.  The updater methods do not
-     * update the underlying database; instead the <code>updateRow</code> or
-     * <code>insertRow</code> methods are called to update the database.
+     * Updates the designated column with a <code>java.sql.Timestamp</code> value.
+     * The updater methods are used to update column values in the current row or
+     * the insert row. The updater methods do not update the underlying database;
+     * instead the <code>updateRow</code> or <code>insertRow</code> methods are
+     * called to update the database.
      *
      * @param columnIndex the first column is 1, the second is 2, ...
-     * @param x           the new column value
+     * @param x the new column value
      * @throws java.sql.SQLException if a database access error occurs
      * @since 1.2
      */
@@ -1445,15 +1413,15 @@
     }
 
     /**
-     * Updates the designated column with an ascii stream value.
-     * The updater methods are used to update column values in the
-     * current row or the insert row.  The updater methods do not
-     * update the underlying database; instead the <code>updateRow</code> or
-     * <code>insertRow</code> methods are called to update the database.
+     * Updates the designated column with an ascii stream value. The updater methods
+     * are used to update column values in the current row or the insert row. The
+     * updater methods do not update the underlying database; instead the
+     * <code>updateRow</code> or <code>insertRow</code> methods are called to update
+     * the database.
      *
      * @param columnIndex the first column is 1, the second is 2, ...
-     * @param x           the new column value
-     * @param length      the length of the stream
+     * @param x the new column value
+     * @param length the length of the stream
      * @throws java.sql.SQLException if a database access error occurs
      * @since 1.2
      */
@@ -1462,15 +1430,15 @@
     }
 
     /**
-     * Updates the designated column with a binary stream value.
-     * The updater methods are used to update column values in the
-     * current row or the insert row.  The updater methods do not
-     * update the underlying database; instead the <code>updateRow</code> or
-     * <code>insertRow</code> methods are called to update the database.
+     * Updates the designated column with a binary stream value. The updater methods
+     * are used to update column values in the current row or the insert row. The
+     * updater methods do not update the underlying database; instead the
+     * <code>updateRow</code> or <code>insertRow</code> methods are called to update
+     * the database.
      *
      * @param columnIndex the first column is 1, the second is 2, ...
-     * @param x           the new column value
-     * @param length      the length of the stream
+     * @param x the new column value
+     * @param length the length of the stream
      * @throws java.sql.SQLException if a database access error occurs
      * @since 1.2
      */
@@ -1479,15 +1447,15 @@
     }
 
     /**
-     * Updates the designated column with a character stream value.
-     * The updater methods are used to update column values in the
-     * current row or the insert row.  The updater methods do not
-     * update the underlying database; instead the <code>updateRow</code> or
-     * <code>insertRow</code> methods are called to update the database.
+     * Updates the designated column with a character stream value. The updater
+     * methods are used to update column values in the current row or the insert
+     * row. The updater methods do not update the underlying database; instead the
+     * <code>updateRow</code> or <code>insertRow</code> methods are called to update
+     * the database.
      *
      * @param columnIndex the first column is 1, the second is 2, ...
-     * @param x           the new column value
-     * @param length      the length of the stream
+     * @param x the new column value
+     * @param length the length of the stream
      * @throws java.sql.SQLException if a database access error occurs
      * @since 1.2
      */
@@ -1496,18 +1464,17 @@
     }
 
     /**
-     * Updates the designated column with an <code>Object</code> value.
-     * The updater methods are used to update column values in the
-     * current row or the insert row.  The updater methods do not
-     * update the underlying database; instead the <code>updateRow</code> or
-     * <code>insertRow</code> methods are called to update the database.
+     * Updates the designated column with an <code>Object</code> value. The updater
+     * methods are used to update column values in the current row or the insert
+     * row. The updater methods do not update the underlying database; instead the
+     * <code>updateRow</code> or <code>insertRow</code> methods are called to update
+     * the database.
      *
      * @param columnIndex the first column is 1, the second is 2, ...
-     * @param x           the new column value
-     * @param scale       for <code>java.sql.Types.DECIMA</code>
-     *                    or <code>java.sql.Types.NUMERIC</code> types,
-     *                    this is the number of digits after the decimal point.  For all other
-     *                    types this value will be ignored.
+     * @param x the new column value
+     * @param scale for <code>java.sql.Types.DECIMA</code> or
+     * <code>java.sql.Types.NUMERIC</code> types, this is the number of digits after
+     * the decimal point. For all other types this value will be ignored.
      * @throws java.sql.SQLException if a database access error occurs
      * @since 1.2
      */
@@ -1516,14 +1483,14 @@
     }
 
     /**
-     * Updates the designated column with an <code>Object</code> value.
-     * The updater methods are used to update column values in the
-     * current row or the insert row.  The updater methods do not
-     * update the underlying database; instead the <code>updateRow</code> or
-     * <code>insertRow</code> methods are called to update the database.
+     * Updates the designated column with an <code>Object</code> value. The updater
+     * methods are used to update column values in the current row or the insert
+     * row. The updater methods do not update the underlying database; instead the
+     * <code>updateRow</code> or <code>insertRow</code> methods are called to update
+     * the database.
      *
      * @param columnIndex the first column is 1, the second is 2, ...
-     * @param x           the new column value
+     * @param x the new column value
      * @throws java.sql.SQLException if a database access error occurs
      * @since 1.2
      */
@@ -1532,11 +1499,11 @@
     }
 
     /**
-     * Updates the designated column with a <code>null</code> value.
-     * The updater methods are used to update column values in the
-     * current row or the insert row.  The updater methods do not
-     * update the underlying database; instead the <code>updateRow</code> or
-     * <code>insertRow</code> methods are called to update the database.
+     * Updates the designated column with a <code>null</code> value. The updater
+     * methods are used to update column values in the current row or the insert
+     * row. The updater methods do not update the underlying database; instead the
+     * <code>updateRow</code> or <code>insertRow</code> methods are called to update
+     * the database.
      *
      * @param columnName the name of the column
      * @throws java.sql.SQLException if a database access error occurs
@@ -1547,14 +1514,14 @@
     }
 
     /**
-     * Updates the designated column with a <code>boolean</code> value.
-     * The updater methods are used to update column values in the
-     * current row or the insert row.  The updater methods do not
-     * update the underlying database; instead the <code>updateRow</code> or
-     * <code>insertRow</code> methods are called to update the database.
+     * Updates the designated column with a <code>boolean</code> value. The updater
+     * methods are used to update column values in the current row or the insert
+     * row. The updater methods do not update the underlying database; instead the
+     * <code>updateRow</code> or <code>insertRow</code> methods are called to update
+     * the database.
      *
      * @param columnName the name of the column
-     * @param x          the new column value
+     * @param x the new column value
      * @throws java.sql.SQLException if a database access error occurs
      * @since 1.2
      */
@@ -1563,14 +1530,14 @@
     }
 
     /**
-     * Updates the designated column with a <code>byte</code> value.
-     * The updater methods are used to update column values in the
-     * current row or the insert row.  The updater methods do not
-     * update the underlying database; instead the <code>updateRow</code> or
-     * <code>insertRow</code> methods are called to update the database.
+     * Updates the designated column with a <code>byte</code> value. The updater
+     * methods are used to update column values in the current row or the insert
+     * row. The updater methods do not update the underlying database; instead the
+     * <code>updateRow</code> or <code>insertRow</code> methods are called to update
+     * the database.
      *
      * @param columnName the name of the column
-     * @param x          the new column value
+     * @param x the new column value
      * @throws java.sql.SQLException if a database access error occurs
      * @since 1.2
      */
@@ -1579,14 +1546,14 @@
     }
 
     /**
-     * Updates the designated column with a <code>short</code> value.
-     * The updater methods are used to update column values in the
-     * current row or the insert row.  The updater methods do not
-     * update the underlying database; instead the <code>updateRow</code> or
-     * <code>insertRow</code> methods are called to update the database.
+     * Updates the designated column with a <code>short</code> value. The updater
+     * methods are used to update column values in the current row or the insert
+     * row. The updater methods do not update the underlying database; instead the
+     * <code>updateRow</code> or <code>insertRow</code> methods are called to update
+     * the database.
      *
      * @param columnName the name of the column
-     * @param x          the new column value
+     * @param x the new column value
      * @throws java.sql.SQLException if a database access error occurs
      * @since 1.2
      */
@@ -1595,14 +1562,14 @@
     }
 
     /**
-     * Updates the designated column with an <code>int</code> value.
-     * The updater methods are used to update column values in the
-     * current row or the insert row.  The updater methods do not
-     * update the underlying database; instead the <code>updateRow</code> or
-     * <code>insertRow</code> methods are called to update the database.
+     * Updates the designated column with an <code>int</code> value. The updater
+     * methods are used to update column values in the current row or the insert
+     * row. The updater methods do not update the underlying database; instead the
+     * <code>updateRow</code> or <code>insertRow</code> methods are called to update
+     * the database.
      *
      * @param columnName the name of the column
-     * @param x          the new column value
+     * @param x the new column value
      * @throws java.sql.SQLException if a database access error occurs
      * @since 1.2
      */
@@ -1611,14 +1578,14 @@
     }
 
     /**
-     * Updates the designated column with a <code>long</code> value.
-     * The updater methods are used to update column values in the
-     * current row or the insert row.  The updater methods do not
-     * update the underlying database; instead the <code>updateRow</code> or
-     * <code>insertRow</code> methods are called to update the database.
+     * Updates the designated column with a <code>long</code> value. The updater
+     * methods are used to update column values in the current row or the insert
+     * row. The updater methods do not update the underlying database; instead the
+     * <code>updateRow</code> or <code>insertRow</code> methods are called to update
+     * the database.
      *
      * @param columnName the name of the column
-     * @param x          the new column value
+     * @param x the new column value
      * @throws java.sql.SQLException if a database access error occurs
      * @since 1.2
      */
@@ -1627,14 +1594,14 @@
     }
 
     /**
-     * Updates the designated column with a <code>float    </code> value.
-     * The updater methods are used to update column values in the
-     * current row or the insert row.  The updater methods do not
-     * update the underlying database; instead the <code>updateRow</code> or
-     * <code>insertRow</code> methods are called to update the database.
+     * Updates the designated column with a <code>float    </code> value. The
+     * updater methods are used to update column values in the current row or the
+     * insert row. The updater methods do not update the underlying database;
+     * instead the <code>updateRow</code> or <code>insertRow</code> methods are
+     * called to update the database.
      *
      * @param columnName the name of the column
-     * @param x          the new column value
+     * @param x the new column value
      * @throws java.sql.SQLException if a database access error occurs
      * @since 1.2
      */
@@ -1643,14 +1610,14 @@
     }
 
     /**
-     * Updates the designated column with a <code>double</code> value.
-     * The updater methods are used to update column values in the
-     * current row or the insert row.  The updater methods do not
-     * update the underlying database; instead the <code>updateRow</code> or
-     * <code>insertRow</code> methods are called to update the database.
+     * Updates the designated column with a <code>double</code> value. The updater
+     * methods are used to update column values in the current row or the insert
+     * row. The updater methods do not update the underlying database; instead the
+     * <code>updateRow</code> or <code>insertRow</code> methods are called to update
+     * the database.
      *
      * @param columnName the name of the column
-     * @param x          the new column value
+     * @param x the new column value
      * @throws java.sql.SQLException if a database access error occurs
      * @since 1.2
      */
@@ -1659,15 +1626,14 @@
     }
 
     /**
-     * Updates the designated column with a <code>java.sql.BigDecimal</code>
-     * value.
-     * The updater methods are used to update column values in the
-     * current row or the insert row.  The updater methods do not
-     * update the underlying database; instead the <code>updateRow</code> or
-     * <code>insertRow</code> methods are called to update the database.
+     * Updates the designated column with a <code>java.sql.BigDecimal</code> value.
+     * The updater methods are used to update column values in the current row or
+     * the insert row. The updater methods do not update the underlying database;
+     * instead the <code>updateRow</code> or <code>insertRow</code> methods are
+     * called to update the database.
      *
      * @param columnName the name of the column
-     * @param x          the new column value
+     * @param x the new column value
      * @throws java.sql.SQLException if a database access error occurs
      * @since 1.2
      */
@@ -1676,14 +1642,14 @@
     }
 
     /**
-     * Updates the designated column with a <code>String</code> value.
-     * The updater methods are used to update column values in the
-     * current row or the insert row.  The updater methods do not
-     * update the underlying database; instead the <code>updateRow</code> or
-     * <code>insertRow</code> methods are called to update the database.
+     * Updates the designated column with a <code>String</code> value. The updater
+     * methods are used to update column values in the current row or the insert
+     * row. The updater methods do not update the underlying database; instead the
+     * <code>updateRow</code> or <code>insertRow</code> methods are called to update
+     * the database.
      *
      * @param columnName the name of the column
-     * @param x          the new column value
+     * @param x the new column value
      * @throws java.sql.SQLException if a database access error occurs
      * @since 1.2
      */
@@ -1694,13 +1660,13 @@
     /**
      * Updates the designated column with a byte array value.
      * <p/>
-     * The updater methods are used to update column values in the
-     * current row or the insert row.  The updater methods do not
-     * update the underlying database; instead the <code>updateRow</code>
-     * or <code>insertRow</code> methods are called to update the database.
+     * The updater methods are used to update column values in the current row or
+     * the insert row. The updater methods do not update the underlying database;
+     * instead the <code>updateRow</code> or <code>insertRow</code> methods are
+     * called to update the database.
      *
      * @param columnName the name of the column
-     * @param x          the new column value
+     * @param x the new column value
      * @throws java.sql.SQLException if a database access error occurs
      * @since 1.2
      */
@@ -1709,14 +1675,14 @@
     }
 
     /**
-     * Updates the designated column with a <code>java.sql.Date</code> value.
-     * The updater methods are used to update column values in the
-     * current row or the insert row.  The updater methods do not
-     * update the underlying database; instead the <code>updateRow</code> or
-     * <code>insertRow</code> methods are called to update the database.
+     * Updates the designated column with a <code>java.sql.Date</code> value. The
+     * updater methods are used to update column values in the current row or the
+     * insert row. The updater methods do not update the underlying database;
+     * instead the <code>updateRow</code> or <code>insertRow</code> methods are
+     * called to update the database.
      *
      * @param columnName the name of the column
-     * @param x          the new column value
+     * @param x the new column value
      * @throws java.sql.SQLException if a database access error occurs
      * @since 1.2
      */
@@ -1725,14 +1691,14 @@
     }
 
     /**
-     * Updates the designated column with a <code>java.sql.Time</code> value.
-     * The updater methods are used to update column values in the
-     * current row or the insert row.  The updater methods do not
-     * update the underlying database; instead the <code>updateRow</code> or
-     * <code>insertRow</code> methods are called to update the database.
+     * Updates the designated column with a <code>java.sql.Time</code> value. The
+     * updater methods are used to update column values in the current row or the
+     * insert row. The updater methods do not update the underlying database;
+     * instead the <code>updateRow</code> or <code>insertRow</code> methods are
+     * called to update the database.
      *
      * @param columnName the name of the column
-     * @param x          the new column value
+     * @param x the new column value
      * @throws java.sql.SQLException if a database access error occurs
      * @since 1.2
      */
@@ -1741,15 +1707,14 @@
     }
 
     /**
-     * Updates the designated column with a <code>java.sql.Timestamp</code>
-     * value.
-     * The updater methods are used to update column values in the
-     * current row or the insert row.  The updater methods do not
-     * update the underlying database; instead the <code>updateRow</code> or
-     * <code>insertRow</code> methods are called to update the database.
+     * Updates the designated column with a <code>java.sql.Timestamp</code> value.
+     * The updater methods are used to update column values in the current row or
+     * the insert row. The updater methods do not update the underlying database;
+     * instead the <code>updateRow</code> or <code>insertRow</code> methods are
+     * called to update the database.
      *
      * @param columnName the name of the column
-     * @param x          the new column value
+     * @param x the new column value
      * @throws java.sql.SQLException if a database access error occurs
      * @since 1.2
      */
@@ -1758,15 +1723,15 @@
     }
 
     /**
-     * Updates the designated column with an ascii stream value.
-     * The updater methods are used to update column values in the
-     * current row or the insert row.  The updater methods do not
-     * update the underlying database; instead the <code>updateRow</code> or
-     * <code>insertRow</code> methods are called to update the database.
+     * Updates the designated column with an ascii stream value. The updater methods
+     * are used to update column values in the current row or the insert row. The
+     * updater methods do not update the underlying database; instead the
+     * <code>updateRow</code> or <code>insertRow</code> methods are called to update
+     * the database.
      *
      * @param columnName the name of the column
-     * @param x          the new column value
-     * @param length     the length of the stream
+     * @param x the new column value
+     * @param length the length of the stream
      * @throws java.sql.SQLException if a database access error occurs
      * @since 1.2
      */
@@ -1775,15 +1740,15 @@
     }
 
     /**
-     * Updates the designated column with a binary stream value.
-     * The updater methods are used to update column values in the
-     * current row or the insert row.  The updater methods do not
-     * update the underlying database; instead the <code>updateRow</code> or
-     * <code>insertRow</code> methods are called to update the database.
+     * Updates the designated column with a binary stream value. The updater methods
+     * are used to update column values in the current row or the insert row. The
+     * updater methods do not update the underlying database; instead the
+     * <code>updateRow</code> or <code>insertRow</code> methods are called to update
+     * the database.
      *
      * @param columnName the name of the column
-     * @param x          the new column value
-     * @param length     the length of the stream
+     * @param x the new column value
+     * @param length the length of the stream
      * @throws java.sql.SQLException if a database access error occurs
      * @since 1.2
      */
@@ -1792,16 +1757,16 @@
     }
 
     /**
-     * Updates the designated column with a character stream value.
-     * The updater methods are used to update column values in the
-     * current row or the insert row.  The updater methods do not
-     * update the underlying database; instead the <code>updateRow</code> or
-     * <code>insertRow</code> methods are called to update the database.
+     * Updates the designated column with a character stream value. The updater
+     * methods are used to update column values in the current row or the insert
+     * row. The updater methods do not update the underlying database; instead the
+     * <code>updateRow</code> or <code>insertRow</code> methods are called to update
+     * the database.
      *
      * @param columnName the name of the column
-     * @param reader     the <code>java.io.Reader</code> object containing
-     *                   the new column value
-     * @param length     the length of the stream
+     * @param reader the <code>java.io.Reader</code> object containing the new
+     * column value
+     * @param length the length of the stream
      * @throws java.sql.SQLException if a database access error occurs
      * @since 1.2
      */
@@ -1810,18 +1775,17 @@
     }
 
     /**
-     * Updates the designated column with an <code>Object</code> value.
-     * The updater methods are used to update column values in the
-     * current row or the insert row.  The updater methods do not
-     * update the underlying database; instead the <code>updateRow</code> or
-     * <code>insertRow</code> methods are called to update the database.
+     * Updates the designated column with an <code>Object</code> value. The updater
+     * methods are used to update column values in the current row or the insert
+     * row. The updater methods do not update the underlying database; instead the
+     * <code>updateRow</code> or <code>insertRow</code> methods are called to update
+     * the database.
      *
      * @param columnName the name of the column
-     * @param x          the new column value
-     * @param scale      for <code>java.sql.Types.DECIMAL</code>
-     *                   or <code>java.sql.Types.NUMERIC</code> types,
-     *                   this is the number of digits after the decimal point.  For all other
-     *                   types this value will be ignored.
+     * @param x the new column value
+     * @param scale for <code>java.sql.Types.DECIMAL</code> or
+     * <code>java.sql.Types.NUMERIC</code> types, this is the number of digits after
+     * the decimal point. For all other types this value will be ignored.
      * @throws java.sql.SQLException if a database access error occurs
      * @since 1.2
      */
@@ -1830,14 +1794,14 @@
     }
 
     /**
-     * Updates the designated column with an <code>Object</code> value.
-     * The updater methods are used to update column values in the
-     * current row or the insert row.  The updater methods do not
-     * update the underlying database; instead the <code>updateRow</code> or
-     * <code>insertRow</code> methods are called to update the database.
+     * Updates the designated column with an <code>Object</code> value. The updater
+     * methods are used to update column values in the current row or the insert
+     * row. The updater methods do not update the underlying database; instead the
+     * <code>updateRow</code> or <code>insertRow</code> methods are called to update
+     * the database.
      *
      * @param columnName the name of the column
-     * @param x          the new column value
+     * @param x the new column value
      * @throws java.sql.SQLException if a database access error occurs
      * @since 1.2
      */
@@ -1846,14 +1810,13 @@
     }
 
     /**
-     * Inserts the contents of the insert row into this
-     * <code>ResultSet</code> object and into the database.
-     * The cursor must be on the insert row when this method is called.
+     * Inserts the contents of the insert row into this <code>ResultSet</code>
+     * object and into the database. The cursor must be on the insert row when this
+     * method is called.
      *
-     * @throws java.sql.SQLException if a database access error occurs,
-     *                               if this method is called when the cursor is not on the insert row,
-     *                               or if not all of non-nullable columns in
-     *                               the insert row have been given a value
+     * @throws java.sql.SQLException if a database access error occurs, if this
+     * method is called when the cursor is not on the insert row, or if not all of
+     * non-nullable columns in the insert row have been given a value
      * @since 1.2
      */
     public void insertRow() throws SQLException {
@@ -1861,12 +1824,12 @@
     }
 
     /**
-     * Updates the underlying database with the new contents of the
-     * current row of this <code>ResultSet</code> object.
-     * This method cannot be called when the cursor is on the insert row.
+     * Updates the underlying database with the new contents of the current row of
+     * this <code>ResultSet</code> object. This method cannot be called when the
+     * cursor is on the insert row.
      *
-     * @throws java.sql.SQLException if a database access error occurs or
-     *                               if this method is called when the cursor is on the insert row
+     * @throws java.sql.SQLException if a database access error occurs or if this
+     * method is called when the cursor is on the insert row
      * @since 1.2
      */
     public void updateRow() throws SQLException {
@@ -1874,12 +1837,12 @@
     }
 
     /**
-     * Deletes the current row from this <code>ResultSet</code> object
-     * and from the underlying database.  This method cannot be called when
-     * the cursor is on the insert row.
+     * Deletes the current row from this <code>ResultSet</code> object and from the
+     * underlying database. This method cannot be called when the cursor is on the
+     * insert row.
      *
-     * @throws java.sql.SQLException if a database access error occurs
-     *                               or if this method is called when the cursor is on the insert row
+     * @throws java.sql.SQLException if a database access error occurs or if this
+     * method is called when the cursor is on the insert row
      * @since 1.2
      */
     public void deleteRow() throws SQLException {
@@ -1887,28 +1850,26 @@
     }
 
     /**
-     * Refreshes the current row with its most recent value in
-     * the database.  This method cannot be called when
-     * the cursor is on the insert row.
+     * Refreshes the current row with its most recent value in the database. This
+     * method cannot be called when the cursor is on the insert row.
      * <p/>
-     * <P>The <code>refreshRow</code> method provides a way for an
-     * application to
-     * explicitly tell the JDBC driver to refetch a row(s) from the
-     * database.  An application may want to call <code>refreshRow</code> when
-     * caching or prefetching is being done by the JDBC driver to
-     * fetch the latest value of a row from the database.  The JDBC driver
-     * may actually refresh multiple rows at once if the fetch size is
-     * greater than one.
+     * <P>
+     * The <code>refreshRow</code> method provides a way for an application to
+     * explicitly tell the JDBC driver to refetch a row(s) from the database. An
+     * application may want to call <code>refreshRow</code> when caching or
+     * prefetching is being done by the JDBC driver to fetch the latest value of a
+     * row from the database. The JDBC driver may actually refresh multiple rows at
+     * once if the fetch size is greater than one.
      * <p/>
-     * <P> All values are refetched subject to the transaction isolation
-     * level and cursor sensitivity.  If <code>refreshRow</code> is called after
-     * calling an updater method, but before calling
-     * the method <code>updateRow</code>, then the
-     * updates made to the row are lost.  Calling the method
+     * <P>
+     * All values are refetched subject to the transaction isolation level and
+     * cursor sensitivity. If <code>refreshRow</code> is called after calling an
+     * updater method, but before calling the method <code>updateRow</code>, then
+     * the updates made to the row are lost. Calling the method
      * <code>refreshRow</code> frequently will likely slow performance.
      *
-     * @throws java.sql.SQLException if a database access error
-     *                               occurs or if this method is called when the cursor is on the insert row
+     * @throws java.sql.SQLException if a database access error occurs or if this
+     * method is called when the cursor is on the insert row
      * @since 1.2
      */
     public void refreshRow() throws SQLException {
@@ -1916,18 +1877,14 @@
     }
 
     /**
-     * Cancels the updates made to the current row in this
-     * <code>ResultSet</code> object.
-     * This method may be called after calling an
-     * updater method(s) and before calling
-     * the method <code>updateRow</code> to roll back
-     * the updates made to a row.  If no updates have been made or
-     * <code>updateRow</code> has already been called, this method has no
-     * effect.
+     * Cancels the updates made to the current row in this <code>ResultSet</code>
+     * object. This method may be called after calling an updater method(s) and
+     * before calling the method <code>updateRow</code> to roll back the updates
+     * made to a row. If no updates have been made or <code>updateRow</code> has
+     * already been called, this method has no effect.
      *
-     * @throws java.sql.SQLException if a database access error
-     *                               occurs or if this method is called when the cursor is
-     *                               on the insert row
+     * @throws java.sql.SQLException if a database access error occurs or if this
+     * method is called when the cursor is on the insert row
      * @since 1.2
      */
     public void cancelRowUpdates() throws SQLException {
@@ -1935,24 +1892,21 @@
     }
 
     /**
-     * Moves the cursor to the insert row.  The current cursor position is
-     * remembered while the cursor is positioned on the insert row.
+     * Moves the cursor to the insert row. The current cursor position is remembered
+     * while the cursor is positioned on the insert row.
      * <p/>
-     * The insert row is a special row associated with an updatable
-     * result set.  It is essentially a buffer where a new row may
-     * be constructed by calling the updater methods prior to
-     * inserting the row into the result set.
+     * The insert row is a special row associated with an updatable result set. It
+     * is essentially a buffer where a new row may be constructed by calling the
+     * updater methods prior to inserting the row into the result set.
      * <p/>
-     * Only the updater, getter,
-     * and <code>insertRow</code> methods may be
-     * called when the cursor is on the insert row.  All of the columns in
-     * a result set must be given a value each time this method is
-     * called before calling <code>insertRow</code>.
-     * An updater method must be called before a
-     * getter method can be called on a column value.
+     * Only the updater, getter, and <code>insertRow</code> methods may be called
+     * when the cursor is on the insert row. All of the columns in a result set must
+     * be given a value each time this method is called before calling
+     * <code>insertRow</code>. An updater method must be called before a getter
+     * method can be called on a column value.
      *
-     * @throws java.sql.SQLException if a database access error occurs
-     *                               or the result set is not updatable
+     * @throws java.sql.SQLException if a database access error occurs or the result
+     * set is not updatable
      * @since 1.2
      */
     public void moveToInsertRow() throws SQLException {
@@ -1960,12 +1914,11 @@
     }
 
     /**
-     * Moves the cursor to the remembered cursor position, usually the
-     * current row.  This method has no effect if the cursor is not on
-     * the insert row.
+     * Moves the cursor to the remembered cursor position, usually the current row.
+     * This method has no effect if the cursor is not on the insert row.
      *
-     * @throws java.sql.SQLException if a database access error occurs
-     *                               or the result set is not updatable
+     * @throws java.sql.SQLException if a database access error occurs or the result
+     * set is not updatable
      * @since 1.2
      */
     public void moveToCurrentRow() throws SQLException {
@@ -1974,14 +1927,13 @@
 
     /**
      * Retrieves the <code>Statement</code> object that produced this
-     * <code>ResultSet</code> object.
-     * If the result set was generated some other way, such as by a
-     * <code>DatabaseMetaData</code> method, this method returns
+     * <code>ResultSet</code> object. If the result set was generated some other
+     * way, such as by a <code>DatabaseMetaData</code> method, this method returns
      * <code>null</code>.
      *
-     * @return the <code>Statment</code> object that produced
-     *         this <code>ResultSet</code> object or <code>null</code>
-     *         if the result set was produced some other way
+     * @return the <code>Statment</code> object that produced this
+     * <code>ResultSet</code> object or <code>null</code> if the result set was
+     * produced some other way
      * @throws java.sql.SQLException if a database access error occurs
      * @since 1.2
      */
@@ -2000,20 +1952,18 @@
     }
 
     /**
-     * Retrieves the value of the designated column in the current row
-     * of this <code>ResultSet</code> object as an <code>Object</code>
-     * in the Java programming language.
-     * If the value is an SQL <code>NULL</code>,
-     * the driver returns a Java <code>null</code>.
-     * This method uses the given <code>Map</code> object
-     * for the custom mapping of the
-     * SQL structured or distinct type that is being retrieved.
+     * Retrieves the value of the designated column in the current row of this
+     * <code>ResultSet</code> object as an <code>Object</code> in the Java
+     * programming language. If the value is an SQL <code>NULL</code>, the driver
+     * returns a Java <code>null</code>. This method uses the given <code>Map</code>
+     * object for the custom mapping of the SQL structured or distinct type that is
+     * being retrieved.
      *
-     * @param i   the first column is 1, the second is 2, ...
-     * @param map a <code>java.util.Map</code> object that contains the mapping
-     *            from SQL type names to classes in the Java programming language
-     * @return an <code>Object</code> in the Java programming language
-     *         representing the SQL value
+     * @param i the first column is 1, the second is 2, ...
+     * @param map a <code>java.util.Map</code> object that contains the mapping from
+     * SQL type names to classes in the Java programming language
+     * @return an <code>Object</code> in the Java programming language representing
+     * the SQL value
      * @throws java.sql.SQLException if a database access error occurs
      * @since 1.2
      */
@@ -2022,13 +1972,12 @@
     }
 
     /**
-     * Retrieves the value of the designated column in the current row
-     * of this <code>ResultSet</code> object as a <code>Ref</code> object
-     * in the Java programming language.
+     * Retrieves the value of the designated column in the current row of this
+     * <code>ResultSet</code> object as a <code>Ref</code> object in the Java
+     * programming language.
      *
      * @param i the first column is 1, the second is 2, ...
-     * @return a <code>Ref</code> object representing an SQL <code>REF</code>
-     *         value
+     * @return a <code>Ref</code> object representing an SQL <code>REF</code> value
      * @throws java.sql.SQLException if a database access error occurs
      * @since 1.2
      */
@@ -2037,13 +1986,13 @@
     }
 
     /**
-     * Retrieves the value of the designated column in the current row
-     * of this <code>ResultSet</code> object as a <code>Blob</code> object
-     * in the Java programming language.
+     * Retrieves the value of the designated column in the current row of this
+     * <code>ResultSet</code> object as a <code>Blob</code> object in the Java
+     * programming language.
      *
      * @param i the first column is 1, the second is 2, ...
-     * @return a <code>Blob</code> object representing the SQL
-     *         <code>BLOB</code> value in the specified column
+     * @return a <code>Blob</code> object representing the SQL <code>BLOB</code>
+     * value in the specified column
      * @throws java.sql.SQLException if a database access error occurs
      * @since 1.2
      */
@@ -2052,13 +2001,13 @@
     }
 
     /**
-     * Retrieves the value of the designated column in the current row
-     * of this <code>ResultSet</code> object as a <code>Clob</code> object
-     * in the Java programming language.
+     * Retrieves the value of the designated column in the current row of this
+     * <code>ResultSet</code> object as a <code>Clob</code> object in the Java
+     * programming language.
      *
      * @param i the first column is 1, the second is 2, ...
-     * @return a <code>Clob</code> object representing the SQL
-     *         <code>CLOB</code> value in the specified column
+     * @return a <code>Clob</code> object representing the SQL <code>CLOB</code>
+     * value in the specified column
      * @throws java.sql.SQLException if a database access error occurs
      * @since 1.2
      */
@@ -2067,13 +2016,13 @@
     }
 
     /**
-     * Retrieves the value of the designated column in the current row
-     * of this <code>ResultSet</code> object as an <code>Array</code> object
-     * in the Java programming language.
+     * Retrieves the value of the designated column in the current row of this
+     * <code>ResultSet</code> object as an <code>Array</code> object in the Java
+     * programming language.
      *
      * @param i the first column is 1, the second is 2, ...
-     * @return an <code>Array</code> object representing the SQL
-     *         <code>ARRAY</code> value in the specified column
+     * @return an <code>Array</code> object representing the SQL <code>ARRAY</code>
+     * value in the specified column
      * @throws java.sql.SQLException if a database access error occurs
      * @since 1.2
      */
@@ -2082,19 +2031,17 @@
     }
 
     /**
-     * Retrieves the value of the designated column in the current row
-     * of this <code>ResultSet</code> object as an <code>Object</code>
-     * in the Java programming language.
-     * If the value is an SQL <code>NULL</code>,
-     * the driver returns a Java <code>null</code>.
-     * This method uses the specified <code>Map</code> object for
-     * custom mapping if appropriate.
+     * Retrieves the value of the designated column in the current row of this
+     * <code>ResultSet</code> object as an <code>Object</code> in the Java
+     * programming language. If the value is an SQL <code>NULL</code>, the driver
+     * returns a Java <code>null</code>. This method uses the specified
+     * <code>Map</code> object for custom mapping if appropriate.
      *
      * @param colName the name of the column from which to retrieve the value
-     * @param map     a <code>java.util.Map</code> object that contains the mapping
-     *                from SQL type names to classes in the Java programming language
-     * @return an <code>Object</code> representing the SQL value in the
-     *         specified column
+     * @param map a <code>java.util.Map</code> object that contains the mapping from
+     * SQL type names to classes in the Java programming language
+     * @return an <code>Object</code> representing the SQL value in the specified
+     * column
      * @throws java.sql.SQLException if a database access error occurs
      * @since 1.2
      */
@@ -2103,13 +2050,13 @@
     }
 
     /**
-     * Retrieves the value of the designated column in the current row
-     * of this <code>ResultSet</code> object as a <code>Ref</code> object
-     * in the Java programming language.
+     * Retrieves the value of the designated column in the current row of this
+     * <code>ResultSet</code> object as a <code>Ref</code> object in the Java
+     * programming language.
      *
      * @param colName the column name
-     * @return a <code>Ref</code> object representing the SQL <code>REF</code>
-     *         value in the specified column
+     * @return a <code>Ref</code> object representing the SQL <code>REF</code> value
+     * in the specified column
      * @throws java.sql.SQLException if a database access error occurs
      * @since 1.2
      */
@@ -2118,13 +2065,13 @@
     }
 
     /**
-     * Retrieves the value of the designated column in the current row
-     * of this <code>ResultSet</code> object as a <code>Blob</code> object
-     * in the Java programming language.
+     * Retrieves the value of the designated column in the current row of this
+     * <code>ResultSet</code> object as a <code>Blob</code> object in the Java
+     * programming language.
      *
      * @param colName the name of the column from which to retrieve the value
      * @return a <code>Blob</code> object representing the SQL <code>BLOB</code>
-     *         value in the specified column
+     * value in the specified column
      * @throws java.sql.SQLException if a database access error occurs
      * @since 1.2
      */
@@ -2133,13 +2080,13 @@
     }
 
     /**
-     * Retrieves the value of the designated column in the current row
-     * of this <code>ResultSet</code> object as a <code>Clob</code> object
-     * in the Java programming language.
+     * Retrieves the value of the designated column in the current row of this
+     * <code>ResultSet</code> object as a <code>Clob</code> object in the Java
+     * programming language.
      *
      * @param colName the name of the column from which to retrieve the value
      * @return a <code>Clob</code> object representing the SQL <code>CLOB</code>
-     *         value in the specified column
+     * value in the specified column
      * @throws java.sql.SQLException if a database access error occurs
      * @since 1.2
      */
@@ -2148,13 +2095,13 @@
     }
 
     /**
-     * Retrieves the value of the designated column in the current row
-     * of this <code>ResultSet</code> object as an <code>Array</code> object
-     * in the Java programming language.
+     * Retrieves the value of the designated column in the current row of this
+     * <code>ResultSet</code> object as an <code>Array</code> object in the Java
+     * programming language.
      *
      * @param colName the name of the column from which to retrieve the value
-     * @return an <code>Array</code> object representing the SQL <code>ARRAY</code> value in
-     *         the specified column
+     * @return an <code>Array</code> object representing the SQL <code>ARRAY</code>
+     * value in the specified column
      * @throws java.sql.SQLException if a database access error occurs
      * @since 1.2
      */
@@ -2163,19 +2110,18 @@
     }
 
     /**
-     * Retrieves the value of the designated column in the current row
-     * of this <code>ResultSet</code> object as a <code>java.sql.Date</code> object
-     * in the Java programming language.
-     * This method uses the given calendar to construct an appropriate millisecond
-     * value for the date if the underlying database does not store
-     * timezone information.
+     * Retrieves the value of the designated column in the current row of this
+     * <code>ResultSet</code> object as a <code>java.sql.Date</code> object in the
+     * Java programming language. This method uses the given calendar to construct
+     * an appropriate millisecond value for the date if the underlying database does
+     * not store timezone information.
      *
      * @param columnIndex the first column is 1, the second is 2, ...
-     * @param cal         the <code>java.util.Calendar</code> object
-     *                    to use in constructing the date
-     * @return the column value as a <code>java.sql.Date</code> object;
-     *         if the value is SQL <code>NULL</code>,
-     *         the value returned is <code>null</code> in the Java programming language
+     * @param cal the <code>java.util.Calendar</code> object to use in constructing
+     * the date
+     * @return the column value as a <code>java.sql.Date</code> object; if the value
+     * is SQL <code>NULL</code>, the value returned is <code>null</code> in the Java
+     * programming language
      * @throws java.sql.SQLException if a database access error occurs
      * @since 1.2
      */
@@ -2184,19 +2130,18 @@
     }
 
     /**
-     * Retrieves the value of the designated column in the current row
-     * of this <code>ResultSet</code> object as a <code>java.sql.Date</code> object
-     * in the Java programming language.
-     * This method uses the given calendar to construct an appropriate millisecond
-     * value for the date if the underlying database does not store
-     * timezone information.
+     * Retrieves the value of the designated column in the current row of this
+     * <code>ResultSet</code> object as a <code>java.sql.Date</code> object in the
+     * Java programming language. This method uses the given calendar to construct
+     * an appropriate millisecond value for the date if the underlying database does
+     * not store timezone information.
      *
      * @param columnName the SQL name of the column from which to retrieve the value
-     * @param cal        the <code>java.util.Calendar</code> object
-     *                   to use in constructing the date
-     * @return the column value as a <code>java.sql.Date</code> object;
-     *         if the value is SQL <code>NULL</code>,
-     *         the value returned is <code>null</code> in the Java programming language
+     * @param cal the <code>java.util.Calendar</code> object to use in constructing
+     * the date
+     * @return the column value as a <code>java.sql.Date</code> object; if the value
+     * is SQL <code>NULL</code>, the value returned is <code>null</code> in the Java
+     * programming language
      * @throws java.sql.SQLException if a database access error occurs
      * @since 1.2
      */
@@ -2205,19 +2150,18 @@
     }
 
     /**
-     * Retrieves the value of the designated column in the current row
-     * of this <code>ResultSet</code> object as a <code>java.sql.Time</code> object
-     * in the Java programming language.
-     * This method uses the given calendar to construct an appropriate millisecond
-     * value for the time if the underlying database does not store
-     * timezone information.
+     * Retrieves the value of the designated column in the current row of this
+     * <code>ResultSet</code> object as a <code>java.sql.Time</code> object in the
+     * Java programming language. This method uses the given calendar to construct
+     * an appropriate millisecond value for the time if the underlying database does
+     * not store timezone information.
      *
      * @param columnIndex the first column is 1, the second is 2, ...
-     * @param cal         the <code>java.util.Calendar</code> object
-     *                    to use in constructing the time
-     * @return the column value as a <code>java.sql.Time</code> object;
-     *         if the value is SQL <code>NULL</code>,
-     *         the value returned is <code>null</code> in the Java programming language
+     * @param cal the <code>java.util.Calendar</code> object to use in constructing
+     * the time
+     * @return the column value as a <code>java.sql.Time</code> object; if the value
+     * is SQL <code>NULL</code>, the value returned is <code>null</code> in the Java
+     * programming language
      * @throws java.sql.SQLException if a database access error occurs
      * @since 1.2
      */
@@ -2226,19 +2170,18 @@
     }
 
     /**
-     * Retrieves the value of the designated column in the current row
-     * of this <code>ResultSet</code> object as a <code>java.sql.Time</code> object
-     * in the Java programming language.
-     * This method uses the given calendar to construct an appropriate millisecond
-     * value for the time if the underlying database does not store
-     * timezone information.
+     * Retrieves the value of the designated column in the current row of this
+     * <code>ResultSet</code> object as a <code>java.sql.Time</code> object in the
+     * Java programming language. This method uses the given calendar to construct
+     * an appropriate millisecond value for the time if the underlying database does
+     * not store timezone information.
      *
      * @param columnName the SQL name of the column
-     * @param cal        the <code>java.util.Calendar</code> object
-     *                   to use in constructing the time
-     * @return the column value as a <code>java.sql.Time</code> object;
-     *         if the value is SQL <code>NULL</code>,
-     *         the value returned is <code>null</code> in the Java programming language
+     * @param cal the <code>java.util.Calendar</code> object to use in constructing
+     * the time
+     * @return the column value as a <code>java.sql.Time</code> object; if the value
+     * is SQL <code>NULL</code>, the value returned is <code>null</code> in the Java
+     * programming language
      * @throws java.sql.SQLException if a database access error occurs
      * @since 1.2
      */
@@ -2247,19 +2190,18 @@
     }
 
     /**
-     * Retrieves the value of the designated column in the current row
-     * of this <code>ResultSet</code> object as a <code>java.sql.Timestamp</code> object
-     * in the Java programming language.
-     * This method uses the given calendar to construct an appropriate millisecond
-     * value for the timestamp if the underlying database does not store
-     * timezone information.
+     * Retrieves the value of the designated column in the current row of this
+     * <code>ResultSet</code> object as a <code>java.sql.Timestamp</code> object in
+     * the Java programming language. This method uses the given calendar to
+     * construct an appropriate millisecond value for the timestamp if the
+     * underlying database does not store timezone information.
      *
      * @param columnIndex the first column is 1, the second is 2, ...
-     * @param cal         the <code>java.util.Calendar</code> object
-     *                    to use in constructing the timestamp
-     * @return the column value as a <code>java.sql.Timestamp</code> object;
-     *         if the value is SQL <code>NULL</code>,
-     *         the value returned is <code>null</code> in the Java programming language
+     * @param cal the <code>java.util.Calendar</code> object to use in constructing
+     * the timestamp
+     * @return the column value as a <code>java.sql.Timestamp</code> object; if the
+     * value is SQL <code>NULL</code>, the value returned is <code>null</code> in
+     * the Java programming language
      * @throws java.sql.SQLException if a database access error occurs
      * @since 1.2
      */
@@ -2268,19 +2210,18 @@
     }
 
     /**
-     * Retrieves the value of the designated column in the current row
-     * of this <code>ResultSet</code> object as a <code>java.sql.Timestamp</code> object
-     * in the Java programming language.
-     * This method uses the given calendar to construct an appropriate millisecond
-     * value for the timestamp if the underlying database does not store
-     * timezone information.
+     * Retrieves the value of the designated column in the current row of this
+     * <code>ResultSet</code> object as a <code>java.sql.Timestamp</code> object in
+     * the Java programming language. This method uses the given calendar to
+     * construct an appropriate millisecond value for the timestamp if the
+     * underlying database does not store timezone information.
      *
      * @param columnName the SQL name of the column
-     * @param cal        the <code>java.util.Calendar</code> object
-     *                   to use in constructing the date
-     * @return the column value as a <code>java.sql.Timestamp</code> object;
-     *         if the value is SQL <code>NULL</code>,
-     *         the value returned is <code>null</code> in the Java programming language
+     * @param cal the <code>java.util.Calendar</code> object to use in constructing
+     * the date
+     * @return the column value as a <code>java.sql.Timestamp</code> object; if the
+     * value is SQL <code>NULL</code>, the value returned is <code>null</code> in
+     * the Java programming language
      * @throws java.sql.SQLException if a database access error occurs
      * @since 1.2
      */
@@ -2289,16 +2230,17 @@
     }
 
     /**
-     * Retrieves the value of the designated column in the current row
-     * of this <code>ResultSet</code> object as a <code>java.net.URL</code>
-     * object in the Java programming language.
+     * Retrieves the value of the designated column in the current row of this
+     * <code>ResultSet</code> object as a <code>java.net.URL</code> object in the
+     * Java programming language.
      *
-     * @param columnIndex the index of the column 1 is the first, 2 is the second,...
-     * @return the column value as a <code>java.net.URL</code> object;
-     *         if the value is SQL <code>NULL</code>,
-     *         the value returned is <code>null</code> in the Java programming language
-     * @throws java.sql.SQLException if a database access error occurs,
-     *                               or if a URL is malformed
+     * @param columnIndex the index of the column 1 is the first, 2 is the
+     * second,...
+     * @return the column value as a <code>java.net.URL</code> object; if the value
+     * is SQL <code>NULL</code>, the value returned is <code>null</code> in the Java
+     * programming language
+     * @throws java.sql.SQLException if a database access error occurs, or if a URL
+     * is malformed
      * @since 1.4
      */
     public URL getURL(int columnIndex) throws SQLException {
@@ -2306,16 +2248,16 @@
     }
 
     /**
-     * Retrieves the value of the designated column in the current row
-     * of this <code>ResultSet</code> object as a <code>java.net.URL</code>
-     * object in the Java programming language.
+     * Retrieves the value of the designated column in the current row of this
+     * <code>ResultSet</code> object as a <code>java.net.URL</code> object in the
+     * Java programming language.
      *
      * @param columnName the SQL name of the column
-     * @return the column value as a <code>java.net.URL</code> object;
-     *         if the value is SQL <code>NULL</code>,
-     *         the value returned is <code>null</code> in the Java programming language
-     * @throws java.sql.SQLException if a database access error occurs
-     *                               or if a URL is malformed
+     * @return the column value as a <code>java.net.URL</code> object; if the value
+     * is SQL <code>NULL</code>, the value returned is <code>null</code> in the Java
+     * programming language
+     * @throws java.sql.SQLException if a database access error occurs or if a URL
+     * is malformed
      * @since 1.4
      */
     public URL getURL(String columnName) throws SQLException {
@@ -2323,14 +2265,14 @@
     }
 
     /**
-     * Updates the designated column with a <code>java.sql.Ref</code> value.
-     * The updater methods are used to update column values in the
-     * current row or the insert row.  The updater methods do not
-     * update the underlying database; instead the <code>updateRow</code> or
-     * <code>insertRow</code> methods are called to update the database.
+     * Updates the designated column with a <code>java.sql.Ref</code> value. The
+     * updater methods are used to update column values in the current row or the
+     * insert row. The updater methods do not update the underlying database;
+     * instead the <code>updateRow</code> or <code>insertRow</code> methods are
+     * called to update the database.
      *
      * @param columnIndex the first column is 1, the second is 2, ...
-     * @param x           the new column value
+     * @param x the new column value
      * @throws java.sql.SQLException if a database access error occurs
      * @since 1.4
      */
@@ -2339,14 +2281,14 @@
     }
 
     /**
-     * Updates the designated column with a <code>java.sql.Ref</code> value.
-     * The updater methods are used to update column values in the
-     * current row or the insert row.  The updater methods do not
-     * update the underlying database; instead the <code>updateRow</code> or
-     * <code>insertRow</code> methods are called to update the database.
+     * Updates the designated column with a <code>java.sql.Ref</code> value. The
+     * updater methods are used to update column values in the current row or the
+     * insert row. The updater methods do not update the underlying database;
+     * instead the <code>updateRow</code> or <code>insertRow</code> methods are
+     * called to update the database.
      *
      * @param columnName the name of the column
-     * @param x          the new column value
+     * @param x the new column value
      * @throws java.sql.SQLException if a database access error occurs
      * @since 1.4
      */
@@ -2355,14 +2297,14 @@
     }
 
     /**
-     * Updates the designated column with a <code>java.sql.Blob</code> value.
-     * The updater methods are used to update column values in the
-     * current row or the insert row.  The updater methods do not
-     * update the underlying database; instead the <code>updateRow</code> or
-     * <code>insertRow</code> methods are called to update the database.
+     * Updates the designated column with a <code>java.sql.Blob</code> value. The
+     * updater methods are used to update column values in the current row or the
+     * insert row. The updater methods do not update the underlying database;
+     * instead the <code>updateRow</code> or <code>insertRow</code> methods are
+     * called to update the database.
      *
      * @param columnIndex the first column is 1, the second is 2, ...
-     * @param x           the new column value
+     * @param x the new column value
      * @throws java.sql.SQLException if a database access error occurs
      * @since 1.4
      */
@@ -2371,14 +2313,14 @@
     }
 
     /**
-     * Updates the designated column with a <code>java.sql.Blob</code> value.
-     * The updater methods are used to update column values in the
-     * current row or the insert row.  The updater methods do not
-     * update the underlying database; instead the <code>updateRow</code> or
-     * <code>insertRow</code> methods are called to update the database.
+     * Updates the designated column with a <code>java.sql.Blob</code> value. The
+     * updater methods are used to update column values in the current row or the
+     * insert row. The updater methods do not update the underlying database;
+     * instead the <code>updateRow</code> or <code>insertRow</code> methods are
+     * called to update the database.
      *
      * @param columnName the name of the column
-     * @param x          the new column value
+     * @param x the new column value
      * @throws java.sql.SQLException if a database access error occurs
      * @since 1.4
      */
@@ -2387,14 +2329,14 @@
     }
 
     /**
-     * Updates the designated column with a <code>java.sql.Clob</code> value.
-     * The updater methods are used to update column values in the
-     * current row or the insert row.  The updater methods do not
-     * update the underlying database; instead the <code>updateRow</code> or
-     * <code>insertRow</code> methods are called to update the database.
+     * Updates the designated column with a <code>java.sql.Clob</code> value. The
+     * updater methods are used to update column values in the current row or the
+     * insert row. The updater methods do not update the underlying database;
+     * instead the <code>updateRow</code> or <code>insertRow</code> methods are
+     * called to update the database.
      *
      * @param columnIndex the first column is 1, the second is 2, ...
-     * @param x           the new column value
+     * @param x the new column value
      * @throws java.sql.SQLException if a database access error occurs
      * @since 1.4
      */
@@ -2403,14 +2345,14 @@
     }
 
     /**
-     * Updates the designated column with a <code>java.sql.Clob</code> value.
-     * The updater methods are used to update column values in the
-     * current row or the insert row.  The updater methods do not
-     * update the underlying database; instead the <code>updateRow</code> or
-     * <code>insertRow</code> methods are called to update the database.
+     * Updates the designated column with a <code>java.sql.Clob</code> value. The
+     * updater methods are used to update column values in the current row or the
+     * insert row. The updater methods do not update the underlying database;
+     * instead the <code>updateRow</code> or <code>insertRow</code> methods are
+     * called to update the database.
      *
      * @param columnName the name of the column
-     * @param x          the new column value
+     * @param x the new column value
      * @throws java.sql.SQLException if a database access error occurs
      * @since 1.4
      */
@@ -2419,14 +2361,14 @@
     }
 
     /**
-     * Updates the designated column with a <code>java.sql.Array</code> value.
-     * The updater methods are used to update column values in the
-     * current row or the insert row.  The updater methods do not
-     * update the underlying database; instead the <code>updateRow</code> or
-     * <code>insertRow</code> methods are called to update the database.
+     * Updates the designated column with a <code>java.sql.Array</code> value. The
+     * updater methods are used to update column values in the current row or the
+     * insert row. The updater methods do not update the underlying database;
+     * instead the <code>updateRow</code> or <code>insertRow</code> methods are
+     * called to update the database.
      *
      * @param columnIndex the first column is 1, the second is 2, ...
-     * @param x           the new column value
+     * @param x the new column value
      * @throws java.sql.SQLException if a database access error occurs
      * @since 1.4
      */
@@ -2435,14 +2377,14 @@
     }
 
     /**
-     * Updates the designated column with a <code>java.sql.Array</code> value.
-     * The updater methods are used to update column values in the
-     * current row or the insert row.  The updater methods do not
-     * update the underlying database; instead the <code>updateRow</code> or
-     * <code>insertRow</code> methods are called to update the database.
+     * Updates the designated column with a <code>java.sql.Array</code> value. The
+     * updater methods are used to update column values in the current row or the
+     * insert row. The updater methods do not update the underlying database;
+     * instead the <code>updateRow</code> or <code>insertRow</code> methods are
+     * called to update the database.
      *
      * @param columnName the name of the column
-     * @param x          the new column value
+     * @param x the new column value
      * @throws java.sql.SQLException if a database access error occurs
      * @since 1.4
      */
diff --git a/appserver/jdbc/jdbc-ra/jdbc-core/src/main/java/com/sun/gjc/spi/base/StatementWrapper.java b/appserver/jdbc/jdbc-ra/jdbc-core/src/main/java/com/sun/gjc/spi/base/StatementWrapper.java
index f53091a..9a6ce0d 100644
--- a/appserver/jdbc/jdbc-ra/jdbc-core/src/main/java/com/sun/gjc/spi/base/StatementWrapper.java
+++ b/appserver/jdbc/jdbc-ra/jdbc-core/src/main/java/com/sun/gjc/spi/base/StatementWrapper.java
@@ -16,11 +16,6 @@
 
 package com.sun.gjc.spi.base;
 
-import com.sun.gjc.common.DataSourceObjectBuilder;
-import com.sun.gjc.util.MethodExecutor;
-import com.sun.gjc.util.StatementLeakDetector;
-import com.sun.gjc.util.StatementLeakListener;
-import com.sun.logging.LogDomains;
 import java.sql.CallableStatement;
 import java.sql.Connection;
 import java.sql.PreparedStatement;
@@ -30,6 +25,13 @@
 import java.util.concurrent.atomic.AtomicInteger;
 import java.util.logging.Level;
 import java.util.logging.Logger;
+
+import com.sun.gjc.common.DataSourceObjectBuilder;
+import com.sun.gjc.util.MethodExecutor;
+import com.sun.gjc.util.StatementLeakDetector;
+import com.sun.gjc.util.StatementLeakListener;
+import com.sun.logging.LogDomains;
+
 import jakarta.resource.ResourceException;
 
 /**
@@ -37,101 +39,93 @@
  */
 public abstract class StatementWrapper implements Statement, StatementLeakListener {
 
-    protected Connection connection = null;
-    protected Statement jdbcStatement = null;
-    protected StatementLeakDetector leakDetector = null;
-    private boolean markedForReclaim = false;
-    protected final static Logger _logger;
-    protected MethodExecutor executor = null;
-    private boolean closeOnCompletion = false;
+    protected final static Logger _logger = LogDomains.getLogger(MethodExecutor.class, LogDomains.RSR_LOGGER);
+
+    protected Connection connection;
+    protected Statement jdbcStatement;
+    protected StatementLeakDetector leakDetector;
+    private boolean markedForReclaim;
+    protected MethodExecutor executor;
+    private boolean closeOnCompletion;
     protected AtomicInteger resultSetCount = new AtomicInteger();
 
 
-    static {
-        _logger = LogDomains.getLogger(MethodExecutor.class, LogDomains.RSR_LOGGER);
-    }
-
     /**
      * Abstract class for wrapping Statement<br>
      *
-     * @param con       ConnectionWrapper <br>
+     * @param con ConnectionWrapper <br>
      * @param statement Statement that is to be wrapped<br>
      */
     public StatementWrapper(Connection con, Statement statement) {
         connection = con;
         jdbcStatement = statement;
         executor = new MethodExecutor();
-        //Start leak tracing if statement is a pure Statement & stmtWrapping is ON
-        //Check if this is an instanceof PS/CS. There could exist
-        //a CustomStatement class in a jdbc driver that implements PS/CS as well
-        //as Statement
-        if(!(this instanceof PreparedStatement) &&
-                !(this instanceof CallableStatement)) {
+
+        // Start leak tracing if statement is a pure Statement & stmtWrapping is ON
+        // Check if this is an instanceof PS/CS. There could exist
+        // a CustomStatement class in a jdbc driver that implements PS/CS as well
+        // as Statement
+        if (!(this instanceof PreparedStatement) && !(this instanceof CallableStatement)) {
             ConnectionHolder wrappedCon = (ConnectionHolder) con;
 
             leakDetector = wrappedCon.getManagedConnection().getLeakDetector();
-            if(leakDetector != null) {
+            if (leakDetector != null) {
                 leakDetector.startStatementLeakTracing(jdbcStatement, this);
             }
         }
-        //If PS or CS, do not start leak tracing here
+        // If PS or CS, do not start leak tracing here
     }
 
     /**
      * Executes the given SQL statement, which may be an <code>INSERT</code>,
-     * <code>UPDATE</code>, or <code>DELETE</code> statement or an
-     * SQL statement that returns nothing, such as an SQL DDL statement.
+     * <code>UPDATE</code>, or <code>DELETE</code> statement or an SQL statement
+     * that returns nothing, such as an SQL DDL statement.
      *
      * @param sql an SQL <code>INSERT</code>, <code>UPDATE</code> or
-     *            <code>DELETE</code> statement or an SQL statement that returns nothing
-     * @return either the row count for <code>INSERT</code>, <code>UPDATE</code>
-     *         or <code>DELETE</code> statements, or <code>0</code> for SQL statements
-     *         that return nothing
+     * <code>DELETE</code> statement or an SQL statement that returns nothing
+     * @return either the row count for <code>INSERT</code>, <code>UPDATE</code> or
+     * <code>DELETE</code> statements, or <code>0</code> for SQL statements that
+     * return nothing
      * @throws java.sql.SQLException if a database access error occurs or the given
-     *                               SQL statement produces a <code>ResultSet</code> object
+     * SQL statement produces a <code>ResultSet</code> object
      */
     public int executeUpdate(final String sql) throws SQLException {
         return jdbcStatement.executeUpdate(sql);
     }
 
     /**
-     * Releases this <code>Statement</code> object's database
-     * and JDBC resources immediately instead of waiting for
-     * this to happen when it is automatically closed.
-     * It is generally good practice to release resources as soon as
-     * you are finished with them to avoid tying up database
-     * resources.
+     * Releases this <code>Statement</code> object's database and JDBC resources
+     * immediately instead of waiting for this to happen when it is automatically
+     * closed. It is generally good practice to release resources as soon as you are
+     * finished with them to avoid tying up database resources.
      * <p/>
-     * Calling the method <code>close</code> on a <code>Statement</code>
-     * object that is already closed has no effect.
+     * Calling the method <code>close</code> on a <code>Statement</code> object that
+     * is already closed has no effect.
      * <p/>
-     * <B>Note:</B> A <code>Statement</code> object is automatically closed
-     * when it is garbage collected. When a <code>Statement</code> object is
-     * closed, its current <code>ResultSet</code> object, if one exists, is
-     * also closed.
+     * <B>Note:</B> A <code>Statement</code> object is automatically closed when it
+     * is garbage collected. When a <code>Statement</code> object is closed, its
+     * current <code>ResultSet</code> object, if one exists, is also closed.
      *
      * @throws java.sql.SQLException if a database access error occurs
      */
     public void close() throws SQLException {
-        //Stop leak tracing
-        if(leakDetector != null) {
+        // Stop leak tracing
+        if (leakDetector != null) {
             leakDetector.stopStatementLeakTracing(jdbcStatement, this);
         }
         jdbcStatement.close();
     }
 
     /**
-     * Retrieves the maximum number of bytes that can be
-     * returned for character and binary column values in a <code>ResultSet</code>
-     * object produced by this <code>Statement</code> object.
-     * This limit applies only to <code>BINARY</code>,
-     * <code>VARBINARY</code>, <code>LONGVARBINARY</code>, <code>CHAR</code>,
-     * <code>VARCHAR</code>, and <code>LONGVARCHAR</code>
-     * columns.  If the limit is exceeded, the excess data is silently
-     * discarded.
+     * Retrieves the maximum number of bytes that can be returned for character and
+     * binary column values in a <code>ResultSet</code> object produced by this
+     * <code>Statement</code> object. This limit applies only to
+     * <code>BINARY</code>, <code>VARBINARY</code>, <code>LONGVARBINARY</code>,
+     * <code>CHAR</code>, <code>VARCHAR</code>, and <code>LONGVARCHAR</code>
+     * columns. If the limit is exceeded, the excess data is silently discarded.
      *
      * @return the current column size limit for columns storing character and
-     *         binary values; zero means there is no limit
+     * binary values; zero means there is no limit
      * @throws java.sql.SQLException if a database access error occurs
      * @see #setMaxFieldSize
      */
@@ -141,17 +135,15 @@
 
     /**
      * Sets the limit for the maximum number of bytes in a <code>ResultSet</code>
-     * column storing character or binary values to
-     * the given number of bytes.  This limit applies
-     * only to <code>BINARY</code>, <code>VARBINARY</code>,
+     * column storing character or binary values to the given number of bytes. This
+     * limit applies only to <code>BINARY</code>, <code>VARBINARY</code>,
      * <code>LONGVARBINARY</code>, <code>CHAR</code>, <code>VARCHAR</code>, and
-     * <code>LONGVARCHAR</code> fields.  If the limit is exceeded, the excess data
-     * is silently discarded. For maximum portability, use values
-     * greater than 256.
+     * <code>LONGVARCHAR</code> fields. If the limit is exceeded, the excess data is
+     * silently discarded. For maximum portability, use values greater than 256.
      *
      * @param max the new column size limit in bytes; zero means there is no limit
-     * @throws java.sql.SQLException if a database access error occurs
-     *                               or the condition max >= 0 is not satisfied
+     * @throws java.sql.SQLException if a database access error occurs or the
+     * condition max >= 0 is not satisfied
      * @see #getMaxFieldSize
      */
     public void setMaxFieldSize(int max) throws SQLException {
@@ -159,14 +151,13 @@
     }
 
     /**
-     * Retrieves the maximum number of rows that a
-     * <code>ResultSet</code> object produced by this
-     * <code>Statement</code> object can contain.  If this limit is exceeded,
-     * the excess rows are silently dropped.
+     * Retrieves the maximum number of rows that a <code>ResultSet</code> object
+     * produced by this <code>Statement</code> object can contain. If this limit is
+     * exceeded, the excess rows are silently dropped.
      *
      * @return the current maximum number of rows for a <code>ResultSet</code>
-     *         object produced by this <code>Statement</code> object;
-     *         zero means there is no limit
+     * object produced by this <code>Statement</code> object; zero means there is no
+     * limit
      * @throws java.sql.SQLException if a database access error occurs
      * @see #setMaxRows
      */
@@ -175,14 +166,13 @@
     }
 
     /**
-     * Sets the limit for the maximum number of rows that any
-     * <code>ResultSet</code> object can contain to the given number.
-     * If the limit is exceeded, the excess
+     * Sets the limit for the maximum number of rows that any <code>ResultSet</code>
+     * object can contain to the given number. If the limit is exceeded, the excess
      * rows are silently dropped.
      *
      * @param max the new max rows limit; zero means there is no limit
-     * @throws java.sql.SQLException if a database access error occurs
-     *                               or the condition max >= 0 is not satisfied
+     * @throws java.sql.SQLException if a database access error occurs or the
+     * condition max >= 0 is not satisfied
      * @see #getMaxRows
      */
     public void setMaxRows(int max) throws SQLException {
@@ -190,16 +180,16 @@
     }
 
     /**
-     * Sets escape processing on or off.
-     * If escape scanning is on (the default), the driver will do
-     * escape substitution before sending the SQL statement to the database.
+     * Sets escape processing on or off. If escape scanning is on (the default), the
+     * driver will do escape substitution before sending the SQL statement to the
+     * database.
      * <p/>
-     * Note: Since prepared statements have usually been parsed prior
-     * to making this call, disabling escape processing for
-     * <code>PreparedStatements</code> objects will have no effect.
+     * Note: Since prepared statements have usually been parsed prior to making this
+     * call, disabling escape processing for <code>PreparedStatements</code> objects
+     * will have no effect.
      *
      * @param enable <code>true</code> to enable escape processing;
-     *               <code>false</code> to disable it
+     * <code>false</code> to disable it
      * @throws java.sql.SQLException if a database access error occurs
      */
     public void setEscapeProcessing(boolean enable) throws SQLException {
@@ -207,12 +197,12 @@
     }
 
     /**
-     * Retrieves the number of seconds the driver will
-     * wait for a <code>Statement</code> object to execute. If the limit is exceeded, a
+     * Retrieves the number of seconds the driver will wait for a
+     * <code>Statement</code> object to execute. If the limit is exceeded, a
      * <code>SQLException</code> is thrown.
      *
-     * @return the current query timeout limit in seconds; zero means there is
-     *         no limit
+     * @return the current query timeout limit in seconds; zero means there is no
+     * limit
      * @throws java.sql.SQLException if a database access error occurs
      * @see #setQueryTimeout
      */
@@ -221,14 +211,14 @@
     }
 
     /**
-     * Sets the number of seconds the driver will wait for a
-     * <code>Statement</code> object to execute to the given number of seconds.
-     * If the limit is exceeded, an <code>SQLException</code> is thrown.
+     * Sets the number of seconds the driver will wait for a <code>Statement</code>
+     * object to execute to the given number of seconds. If the limit is exceeded,
+     * an <code>SQLException</code> is thrown.
      *
-     * @param seconds the new query timeout limit in seconds; zero means
-     *                there is no limit
-     * @throws java.sql.SQLException if a database access error occurs
-     *                               or the condition seconds >= 0 is not satisfied
+     * @param seconds the new query timeout limit in seconds; zero means there is no
+     * limit
+     * @throws java.sql.SQLException if a database access error occurs or the
+     * condition seconds >= 0 is not satisfied
      * @see #getQueryTimeout
      */
     public void setQueryTimeout(int seconds) throws SQLException {
@@ -236,10 +226,9 @@
     }
 
     /**
-     * Cancels this <code>Statement</code> object if both the DBMS and
-     * driver support aborting an SQL statement.
-     * This method can be used by one thread to cancel a statement that
-     * is being executed by another thread.
+     * Cancels this <code>Statement</code> object if both the DBMS and driver
+     * support aborting an SQL statement. This method can be used by one thread to
+     * cancel a statement that is being executed by another thread.
      *
      * @throws java.sql.SQLException if a database access error occurs
      */
@@ -248,33 +237,34 @@
     }
 
     /**
-     * Retrieves the first warning reported by calls on this <code>Statement</code> object.
-     * Subsequent <code>Statement</code> object warnings will be chained to this
-     * <code>SQLWarning</code> object.
+     * Retrieves the first warning reported by calls on this <code>Statement</code>
+     * object. Subsequent <code>Statement</code> object warnings will be chained to
+     * this <code>SQLWarning</code> object.
      * <p/>
-     * <p>The warning chain is automatically cleared each time
-     * a statement is (re)executed. This method may not be called on a closed
-     * <code>Statement</code> object; doing so will cause an <code>SQLException</code>
-     * to be thrown.
+     * <p>
+     * The warning chain is automatically cleared each time a statement is
+     * (re)executed. This method may not be called on a closed
+     * <code>Statement</code> object; doing so will cause an
+     * <code>SQLException</code> to be thrown.
      * <p/>
-     * <P><B>Note:</B> If you are processing a <code>ResultSet</code> object, any
-     * warnings associated with reads on that <code>ResultSet</code> object
-     * will be chained on it rather than on the <code>Statement</code>
-     * object that produced it.
+     * <P>
+     * <B>Note:</B> If you are processing a <code>ResultSet</code> object, any
+     * warnings associated with reads on that <code>ResultSet</code> object will be
+     * chained on it rather than on the <code>Statement</code> object that produced
+     * it.
      *
-     * @return the first <code>SQLWarning</code> object or <code>null</code>
-     *         if there are no warnings
+     * @return the first <code>SQLWarning</code> object or <code>null</code> if
+     * there are no warnings
      * @throws java.sql.SQLException if a database access error occurs or this
-     *                               method is called on a closed statement
+     * method is called on a closed statement
      */
     public SQLWarning getWarnings() throws SQLException {
         return jdbcStatement.getWarnings();
     }
 
     /**
-     * Clears all the warnings reported on this <code>Statement</code>
-     * object. After a call to this method,
-     * the method <code>getWarnings</code> will return
+     * Clears all the warnings reported on this <code>Statement</code> object. After
+     * a call to this method, the method <code>getWarnings</code> will return
      * <code>null</code> until a new warning is reported for this
      * <code>Statement</code> object.
      *
@@ -285,24 +275,23 @@
     }
 
     /**
-     * Sets the SQL cursor name to the given <code>String</code>, which
-     * will be used by subsequent <code>Statement</code> object
-     * <code>execute</code> methods. This name can then be
-     * used in SQL positioned update or delete statements to identify the
-     * current row in the <code>ResultSet</code> object generated by this
-     * statement.  If the database does not support positioned update/delete,
-     * this method is a noop.  To insure that a cursor has the proper isolation
-     * level to support updates, the cursor's <code>SELECT</code> statement
-     * should have the form <code>SELECT FOR UPDATE</code>.  If
-     * <code>FOR UPDATE</code> is not present, positioned updates may fail.
+     * Sets the SQL cursor name to the given <code>String</code>, which will be used
+     * by subsequent <code>Statement</code> object <code>execute</code> methods.
+     * This name can then be used in SQL positioned update or delete statements to
+     * identify the current row in the <code>ResultSet</code> object generated by
+     * this statement. If the database does not support positioned update/delete,
+     * this method is a noop. To insure that a cursor has the proper isolation level
+     * to support updates, the cursor's <code>SELECT</code> statement should have
+     * the form <code>SELECT FOR UPDATE</code>. If <code>FOR UPDATE</code> is not
+     * present, positioned updates may fail.
      * <p/>
-     * <P><B>Note:</B> By definition, the execution of positioned updates and
-     * deletes must be done by a different <code>Statement</code> object than
-     * the one that generated the <code>ResultSet</code> object being used for
-     * positioning. Also, cursor names must be unique within a connection.
+     * <P>
+     * <B>Note:</B> By definition, the execution of positioned updates and deletes
+     * must be done by a different <code>Statement</code> object than the one that
+     * generated the <code>ResultSet</code> object being used for positioning. Also,
+     * cursor names must be unique within a connection.
      *
-     * @param name the new cursor name, which must be unique within
-     *             a connection
+     * @param name the new cursor name, which must be unique within a connection
      * @throws java.sql.SQLException if a database access error occurs
      */
     public void setCursorName(String name) throws SQLException {
@@ -310,23 +299,20 @@
     }
 
     /**
-     * Executes the given SQL statement, which may return multiple results.
-     * In some (uncommon) situations, a single SQL statement may return
-     * multiple result sets and/or update counts.  Normally you can ignore
-     * this unless you are (1) executing a stored procedure that you know may
-     * return multiple results or (2) you are dynamically executing an
-     * unknown SQL string.
+     * Executes the given SQL statement, which may return multiple results. In some
+     * (uncommon) situations, a single SQL statement may return multiple result sets
+     * and/or update counts. Normally you can ignore this unless you are (1)
+     * executing a stored procedure that you know may return multiple results or (2)
+     * you are dynamically executing an unknown SQL string.
      * <p/>
      * The <code>execute</code> method executes an SQL statement and indicates the
-     * form of the first result.  You must then use the methods
-     * <code>getResultSet</code> or <code>getUpdateCount</code>
-     * to retrieve the result, and <code>getMoreResults</code> to
-     * move to any subsequent result(s).
+     * form of the first result. You must then use the methods
+     * <code>getResultSet</code> or <code>getUpdateCount</code> to retrieve the
+     * result, and <code>getMoreResults</code> to move to any subsequent result(s).
      *
      * @param sql any SQL statement
      * @return <code>true</code> if the first result is a <code>ResultSet</code>
-     *         object; <code>false</code> if it is an update count or there are
-     *         no results
+     * object; <code>false</code> if it is an update count or there are no results
      * @throws java.sql.SQLException if a database access error occurs
      * @see #getResultSet
      * @see #getUpdateCount
@@ -336,14 +322,13 @@
         return jdbcStatement.execute(sql);
     }
 
-
     /**
-     * Retrieves the current result as an update count;
-     * if the result is a <code>ResultSet</code> object or there are no more results, -1
-     * is returned. This method should be called only once per result.
+     * Retrieves the current result as an update count; if the result is a
+     * <code>ResultSet</code> object or there are no more results, -1 is returned.
+     * This method should be called only once per result.
      *
      * @return the current result as an update count; -1 if the current result is a
-     *         <code>ResultSet</code> object or there are no more results
+     * <code>ResultSet</code> object or there are no more results
      * @throws java.sql.SQLException if a database access error occurs
      * @see #execute
      */
@@ -353,19 +338,21 @@
 
     /**
      * Moves to this <code>Statement</code> object's next result, returns
-     * <code>true</code> if it is a <code>ResultSet</code> object, and
-     * implicitly closes any current <code>ResultSet</code>
-     * object(s) obtained with the method <code>getResultSet</code>.
+     * <code>true</code> if it is a <code>ResultSet</code> object, and implicitly
+     * closes any current <code>ResultSet</code> object(s) obtained with the method
+     * <code>getResultSet</code>.
      * <p/>
-     * <P>There are no more results when the following is true:
+     * <P>
+     * There are no more results when the following is true:
+     *
      * <PRE>
      * // stmt is a Statement object
      * ((stmt.getMoreResults() == false) && (stmt.getUpdateCount() == -1))
      * </PRE>
      *
      * @return <code>true</code> if the next result is a <code>ResultSet</code>
-     *         object; <code>false</code> if it is an update count or there are
-     *         no more results
+     * object; <code>false</code> if it is an update count or there are no more
+     * results
      * @throws java.sql.SQLException if a database access error occurs
      * @see #execute
      */
@@ -374,21 +361,18 @@
     }
 
     /**
-     * Gives the driver a hint as to the direction in which
-     * rows will be processed in <code>ResultSet</code>
-     * objects created using this <code>Statement</code> object.  The
-     * default value is <code>ResultSet.FETCH_FORWARD</code>.
+     * Gives the driver a hint as to the direction in which rows will be processed
+     * in <code>ResultSet</code> objects created using this <code>Statement</code>
+     * object. The default value is <code>ResultSet.FETCH_FORWARD</code>.
      * <p/>
-     * Note that this method sets the default fetch direction for
-     * result sets generated by this <code>Statement</code> object.
-     * Each result set has its own methods for getting and setting
-     * its own fetch direction.
+     * Note that this method sets the default fetch direction for result sets
+     * generated by this <code>Statement</code> object. Each result set has its own
+     * methods for getting and setting its own fetch direction.
      *
      * @param direction the initial direction for processing rows
-     * @throws java.sql.SQLException if a database access error occurs
-     *                               or the given direction
-     *                               is not one of <code>ResultSet.FETCH_FORWARD</code>,
-     *                               <code>ResultSet.FETCH_REVERSE</code>, or <code>ResultSet.FETCH_UNKNOWN</code>
+     * @throws java.sql.SQLException if a database access error occurs or the given
+     * direction is not one of <code>ResultSet.FETCH_FORWARD</code>,
+     * <code>ResultSet.FETCH_REVERSE</code>, or <code>ResultSet.FETCH_UNKNOWN</code>
      * @see #getFetchDirection
      * @since 1.2
      */
@@ -397,15 +381,14 @@
     }
 
     /**
-     * Retrieves the direction for fetching rows from
-     * database tables that is the default for result sets
-     * generated from this <code>Statement</code> object.
-     * If this <code>Statement</code> object has not set
-     * a fetch direction by calling the method <code>setFetchDirection</code>,
-     * the return value is implementation-specific.
+     * Retrieves the direction for fetching rows from database tables that is the
+     * default for result sets generated from this <code>Statement</code> object. If
+     * this <code>Statement</code> object has not set a fetch direction by calling
+     * the method <code>setFetchDirection</code>, the return value is
+     * implementation-specific.
      *
-     * @return the default fetch direction for result sets generated
-     *         from this <code>Statement</code> object
+     * @return the default fetch direction for result sets generated from this
+     * <code>Statement</code> object
      * @throws java.sql.SQLException if a database access error occurs
      * @see #setFetchDirection
      * @since 1.2
@@ -415,16 +398,15 @@
     }
 
     /**
-     * Gives the JDBC driver a hint as to the number of rows that should
-     * be fetched from the database when more rows are needed.  The number
-     * of rows specified affects only result sets created using this
-     * statement. If the value specified is zero, then the hint is ignored.
-     * The default value is zero.
+     * Gives the JDBC driver a hint as to the number of rows that should be fetched
+     * from the database when more rows are needed. The number of rows specified
+     * affects only result sets created using this statement. If the value specified
+     * is zero, then the hint is ignored. The default value is zero.
      *
      * @param rows the number of rows to fetch
      * @throws java.sql.SQLException if a database access error occurs, or the
-     *                               condition 0 <= <code>rows</code> <= <code>this.getMaxRows()</code>
-     *                               is not satisfied.
+     * condition 0 <= <code>rows</code> <= <code>this.getMaxRows()</code> is not
+     * satisfied.
      * @see #getFetchSize
      * @since 1.2
      */
@@ -433,15 +415,14 @@
     }
 
     /**
-     * Retrieves the number of result set rows that is the default
-     * fetch size for <code>ResultSet</code> objects
-     * generated from this <code>Statement</code> object.
-     * If this <code>Statement</code> object has not set
-     * a fetch size by calling the method <code>setFetchSize</code>,
-     * the return value is implementation-specific.
+     * Retrieves the number of result set rows that is the default fetch size for
+     * <code>ResultSet</code> objects generated from this <code>Statement</code>
+     * object. If this <code>Statement</code> object has not set a fetch size by
+     * calling the method <code>setFetchSize</code>, the return value is
+     * implementation-specific.
      *
-     * @return the default fetch size for result sets generated
-     *         from this <code>Statement</code> object
+     * @return the default fetch size for result sets generated from this
+     * <code>Statement</code> object
      * @throws java.sql.SQLException if a database access error occurs
      * @see #setFetchSize
      * @since 1.2
@@ -455,7 +436,7 @@
      * generated by this <code>Statement</code> object.
      *
      * @return either <code>ResultSet.CONCUR_READ_ONLY</code> or
-     *         <code>ResultSet.CONCUR_UPDATABLE</code>
+     * <code>ResultSet.CONCUR_UPDATABLE</code>
      * @throws java.sql.SQLException if a database access error occurs
      * @since 1.2
      */
@@ -464,12 +445,12 @@
     }
 
     /**
-     * Retrieves the result set type for <code>ResultSet</code> objects
-     * generated by this <code>Statement</code> object.
+     * Retrieves the result set type for <code>ResultSet</code> objects generated by
+     * this <code>Statement</code> object.
      *
      * @return one of <code>ResultSet.TYPE_FORWARD_ONLY</code>,
-     *         <code>ResultSet.TYPE_SCROLL_INSENSITIVE</code>, or
-     *         <code>ResultSet.TYPE_SCROLL_SENSITIVE</code>
+     * <code>ResultSet.TYPE_SCROLL_INSENSITIVE</code>, or
+     * <code>ResultSet.TYPE_SCROLL_SENSITIVE</code>
      * @throws java.sql.SQLException if a database access error occurs
      * @since 1.2
      */
@@ -479,15 +460,15 @@
 
     /**
      * Adds the given SQL command to the current list of commmands for this
-     * <code>Statement</code> object. The commands in this list can be
-     * executed as a batch by calling the method <code>executeBatch</code>.
+     * <code>Statement</code> object. The commands in this list can be executed as a
+     * batch by calling the method <code>executeBatch</code>.
      * <p/>
-     * <B>NOTE:</B>  This method is optional.
+     * <B>NOTE:</B> This method is optional.
      *
      * @param sql typically this is a static SQL <code>INSERT</code> or
-     *            <code>UPDATE</code> statement
+     * <code>UPDATE</code> statement
      * @throws java.sql.SQLException if a database access error occurs, or the
-     *                               driver does not support batch updates
+     * driver does not support batch updates
      * @see #executeBatch
      * @since 1.2
      */
@@ -496,13 +477,12 @@
     }
 
     /**
-     * Empties this <code>Statement</code> object's current list of
-     * SQL commands.
+     * Empties this <code>Statement</code> object's current list of SQL commands.
      * <p/>
-     * <B>NOTE:</B>  This method is optional.
+     * <B>NOTE:</B> This method is optional.
      *
-     * @throws java.sql.SQLException if a database access error occurs or the
-     *                               driver does not support batch updates
+     * @throws java.sql.SQLException if a database access error occurs or the driver
+     * does not support batch updates
      * @see #addBatch
      * @since 1.2
      */
@@ -511,51 +491,48 @@
     }
 
     /**
-     * Submits a batch of commands to the database for execution and
-     * if all commands execute successfully, returns an array of update counts.
-     * The <code>int</code> elements of the array that is returned are ordered
-     * to correspond to the commands in the batch, which are ordered
-     * according to the order in which they were added to the batch.
-     * The elements in the array returned by the method <code>executeBatch</code>
-     * may be one of the following:
+     * Submits a batch of commands to the database for execution and if all commands
+     * execute successfully, returns an array of update counts. The <code>int</code>
+     * elements of the array that is returned are ordered to correspond to the
+     * commands in the batch, which are ordered according to the order in which they
+     * were added to the batch. The elements in the array returned by the method
+     * <code>executeBatch</code> may be one of the following:
      * <OL>
-     * <LI>A number greater than or equal to zero -- indicates that the
-     * command was processed successfully and is an update count giving the
-     * number of rows in the database that were affected by the command's
-     * execution
+     * <LI>A number greater than or equal to zero -- indicates that the command was
+     * processed successfully and is an update count giving the number of rows in
+     * the database that were affected by the command's execution
      * <LI>A value of <code>SUCCESS_NO_INFO</code> -- indicates that the command was
-     * processed successfully but that the number of rows affected is
-     * unknown
+     * processed successfully but that the number of rows affected is unknown
      * <p/>
-     * If one of the commands in a batch update fails to execute properly,
-     * this method throws a <code>BatchUpdateException</code>, and a JDBC
-     * driver may or may not continue to process the remaining commands in
-     * the batch.  However, the driver's behavior must be consistent with a
-     * particular DBMS, either always continuing to process commands or never
-     * continuing to process commands.  If the driver continues processing
-     * after a failure, the array returned by the method
-     * <code>BatchUpdateException.getUpdateCounts</code>
-     * will contain as many elements as there are commands in the batch, and
-     * at least one of the elements will be the following:
+     * If one of the commands in a batch update fails to execute properly, this
+     * method throws a <code>BatchUpdateException</code>, and a JDBC driver may or
+     * may not continue to process the remaining commands in the batch. However, the
+     * driver's behavior must be consistent with a particular DBMS, either always
+     * continuing to process commands or never continuing to process commands. If
+     * the driver continues processing after a failure, the array returned by the
+     * method <code>BatchUpdateException.getUpdateCounts</code> will contain as many
+     * elements as there are commands in the batch, and at least one of the elements
+     * will be the following:
      * <p/>
-     * <LI>A value of <code>EXECUTE_FAILED</code> -- indicates that the command failed
-     * to execute successfully and occurs only if a driver continues to
+     * <LI>A value of <code>EXECUTE_FAILED</code> -- indicates that the command
+     * failed to execute successfully and occurs only if a driver continues to
      * process commands after a command fails
      * </OL>
      * <p/>
-     * A driver is not required to implement this method.
-     * The possible implementations and return values have been modified in
-     * the Java 2 SDK, Standard Edition, version 1.3 to
-     * accommodate the option of continuing to proccess commands in a batch
-     * update after a <code>BatchUpdateException</code> obejct has been thrown.
+     * A driver is not required to implement this method. The possible
+     * implementations and return values have been modified in the Java 2 SDK,
+     * Standard Edition, version 1.3 to accommodate the option of continuing to
+     * proccess commands in a batch update after a <code>BatchUpdateException</code>
+     * obejct has been thrown.
      *
-     * @return an array of update counts containing one element for each
-     *         command in the batch.  The elements of the array are ordered according
-     *         to the order in which commands were added to the batch.
-     * @throws java.sql.SQLException if a database access error occurs or the
-     *                               driver does not support batch statements. Throws {@link java.sql.BatchUpdateException}
-     *                               (a subclass of <code>SQLException</code>) if one of the commands sent to the
-     *                               database fails to execute properly or attempts to return a result set.
+     * @return an array of update counts containing one element for each command in
+     * the batch. The elements of the array are ordered according to the order in
+     * which commands were added to the batch.
+     * @throws java.sql.SQLException if a database access error occurs or the driver
+     * does not support batch statements. Throws
+     * {@link java.sql.BatchUpdateException} (a subclass of
+     * <code>SQLException</code>) if one of the commands sent to the database fails
+     * to execute properly or attempts to return a result set.
      * @since 1.3
      */
     public int[] executeBatch() throws SQLException {
@@ -563,8 +540,8 @@
     }
 
     /**
-     * Retrieves the <code>Connection</code> object
-     * that produced this <code>Statement</code> object.
+     * Retrieves the <code>Connection</code> object that produced this
+     * <code>Statement</code> object.
      *
      * @return the connection that produced this statement
      * @throws java.sql.SQLException if a database access error occurs
@@ -585,32 +562,33 @@
     }
 
     /**
-     * Moves to this <code>Statement</code> object's next result, deals with
-     * any current <code>ResultSet</code> object(s) according  to the instructions
-     * specified by the given flag, and returns
-     * <code>true</code> if the next result is a <code>ResultSet</code> object.
+     * Moves to this <code>Statement</code> object's next result, deals with any
+     * current <code>ResultSet</code> object(s) according to the instructions
+     * specified by the given flag, and returns <code>true</code> if the next result
+     * is a <code>ResultSet</code> object.
      * <p/>
-     * <P>There are no more results when the following is true:
+     * <P>
+     * There are no more results when the following is true:
+     *
      * <PRE>
      * // stmt is a Statement object
      * ((stmt.getMoreResults() == false) && (stmt.getUpdateCount() == -1))
      * </PRE>
      *
-     * @param current one of the following <code>Statement</code>
-     *                constants indicating what should happen to current
-     *                <code>ResultSet</code> objects obtained using the method
-     *                <code>getResultSet</code>:
-     *                <code>Statement.CLOSE_CURRENT_RESULT</code>,
-     *                <code>Statement.KEEP_CURRENT_RESULT</code>, or
-     *                <code>Statement.CLOSE_ALL_RESULTS</code>
+     * @param current one of the following <code>Statement</code> constants
+     * indicating what should happen to current <code>ResultSet</code> objects
+     * obtained using the method <code>getResultSet</code>:
+     * <code>Statement.CLOSE_CURRENT_RESULT</code>,
+     * <code>Statement.KEEP_CURRENT_RESULT</code>, or
+     * <code>Statement.CLOSE_ALL_RESULTS</code>
      * @return <code>true</code> if the next result is a <code>ResultSet</code>
-     *         object; <code>false</code> if it is an update count or there are no
-     *         more results
-     * @throws java.sql.SQLException if a database access error occurs or the argument
-     *                               supplied is not one of the following:
-     *                               <code>Statement.CLOSE_CURRENT_RESULT</code>,
-     *                               <code>Statement.KEEP_CURRENT_RESULT</code>, or
-     *                               <code>Statement.CLOSE_ALL_RESULTS</code>
+     * object; <code>false</code> if it is an update count or there are no more
+     * results
+     * @throws java.sql.SQLException if a database access error occurs or the
+     * argument supplied is not one of the following:
+     * <code>Statement.CLOSE_CURRENT_RESULT</code>,
+     * <code>Statement.KEEP_CURRENT_RESULT</code>, or
+     * <code>Statement.CLOSE_ALL_RESULTS</code>
      * @see #execute
      * @since 1.4
      */
@@ -619,25 +597,22 @@
     }
 
     /**
-     * Executes the given SQL statement and signals the driver with the
-     * given flag about whether the
-     * auto-generated keys produced by this <code>Statement</code> object
-     * should be made available for retrieval.
+     * Executes the given SQL statement and signals the driver with the given flag
+     * about whether the auto-generated keys produced by this <code>Statement</code>
+     * object should be made available for retrieval.
      *
-     * @param sql               must be an SQL <code>INSERT</code>, <code>UPDATE</code> or
-     *                          <code>DELETE</code> statement or an SQL statement that
-     *                          returns nothing
-     * @param autoGeneratedKeys a flag indicating whether auto-generated keys
-     *                          should be made available for retrieval;
-     *                          one of the following constants:
-     *                          <code>Statement.RETURN_GENERATED_KEYS</code>
-     *                          <code>Statement.NO_GENERATED_KEYS</code>
-     * @return either the row count for <code>INSERT</code>, <code>UPDATE</code>
-     *         or <code>DELETE</code> statements, or <code>0</code> for SQL
-     *         statements that return nothing
+     * @param sql must be an SQL <code>INSERT</code>, <code>UPDATE</code> or
+     * <code>DELETE</code> statement or an SQL statement that returns nothing
+     * @param autoGeneratedKeys a flag indicating whether auto-generated keys should
+     * be made available for retrieval; one of the following constants:
+     * <code>Statement.RETURN_GENERATED_KEYS</code>
+     * <code>Statement.NO_GENERATED_KEYS</code>
+     * @return either the row count for <code>INSERT</code>, <code>UPDATE</code> or
+     * <code>DELETE</code> statements, or <code>0</code> for SQL statements that
+     * return nothing
      * @throws java.sql.SQLException if a database access error occurs, the given
-     *                               SQL statement returns a <code>ResultSet</code> object, or
-     *                               the given constant is not one of those allowed
+     * SQL statement returns a <code>ResultSet</code> object, or the given constant
+     * is not one of those allowed
      * @since 1.4
      */
     public int executeUpdate(final String sql, int autoGeneratedKeys) throws SQLException {
@@ -646,22 +621,21 @@
 
     /**
      * Executes the given SQL statement and signals the driver that the
-     * auto-generated keys indicated in the given array should be made available
-     * for retrieval.  The driver will ignore the array if the SQL statement
-     * is not an <code>INSERT</code> statement.
+     * auto-generated keys indicated in the given array should be made available for
+     * retrieval. The driver will ignore the array if the SQL statement is not an
+     * <code>INSERT</code> statement.
      *
-     * @param sql           an SQL <code>INSERT</code>, <code>UPDATE</code> or
-     *                      <code>DELETE</code> statement or an SQL statement that returns nothing,
-     *                      such as an SQL DDL statement
-     * @param columnIndexes an array of column indexes indicating the columns
-     *                      that should be returned from the inserted row
-     * @return either the row count for <code>INSERT</code>, <code>UPDATE</code>,
-     *         or <code>DELETE</code> statements, or 0 for SQL statements
-     *         that return nothing
+     * @param sql an SQL <code>INSERT</code>, <code>UPDATE</code> or
+     * <code>DELETE</code> statement or an SQL statement that returns nothing, such
+     * as an SQL DDL statement
+     * @param columnIndexes an array of column indexes indicating the columns that
+     * should be returned from the inserted row
+     * @return either the row count for <code>INSERT</code>, <code>UPDATE</code>, or
+     * <code>DELETE</code> statements, or 0 for SQL statements that return nothing
      * @throws java.sql.SQLException if a database access error occurs, the SQL
-     *                               statement returns a <code>ResultSet</code> object, or the
-     *                               second argument supplied to this method is not an <code>int</code> array
-     *                               whose elements are valid column indexes
+     * statement returns a <code>ResultSet</code> object, or the second argument
+     * supplied to this method is not an <code>int</code> array whose elements are
+     * valid column indexes
      * @since 1.4
      */
     public int executeUpdate(final String sql, int columnIndexes[]) throws SQLException {
@@ -670,21 +644,20 @@
 
     /**
      * Executes the given SQL statement and signals the driver that the
-     * auto-generated keys indicated in the given array should be made available
-     * for retrieval.  The driver will ignore the array if the SQL statement
-     * is not an <code>INSERT</code> statement.
+     * auto-generated keys indicated in the given array should be made available for
+     * retrieval. The driver will ignore the array if the SQL statement is not an
+     * <code>INSERT</code> statement.
      *
-     * @param sql         an SQL <code>INSERT</code>, <code>UPDATE</code> or
-     *                    <code>DELETE</code> statement or an SQL statement that returns nothing
+     * @param sql an SQL <code>INSERT</code>, <code>UPDATE</code> or
+     * <code>DELETE</code> statement or an SQL statement that returns nothing
      * @param columnNames an array of the names of the columns that should be
-     *                    returned from the inserted row
-     * @return either the row count for <code>INSERT</code>, <code>UPDATE</code>,
-     *         or <code>DELETE</code> statements, or 0 for SQL statements
-     *         that return nothing
+     * returned from the inserted row
+     * @return either the row count for <code>INSERT</code>, <code>UPDATE</code>, or
+     * <code>DELETE</code> statements, or 0 for SQL statements that return nothing
      * @throws java.sql.SQLException if a database access error occurs, the SQL
-     *                               statement returns a <code>ResultSet</code> object, or the
-     *                               second argument supplied to this method is not a <code>String</code> array
-     *                               whose elements are valid column names
+     * statement returns a <code>ResultSet</code> object, or the second argument
+     * supplied to this method is not a <code>String</code> array whose elements are
+     * valid column names
      * @since 1.4
      */
     public int executeUpdate(final String sql, String columnNames[]) throws SQLException {
@@ -692,37 +665,33 @@
     }
 
     /**
-     * Executes the given SQL statement, which may return multiple results,
-     * and signals the driver that any
-     * auto-generated keys should be made available
-     * for retrieval.  The driver will ignore this signal if the SQL statement
-     * is not an <code>INSERT</code> statement.
+     * Executes the given SQL statement, which may return multiple results, and
+     * signals the driver that any auto-generated keys should be made available for
+     * retrieval. The driver will ignore this signal if the SQL statement is not an
+     * <code>INSERT</code> statement.
      * <p/>
-     * In some (uncommon) situations, a single SQL statement may return
-     * multiple result sets and/or update counts.  Normally you can ignore
-     * this unless you are (1) executing a stored procedure that you know may
-     * return multiple results or (2) you are dynamically executing an
-     * unknown SQL string.
+     * In some (uncommon) situations, a single SQL statement may return multiple
+     * result sets and/or update counts. Normally you can ignore this unless you are
+     * (1) executing a stored procedure that you know may return multiple results or
+     * (2) you are dynamically executing an unknown SQL string.
      * <p/>
      * The <code>execute</code> method executes an SQL statement and indicates the
-     * form of the first result.  You must then use the methods
-     * <code>getResultSet</code> or <code>getUpdateCount</code>
-     * to retrieve the result, and <code>getMoreResults</code> to
-     * move to any subsequent result(s).
+     * form of the first result. You must then use the methods
+     * <code>getResultSet</code> or <code>getUpdateCount</code> to retrieve the
+     * result, and <code>getMoreResults</code> to move to any subsequent result(s).
      *
-     * @param sql               any SQL statement
-     * @param autoGeneratedKeys a constant indicating whether auto-generated
-     *                          keys should be made available for retrieval using the method
-     *                          <code>getGeneratedKeys</code>; one of the following constants:
-     *                          <code>Statement.RETURN_GENERATED_KEYS</code> or
-     *                          <code>Statement.NO_GENERATED_KEYS</code>
+     * @param sql any SQL statement
+     * @param autoGeneratedKeys a constant indicating whether auto-generated keys
+     * should be made available for retrieval using the method
+     * <code>getGeneratedKeys</code>; one of the following constants:
+     * <code>Statement.RETURN_GENERATED_KEYS</code> or
+     * <code>Statement.NO_GENERATED_KEYS</code>
      * @return <code>true</code> if the first result is a <code>ResultSet</code>
-     *         object; <code>false</code> if it is an update count or there are
-     *         no results
+     * object; <code>false</code> if it is an update count or there are no results
      * @throws java.sql.SQLException if a database access error occurs or the second
-     *                               parameter supplied to this method is not
-     *                               <code>Statement.RETURN_GENERATED_KEYS</code> or
-     *                               <code>Statement.NO_GENERATED_KEYS</code>.
+     * parameter supplied to this method is not
+     * <code>Statement.RETURN_GENERATED_KEYS</code> or
+     * <code>Statement.NO_GENERATED_KEYS</code>.
      * @see #getResultSet
      * @see #getUpdateCount
      * @see #getMoreResults
@@ -734,36 +703,32 @@
     }
 
     /**
-     * Executes the given SQL statement, which may return multiple results,
-     * and signals the driver that the
-     * auto-generated keys indicated in the given array should be made available
-     * for retrieval.  This array contains the indexes of the columns in the
-     * target table that contain the auto-generated keys that should be made
-     * available. The driver will ignore the array if the given SQL statement
-     * is not an <code>INSERT</code> statement.
+     * Executes the given SQL statement, which may return multiple results, and
+     * signals the driver that the auto-generated keys indicated in the given array
+     * should be made available for retrieval. This array contains the indexes of
+     * the columns in the target table that contain the auto-generated keys that
+     * should be made available. The driver will ignore the array if the given SQL
+     * statement is not an <code>INSERT</code> statement.
      * <p/>
-     * Under some (uncommon) situations, a single SQL statement may return
-     * multiple result sets and/or update counts.  Normally you can ignore
-     * this unless you are (1) executing a stored procedure that you know may
-     * return multiple results or (2) you are dynamically executing an
-     * unknown SQL string.
+     * Under some (uncommon) situations, a single SQL statement may return multiple
+     * result sets and/or update counts. Normally you can ignore this unless you are
+     * (1) executing a stored procedure that you know may return multiple results or
+     * (2) you are dynamically executing an unknown SQL string.
      * <p/>
      * The <code>execute</code> method executes an SQL statement and indicates the
-     * form of the first result.  You must then use the methods
-     * <code>getResultSet</code> or <code>getUpdateCount</code>
-     * to retrieve the result, and <code>getMoreResults</code> to
-     * move to any subsequent result(s).
+     * form of the first result. You must then use the methods
+     * <code>getResultSet</code> or <code>getUpdateCount</code> to retrieve the
+     * result, and <code>getMoreResults</code> to move to any subsequent result(s).
      *
-     * @param sql           any SQL statement
-     * @param columnIndexes an array of the indexes of the columns in the
-     *                      inserted row that should be  made available for retrieval by a
-     *                      call to the method <code>getGeneratedKeys</code>
+     * @param sql any SQL statement
+     * @param columnIndexes an array of the indexes of the columns in the inserted
+     * row that should be made available for retrieval by a call to the method
+     * <code>getGeneratedKeys</code>
      * @return <code>true</code> if the first result is a <code>ResultSet</code>
-     *         object; <code>false</code> if it is an update count or there
-     *         are no results
+     * object; <code>false</code> if it is an update count or there are no results
      * @throws java.sql.SQLException if a database access error occurs or the
-     *                               elements in the <code>int</code> array passed to this method
-     *                               are not valid column indexes
+     * elements in the <code>int</code> array passed to this method are not valid
+     * column indexes
      * @see #getResultSet
      * @see #getUpdateCount
      * @see #getMoreResults
@@ -774,36 +739,33 @@
     }
 
     /**
-     * Executes the given SQL statement, which may return multiple results,
-     * and signals the driver that the
-     * auto-generated keys indicated in the given array should be made available
-     * for retrieval. This array contains the names of the columns in the
-     * target table that contain the auto-generated keys that should be made
-     * available. The driver will ignore the array if the given SQL statement
-     * is not an <code>INSERT</code> statement.
+     * Executes the given SQL statement, which may return multiple results, and
+     * signals the driver that the auto-generated keys indicated in the given array
+     * should be made available for retrieval. This array contains the names of the
+     * columns in the target table that contain the auto-generated keys that should
+     * be made available. The driver will ignore the array if the given SQL
+     * statement is not an <code>INSERT</code> statement.
      * <p/>
-     * In some (uncommon) situations, a single SQL statement may return
-     * multiple result sets and/or update counts.  Normally you can ignore
-     * this unless you are (1) executing a stored procedure that you know may
-     * return multiple results or (2) you are dynamically executing an
-     * unknown SQL string.
+     * In some (uncommon) situations, a single SQL statement may return multiple
+     * result sets and/or update counts. Normally you can ignore this unless you are
+     * (1) executing a stored procedure that you know may return multiple results or
+     * (2) you are dynamically executing an unknown SQL string.
      * <p/>
      * The <code>execute</code> method executes an SQL statement and indicates the
-     * form of the first result.  You must then use the methods
-     * <code>getResultSet</code> or <code>getUpdateCount</code>
-     * to retrieve the result, and <code>getMoreResults</code> to
-     * move to any subsequent result(s).
+     * form of the first result. You must then use the methods
+     * <code>getResultSet</code> or <code>getUpdateCount</code> to retrieve the
+     * result, and <code>getMoreResults</code> to move to any subsequent result(s).
      *
-     * @param sql         any SQL statement
-     * @param columnNames an array of the names of the columns in the inserted
-     *                    row that should be made available for retrieval by a call to the
-     *                    method <code>getGeneratedKeys</code>
+     * @param sql any SQL statement
+     * @param columnNames an array of the names of the columns in the inserted row
+     * that should be made available for retrieval by a call to the method
+     * <code>getGeneratedKeys</code>
      * @return <code>true</code> if the next result is a <code>ResultSet</code>
-     *         object; <code>false</code> if it is an update count or there
-     *         are no more results
+     * object; <code>false</code> if it is an update count or there are no more
+     * results
      * @throws java.sql.SQLException if a database access error occurs or the
-     *                               elements of the <code>String</code> array passed to this
-     *                               method are not valid column names
+     * elements of the <code>String</code> array passed to this method are not valid
+     * column names
      * @see #getResultSet
      * @see #getUpdateCount
      * @see #getMoreResults
@@ -819,7 +781,7 @@
      * generated by this <code>Statement</code> object.
      *
      * @return either <code>ResultSet.HOLD_CURSORS_OVER_COMMIT</code> or
-     *         <code>ResultSet.CLOSE_CURSORS_AT_COMMIT</code>
+     * <code>ResultSet.CLOSE_CURSORS_AT_COMMIT</code>
      * @throws java.sql.SQLException if a database access error occurs
      * @since 1.4
      */
@@ -865,8 +827,7 @@
     public boolean isCloseOnCompletion() throws SQLException {
         if (DataSourceObjectBuilder.isJDBC41()) {
             try {
-                return (Boolean) executor.invokeMethod(jdbcStatement,
-                        "isCloseOnCompletion", null);
+                return (Boolean) executor.invokeMethod(jdbcStatement, "isCloseOnCompletion", null);
             } catch (ResourceException ex) {
                 _logger.log(Level.SEVERE, "jdbc.ex_stmt_wrapper", ex);
                 throw new SQLException(ex);
diff --git a/appserver/jdbc/jdbc-ra/jdbc-core/src/main/java/com/sun/gjc/spi/base/datastructure/Cache.java b/appserver/jdbc/jdbc-ra/jdbc-core/src/main/java/com/sun/gjc/spi/base/datastructure/Cache.java
index 2611b26..71c3313 100644
--- a/appserver/jdbc/jdbc-ra/jdbc-core/src/main/java/com/sun/gjc/spi/base/datastructure/Cache.java
+++ b/appserver/jdbc/jdbc-ra/jdbc-core/src/main/java/com/sun/gjc/spi/base/datastructure/Cache.java
@@ -25,64 +25,63 @@
 public interface Cache {
 
     /**
-     * Check if an entry is found for this key object. If found, the entry is
-     * put in the result object and back into the list.
+     * Check if an entry is found for this key object. If found, the entry is put in
+     * the result object and back into the list.
      *
      * @param key whose mapping entry is to be checked.
-     * @return result object that contains the key with the entry if not busy
-     * or null when
-     * (1) object not found in cache
-     * (2) object found but is busy
+     * @return result object that contains the key with the entry if not busy or
+     * null when (1) object not found in cache (2) object found but is busy
      */
-    public Object checkAndUpdateCache(CacheObjectKey key);
+    Object checkAndUpdateCache(CacheObjectKey key);
 
     /**
      * Add key and entry value into the cache.
+     *
      * @param key that contains the sql string and its type (PS/CS)
-     * @param entry that is the wrapper of PreparedStatement or
-     * CallableStatement
+     * @param entry that is the wrapper of PreparedStatement or CallableStatement
      * @param force If existing key is to be overwritten
      */
-    public void addToCache(CacheObjectKey key, Object entry, boolean force);
+    void addToCache(CacheObjectKey key, Object entry, boolean force);
 
     /**
      * Clear statement cache
      */
-    public void clearCache();
+    void clearCache();
 
     /**
-     * Remove all statements stored in the statement cache after closing
-     * the statement objects. Used when the statement cache size exceeds
-     * user defined maximum cache size.
+     * Remove all statements stored in the statement cache after closing the
+     * statement objects. Used when the statement cache size exceeds user defined
+     * maximum cache size.
      */
-    public void purge();
+    void purge();
 
     /**
-     * Closing all statements in statement cache and flush the statement cache
-     * of all the statements. Used when a physical connection to the underlying
+     * Closing all statements in statement cache and flush the statement cache of
+     * all the statements. Used when a physical connection to the underlying
      * resource manager is destroyed.
      */
-    public void flushCache();
+    void flushCache();
 
     /**
      * Get the size of statement cache
+     *
      * @return int statement cache size
      */
-    public int getSize();
+    int getSize();
 
     /**
      * Check if the statement cache is synchronized.
+     *
      * @return boolean synchronized flag.
      */
-    public boolean isSynchronized();
+    boolean isSynchronized();
 
     /**
-     * Remove the specified entry stored in the statement cache after closing
-     * the statement object associated with this entry. Used when statement is
-     * being reclaimed and is being used for the subsequent requests from the
-     * application.
+     * Remove the specified entry stored in the statement cache after closing the
+     * statement object associated with this entry. Used when statement is being
+     * reclaimed and is being used for the subsequent requests from the application.
      *
      * @param entry
      */
-    public void purge(Object entry);
+    void purge(Object entry);
 }
diff --git a/appserver/jdbc/jdbc-ra/jdbc-core/src/main/java/com/sun/gjc/spi/base/datastructure/CacheFactory.java b/appserver/jdbc/jdbc-ra/jdbc-core/src/main/java/com/sun/gjc/spi/base/datastructure/CacheFactory.java
index 51acc7f..6cecdc3 100644
--- a/appserver/jdbc/jdbc-ra/jdbc-core/src/main/java/com/sun/gjc/spi/base/datastructure/CacheFactory.java
+++ b/appserver/jdbc/jdbc-ra/jdbc-core/src/main/java/com/sun/gjc/spi/base/datastructure/CacheFactory.java
@@ -16,92 +16,85 @@
 
 package com.sun.gjc.spi.base.datastructure;
 
+import static java.util.logging.Level.FINE;
+import static java.util.logging.Level.WARNING;
+
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.util.logging.Logger;
+
+import org.glassfish.resourcebase.resources.api.PoolInfo;
+
 import com.sun.enterprise.util.i18n.StringManager;
 import com.sun.gjc.common.DataSourceObjectBuilder;
 import com.sun.logging.LogDomains;
-import org.glassfish.resourcebase.resources.api.PoolInfo;
 
 import jakarta.resource.ResourceException;
-import java.lang.reflect.Constructor;
-import java.security.AccessController;
-import java.security.PrivilegedAction;
-import java.util.logging.Level;
-import java.util.logging.Logger;
 
 /**
- * Creates an appropriate statement cache datastructure used in the
- * Resource Adapter.
+ * Creates an appropriate statement cache datastructure used in the Resource
+ * Adapter.
  *
  * @author Shalini M
  */
 public class CacheFactory {
-    protected final static Logger _logger =
-            LogDomains.getLogger(CacheFactory.class, LogDomains.RSR_LOGGER);
+    protected final static Logger _logger = LogDomains.getLogger(CacheFactory.class, LogDomains.RSR_LOGGER);
 
-    protected final static StringManager localStrings =
-            StringManager.getManager(DataSourceObjectBuilder.class);
+    protected final static StringManager localStrings = StringManager.getManager(DataSourceObjectBuilder.class);
 
-    public static Cache getDataStructure(PoolInfo poolInfo, String cacheType,
-            int maxSize) throws ResourceException {
+    public static Cache getDataStructure(PoolInfo poolInfo, String cacheType, int maxSize) throws ResourceException {
         Cache stmtCacheStructure;
 
-        if(cacheType == null || cacheType.trim().equals("")) {
+        if (cacheType == null || cacheType.trim().equals("")) {
             debug("Initializing LRU Cache Implementation");
             stmtCacheStructure = new LRUCacheImpl(poolInfo, maxSize);
-        } else if(cacheType.equals("FIXED")) {
+        } else if (cacheType.equals("FIXED")) {
             debug("Initializing FIXED Cache Implementation");
             stmtCacheStructure = new FIXEDCacheImpl(poolInfo, maxSize);
         } else { // consider the value of cacheType as a className
-            stmtCacheStructure = initCustomCacheStructurePrivileged(cacheType,
-                    maxSize);
+            stmtCacheStructure = initCustomCacheStructurePrivileged(cacheType, maxSize);
         }
-        if(!stmtCacheStructure.isSynchronized()) {
+
+        if (!stmtCacheStructure.isSynchronized()) {
             return new SynchronizedCache(stmtCacheStructure);
         }
+
         return stmtCacheStructure;
     }
 
-    private static Cache initCustomCacheStructurePrivileged(
-            final String className, final int cacheSize) throws ResourceException {
-        Object result = AccessController.doPrivileged(new PrivilegedAction() {
+    private static Cache initCustomCacheStructurePrivileged(final String className, final int cacheSize) throws ResourceException {
+        Object result = AccessController.doPrivileged(new PrivilegedAction<>() {
             public Object run() {
 
                 Object result = null;
                 try {
                     result = initializeCacheStructure(className, cacheSize);
                 } catch (Exception e) {
-                    _logger.log(Level.WARNING, localStrings.getString(
-                            "jdbc.statement-cache.datastructure.init.failure",
-                            className));
-                    _logger.log(Level.WARNING, localStrings.getString(
-                            "jdbc.statement-cache.datastructure.init.failure.exception",
-                            e));
+                    _logger.log(WARNING,
+                            localStrings.getString("jdbc.statement-cache.datastructure.init.failure", className));
+                    _logger.log(WARNING,
+                            localStrings.getString("jdbc.statement-cache.datastructure.init.failure.exception", e));
                 }
+
                 return result;
             }
         });
+
         if (result != null) {
             return (Cache) result;
-        } else {
-            throw new ResourceException("Unable to initalize custom DataStructure " +
-                    "for Statement Cahe : " + className);
         }
+
+        throw new ResourceException("Unable to initalize custom DataStructure " + "for Statement Cahe : " + className);
     }
 
-    private static Cache initializeCacheStructure(String className,
-            int maxSize) throws Exception {
-        Cache ds;
-        Object[] constructorParameters = new Object[]{maxSize};
+    private static Cache initializeCacheStructure(String className, int maxSize) throws Exception {
+        Class<?> class1 = Class.forName(className);
 
-        Class class1 = Class.forName(className);
-        Constructor constructor = class1.getConstructor(class1, Integer.class);
-        ds = (Cache) constructor.newInstance(constructorParameters);
-        return ds;
+        return (Cache) class1.getConstructor(class1, Integer.class)
+                             .newInstance(new Object[] { maxSize });
     }
 
     private static void debug(String debugStatement) {
-        if(_logger.isLoggable(Level.FINE)) {
-            _logger.log(Level.FINE, debugStatement);
-        }
+        _logger.log(FINE, debugStatement);
     }
 }
diff --git a/appserver/jdbc/jdbc-ra/jdbc-core/src/main/java/com/sun/gjc/spi/base/datastructure/FIXEDCacheImpl.java b/appserver/jdbc/jdbc-ra/jdbc-core/src/main/java/com/sun/gjc/spi/base/datastructure/FIXEDCacheImpl.java
index 5894e3c..20696a1 100644
--- a/appserver/jdbc/jdbc-ra/jdbc-core/src/main/java/com/sun/gjc/spi/base/datastructure/FIXEDCacheImpl.java
+++ b/appserver/jdbc/jdbc-ra/jdbc-core/src/main/java/com/sun/gjc/spi/base/datastructure/FIXEDCacheImpl.java
@@ -16,9 +16,10 @@
 
 package com.sun.gjc.spi.base.datastructure;
 
+import org.glassfish.resourcebase.resources.api.PoolInfo;
+
 import com.sun.gjc.spi.base.CacheObjectKey;
 import com.sun.gjc.spi.base.PreparedStatementWrapper;
-import org.glassfish.resourcebase.resources.api.PoolInfo;
 
 /**
  * This ia a FIXED size cache implementation.
diff --git a/appserver/jdbc/jdbc-ra/jdbc-core/src/main/java/com/sun/gjc/spi/base/datastructure/LRUCacheImpl.java b/appserver/jdbc/jdbc-ra/jdbc-core/src/main/java/com/sun/gjc/spi/base/datastructure/LRUCacheImpl.java
index f986477..0ef4a89 100644
--- a/appserver/jdbc/jdbc-ra/jdbc-core/src/main/java/com/sun/gjc/spi/base/datastructure/LRUCacheImpl.java
+++ b/appserver/jdbc/jdbc-ra/jdbc-core/src/main/java/com/sun/gjc/spi/base/datastructure/LRUCacheImpl.java
@@ -16,12 +16,6 @@
 
 package com.sun.gjc.spi.base.datastructure;
 
-import com.sun.gjc.monitoring.StatementCacheProbeProvider;
-import com.sun.gjc.spi.base.CacheObjectKey;
-import com.sun.gjc.spi.base.PreparedStatementWrapper;
-import com.sun.logging.LogDomains;
-import org.glassfish.resourcebase.resources.api.PoolInfo;
-
 import java.sql.SQLException;
 import java.util.Iterator;
 import java.util.LinkedHashMap;
@@ -30,81 +24,92 @@
 import java.util.logging.Level;
 import java.util.logging.Logger;
 
+import org.glassfish.resourcebase.resources.api.PoolInfo;
+
+import com.sun.gjc.monitoring.StatementCacheProbeProvider;
+import com.sun.gjc.spi.base.CacheObjectKey;
+import com.sun.gjc.spi.base.PreparedStatementWrapper;
+import com.sun.logging.LogDomains;
+
 /**
  *
  * @author Shalini M
  */
 public class LRUCacheImpl implements Cache {
 
+    protected final static Logger _logger = LogDomains.getLogger(LRUCacheImpl.class, LogDomains.RSR_LOGGER);
+
     /**
      * Stores the objects for statement caching
      */
     private Map<CacheObjectKey, CacheEntry> list;
+
     /**
      * Size of the cache
      */
-    private int maxSize ;
-    protected final static Logger _logger;
-    private StatementCacheProbeProvider probeProvider = null;
+    private int maxSize;
+    private StatementCacheProbeProvider probeProvider;
     private PoolInfo poolInfo;
 
-    static {
-        _logger = LogDomains.getLogger(LRUCacheImpl.class, LogDomains.RSR_LOGGER);
-    }
 
-    public LRUCacheImpl(PoolInfo poolInfo, int maxSize){
+    public LRUCacheImpl(PoolInfo poolInfo, int maxSize) {
         this.maxSize = maxSize;
         this.poolInfo = poolInfo;
         list = new LinkedHashMap<CacheObjectKey, CacheEntry>();
+
         try {
             probeProvider = new StatementCacheProbeProvider();
-        } catch(Exception ex) {
-            //TODO logger
+        } catch (Exception ex) {
+            // TODO logger
         }
     }
 
     /**
-     * Check if an entry is found for this key object. If found, the entry is
-     * put in the result object and back into the list.
+     * Check if an entry is found for this key object. If found, the entry is put in
+     * the result object and back into the list.
      *
      * @param key key whose mapping entry is to be checked.
-     * @return result object that contains the key with the entry if not
-     * null when
+     * @return result object that contains the key with the entry if not null when
      * (1) object not found in cache
      */
     public Object checkAndUpdateCache(CacheObjectKey key) {
         Object result = null;
+
         CacheEntry entry = list.get(key);
-        if(entry != null) {
-            //Cache hit
+        if (entry != null) {
+            // Cache hit
             result = entry.entryObj;
-            if(_logger.isLoggable(Level.FINEST)) {
-                _logger.finest("Cache Hit");
-            }
-            //TODO-SC Busy cache hits?
-            probeProvider.statementCacheHitEvent(poolInfo.getName(), poolInfo.getApplicationName(), poolInfo.getModuleName());
+            _logger.finest("Cache Hit");
+
+            // TODO-SC Busy cache hits?
+            probeProvider.statementCacheHitEvent(
+                poolInfo.getName(),
+                poolInfo.getApplicationName(),
+                poolInfo.getModuleName());
         } else {
-            //Cache miss
-            if(_logger.isLoggable(Level.FINEST)) {
-                _logger.finest("Cache Miss");
-            }
-            probeProvider.statementCacheMissEvent(poolInfo.getName(), poolInfo.getApplicationName(), poolInfo.getModuleName());
+            // Cache miss
+            _logger.finest("Cache Miss");
+            probeProvider.statementCacheMissEvent(
+                poolInfo.getName(),
+                poolInfo.getApplicationName(),
+                poolInfo.getModuleName());
         }
+
         return result;
     }
 
     /**
      * Add the key and entry value into the cache.
+     *
      * @param key key that contains the sql string and its type (PS/CS)
-     * @param o entry that is the wrapper of PreparedStatement or
-     * CallableStatement
+     * @param o entry that is the wrapper of PreparedStatement or CallableStatement
      * @param force If the already existing key is to be overwritten
      */
     public void addToCache(CacheObjectKey key, Object o, boolean force) {
-        if(force || !list.containsKey(key)){
-            //overwrite or if not already found in cache
+        if (force || !list.containsKey(key)) {
+            // overwrite or if not already found in cache
 
-            if(list.size() >= maxSize){
+            if (list.size() >= maxSize) {
                 purge();
             }
             CacheEntry entry = new CacheEntry(o);
@@ -115,15 +120,13 @@
     /**
      * Clears the statement cache
      */
-    public void clearCache(){
-        if (_logger.isLoggable(Level.FINE)) {
-            _logger.fine("clearing objects in cache");
-        }
-       list.clear();
+    public void clearCache() {
+        _logger.fine("clearing objects in cache");
+        list.clear();
     }
 
     public void flushCache() {
-        while(list.size()!=0){
+        while (list.size() != 0) {
             purge();
         }
     }
@@ -131,20 +134,18 @@
     public void purge() {
         Set<Map.Entry<CacheObjectKey, CacheEntry>> entrySet = list.entrySet();
         Iterator entrySetIterator = entrySet.iterator();
-//        Iterator keyIterator = list.keySet().iterator();
-        while(entrySetIterator.hasNext()){
-//            CacheObjectKey key = (CacheObjectKey) entrySetIterator.next();
-            Map.Entry<CacheObjectKey, CacheEntry> entryTuple =
-                    (Map.Entry<CacheObjectKey, CacheEntry>) entrySetIterator.next();
+        while (entrySetIterator.hasNext()) {
+            Map.Entry<CacheObjectKey, CacheEntry> entryTuple = (Map.Entry<CacheObjectKey, CacheEntry>) entrySetIterator
+                    .next();
             CacheEntry entry = entryTuple.getValue();
-            try{
-                //TODO Move to a more generic Contract and invoke close()
-                //PreparedStatementWrapper could implement the contract instead
-                PreparedStatementWrapper ps = (PreparedStatementWrapper)entry.entryObj;
+            try {
+                // TODO Move to a more generic Contract and invoke close()
+                // PreparedStatementWrapper could implement the contract instead
+                PreparedStatementWrapper ps = (PreparedStatementWrapper) entry.entryObj;
                 ps.setCached(false);
                 ps.close();
-            }catch(SQLException e){
-                //ignore
+            } catch (SQLException e) {
+                // ignore
             }
             entrySetIterator.remove();
             break;
@@ -156,27 +157,23 @@
         PreparedStatementWrapper tmpPS = (PreparedStatementWrapper) obj;
         Set<Map.Entry<CacheObjectKey, CacheEntry>> entrySet = list.entrySet();
         Iterator entrySetIterator = entrySet.iterator();
-//        Iterator keyIterator = list.keySet().iterator();
-        while(entrySetIterator.hasNext()){
-//            CacheObjectKey key = (CacheObjectKey)keyIterator.next();
-//            CacheEntry entry = list.get(key);
-            Map.Entry<CacheObjectKey, CacheEntry> entryTuple =
-                    (Map.Entry<CacheObjectKey, CacheEntry>) entrySetIterator.next();
+
+        while (entrySetIterator.hasNext()) {
+            Map.Entry<CacheObjectKey, CacheEntry> entryTuple = (Map.Entry<CacheObjectKey, CacheEntry>) entrySetIterator
+                    .next();
             CacheEntry entry = entryTuple.getValue();
-            try{
-                //TODO Move to a more generic Contract and invoke close()
-                //PreparedStatementWrapper could implement the contract instead
-                PreparedStatementWrapper ps = (PreparedStatementWrapper)entry.entryObj;
-                if(ps.equals(tmpPS)) {
-                    //Found the entry in the cache. Remove this entry.
-                    if(_logger.isLoggable(Level.FINEST)) {
-                        _logger.log(Level.FINEST, "Purging an entry from cache");
-                    }
+            try {
+                // TODO Move to a more generic Contract and invoke close()
+                // PreparedStatementWrapper could implement the contract instead
+                PreparedStatementWrapper ps = (PreparedStatementWrapper) entry.entryObj;
+                if (ps.equals(tmpPS)) {
+                    // Found the entry in the cache. Remove this entry.
+                    _logger.log(Level.FINEST, "Purging an entry from cache");
                     ps.setCached(false);
                     ps.close();
                 }
-            }catch(SQLException e){
-                //ignore
+            } catch (SQLException e) {
+                // ignore
             }
             entrySetIterator.remove();
             break;
@@ -185,10 +182,11 @@
 
     /**
      * Returns the number of entries in the statement cache
+     *
      * @return has integer value
      */
     public int getSize() {
-       return list.size();
+        return list.size();
     }
 
     public int getMaxSize() {
@@ -196,26 +194,17 @@
     }
 
     /**
-     * Cache object that has an entry. This is used to put inside the
-     * statement cache.
+     * Cache object that has an entry. This is used to put inside the statement
+     * cache.
      */
-    public static class CacheEntry{
+    public static class CacheEntry {
         private Object entryObj;
 
-        public CacheEntry(Object o){
+        public CacheEntry(Object o) {
             this.entryObj = o;
         }
     }
 
-    /*public Set getObjects(){
-        //TODO-SC-DEFER can the set be "type-safe"
-        Set set = new HashSet();
-        for(CacheEntry entry : list.values()){
-            set.add(entry.entryObj);
-        }
-        return set;
-    }*/
-
     public boolean isSynchronized() {
         return false;
     }
diff --git a/appserver/jdbc/jdbc-ra/jdbc-core/src/main/java/com/sun/gjc/util/MethodExecutor.java b/appserver/jdbc/jdbc-ra/jdbc-core/src/main/java/com/sun/gjc/util/MethodExecutor.java
index 842e247..a9c2836 100644
--- a/appserver/jdbc/jdbc-ra/jdbc-core/src/main/java/com/sun/gjc/util/MethodExecutor.java
+++ b/appserver/jdbc/jdbc-ra/jdbc-core/src/main/java/com/sun/gjc/util/MethodExecutor.java
@@ -16,52 +16,52 @@
 
 package com.sun.gjc.util;
 
-import com.sun.enterprise.util.i18n.StringManager;
-import com.sun.gjc.common.DataSourceObjectBuilder;
-import com.sun.logging.LogDomains;
+import static java.util.logging.Level.FINEST;
 
-import jakarta.resource.ResourceException;
+import java.io.IOException;
+import java.io.Serializable;
+import java.io.StringBufferInputStream;
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
 import java.security.AccessController;
 import java.security.PrivilegedAction;
 import java.security.PrivilegedActionException;
 import java.security.PrivilegedExceptionAction;
-import java.util.Vector;
+import java.util.Enumeration;
 import java.util.Properties;
+import java.util.Vector;
 import java.util.logging.Level;
 import java.util.logging.Logger;
 
+import com.sun.enterprise.util.i18n.StringManager;
+import com.sun.gjc.common.DataSourceObjectBuilder;
+import com.sun.logging.LogDomains;
+
+import jakarta.resource.ResourceException;
+
 /**
  * Execute the methods based on the parameters.
  *
  * @author Binod P.G
  * @version 1.0, 02/07/23
  */
-public class MethodExecutor implements java.io.Serializable {
+public class MethodExecutor implements Serializable {
 
-    private static Logger _logger;
+    private static final long serialVersionUID = 1L;
 
-    static {
-        _logger = LogDomains.getLogger(MethodExecutor.class, LogDomains.RSR_LOGGER);
-    }
-
-    private boolean debug = false;
+    private static Logger _logger = LogDomains.getLogger(MethodExecutor.class, LogDomains.RSR_LOGGER);
+    private static StringManager sm = StringManager.getManager(DataSourceObjectBuilder.class);
 
     private final static String newline = System.getProperty("line.separator");
 
-    private static StringManager sm = StringManager.getManager(
-            DataSourceObjectBuilder.class);
-
     /**
      * Exceute a simple set Method.
      *
-     * @param value  Value to be set.
+     * @param value Value to be set.
      * @param method <code>Method</code> object.
-     * @param obj    Object on which the method to be executed.
-     * @throws <code>ResourceException</code>,
-     *          in case of the mismatch of parameter values or
-     *          a security violation.
+     * @param obj Object on which the method to be executed.
+     * @throws <code>ResourceException</code>, in case of the mismatch of parameter
+     * values or a security violation.
      */
     public void runJavaBeanMethod(String value, Method method, Object obj) throws ResourceException {
         if (value == null || value.trim().equals("")) {
@@ -74,29 +74,26 @@
             values[0] = convertType(parameters[0], value);
 
             final ResourceException[] exception = new ResourceException[1];
-            AccessController
-                .doPrivileged(new PrivilegedAction() {
-                    public Object run() {
-                        try {
-                            method.setAccessible(true);
-                            method.invoke(obj, values);
-                        } catch (IllegalAccessException | InvocationTargetException | SecurityException iae) {
-                            _logger.log(Level.SEVERE, "jdbc.exc_jb_val", value);
-                            _logger.log(Level.SEVERE, "", iae);
-                            String msg = sm.getString("me.access_denied",
-                                method.getName());
-                            exception[0] = new ResourceException(msg);
-                        } catch (IllegalArgumentException ie) {
-                            _logger.log(Level.SEVERE, "jdbc.exc_jb_val", value);
-                            _logger.log(Level.SEVERE, "", ie);
-                            String msg = sm
-                                .getString("me.illegal_args", method.getName());
-                            exception[0] = new ResourceException(msg);
-                        }
-                        return null;
+            AccessController.doPrivileged(new PrivilegedAction() {
+                public Object run() {
+                    try {
+                        method.setAccessible(true);
+                        method.invoke(obj, values);
+                    } catch (IllegalAccessException | InvocationTargetException | SecurityException iae) {
+                        _logger.log(Level.SEVERE, "jdbc.exc_jb_val", value);
+                        _logger.log(Level.SEVERE, "", iae);
+                        String msg = sm.getString("me.access_denied", method.getName());
+                        exception[0] = new ResourceException(msg);
+                    } catch (IllegalArgumentException ie) {
+                        _logger.log(Level.SEVERE, "jdbc.exc_jb_val", value);
+                        _logger.log(Level.SEVERE, "", ie);
+                        String msg = sm.getString("me.illegal_args", method.getName());
+                        exception[0] = new ResourceException(msg);
                     }
-                });
-            if( exception[0] != null){
+                    return null;
+                }
+            });
+            if (exception[0] != null) {
                 throw exception[0];
             }
         }
@@ -106,28 +103,27 @@
      * Executes the method.
      *
      * @param method <code>Method</code> object.
-     * @param obj    Object on which the method to be executed.
+     * @param obj Object on which the method to be executed.
      * @param values Parameter values for executing the method.
-     * @throws <code>ResourceException</code>,
-     *          in case of the mismatch of parameter values or
-     *          a security violation.
+     * @throws <code>ResourceException</code>, in case of the mismatch of parameter
+     * values or a security violation.
      */
     public void runMethod(Method method, Object obj, Vector values) throws ResourceException {
-            Class[] parameters = method.getParameterTypes();
-            if (values.size() != parameters.length) {
-                return;
+        Class[] parameters = method.getParameterTypes();
+        if (values.size() != parameters.length) {
+            return;
+        }
+        Object[] actualValues = new Object[parameters.length];
+        for (int i = 0; i < parameters.length; i++) {
+            String val = (String) values.get(i);
+            if (val.trim().equals("NULL")) {
+                actualValues[i] = null;
+            } else {
+                actualValues[i] = convertType(parameters[i], val);
             }
-            Object[] actualValues = new Object[parameters.length];
-            for (int i = 0; i < parameters.length; i++) {
-                String val = (String) values.get(i);
-                if (val.trim().equals("NULL")) {
-                    actualValues[i] = null;
-                } else {
-                    actualValues[i] = convertType(parameters[i], val);
-                }
-            }
+        }
         final ResourceException[] exception = new ResourceException[1];
-         AccessController.doPrivileged(new PrivilegedAction() {
+        AccessController.doPrivileged(new PrivilegedAction() {
             public Object run() {
                 try {
                     method.setAccessible(true);
@@ -135,20 +131,18 @@
                 } catch (IllegalAccessException | InvocationTargetException | SecurityException iae) {
                     _logger.log(Level.SEVERE, "jdbc.exc_jb_val", values);
                     _logger.log(Level.SEVERE, "", iae);
-                    String msg = sm
-                        .getString("me.access_denied", method.getName());
+                    String msg = sm.getString("me.access_denied", method.getName());
                     exception[0] = new ResourceException(msg);
                 } catch (IllegalArgumentException ie) {
                     _logger.log(Level.SEVERE, "jdbc.exc_jb_val", values);
                     _logger.log(Level.SEVERE, "", ie);
-                    String msg = sm
-                        .getString("me.illegal_args", method.getName());
+                    String msg = sm.getString("me.illegal_args", method.getName());
                     exception[0] = new ResourceException(msg);
                 }
                 return null;
             }
         });
-        if( exception[0] != null){
+        if (exception[0] != null) {
             throw exception[0];
         }
     }
@@ -156,12 +150,11 @@
     /**
      * Converts the type from String to the Class type.
      *
-     * @param type      Class name to which the conversion is required.
+     * @param type Class name to which the conversion is required.
      * @param parameter String value to be converted.
      * @return Converted value.
-     * @throws <code>ResourceException</code>,
-     *          in case of the mismatch of parameter values or
-     *          a security violation.
+     * @throws <code>ResourceException</code>, in case of the mismatch of parameter
+     * values or a security violation.
      */
     private Object convertType(Class type, String parameter) throws ResourceException {
         try {
@@ -208,7 +201,8 @@
 
             if (typeName.equals("java.util.Properties")) {
                 Properties p = stringToProperties(parameter);
-                if (p!= null) return p;
+                if (p != null)
+                    return p;
             }
 
             return parameter;
@@ -219,10 +213,9 @@
         }
     }
 
-    public Object invokeMethod(Object object, String methodName,
-            Class<?>[] valueTypes, Object... values) throws ResourceException {
+    public Object invokeMethod(Object object, String methodName, Class<?>[] valueTypes, Object... values) throws ResourceException {
         Object returnValue = null;
-        Method actualMethod ;
+        Method actualMethod;
         try {
             actualMethod = object.getClass().getMethod(methodName, valueTypes);
         } catch (NoSuchMethodException ex) {
@@ -232,15 +225,14 @@
         }
         if (actualMethod != null) {
             try {
-                returnValue = AccessController.doPrivileged(
-                    (PrivilegedExceptionAction<Object>) () -> {
-                            actualMethod.setAccessible(true);
-                            return actualMethod.invoke(object, values);
-                    });
+                returnValue = AccessController.doPrivileged((PrivilegedExceptionAction<Object>) () -> {
+                    actualMethod.setAccessible(true);
+                    return actualMethod.invoke(object, values);
+                });
             } catch (PrivilegedActionException e) {
-                if(e.getException() != null){
+                if (e.getException() != null) {
                     throw new ResourceException(e.getException());
-                }else{
+                } else {
                     throw new ResourceException(e);
                 }
             }
@@ -248,44 +240,43 @@
         return returnValue;
     }
 
-    private Properties stringToProperties(String parameter)
-    {
-         if (parameter == null) return null;
-         String s = parameter.trim();
-         if (!((s.startsWith("(") && s.endsWith(")")))) {
-            return null; // not a "( .... )" syntax
-         }
-         s = s.substring(1,s.length()-1);
-         s = s.replaceAll("(?<!\\\\),",newline); // , -> \n
-         s = s.replaceAll("\\\\,",",");  // escape-"," -> ,
-
-         Properties p = new Properties();
-         Properties prop = new Properties();
-         try {
-            p.load(new java.io.StringBufferInputStream(s));
-         } catch (java.io.IOException ex) {
-            if (_logger.isLoggable(Level.FINEST)) {
-               _logger.log(Level.FINEST, "Parsing string to properties: {0}", ex.getMessage());
-            }
+    private Properties stringToProperties(String parameter) {
+        if (parameter == null)
             return null;
-         }
-         // cleanup trailing whitespace in value
-         for (java.util.Enumeration propKeys = p.propertyNames();
-               propKeys.hasMoreElements();) {
-             String tmpKey = (String)propKeys.nextElement();
-             String tmpValue = p.getProperty(tmpKey);
-             // Trim spaces
-             tmpValue = tmpValue.trim();
-             // Quoted string.
-             if (tmpValue.length() > 1 && tmpValue.startsWith("\"")
-                     && tmpValue.endsWith("\"")) {
-                tmpValue = tmpValue.substring(1,tmpValue.length()-1);
-             }
-             prop.put(tmpKey, tmpValue);
-         }
-         if (_logger.isLoggable(Level.FINEST)) {
-               _logger.log(Level.FINEST, "Parsing string to properties: {0}size:{1}", new Object[]{prop, prop.size()});
-         }
-         return prop;
+        String s = parameter.trim();
+        if (!((s.startsWith("(") && s.endsWith(")")))) {
+            return null; // not a "( .... )" syntax
+        }
+        s = s.substring(1, s.length() - 1);
+        s = s.replaceAll("(?<!\\\\),", newline); // , -> \n
+        s = s.replaceAll("\\\\,", ","); // escape-"," -> ,
+
+        Properties p = new Properties();
+        Properties prop = new Properties();
+        try {
+            p.load(new StringBufferInputStream(s));
+        } catch (IOException ex) {
+            _logger.log(FINEST, "Parsing string to properties: {0}", ex.getMessage());
+            return null;
+        }
+
+        // cleanup trailing whitespace in value
+        for (Enumeration propKeys = p.propertyNames(); propKeys.hasMoreElements();) {
+            String tmpKey = (String) propKeys.nextElement();
+            String tmpValue = p.getProperty(tmpKey);
+            // Trim spaces
+            tmpValue = tmpValue.trim();
+            // Quoted string.
+            if (tmpValue.length() > 1 && tmpValue.startsWith("\"") && tmpValue.endsWith("\"")) {
+                tmpValue = tmpValue.substring(1, tmpValue.length() - 1);
+            }
+            prop.put(tmpKey, tmpValue);
+        }
+
+        if (_logger.isLoggable(FINEST)) {
+            _logger.log(FINEST, "Parsing string to properties: {0}size:{1}", new Object[] { prop, prop.size() });
+        }
+
+        return prop;
     }
 }
diff --git a/appserver/jdbc/jdbc-ra/jdbc-core/src/main/java/com/sun/gjc/util/ResultSetClosedEventListener.java b/appserver/jdbc/jdbc-ra/jdbc-core/src/main/java/com/sun/gjc/util/ResultSetClosedEventListener.java
index 0a16dd0..3a74810 100644
--- a/appserver/jdbc/jdbc-ra/jdbc-core/src/main/java/com/sun/gjc/util/ResultSetClosedEventListener.java
+++ b/appserver/jdbc/jdbc-ra/jdbc-core/src/main/java/com/sun/gjc/util/ResultSetClosedEventListener.java
@@ -27,8 +27,8 @@
 public interface ResultSetClosedEventListener {
 
     /**
-     * Used to perform operations like statement closeOnCompletion when the
-     * result set object is closed.
+     * Used to perform operations like statement closeOnCompletion when the result
+     * set object is closed.
      */
-    public void resultSetClosed() throws SQLException;
+    void resultSetClosed() throws SQLException;
 }
diff --git a/appserver/jdbc/jdbc-ra/jdbc-core/src/main/java/com/sun/gjc/util/SQLTrace.java b/appserver/jdbc/jdbc-ra/jdbc-core/src/main/java/com/sun/gjc/util/SQLTrace.java
index 8d4e5d3..6aa0084 100644
--- a/appserver/jdbc/jdbc-ra/jdbc-core/src/main/java/com/sun/gjc/util/SQLTrace.java
+++ b/appserver/jdbc/jdbc-ra/jdbc-core/src/main/java/com/sun/gjc/util/SQLTrace.java
@@ -17,9 +17,9 @@
 package com.sun.gjc.util;
 
 /**
- * Store the sql queries executed by applications along with the number of
- * times executed and the time stamp of the last usage.
- * Used for monitoring information.
+ * Store the sql queries executed by applications along with the number of times
+ * executed and the time stamp of the last usage. Used for monitoring
+ * information.
  *
  * @author Shalini M
  */
@@ -90,8 +90,8 @@
     }
 
     /**
-     * Check for equality of the SQLTrace with the object passed by
-     * comparing the queryName stored.
+     * Check for equality of the SQLTrace with the object passed by comparing the
+     * queryName stored.
      *
      * @param obj against which the equality is to be checked.
      * @return true or false
@@ -101,12 +101,11 @@
         if (obj == null) {
             return false;
         }
-        if(!(obj instanceof SQLTrace)) {
+        if (!(obj instanceof SQLTrace)) {
             return false;
         }
         final SQLTrace other = (SQLTrace) obj;
-        if ((this.queryName == null) || (other.queryName == null) ||
-                !this.queryName.equals(other.queryName)) {
+        if ((this.queryName == null) || (other.queryName == null) || !this.queryName.equals(other.queryName)) {
             return false;
         }
         return true;
@@ -114,6 +113,7 @@
 
     /**
      * Generate hash code for this obejct using all the fields.
+     *
      * @return
      */
     @Override
@@ -140,15 +140,15 @@
             compare = 1;
         }
         if (compare == 0) {
-            //same number of executions. Hence compare based on time.
+            // same number of executions. Hence compare based on time.
             long timeCompare = this.getLastUsageTime() - t;
-            if(timeCompare == 0) {
+            if (timeCompare == 0) {
                 compare = 0;
-            } else if(timeCompare < 0) {
-                //compare = -1;
+            } else if (timeCompare < 0) {
+                // compare = -1;
                 compare = 1;
             } else {
-                //compare = 1;
+                // compare = 1;
                 compare = -1;
             }
         }
diff --git a/appserver/jdbc/jdbc-ra/jdbc-core/src/main/java/com/sun/gjc/util/SQLTraceCache.java b/appserver/jdbc/jdbc-ra/jdbc-core/src/main/java/com/sun/gjc/util/SQLTraceCache.java
index b69a7b3..c63b4a7 100644
--- a/appserver/jdbc/jdbc-ra/jdbc-core/src/main/java/com/sun/gjc/util/SQLTraceCache.java
+++ b/appserver/jdbc/jdbc-ra/jdbc-core/src/main/java/com/sun/gjc/util/SQLTraceCache.java
@@ -16,7 +16,6 @@
 
 package com.sun.gjc.util;
 
-import com.sun.logging.LogDomains;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.Iterator;
@@ -25,6 +24,8 @@
 import java.util.logging.Level;
 import java.util.logging.Logger;
 
+import com.sun.logging.LogDomains;
+
 /**
  * Maintains the Sql Tracing Cache used to store SQL statements used by the
  * applications. This is used by the JDBCRA monitoring to display the most
@@ -34,17 +35,16 @@
  */
 public class SQLTraceCache {
 
-    //List of sql trace objects
+    // List of sql trace objects
     private final List<SQLTrace> list;
-    //Maximum size of the cache.
+    // Maximum size of the cache.
     private int numTopQueriesToReport = 10;
     private long timeToKeepQueries = 60 * 1000;
     private SQLTraceTimerTask sqlTraceTimerTask;
     private String poolName;
     private String appName;
     private String moduleName;
-    private final static Logger _logger = LogDomains.getLogger(SQLTraceCache.class,
-            LogDomains.RSR_LOGGER);
+    private final static Logger _logger = LogDomains.getLogger(SQLTraceCache.class, LogDomains.RSR_LOGGER);
     private static final String LINE_BREAK = "%%%EOL%%%";
 
     public SQLTraceCache(String poolName, String appName, String moduleName, int maxSize, long timeToKeepQueries) {
@@ -65,23 +65,23 @@
     }
 
     /**
-     * Schedule timer to perform purgeEntries on the cache after the
-     * specified timeToKeepQueries delay and period.
+     * Schedule timer to perform purgeEntries on the cache after the specified
+     * timeToKeepQueries delay and period.
      */
     public void scheduleTimerTask(Timer timer) {
 
-        if(sqlTraceTimerTask != null) {
+        if (sqlTraceTimerTask != null) {
             sqlTraceTimerTask.cancel();
             sqlTraceTimerTask = null;
         }
 
         sqlTraceTimerTask = initializeTimerTask();
 
-        if(timer != null) {
+        if (timer != null) {
 
             timer.scheduleAtFixedRate(sqlTraceTimerTask, timeToKeepQueries, timeToKeepQueries);
         }
-        if(_logger.isLoggable(Level.FINEST)) {
+        if (_logger.isLoggable(Level.FINEST)) {
             _logger.finest("Scheduled Sql Trace Caching timer task");
         }
     }
@@ -91,7 +91,7 @@
      */
     public synchronized void cancelTimerTask() {
 
-        if(_logger.isLoggable(Level.FINEST)) {
+        if (_logger.isLoggable(Level.FINEST)) {
             _logger.finest("Cancelling Sql Trace Caching timer task");
         }
         if (sqlTraceTimerTask != null) {
@@ -106,18 +106,17 @@
      * @return SQLTraceTimerTask
      */
     private SQLTraceTimerTask initializeTimerTask() {
-        if(_logger.isLoggable(Level.FINEST)) {
+        if (_logger.isLoggable(Level.FINEST)) {
             _logger.finest("Initializing Sql Trace Caching timer task");
         }
         return new SQLTraceTimerTask(this);
     }
 
     /**
-     * Request for adding a sql query in the form of SQLTrace to this cache.
-     * If the query is already found
-     * in the list, the number of times it is executed is incremented by one
-     * along with the timestamp.
-     * If the query is a new one, it is added to the list.
+     * Request for adding a sql query in the form of SQLTrace to this cache. If the
+     * query is already found in the list, the number of times it is executed is
+     * incremented by one along with the timestamp. If the query is a new one, it is
+     * added to the list.
      *
      * @param cacheObj
      * @return
@@ -127,14 +126,14 @@
             if (cacheObj != null) {
                 int index = list.indexOf(cacheObj);
                 if (index != -1) {
-                    //If already found in the cache
-                    //equals is invoked here and hence comparison based on query name is done
-                    //Get the object at the index to update the numExecutions
-                    SQLTrace cache = (SQLTrace) list.get(index);
+                    // If already found in the cache
+                    // equals is invoked here and hence comparison based on query name is done
+                    // Get the object at the index to update the numExecutions
+                    SQLTrace cache = list.get(index);
                     cache.setNumExecutions(cache.getNumExecutions() + 1);
                     cache.setLastUsageTime(System.currentTimeMillis());
                 } else {
-                    //First occurrence of the query. query to be added.
+                    // First occurrence of the query. query to be added.
                     cacheObj.setNumExecutions(1);
                     cacheObj.setLastUsageTime(System.currentTimeMillis());
                     list.add(cacheObj);
@@ -144,18 +143,18 @@
     }
 
     /**
-     * Entries are removed from the list after sorting
-     * them in the least frequently used order. Only numTopQueriesToReport number of
-     * entries are maintained in the list after the purgeEntries.
+     * Entries are removed from the list after sorting them in the least frequently
+     * used order. Only numTopQueriesToReport number of entries are maintained in
+     * the list after the purgeEntries.
      */
     public void purgeEntries() {
-        synchronized(list) {
+        synchronized (list) {
             Collections.sort(list, Collections.reverseOrder());
             Iterator i = list.iterator();
             while (i.hasNext()) {
                 SQLTrace cacheObj = (SQLTrace) i.next();
                 if (list.size() > numTopQueriesToReport) {
-                    if(_logger.isLoggable(Level.FINEST)) {
+                    if (_logger.isLoggable(Level.FINEST)) {
                         _logger.finest("removing sql=" + cacheObj.getQueryName());
                     }
                     i.remove();
@@ -163,23 +162,23 @@
                     break;
                 }
             }
-            //sort by most frequently used queries first
+            // sort by most frequently used queries first
             Collections.sort(list);
         }
     }
 
     /**
-     * Returns the String representation of the list of traced sql queries
-     * ordered by the number most frequently used, followed by the usage
-     * timestamp. Only the top 'n' queries represented by the numTopQueriesToReport are
-     * chosen for display.
+     * Returns the String representation of the list of traced sql queries ordered
+     * by the number most frequently used, followed by the usage timestamp. Only the
+     * top 'n' queries represented by the numTopQueriesToReport are chosen for
+     * display.
      *
      * @return string representation of the list of sql queries sorted
      */
     public String getTopQueries() {
         purgeEntries();
         StringBuffer sb = new StringBuffer();
-        for(SQLTrace cache : list) {
+        for (SQLTrace cache : list) {
             sb.append(LINE_BREAK);
             sb.append(cache.getQueryName());
         }
diff --git a/appserver/jdbc/jdbc-ra/jdbc-core/src/main/java/com/sun/gjc/util/SQLTraceDelegator.java b/appserver/jdbc/jdbc-ra/jdbc-core/src/main/java/com/sun/gjc/util/SQLTraceDelegator.java
index db65197..1a94b6c 100644
--- a/appserver/jdbc/jdbc-ra/jdbc-core/src/main/java/com/sun/gjc/util/SQLTraceDelegator.java
+++ b/appserver/jdbc/jdbc-ra/jdbc-core/src/main/java/com/sun/gjc/util/SQLTraceDelegator.java
@@ -16,35 +16,31 @@
 
 package com.sun.gjc.util;
 
-import com.sun.gjc.monitoring.JdbcRAConstants;
-import com.sun.gjc.monitoring.SQLTraceProbeProvider;
+import static java.util.logging.Level.FINEST;
+
 import java.util.ArrayList;
 import java.util.List;
-import java.util.logging.Level;
 import java.util.logging.Logger;
 
-import com.sun.logging.LogDomains;
 import org.glassfish.api.jdbc.SQLTraceListener;
 import org.glassfish.api.jdbc.SQLTraceRecord;
 
+import com.sun.gjc.monitoring.JdbcRAConstants;
+import com.sun.gjc.monitoring.SQLTraceProbeProvider;
+import com.sun.logging.LogDomains;
+
 /**
- * Implementation of SQLTraceListener to listen to events related to a
- * sql record tracing. The registry allows multiple listeners
- * to listen to the sql tracing events. Maintains a list of listeners.
+ * Implementation of SQLTraceListener to listen to events related to a sql
+ * record tracing. The registry allows multiple listeners to listen to the sql
+ * tracing events. Maintains a list of listeners.
  *
  * @author Shalini M
  */
-//@Singleton
 public class SQLTraceDelegator implements SQLTraceListener {
 
-    private static Logger _logger;
+    private static Logger _logger = LogDomains.getLogger(MethodExecutor.class, LogDomains.RSR_LOGGER);
 
-    static {
-        _logger = LogDomains
-            .getLogger(MethodExecutor.class, LogDomains.RSR_LOGGER);
-    }
-
-    //List of listeners
+    // List of listeners
     protected List<SQLTraceListener> sqlTraceListenersList;
     private String poolName;
     private String appName;
@@ -63,43 +59,46 @@
     }
 
     /**
-     * Add a listener to the list of sql trace listeners maintained by
-     * this registry.
+     * Add a listener to the list of sql trace listeners maintained by this
+     * registry.
+     *
      * @param listener
      */
     public void registerSQLTraceListener(SQLTraceListener listener) {
-        if(sqlTraceListenersList == null) {
-                sqlTraceListenersList = new ArrayList<SQLTraceListener>();
+        if (sqlTraceListenersList == null) {
+            sqlTraceListenersList = new ArrayList<SQLTraceListener>();
         }
         sqlTraceListenersList.add(listener);
     }
 
-
-   public void sqlTrace(SQLTraceRecord record) {
-       if (sqlTraceListenersList != null) {
-           for (SQLTraceListener listener : sqlTraceListenersList) {
-               try {
-                   listener.sqlTrace(record);
-               }catch(Exception e){
-                   //it is possible that any of the implementations may fail processing a trace record.
-                   //do not propagate such failures. Log them as FINEST.
-                   if(_logger.isLoggable(Level.FINEST)){
-                       _logger.log(Level.FINEST, "exception from one of the SQL trace listeners ["+listener.getClass().getName()+"]", e);
-                   }
-               }
-           }
-       }
+    public void sqlTrace(SQLTraceRecord record) {
+        if (sqlTraceListenersList != null) {
+            for (SQLTraceListener listener : sqlTraceListenersList) {
+                try {
+                    listener.sqlTrace(record);
+                } catch (Exception e) {
+                    // it is possible that any of the implementations may fail processing a trace
+                    // record.
+                    // do not propagate such failures. Log them as FINEST.
+                    if (_logger.isLoggable(FINEST)) {
+                        _logger.log(FINEST,
+                                "exception from one of the SQL trace listeners [" + listener.getClass().getName() + "]",
+                                e);
+                    }
+                }
+            }
+        }
 
         if (record != null) {
             record.setPoolName(poolName);
             String methodName = record.getMethodName();
-            //Check if the method name is one in which sql query is used
+            // Check if the method name is one in which sql query is used
             if (isMethodValidForCaching(methodName)) {
                 Object[] params = record.getParams();
                 if (params != null && params.length > 0) {
                     String sqlQuery = null;
                     for (Object param : params) {
-                        if(param instanceof String) {
+                        if (param instanceof String) {
                             sqlQuery = param.toString();
                         }
                         break;
@@ -112,15 +111,15 @@
         }
     }
 
-   /**
-    * Check if the method name from the sql trace record can be used to
-    * retrieve a sql string for caching purpose. Most of the method names do not
-    * contain a sql string and hence are unusable for caching the sql strings.
-    * These method names are filtered in this method.
-    *
-    * @param methodName
-    * @return true if method name can be used to get a sql string for caching.
-    */
+    /**
+     * Check if the method name from the sql trace record can be used to retrieve a
+     * sql string for caching purpose. Most of the method names do not contain a sql
+     * string and hence are unusable for caching the sql strings. These method names
+     * are filtered in this method.
+     *
+     * @param methodName
+     * @return true if method name can be used to get a sql string for caching.
+     */
     private boolean isMethodValidForCaching(String methodName) {
         return JdbcRAConstants.validSqlTracingMethodNames.contains(methodName);
     }
diff --git a/appserver/jdbc/jdbc-ra/jdbc-core/src/main/java/com/sun/gjc/util/SQLTraceLogger.java b/appserver/jdbc/jdbc-ra/jdbc-core/src/main/java/com/sun/gjc/util/SQLTraceLogger.java
index 6c000e8..f70cce8 100644
--- a/appserver/jdbc/jdbc-ra/jdbc-core/src/main/java/com/sun/gjc/util/SQLTraceLogger.java
+++ b/appserver/jdbc/jdbc-ra/jdbc-core/src/main/java/com/sun/gjc/util/SQLTraceLogger.java
@@ -16,15 +16,17 @@
 
 package com.sun.gjc.util;
 
-import com.sun.logging.LogDomains;
 import java.util.logging.Level;
 import java.util.logging.Logger;
+
 import org.glassfish.api.jdbc.SQLTraceListener;
 import org.glassfish.api.jdbc.SQLTraceRecord;
 
+import com.sun.logging.LogDomains;
+
 /**
- * Implementation of SQLTraceListener to listen to events related to a
- * sql record tracing.
+ * Implementation of SQLTraceListener to listen to events related to a sql
+ * record tracing.
  *
  * @author Shalini M
  */
diff --git a/appserver/jdbc/jdbc-ra/jdbc-core/src/main/java/com/sun/gjc/util/SQLTraceTimerTask.java b/appserver/jdbc/jdbc-ra/jdbc-core/src/main/java/com/sun/gjc/util/SQLTraceTimerTask.java
index d53b634..434e151 100644
--- a/appserver/jdbc/jdbc-ra/jdbc-core/src/main/java/com/sun/gjc/util/SQLTraceTimerTask.java
+++ b/appserver/jdbc/jdbc-ra/jdbc-core/src/main/java/com/sun/gjc/util/SQLTraceTimerTask.java
@@ -37,7 +37,7 @@
      */
     @Override
     public void run() {
-        //Redirecting the purge operation of the cache to the cache factory
+        // Redirecting the purge operation of the cache to the cache factory
         cache.purgeEntries();
     }
 
diff --git a/appserver/jdbc/jdbc-ra/jdbc-core/src/main/java/com/sun/gjc/util/SecurityUtils.java b/appserver/jdbc/jdbc-ra/jdbc-core/src/main/java/com/sun/gjc/util/SecurityUtils.java
index dd71311..39966fb 100644
--- a/appserver/jdbc/jdbc-ra/jdbc-core/src/main/java/com/sun/gjc/util/SecurityUtils.java
+++ b/appserver/jdbc/jdbc-ra/jdbc-core/src/main/java/com/sun/gjc/util/SecurityUtils.java
@@ -16,20 +16,23 @@
 
 package com.sun.gjc.util;
 
-import com.sun.enterprise.util.i18n.StringManager;
-import com.sun.gjc.common.DataSourceObjectBuilder;
-import com.sun.gjc.spi.ConnectionRequestInfoImpl;
-
-import jakarta.resource.ResourceException;
-import jakarta.resource.spi.ManagedConnectionFactory;
-import jakarta.resource.spi.security.PasswordCredential;
-import javax.security.auth.Subject;
 import java.security.AccessController;
 import java.security.PrivilegedAction;
 import java.util.Arrays;
 import java.util.Iterator;
 import java.util.Set;
 
+import javax.security.auth.Subject;
+
+import com.sun.enterprise.util.i18n.StringManager;
+import com.sun.gjc.common.DataSourceObjectBuilder;
+import com.sun.gjc.spi.ConnectionRequestInfoImpl;
+
+import jakarta.resource.ResourceException;
+import jakarta.resource.spi.ConnectionRequestInfo;
+import jakarta.resource.spi.ManagedConnectionFactory;
+import jakarta.resource.spi.security.PasswordCredential;
+
 /**
  * SecurityUtils for Generic JDBC Connector.
  *
@@ -38,51 +41,50 @@
  */
 public class SecurityUtils {
 
-    static private StringManager sm = StringManager.getManager(
-            DataSourceObjectBuilder.class);
+    static private StringManager sm = StringManager.getManager(DataSourceObjectBuilder.class);
 
     /**
-     * This method returns the <code>PasswordCredential</code> object, given
-     * the <code>ManagedConnectionFactory</code>, subject and the
+     * This method returns the <code>PasswordCredential</code> object, given the
+     * <code>ManagedConnectionFactory</code>, subject and the
      * <code>ConnectionRequestInfo</code>. It first checks if the
-     * <code>ConnectionRequestInfo</code> is null or not. If it is not null,
-     * it constructs a <code>PasswordCredential</code> object with
-     * the user and password fields from the <code>ConnectionRequestInfo</code> and returns this
-     * <code>PasswordCredential</code> object. If the <code>ConnectionRequestInfo</code>
-     * is null, it retrieves the <code>PasswordCredential</code> objects from
-     * the <code>Subject</code> parameter and returns the first
-     * <code>PasswordCredential</code> object which contains a
-     * <code>ManagedConnectionFactory</code>, instance equivalent
-     * to the <code>ManagedConnectionFactory</code>, parameter.
+     * <code>ConnectionRequestInfo</code> is null or not. If it is not null, it
+     * constructs a <code>PasswordCredential</code> object with the user and
+     * password fields from the <code>ConnectionRequestInfo</code> and returns this
+     * <code>PasswordCredential</code> object. If the
+     * <code>ConnectionRequestInfo</code> is null, it retrieves the
+     * <code>PasswordCredential</code> objects from the <code>Subject</code>
+     * parameter and returns the first <code>PasswordCredential</code> object which
+     * contains a <code>ManagedConnectionFactory</code>, instance equivalent to the
+     * <code>ManagedConnectionFactory</code>, parameter.
      *
-     * @param mcf     <code>ManagedConnectionFactory</code>
+     * @param mcf <code>ManagedConnectionFactory</code>
      * @param subject <code>Subject</code>
-     * @param info    <code>ConnectionRequestInfo</code>
+     * @param info <code>ConnectionRequestInfo</code>
      * @return <code>PasswordCredential</code>
      * @throws <code>ResourceException</code> generic exception if operation fails
-     * @throws <code>SecurityException</code> if access to the <code>Subject</code> instance is denied
+     * @throws <code>SecurityException</code> if access to the <code>Subject</code>
+     * instance is denied
      */
-    public static PasswordCredential getPasswordCredential(final ManagedConnectionFactory mcf,
-                                                           final Subject subject, jakarta.resource.spi.ConnectionRequestInfo info) throws ResourceException {
+    public static PasswordCredential getPasswordCredential(final ManagedConnectionFactory mcf, final Subject subject,
+            ConnectionRequestInfo info) throws ResourceException {
 
         if (info == null) {
             if (subject == null) {
                 return null;
             } else {
-                PasswordCredential pc = (PasswordCredential) AccessController.doPrivileged
-                        (new PrivilegedAction() {
-                            public Object run() {
-                                Set passwdCredentialSet = subject.getPrivateCredentials(PasswordCredential.class);
-                                Iterator iter = passwdCredentialSet.iterator();
-                                while (iter.hasNext()) {
-                                    PasswordCredential temp = (PasswordCredential) iter.next();
-                                    if (temp.getManagedConnectionFactory().equals(mcf)) {
-                                        return temp;
-                                    }
-                                }
-                                return null;
+                PasswordCredential pc = (PasswordCredential) AccessController.doPrivileged(new PrivilegedAction() {
+                    public Object run() {
+                        Set passwdCredentialSet = subject.getPrivateCredentials(PasswordCredential.class);
+                        Iterator iter = passwdCredentialSet.iterator();
+                        while (iter.hasNext()) {
+                            PasswordCredential temp = (PasswordCredential) iter.next();
+                            if (temp.getManagedConnectionFactory().equals(mcf)) {
+                                return temp;
                             }
-                        });
+                        }
+                        return null;
+                    }
+                });
                 if (pc == null) {
                     String msg = sm.getString("su.no_passwd_cred");
                     throw new jakarta.resource.spi.SecurityException(msg);
@@ -103,24 +105,23 @@
      *
      * @param str1 <code>String</code>
      * @param str2 <code>String</code>
-     * @return true    if the two strings are equal
-     *         false    otherwise
+     * @return true if the two strings are equal false otherwise
      */
     static private boolean isEqual(String str1, String str2) {
         if (str1 == null) {
             return (str2 == null);
-        } else {
-            return str1.equals(str2);
         }
+
+        return str1.equals(str2);
     }
 
     /**
-     * Returns true if two <code>PasswordCredential</code> objects are equal; false otherwise
+     * Returns true if two <code>PasswordCredential</code> objects are equal; false
+     * otherwise
      *
      * @param pC1 <code>PasswordCredential</code>
      * @param pC2 <code>PasswordCredential</code>
-     * @return true    if the two PasswordCredentials are equal
-     *         false    otherwise
+     * @return true if the two PasswordCredentials are equal false otherwise
      */
     static public boolean isPasswordCredentialEqual(PasswordCredential pC1, PasswordCredential pC2) {
         if (pC1 == pC2)
@@ -130,6 +131,7 @@
         if (!isEqual(pC1.getUserName(), pC2.getUserName())) {
             return false;
         }
+
         return Arrays.equals(pC1.getPassword(), pC2.getPassword());
     }
 }
diff --git a/appserver/jdbc/jdbc-ra/jdbc-core/src/main/java/com/sun/gjc/util/StatementLeakDetector.java b/appserver/jdbc/jdbc-ra/jdbc-core/src/main/java/com/sun/gjc/util/StatementLeakDetector.java
index 1d0c28a..5ff9448 100644
--- a/appserver/jdbc/jdbc-ra/jdbc-core/src/main/java/com/sun/gjc/util/StatementLeakDetector.java
+++ b/appserver/jdbc/jdbc-ra/jdbc-core/src/main/java/com/sun/gjc/util/StatementLeakDetector.java
@@ -16,10 +16,7 @@
 
 package com.sun.gjc.util;
 
-import com.sun.enterprise.util.i18n.StringManager;
-import com.sun.gjc.monitoring.StatementLeakProbeProvider;
-import com.sun.logging.LogDomains;
-import org.glassfish.resourcebase.resources.api.PoolInfo;
+import static java.util.logging.Level.WARNING;
 
 import java.sql.SQLException;
 import java.sql.Statement;
@@ -28,9 +25,14 @@
 import java.util.Map;
 import java.util.Timer;
 import java.util.TimerTask;
-import java.util.logging.Level;
 import java.util.logging.Logger;
 
+import org.glassfish.resourcebase.resources.api.PoolInfo;
+
+import com.sun.enterprise.util.i18n.StringManager;
+import com.sun.gjc.monitoring.StatementLeakProbeProvider;
+import com.sun.logging.LogDomains;
+
 /**
  * Statement leak detector that prints the stack trace of the thread when a
  * statement object is leaked. Once the leak timeout expires, a statement leak
@@ -46,18 +48,16 @@
     private boolean statementLeakTracing;
     private long statementLeakTimeoutInMillis;
     private boolean statementLeakReclaim;
-    //Lock on HashMap to trace statement leaks
+    // Lock on HashMap to trace statement leaks
     private final Object statementLeakLock;
     private Map<Statement, StatementLeakListener> listeners;
-    private final static Logger _logger = LogDomains.getLogger(
-            StatementLeakDetector.class, LogDomains.RSR_LOGGER);
-    private final static StringManager localStrings =
-            StringManager.getManager(StatementLeakDetector.class);
+    private final static Logger _logger = LogDomains.getLogger(StatementLeakDetector.class, LogDomains.RSR_LOGGER);
+    private final static StringManager localStrings = StringManager.getManager(StatementLeakDetector.class);
     private Timer timer;
     private StatementLeakProbeProvider stmtLeakProbeProvider = null;
 
-    public StatementLeakDetector(PoolInfo poolInfo, boolean leakTracing,
-            long leakTimeoutInMillis, boolean leakReclaim, Timer timer) {
+    public StatementLeakDetector(PoolInfo poolInfo, boolean leakTracing, long leakTimeoutInMillis, boolean leakReclaim,
+            Timer timer) {
         this.poolInfo = poolInfo;
         statementLeakThreadStackHashMap = new HashMap<Statement, StackTraceElement[]>();
         statementLeakTimerTaskHashMap = new HashMap<Statement, StatementLeakTask>();
@@ -79,7 +79,6 @@
         statementLeakReclaim = leakReclaim;
     }
 
-
     private void registerListener(Statement stmt, StatementLeakListener listener) {
         listeners.put(stmt, listener);
     }
@@ -88,12 +87,11 @@
         listeners.remove(stmt);
     }
 
-
     /**
      * Starts statement leak tracing
      *
      * @param stmt Statement which needs to be traced
-     * @param listener       Leak Listener
+     * @param listener Leak Listener
      */
     public void startStatementLeakTracing(Statement stmt, StatementLeakListener listener) {
         synchronized (statementLeakLock) {
@@ -104,9 +102,7 @@
                 registerListener(stmt, listener);
                 if (timer != null) {
                     timer.schedule(statementLeakTask, statementLeakTimeoutInMillis);
-                    if(_logger.isLoggable(Level.FINEST)) {
-                        _logger.finest("Scheduled Statement leak tracing timer task");
-                    }
+                    _logger.finest("Scheduled Statement leak tracing timer task");
                 }
             }
         }
@@ -116,25 +112,21 @@
      * Stops statement leak tracing
      *
      * @param stmt Statement which needs to be traced
-     * @param listener       Leak Listener
+     * @param listener Leak Listener
      */
     public void stopStatementLeakTracing(Statement stmt, StatementLeakListener listener) {
         synchronized (statementLeakLock) {
             if (statementLeakThreadStackHashMap.containsKey(stmt)) {
                 statementLeakThreadStackHashMap.remove(stmt);
-                StatementLeakTask statementLeakTask =
-                        statementLeakTimerTaskHashMap.remove(stmt);
+                StatementLeakTask statementLeakTask = statementLeakTimerTaskHashMap.remove(stmt);
                 statementLeakTask.cancel();
                 timer.purge();
-                if(_logger.isLoggable(Level.FINEST)) {
-                    _logger.finest("Stopped Statement leak tracing timer task");
-                }
+                _logger.finest("Stopped Statement leak tracing timer task");
                 unRegisterListener(stmt);
             }
         }
     }
 
-
     /**
      * Logs the potential statement leaks
      *
@@ -145,21 +137,19 @@
             if (statementLeakThreadStackHashMap.containsKey(stmt)) {
                 StackTraceElement[] threadStack = statementLeakThreadStackHashMap.remove(stmt);
                 StatementLeakListener stmtLeakListener = listeners.get(stmt);
-                stmtLeakProbeProvider.potentialStatementLeakEvent(poolInfo.getName(),
-                        poolInfo.getApplicationName(), poolInfo.getModuleName());
+                stmtLeakProbeProvider.potentialStatementLeakEvent(poolInfo.getName(), poolInfo.getApplicationName(),
+                        poolInfo.getModuleName());
                 printStatementLeakTrace(threadStack);
                 statementLeakTimerTaskHashMap.remove(stmt);
                 if (statementLeakReclaim) {
                     try {
                         stmtLeakListener.reclaimStatement();
                     } catch (SQLException ex) {
-                        Object[] params = new Object[]{poolInfo, ex};
-                        _logger.log(Level.WARNING,
-                                "statement.leak.detector_reclaim_statement_failure",
-                                params);
+                        Object[] params = new Object[] { poolInfo, ex };
+                        _logger.log(WARNING, "statement.leak.detector_reclaim_statement_failure", params);
                     }
                 }
-                //Unregister here as the listeners would still be present in the map.
+                // Unregister here as the listeners would still be present in the map.
                 unRegisterListener(stmt);
             }
         }
@@ -172,30 +162,30 @@
      */
     private void printStatementLeakTrace(StackTraceElement[] threadStackTrace) {
         StringBuffer stackTrace = new StringBuffer();
-        String msg = localStrings.getStringWithDefault(
-                "potential.statement.leak.msg",
-                "A potential statement leak detected for connection pool " + poolInfo +
-                        ". The stack trace of the thread is provided below : ",
-                new Object[]{poolInfo});
+        String msg = localStrings
+                .getStringWithDefault(
+                        "potential.statement.leak.msg", "A potential statement leak detected for connection pool "
+                                + poolInfo + ". The stack trace of the thread is provided below : ",
+                        new Object[] { poolInfo });
         stackTrace.append(msg);
         stackTrace.append("\n");
         for (int i = 2; i < threadStackTrace.length; i++) {
             stackTrace.append(threadStackTrace[i].toString());
             stackTrace.append("\n");
         }
-        _logger.log(Level.WARNING, stackTrace.toString(), "ConnectionPoolName=" + poolInfo);
+        _logger.log(WARNING, stackTrace.toString(), "ConnectionPoolName=" + poolInfo);
     }
 
     /**
-     * Clear all statement leak tracing tasks in case of statement leak
-     * tracing being turned off
+     * Clear all statement leak tracing tasks in case of statement leak tracing
+     * being turned off
      */
     public void clearAllStatementLeakTasks() {
         synchronized (statementLeakLock) {
-            Iterator<Map.Entry<Statement, StatementLeakTask>> entryIterator =
-                    statementLeakTimerTaskHashMap.entrySet().iterator();
+            Iterator<Map.Entry<Statement, StatementLeakTask>> entryIterator = statementLeakTimerTaskHashMap.entrySet()
+                    .iterator();
             while (entryIterator.hasNext()) {
-                Map.Entry<Statement,StatementLeakTask> entry = entryIterator.next();
+                Map.Entry<Statement, StatementLeakTask> entry = entryIterator.next();
                 StatementLeakTask statementLeakTask = entry.getValue();
                 statementLeakTask.cancel();
             }
@@ -206,7 +196,6 @@
         }
     }
 
-
     private class StatementLeakTask extends TimerTask {
 
         private Statement statement;
diff --git a/appserver/jdbc/jdbc-ra/jdbc-core/src/main/java/com/sun/gjc/util/StatementLeakListener.java b/appserver/jdbc/jdbc-ra/jdbc-core/src/main/java/com/sun/gjc/util/StatementLeakListener.java
index f4c268e..5bdce2b 100644
--- a/appserver/jdbc/jdbc-ra/jdbc-core/src/main/java/com/sun/gjc/util/StatementLeakListener.java
+++ b/appserver/jdbc/jdbc-ra/jdbc-core/src/main/java/com/sun/gjc/util/StatementLeakListener.java
@@ -30,6 +30,6 @@
     /**
      * Reclaim the leaked statement
      */
-    public void reclaimStatement() throws SQLException;
+    void reclaimStatement() throws SQLException;
 
 }
diff --git a/appserver/jdbc/jdbc-ra/jdbc40/src/main/java/com/sun/gjc/spi/jdbc40/CallableStatementWrapper40.java b/appserver/jdbc/jdbc-ra/jdbc40/src/main/java/com/sun/gjc/spi/jdbc40/CallableStatementWrapper40.java
index 366cc53..65176ec 100644
--- a/appserver/jdbc/jdbc-ra/jdbc40/src/main/java/com/sun/gjc/spi/jdbc40/CallableStatementWrapper40.java
+++ b/appserver/jdbc/jdbc-ra/jdbc40/src/main/java/com/sun/gjc/spi/jdbc40/CallableStatementWrapper40.java
@@ -16,13 +16,24 @@
 
 package com.sun.gjc.spi.jdbc40;
 
-import com.sun.gjc.common.DataSourceObjectBuilder;
-import com.sun.gjc.spi.base.CallableStatementWrapper;
+import static com.sun.gjc.common.DataSourceObjectBuilder.isJDBC41;
+import static java.util.logging.Level.SEVERE;
 
 import java.io.InputStream;
 import java.io.Reader;
-import java.sql.*;
-import java.util.logging.Level;
+import java.sql.Blob;
+import java.sql.CallableStatement;
+import java.sql.Clob;
+import java.sql.Connection;
+import java.sql.NClob;
+import java.sql.ResultSet;
+import java.sql.RowId;
+import java.sql.SQLException;
+import java.sql.SQLFeatureNotSupportedException;
+import java.sql.SQLXML;
+
+import com.sun.gjc.spi.base.CallableStatementWrapper;
+
 import jakarta.resource.ResourceException;
 
 /**
@@ -32,12 +43,10 @@
     /**
      * Creates a new instance of CallableStatement wrapper for JDBC 3.0<br>
      *
-     * @param con       ConnectionWrapper<br>
+     * @param con ConnectionWrapper<br>
      * @param statement CallableStatement that is wrapped<br>
      */
-    public CallableStatementWrapper40(Connection con, CallableStatement statement,
-                                      boolean cachingEnabled)
-            throws SQLException {
+    public CallableStatementWrapper40(Connection con, CallableStatement statement, boolean cachingEnabled) throws SQLException {
         super(con, statement, cachingEnabled);
     }
 
@@ -47,12 +56,14 @@
      *
      * @param parameterIndex the first parameter is 1, the second is 2, ...
      * @return a <code>java.io.Reader</code> object that contains the parameter
-     *         value; if the value is SQL <code>NULL</code>, the value returned is
-     *         <code>null</code> in the Java programming language.
-     * @throws SQLException if the parameterIndex is not valid; if a database access error occurs or
-     *                      this method is called on a closed <code>CallableStatement</code>
+     * value; if the value is SQL <code>NULL</code>, the value returned is
+     * <code>null</code> in the Java programming language.
+     * @throws SQLException if the parameterIndex is not valid; if a database access
+     * error occurs or this method is called on a closed
+     * <code>CallableStatement</code>
      * @since 1.6
      */
+    @Override
     public Reader getCharacterStream(int parameterIndex) throws SQLException {
         return callableStatement.getCharacterStream(parameterIndex);
     }
@@ -63,62 +74,60 @@
      *
      * @param parameterName the name of the parameter
      * @return a <code>java.io.Reader</code> object that contains the parameter
-     *         value; if the value is SQL <code>NULL</code>, the value returned is
-     *         <code>null</code> in the Java programming language
+     * value; if the value is SQL <code>NULL</code>, the value returned is
+     * <code>null</code> in the Java programming language
      * @throws SQLException if parameterName does not correspond to a named
-     *                      parameter; if a database access error occurs or
-     *                      this method is called on a closed <code>CallableStatement</code>
-     * @throws SQLFeatureNotSupportedException
-     *                      if the JDBC driver does not support
-     *                      this method
+     * parameter; if a database access error occurs or this method is called on a
+     * closed <code>CallableStatement</code>
+     * @throws SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
      * @since 1.6
      */
+    @Override
     public Reader getCharacterStream(String parameterName) throws SQLException {
         return callableStatement.getCharacterStream(parameterName);
     }
 
     /**
      * Retrieves the value of the designated parameter as a
-     * <code>java.io.Reader</code> object in the Java programming language.
-     * It is intended for use when
-     * accessing  <code>NCHAR</code>,<code>NVARCHAR</code>
-     * and <code>LONGNVARCHAR</code> parameters.
+     * <code>java.io.Reader</code> object in the Java programming language. It is
+     * intended for use when accessing <code>NCHAR</code>,<code>NVARCHAR</code> and
+     * <code>LONGNVARCHAR</code> parameters.
      *
      * @param parameterIndex the first parameter is 1, the second is 2, ...
      * @return a <code>java.io.Reader</code> object that contains the parameter
-     *         value; if the value is SQL <code>NULL</code>, the value returned is
-     *         <code>null</code> in the Java programming language.
-     * @throws SQLException if the parameterIndex is not valid;
-     *                      if a database access error occurs or
-     *                      this method is called on a closed <code>CallableStatement</code>
-     * @throws SQLFeatureNotSupportedException
-     *                      if the JDBC driver does not support
-     *                      this method
+     * value; if the value is SQL <code>NULL</code>, the value returned is
+     * <code>null</code> in the Java programming language.
+     * @throws SQLException if the parameterIndex is not valid; if a database access
+     * error occurs or this method is called on a closed
+     * <code>CallableStatement</code>
+     * @throws SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
      * @since 1.6
      */
+    @Override
     public Reader getNCharacterStream(int parameterIndex) throws SQLException {
         return callableStatement.getNCharacterStream(parameterIndex);
     }
 
     /**
      * Retrieves the value of the designated parameter as a
-     * <code>java.io.Reader</code> object in the Java programming language.
-     * It is intended for use when
-     * accessing  <code>NCHAR</code>,<code>NVARCHAR</code>
-     * and <code>LONGNVARCHAR</code> parameters.
+     * <code>java.io.Reader</code> object in the Java programming language. It is
+     * intended for use when accessing <code>NCHAR</code>,<code>NVARCHAR</code> and
+     * <code>LONGNVARCHAR</code> parameters.
      *
      * @param parameterName the name of the parameter
      * @return a <code>java.io.Reader</code> object that contains the parameter
-     *         value; if the value is SQL <code>NULL</code>, the value returned is
-     *         <code>null</code> in the Java programming language
+     * value; if the value is SQL <code>NULL</code>, the value returned is
+     * <code>null</code> in the Java programming language
      * @throws SQLException if parameterName does not correspond to a named
-     *                      parameter; if a database access error occurs or
-     *                      this method is called on a closed <code>CallableStatement</code>
-     * @throws SQLFeatureNotSupportedException
-     *                      if the JDBC driver does not support
-     *                      this method
+     * parameter; if a database access error occurs or this method is called on a
+     * closed <code>CallableStatement</code>
+     * @throws SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
      * @since 1.6
      */
+    @Override
     public Reader getNCharacterStream(String parameterName) throws SQLException {
         return callableStatement.getNCharacterStream(parameterName);
     }
@@ -127,21 +136,19 @@
      * Retrieves the value of the designated JDBC <code>NCLOB</code> parameter as a
      * <code>java.sql.NClob</code> object in the Java programming language.
      *
-     * @param parameterIndex the first parameter is 1, the second is 2, and
-     *                       so on
-     * @return the parameter value as a <code>NClob</code> object in the
-     *         Java programming language.  If the value was SQL <code>NULL</code>, the
-     *         value <code>null</code> is returned.
-     * @throws SQLException if the parameterIndex is not valid;
-     *                      if the driver does not support national
-     *                      character sets;  if the driver can detect that a data conversion
-     *                      error could occur; if a database access error occurs or
-     *                      this method is called on a closed <code>CallableStatement</code>
-     * @throws SQLFeatureNotSupportedException
-     *                      if the JDBC driver does not support
-     *                      this method
+     * @param parameterIndex the first parameter is 1, the second is 2, and so on
+     * @return the parameter value as a <code>NClob</code> object in the Java
+     * programming language. If the value was SQL <code>NULL</code>, the value
+     * <code>null</code> is returned.
+     * @throws SQLException if the parameterIndex is not valid; if the driver does
+     * not support national character sets; if the driver can detect that a data
+     * conversion error could occur; if a database access error occurs or this
+     * method is called on a closed <code>CallableStatement</code>
+     * @throws SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
      * @since 1.6
      */
+    @Override
     public NClob getNClob(int parameterIndex) throws SQLException {
         return callableStatement.getNClob(parameterIndex);
     }
@@ -151,76 +158,69 @@
      * <code>java.sql.NClob</code> object in the Java programming language.
      *
      * @param parameterName the name of the parameter
-     * @return the parameter value as a <code>NClob</code> object in the
-     *         Java programming language.  If the value was SQL <code>NULL</code>,
-     *         the value <code>null</code> is returned.
+     * @return the parameter value as a <code>NClob</code> object in the Java
+     * programming language. If the value was SQL <code>NULL</code>, the value
+     * <code>null</code> is returned.
      * @throws SQLException if parameterName does not correspond to a named
-     *                      parameter; if the driver does not support national
-     *                      character sets;  if the driver can detect that a data conversion
-     *                      error could occur; if a database access error occurs or
-     *                      this method is called on a closed <code>CallableStatement</code>
-     * @throws SQLFeatureNotSupportedException
-     *                      if the JDBC driver does not support
-     *                      this method
+     * parameter; if the driver does not support national character sets; if the
+     * driver can detect that a data conversion error could occur; if a database
+     * access error occurs or this method is called on a closed
+     * <code>CallableStatement</code>
+     * @throws SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
      * @since 1.6
      */
+    @Override
     public NClob getNClob(String parameterName) throws SQLException {
         return callableStatement.getNClob(parameterName);
     }
 
     /**
      * Retrieves the value of the designated <code>NCHAR</code>,
-     * <code>NVARCHAR</code>
-     * or <code>LONGNVARCHAR</code> parameter as
-     * a <code>String</code> in the Java programming language.
+     * <code>NVARCHAR</code> or <code>LONGNVARCHAR</code> parameter as a
+     * <code>String</code> in the Java programming language.
      * <p/>
-     * For the fixed-length type JDBC <code>NCHAR</code>,
-     * the <code>String</code> object
-     * returned has exactly the same value the SQL
-     * <code>NCHAR</code> value had in the
-     * database, including any padding added by the database.
+     * For the fixed-length type JDBC <code>NCHAR</code>, the <code>String</code>
+     * object returned has exactly the same value the SQL <code>NCHAR</code> value
+     * had in the database, including any padding added by the database.
      *
      * @param parameterIndex index of the first parameter is 1, the second is 2, ...
-     * @return a <code>String</code> object that maps an
-     *         <code>NCHAR</code>, <code>NVARCHAR</code> or <code>LONGNVARCHAR</code> value
-     * @throws SQLException if the parameterIndex is not valid;
-     *                      if a database access error occurs or
-     *                      this method is called on a closed <code>CallableStatement</code>
-     * @throws SQLFeatureNotSupportedException
-     *                      if the JDBC driver does not support
-     *                      this method
+     * @return a <code>String</code> object that maps an <code>NCHAR</code>,
+     * <code>NVARCHAR</code> or <code>LONGNVARCHAR</code> value
+     * @throws SQLException if the parameterIndex is not valid; if a database access
+     * error occurs or this method is called on a closed
+     * <code>CallableStatement</code>
+     * @throws SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
      * @see #setNString
      * @since 1.6
      */
+    @Override
     public String getNString(int parameterIndex) throws SQLException {
         return callableStatement.getNString(parameterIndex);
     }
 
     /**
      * Retrieves the value of the designated <code>NCHAR</code>,
-     * <code>NVARCHAR</code>
-     * or <code>LONGNVARCHAR</code> parameter as
-     * a <code>String</code> in the Java programming language.
+     * <code>NVARCHAR</code> or <code>LONGNVARCHAR</code> parameter as a
+     * <code>String</code> in the Java programming language.
      * <p/>
-     * For the fixed-length type JDBC <code>NCHAR</code>,
-     * the <code>String</code> object
-     * returned has exactly the same value the SQL
-     * <code>NCHAR</code> value had in the
-     * database, including any padding added by the database.
+     * For the fixed-length type JDBC <code>NCHAR</code>, the <code>String</code>
+     * object returned has exactly the same value the SQL <code>NCHAR</code> value
+     * had in the database, including any padding added by the database.
      *
      * @param parameterName the name of the parameter
-     * @return a <code>String</code> object that maps an
-     *         <code>NCHAR</code>, <code>NVARCHAR</code> or <code>LONGNVARCHAR</code> value
+     * @return a <code>String</code> object that maps an <code>NCHAR</code>,
+     * <code>NVARCHAR</code> or <code>LONGNVARCHAR</code> value
      * @throws SQLException if parameterName does not correspond to a named
-     *                      parameter;
-     *                      if a database access error occurs or
-     *                      this method is called on a closed <code>CallableStatement</code>
-     * @throws SQLFeatureNotSupportedException
-     *                      if the JDBC driver does not support
-     *                      this method
+     * parameter; if a database access error occurs or this method is called on a
+     * closed <code>CallableStatement</code>
+     * @throws SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
      * @see #setNString
      * @since 1.6
      */
+    @Override
     public String getNString(String parameterName) throws SQLException {
         return callableStatement.getNString(parameterName);
     }
@@ -230,17 +230,18 @@
      * <code>java.sql.RowId</code> object.
      *
      * @param parameterIndex the first parameter is 1, the second is 2,...
-     * @return a <code>RowId</code> object that represents the JDBC <code>ROWID</code>
-     *         value is used as the designated parameter. If the parameter contains
-     *         a SQL <code>NULL</code>, then a <code>null</code> value is returned.
-     * @throws SQLException if the parameterIndex is not valid;
-     *                      if a database access error occurs or
-     *                      this method is called on a closed <code>CallableStatement</code>
-     * @throws SQLFeatureNotSupportedException
-     *                      if the JDBC driver does not support
-     *                      this method
+     * @return a <code>RowId</code> object that represents the JDBC
+     * <code>ROWID</code> value is used as the designated parameter. If the
+     * parameter contains a SQL <code>NULL</code>, then a <code>null</code> value is
+     * returned.
+     * @throws SQLException if the parameterIndex is not valid; if a database access
+     * error occurs or this method is called on a closed
+     * <code>CallableStatement</code>
+     * @throws SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
      * @since 1.6
      */
+    @Override
     public RowId getRowId(int parameterIndex) throws SQLException {
         return callableStatement.getRowId(parameterIndex);
     }
@@ -250,17 +251,18 @@
      * <code>java.sql.RowId</code> object.
      *
      * @param parameterName the name of the parameter
-     * @return a <code>RowId</code> object that represents the JDBC <code>ROWID</code>
-     *         value is used as the designated parameter. If the parameter contains
-     *         a SQL <code>NULL</code>, then a <code>null</code> value is returned.
+     * @return a <code>RowId</code> object that represents the JDBC
+     * <code>ROWID</code> value is used as the designated parameter. If the
+     * parameter contains a SQL <code>NULL</code>, then a <code>null</code> value is
+     * returned.
      * @throws SQLException if parameterName does not correspond to a named
-     *                      parameter; if a database access error occurs or
-     *                      this method is called on a closed <code>CallableStatement</code>
-     * @throws SQLFeatureNotSupportedException
-     *                      if the JDBC driver does not support
-     *                      this method
+     * parameter; if a database access error occurs or this method is called on a
+     * closed <code>CallableStatement</code>
+     * @throws SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
      * @since 1.6
      */
+    @Override
     public RowId getRowId(String parameterName) throws SQLException {
         return callableStatement.getRowId(parameterName);
     }
@@ -271,14 +273,14 @@
      *
      * @param parameterIndex index of the first parameter is 1, the second is 2, ...
      * @return a <code>SQLXML</code> object that maps an <code>SQL XML</code> value
-     * @throws SQLException if the parameterIndex is not valid;
-     *                      if a database access error occurs or
-     *                      this method is called on a closed <code>CallableStatement</code>
-     * @throws SQLFeatureNotSupportedException
-     *                      if the JDBC driver does not support
-     *                      this method
+     * @throws SQLException if the parameterIndex is not valid; if a database access
+     * error occurs or this method is called on a closed
+     * <code>CallableStatement</code>
+     * @throws SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
      * @since 1.6
      */
+    @Override
     public SQLXML getSQLXML(int parameterIndex) throws SQLException {
         return callableStatement.getSQLXML(parameterIndex);
     }
@@ -290,1048 +292,1102 @@
      * @param parameterName the name of the parameter
      * @return a <code>SQLXML</code> object that maps an <code>SQL XML</code> value
      * @throws SQLException if parameterName does not correspond to a named
-     *                      parameter; if a database access error occurs or
-     *                      this method is called on a closed <code>CallableStatement</code>
-     * @throws SQLFeatureNotSupportedException
-     *                      if the JDBC driver does not support
-     *                      this method
+     * parameter; if a database access error occurs or this method is called on a
+     * closed <code>CallableStatement</code>
+     * @throws SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
      * @since 1.6
      */
+    @Override
     public SQLXML getSQLXML(String parameterName) throws SQLException {
         return callableStatement.getSQLXML(parameterName);
     }
 
     /**
-     * Sets the designated parameter to the given input stream.
-     * When a very large ASCII value is input to a <code>LONGVARCHAR</code>
-     * parameter, it may be more practical to send it via a
-     * <code>java.io.InputStream</code>. Data will be read from the stream
-     * as needed until end-of-file is reached.  The JDBC driver will
-     * do any necessary conversion from ASCII to the database char format.
+     * Sets the designated parameter to the given input stream. When a very large
+     * ASCII value is input to a <code>LONGVARCHAR</code> parameter, it may be more
+     * practical to send it via a <code>java.io.InputStream</code>. Data will be
+     * read from the stream as needed until end-of-file is reached. The JDBC driver
+     * will do any necessary conversion from ASCII to the database char format.
      * <p/>
-     * <P><B>Note:</B> This stream object can either be a standard
-     * Java stream object or your own subclass that implements the
-     * standard interface.
-     * <P><B>Note:</B> Consult your JDBC driver documentation to determine if
-     * it might be more efficient to use a version of
-     * <code>setAsciiStream</code> which takes a length parameter.
+     * <P>
+     * <B>Note:</B> This stream object can either be a standard Java stream object
+     * or your own subclass that implements the standard interface.
+     * <P>
+     * <B>Note:</B> Consult your JDBC driver documentation to determine if it might
+     * be more efficient to use a version of <code>setAsciiStream</code> which takes
+     * a length parameter.
      *
      * @param parameterName the name of the parameter
-     * @param x             the Java input stream that contains the ASCII parameter value
+     * @param x the Java input stream that contains the ASCII parameter value
      * @throws SQLException if parameterName does not correspond to a named
-     *                      parameter; if a database access error occurs or
-     *                      this method is called on a closed <code>CallableStatement</code>
-     * @throws SQLFeatureNotSupportedException
-     *                      if the JDBC driver does not support this method
+     * parameter; if a database access error occurs or this method is called on a
+     * closed <code>CallableStatement</code>
+     * @throws SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
      * @since 1.6
      */
+    @Override
     public void setAsciiStream(String parameterName, InputStream x) throws SQLException {
         callableStatement.setAsciiStream(parameterName, x);
     }
 
     /**
-     * Sets the designated parameter to the given input stream, which will have
-     * the specified number of bytes.
-     * When a very large ASCII value is input to a <code>LONGVARCHAR</code>
-     * parameter, it may be more practical to send it via a
-     * <code>java.io.InputStream</code>. Data will be read from the stream
-     * as needed until end-of-file is reached.  The JDBC driver will
-     * do any necessary conversion from ASCII to the database char format.
+     * Sets the designated parameter to the given input stream, which will have the
+     * specified number of bytes. When a very large ASCII value is input to a
+     * <code>LONGVARCHAR</code> parameter, it may be more practical to send it via a
+     * <code>java.io.InputStream</code>. Data will be read from the stream as needed
+     * until end-of-file is reached. The JDBC driver will do any necessary
+     * conversion from ASCII to the database char format.
      * <p/>
-     * <P><B>Note:</B> This stream object can either be a standard
-     * Java stream object or your own subclass that implements the
-     * standard interface.
+     * <P>
+     * <B>Note:</B> This stream object can either be a standard Java stream object
+     * or your own subclass that implements the standard interface.
      *
      * @param parameterName the name of the parameter
-     * @param x             the Java input stream that contains the ASCII parameter value
-     * @param length        the number of bytes in the stream
+     * @param x the Java input stream that contains the ASCII parameter value
+     * @param length the number of bytes in the stream
      * @throws SQLException if parameterName does not correspond to a named
-     *                      parameter; if a database access error occurs or
-     *                      this method is called on a closed <code>CallableStatement</code>
-     * @throws SQLFeatureNotSupportedException
-     *                      if the JDBC driver does not support
-     *                      this method
+     * parameter; if a database access error occurs or this method is called on a
+     * closed <code>CallableStatement</code>
+     * @throws SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
      * @since 1.6
      */
+    @Override
     public void setAsciiStream(String parameterName, InputStream x, long length) throws SQLException {
         callableStatement.setAsciiStream(parameterName, x, length);
     }
 
     /**
-     * Sets the designated parameter to the given input stream.
-     * When a very large binary value is input to a <code>LONGVARBINARY</code>
-     * parameter, it may be more practical to send it via a
-     * <code>java.io.InputStream</code> object. The data will be read from the
-     * stream as needed until end-of-file is reached.
+     * Sets the designated parameter to the given input stream. When a very large
+     * binary value is input to a <code>LONGVARBINARY</code> parameter, it may be
+     * more practical to send it via a <code>java.io.InputStream</code> object. The
+     * data will be read from the stream as needed until end-of-file is reached.
      * <p/>
-     * <P><B>Note:</B> This stream object can either be a standard
-     * Java stream object or your own subclass that implements the
-     * standard interface.
-     * <P><B>Note:</B> Consult your JDBC driver documentation to determine if
-     * it might be more efficient to use a version of
-     * <code>setBinaryStream</code> which takes a length parameter.
+     * <P>
+     * <B>Note:</B> This stream object can either be a standard Java stream object
+     * or your own subclass that implements the standard interface.
+     * <P>
+     * <B>Note:</B> Consult your JDBC driver documentation to determine if it might
+     * be more efficient to use a version of <code>setBinaryStream</code> which
+     * takes a length parameter.
      *
      * @param parameterName the name of the parameter
-     * @param x             the java input stream which contains the binary parameter value
+     * @param x the java input stream which contains the binary parameter value
      * @throws SQLException if parameterName does not correspond to a named
-     *                      parameter; if a database access error occurs or
-     *                      this method is called on a closed <code>CallableStatement</code>
-     * @throws SQLFeatureNotSupportedException
-     *                      if the JDBC driver does not support this method
+     * parameter; if a database access error occurs or this method is called on a
+     * closed <code>CallableStatement</code>
+     * @throws SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
      * @since 1.6
      */
+    @Override
     public void setBinaryStream(String parameterName, InputStream x) throws SQLException {
         callableStatement.setBinaryStream(parameterName, x);
     }
 
     /**
-     * Sets the designated parameter to the given input stream, which will have
-     * the specified number of bytes.
-     * When a very large binary value is input to a <code>LONGVARBINARY</code>
-     * parameter, it may be more practical to send it via a
-     * <code>java.io.InputStream</code> object. The data will be read from the stream
-     * as needed until end-of-file is reached.
+     * Sets the designated parameter to the given input stream, which will have the
+     * specified number of bytes. When a very large binary value is input to a
+     * <code>LONGVARBINARY</code> parameter, it may be more practical to send it via
+     * a <code>java.io.InputStream</code> object. The data will be read from the
+     * stream as needed until end-of-file is reached.
      * <p/>
-     * <P><B>Note:</B> This stream object can either be a standard
-     * Java stream object or your own subclass that implements the
-     * standard interface.
+     * <P>
+     * <B>Note:</B> This stream object can either be a standard Java stream object
+     * or your own subclass that implements the standard interface.
      *
      * @param parameterName the name of the parameter
-     * @param x             the java input stream which contains the binary parameter value
-     * @param length        the number of bytes in the stream
+     * @param x the java input stream which contains the binary parameter value
+     * @param length the number of bytes in the stream
      * @throws SQLException if parameterName does not correspond to a named
-     *                      parameter; if a database access error occurs or
-     *                      this method is called on a closed <code>CallableStatement</code>
-     * @throws SQLFeatureNotSupportedException
-     *                      if the JDBC driver does not support
-     *                      this method
+     * parameter; if a database access error occurs or this method is called on a
+     * closed <code>CallableStatement</code>
+     * @throws SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
      * @since 1.6
      */
+    @Override
     public void setBinaryStream(String parameterName, InputStream x, long length) throws SQLException {
         callableStatement.setBinaryStream(parameterName, x, length);
     }
 
     /**
      * Sets the designated parameter to the given <code>java.sql.Blob</code> object.
-     * The driver converts this to an SQL <code>BLOB</code> value when it
-     * sends it to the database.
+     * The driver converts this to an SQL <code>BLOB</code> value when it sends it
+     * to the database.
      *
      * @param parameterName the name of the parameter
-     * @param x             a <code>Blob</code> object that maps an SQL <code>BLOB</code> value
+     * @param x a <code>Blob</code> object that maps an SQL <code>BLOB</code> value
      * @throws SQLException if parameterName does not correspond to a named
-     *                      parameter; if a database access error occurs or
-     *                      this method is called on a closed <code>CallableStatement</code>
-     * @throws SQLFeatureNotSupportedException
-     *                      if the JDBC driver does not support
-     *                      this method
+     * parameter; if a database access error occurs or this method is called on a
+     * closed <code>CallableStatement</code>
+     * @throws SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
      * @since 1.6
      */
+    @Override
     public void setBlob(String parameterName, Blob x) throws SQLException {
         callableStatement.setBlob(parameterName, x);
     }
 
     /**
-     * Sets the designated parameter to a <code>InputStream</code> object.
-     * This method differs from the <code>setBinaryStream (int, InputStream)</code>
-     * method because it informs the driver that the parameter value should be
-     * sent to the server as a <code>BLOB</code>.  When the <code>setBinaryStream</code> method is used,
-     * the driver may have to do extra work to determine whether the parameter
-     * data should be send to the server as a <code>LONGVARBINARY</code> or a <code>BLOB</code>
+     * Sets the designated parameter to a <code>InputStream</code> object. This
+     * method differs from the <code>setBinaryStream (int, InputStream)</code>
+     * method because it informs the driver that the parameter value should be sent
+     * to the server as a <code>BLOB</code>. When the <code>setBinaryStream</code>
+     * method is used, the driver may have to do extra work to determine whether the
+     * parameter data should be send to the server as a <code>LONGVARBINARY</code>
+     * or a <code>BLOB</code>
      * <p/>
-     * <P><B>Note:</B> Consult your JDBC driver documentation to determine if
-     * it might be more efficient to use a version of
-     * <code>setBlob</code> which takes a length parameter.
+     * <P>
+     * <B>Note:</B> Consult your JDBC driver documentation to determine if it might
+     * be more efficient to use a version of <code>setBlob</code> which takes a
+     * length parameter.
      *
      * @param parameterName the name of the parameter
-     * @param inputStream   An object that contains the data to set the parameter
-     *                      value to.
+     * @param inputStream An object that contains the data to set the parameter
+     * value to.
      * @throws SQLException if parameterName does not correspond to a named
-     *                      parameter; if a database access error occurs or
-     *                      this method is called on a closed <code>CallableStatement</code>
-     * @throws SQLFeatureNotSupportedException
-     *                      if the JDBC driver does not support this method
+     * parameter; if a database access error occurs or this method is called on a
+     * closed <code>CallableStatement</code>
+     * @throws SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
      * @since 1.6
      */
+    @Override
     public void setBlob(String parameterName, InputStream inputStream) throws SQLException {
         callableStatement.setBlob(parameterName, inputStream);
     }
 
     /**
-     * Sets the designated parameter to a <code>InputStream</code> object.  The <code>inputstream</code> must contain  the number
-     * of characters specified by length, otherwise a <code>SQLException</code> will be
-     * generated when the <code>CallableStatement</code> is executed.
-     * This method differs from the <code>setBinaryStream (int, InputStream, int)</code>
-     * method because it informs the driver that the parameter value should be
-     * sent to the server as a <code>BLOB</code>.  When the <code>setBinaryStream</code> method is used,
-     * the driver may have to do extra work to determine whether the parameter
-     * data should be sent to the server as a <code>LONGVARBINARY</code> or a <code>BLOB</code>
+     * Sets the designated parameter to a <code>InputStream</code> object. The
+     * <code>inputstream</code> must contain the number of characters specified by
+     * length, otherwise a <code>SQLException</code> will be generated when the
+     * <code>CallableStatement</code> is executed. This method differs from the
+     * <code>setBinaryStream (int, InputStream, int)</code> method because it
+     * informs the driver that the parameter value should be sent to the server as a
+     * <code>BLOB</code>. When the <code>setBinaryStream</code> method is used, the
+     * driver may have to do extra work to determine whether the parameter data
+     * should be sent to the server as a <code>LONGVARBINARY</code> or a
+     * <code>BLOB</code>
      *
-     * @param parameterName the name of the parameter to be set
-     *                      the second is 2, ...
-     * @param inputStream   An object that contains the data to set the parameter
-     *                      value to.
-     * @param length        the number of bytes in the parameter data.
+     * @param parameterName the name of the parameter to be set the second is 2, ...
+     * @param inputStream An object that contains the data to set the parameter
+     * value to.
+     * @param length the number of bytes in the parameter data.
      * @throws SQLException if parameterName does not correspond to a named
-     *                      parameter; if the length specified
-     *                      is less than zero; if the number of bytes in the inputstream does not match
-     *                      the specfied length; if a database access error occurs or
-     *                      this method is called on a closed <code>CallableStatement</code>
-     * @throws SQLFeatureNotSupportedException
-     *                      if the JDBC driver does not support
-     *                      this method
+     * parameter; if the length specified is less than zero; if the number of bytes
+     * in the inputstream does not match the specfied length; if a database access
+     * error occurs or this method is called on a closed
+     * <code>CallableStatement</code>
+     * @throws SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
      * @since 1.6
      */
+    @Override
     public void setBlob(String parameterName, InputStream inputStream, long length) throws SQLException {
         callableStatement.setBlob(parameterName, inputStream, length);
     }
 
     /**
-     * Sets the designated parameter to the given <code>Reader</code>
-     * object.
-     * When a very large UNICODE value is input to a <code>LONGVARCHAR</code>
-     * parameter, it may be more practical to send it via a
-     * <code>java.io.Reader</code> object. The data will be read from the stream
-     * as needed until end-of-file is reached.  The JDBC driver will
-     * do any necessary conversion from UNICODE to the database char format.
+     * Sets the designated parameter to the given <code>Reader</code> object. When a
+     * very large UNICODE value is input to a <code>LONGVARCHAR</code> parameter, it
+     * may be more practical to send it via a <code>java.io.Reader</code> object.
+     * The data will be read from the stream as needed until end-of-file is reached.
+     * The JDBC driver will do any necessary conversion from UNICODE to the database
+     * char format.
      * <p/>
-     * <P><B>Note:</B> This stream object can either be a standard
-     * Java stream object or your own subclass that implements the
-     * standard interface.
-     * <P><B>Note:</B> Consult your JDBC driver documentation to determine if
-     * it might be more efficient to use a version of
-     * <code>setCharacterStream</code> which takes a length parameter.
+     * <P>
+     * <B>Note:</B> This stream object can either be a standard Java stream object
+     * or your own subclass that implements the standard interface.
+     * <P>
+     * <B>Note:</B> Consult your JDBC driver documentation to determine if it might
+     * be more efficient to use a version of <code>setCharacterStream</code> which
+     * takes a length parameter.
      *
      * @param parameterName the name of the parameter
-     * @param reader        the <code>java.io.Reader</code> object that contains the
-     *                      Unicode data
+     * @param reader the <code>java.io.Reader</code> object that contains the
+     * Unicode data
      * @throws SQLException if parameterName does not correspond to a named
-     *                      parameter; if a database access error occurs or
-     *                      this method is called on a closed <code>CallableStatement</code>
-     * @throws SQLFeatureNotSupportedException
-     *                      if the JDBC driver does not support this method
+     * parameter; if a database access error occurs or this method is called on a
+     * closed <code>CallableStatement</code>
+     * @throws SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
      * @since 1.6
      */
+    @Override
     public void setCharacterStream(String parameterName, Reader reader) throws SQLException {
         callableStatement.setCharacterStream(parameterName, reader);
     }
 
     /**
-     * Sets the designated parameter to the given <code>Reader</code>
-     * object, which is the given number of characters long.
-     * When a very large UNICODE value is input to a <code>LONGVARCHAR</code>
-     * parameter, it may be more practical to send it via a
-     * <code>java.io.Reader</code> object. The data will be read from the stream
-     * as needed until end-of-file is reached.  The JDBC driver will
-     * do any necessary conversion from UNICODE to the database char format.
+     * Sets the designated parameter to the given <code>Reader</code> object, which
+     * is the given number of characters long. When a very large UNICODE value is
+     * input to a <code>LONGVARCHAR</code> parameter, it may be more practical to
+     * send it via a <code>java.io.Reader</code> object. The data will be read from
+     * the stream as needed until end-of-file is reached. The JDBC driver will do
+     * any necessary conversion from UNICODE to the database char format.
      * <p/>
-     * <P><B>Note:</B> This stream object can either be a standard
-     * Java stream object or your own subclass that implements the
-     * standard interface.
+     * <P>
+     * <B>Note:</B> This stream object can either be a standard Java stream object
+     * or your own subclass that implements the standard interface.
      *
      * @param parameterName the name of the parameter
-     * @param reader        the <code>java.io.Reader</code> object that
-     *                      contains the UNICODE data used as the designated parameter
-     * @param length        the number of characters in the stream
+     * @param reader the <code>java.io.Reader</code> object that contains the
+     * UNICODE data used as the designated parameter
+     * @param length the number of characters in the stream
      * @throws SQLException if parameterName does not correspond to a named
-     *                      parameter; if a database access error occurs or
-     *                      this method is called on a closed <code>CallableStatement</code>
-     * @throws SQLFeatureNotSupportedException
-     *                      if the JDBC driver does not support
-     *                      this method
+     * parameter; if a database access error occurs or this method is called on a
+     * closed <code>CallableStatement</code>
+     * @throws SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
      * @since 1.6
      */
+    @Override
     public void setCharacterStream(String parameterName, Reader reader, long length) throws SQLException {
         callableStatement.setCharacterStream(parameterName, reader, length);
     }
 
     /**
      * Sets the designated parameter to the given <code>java.sql.Clob</code> object.
-     * The driver converts this to an SQL <code>CLOB</code> value when it
-     * sends it to the database.
+     * The driver converts this to an SQL <code>CLOB</code> value when it sends it
+     * to the database.
      *
      * @param parameterName the name of the parameter
-     * @param x             a <code>Clob</code> object that maps an SQL <code>CLOB</code> value
+     * @param x a <code>Clob</code> object that maps an SQL <code>CLOB</code> value
      * @throws SQLException if parameterName does not correspond to a named
-     *                      parameter; if a database access error occurs or
-     *                      this method is called on a closed <code>CallableStatement</code>
-     * @throws SQLFeatureNotSupportedException
-     *                      if the JDBC driver does not support
-     *                      this method
+     * parameter; if a database access error occurs or this method is called on a
+     * closed <code>CallableStatement</code>
+     * @throws SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
      * @since 1.6
      */
+    @Override
     public void setClob(String parameterName, Clob x) throws SQLException {
         callableStatement.setClob(parameterName, x);
     }
 
     /**
-     * Sets the designated parameter to a <code>Reader</code> object.
-     * This method differs from the <code>setCharacterStream (int, Reader)</code> method
-     * because it informs the driver that the parameter value should be sent to
-     * the server as a <code>CLOB</code>.  When the <code>setCharacterStream</code> method is used, the
-     * driver may have to do extra work to determine whether the parameter
-     * data should be send to the server as a <code>LONGVARCHAR</code> or a <code>CLOB</code>
+     * Sets the designated parameter to a <code>Reader</code> object. This method
+     * differs from the <code>setCharacterStream (int, Reader)</code> method because
+     * it informs the driver that the parameter value should be sent to the server
+     * as a <code>CLOB</code>. When the <code>setCharacterStream</code> method is
+     * used, the driver may have to do extra work to determine whether the parameter
+     * data should be send to the server as a <code>LONGVARCHAR</code> or a
+     * <code>CLOB</code>
      * <p/>
-     * <P><B>Note:</B> Consult your JDBC driver documentation to determine if
-     * it might be more efficient to use a version of
-     * <code>setClob</code> which takes a length parameter.
+     * <P>
+     * <B>Note:</B> Consult your JDBC driver documentation to determine if it might
+     * be more efficient to use a version of <code>setClob</code> which takes a
+     * length parameter.
      *
      * @param parameterName the name of the parameter
-     * @param reader        An object that contains the data to set the parameter value to.
+     * @param reader An object that contains the data to set the parameter value to.
      * @throws SQLException if parameterName does not correspond to a named
-     *                      parameter; if a database access error occurs or this method is called on
-     *                      a closed <code>CallableStatement</code>
-     * @throws SQLFeatureNotSupportedException
-     *                      if the JDBC driver does not support this method
+     * parameter; if a database access error occurs or this method is called on a
+     * closed <code>CallableStatement</code>
+     * @throws SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
      * @since 1.6
      */
+    @Override
     public void setClob(String parameterName, Reader reader) throws SQLException {
         callableStatement.setClob(parameterName, reader);
     }
 
     /**
      * Sets the designated parameter to a <code>Reader</code> object. The
-     * <code>Reader</code> reads the data till end-of-file is reached. The
-     * driver does the necessary conversion from Java character format to
-     * the national character set in the database.
+     * <code>Reader</code> reads the data till end-of-file is reached. The driver
+     * does the necessary conversion from Java character format to the national
+     * character set in the database.
      * <p/>
-     * <P><B>Note:</B> This stream object can either be a standard
-     * Java stream object or your own subclass that implements the
-     * standard interface.
-     * <P><B>Note:</B> Consult your JDBC driver documentation to determine if
-     * it might be more efficient to use a version of
-     * <code>setNCharacterStream</code> which takes a length parameter.
+     * <P>
+     * <B>Note:</B> This stream object can either be a standard Java stream object
+     * or your own subclass that implements the standard interface.
+     * <P>
+     * <B>Note:</B> Consult your JDBC driver documentation to determine if it might
+     * be more efficient to use a version of <code>setNCharacterStream</code> which
+     * takes a length parameter.
      *
      * @param parameterName the name of the parameter
-     * @param value         the parameter value
+     * @param value the parameter value
      * @throws SQLException if parameterName does not correspond to a named
-     *                      parameter; if the driver does not support national
-     *                      character sets;  if the driver can detect that a data conversion
-     *                      error could occur; if a database access error occurs; or
-     *                      this method is called on a closed <code>CallableStatement</code>
-     * @throws SQLFeatureNotSupportedException
-     *                      if the JDBC driver does not support this method
+     * parameter; if the driver does not support national character sets; if the
+     * driver can detect that a data conversion error could occur; if a database
+     * access error occurs; or this method is called on a closed
+     * <code>CallableStatement</code>
+     * @throws SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
      * @since 1.6
      */
+    @Override
     public void setNCharacterStream(String parameterName, Reader value) throws SQLException {
         callableStatement.setNCharacterStream(parameterName, value);
     }
 
     /**
      * Sets the designated parameter to a <code>Reader</code> object. The
-     * <code>Reader</code> reads the data till end-of-file is reached. The
-     * driver does the necessary conversion from Java character format to
-     * the national character set in the database.
+     * <code>Reader</code> reads the data till end-of-file is reached. The driver
+     * does the necessary conversion from Java character format to the national
+     * character set in the database.
      *
      * @param parameterName the name of the parameter to be set
-     * @param value         the parameter value
-     * @param length        the number of characters in the parameter data.
+     * @param value the parameter value
+     * @param length the number of characters in the parameter data.
      * @throws SQLException if parameterName does not correspond to a named
-     *                      parameter; if the driver does not support national
-     *                      character sets;  if the driver can detect that a data conversion
-     *                      error could occur; if a database access error occurs or
-     *                      this method is called on a closed <code>CallableStatement</code>
-     * @throws SQLFeatureNotSupportedException
-     *                      if the JDBC driver does not support
-     *                      this method
+     * parameter; if the driver does not support national character sets; if the
+     * driver can detect that a data conversion error could occur; if a database
+     * access error occurs or this method is called on a closed
+     * <code>CallableStatement</code>
+     * @throws SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
      * @since 1.6
      */
+    @Override
     public void setNCharacterStream(String parameterName, Reader value, long length) throws SQLException {
         callableStatement.setNCharacterStream(parameterName, value, length);
     }
 
     /**
-     * Sets the designated parameter to a <code>Reader</code> object.
-     * This method differs from the <code>setCharacterStream (int, Reader)</code> method
-     * because it informs the driver that the parameter value should be sent to
-     * the server as a <code>NCLOB</code>.  When the <code>setCharacterStream</code> method is used, the
-     * driver may have to do extra work to determine whether the parameter
-     * data should be send to the server as a <code>LONGNVARCHAR</code> or a <code>NCLOB</code>
-     * <P><B>Note:</B> Consult your JDBC driver documentation to determine if
-     * it might be more efficient to use a version of
-     * <code>setNClob</code> which takes a length parameter.
+     * Sets the designated parameter to a <code>Reader</code> object. This method
+     * differs from the <code>setCharacterStream (int, Reader)</code> method because
+     * it informs the driver that the parameter value should be sent to the server
+     * as a <code>NCLOB</code>. When the <code>setCharacterStream</code> method is
+     * used, the driver may have to do extra work to determine whether the parameter
+     * data should be send to the server as a <code>LONGNVARCHAR</code> or a
+     * <code>NCLOB</code>
+     * <P>
+     * <B>Note:</B> Consult your JDBC driver documentation to determine if it might
+     * be more efficient to use a version of <code>setNClob</code> which takes a
+     * length parameter.
      *
      * @param parameterName the name of the parameter
-     * @param reader        An object that contains the data to set the parameter value to.
+     * @param reader An object that contains the data to set the parameter value to.
      * @throws SQLException if parameterName does not correspond to a named
-     *                      parameter; if the driver does not support national character sets;
-     *                      if the driver can detect that a data conversion
-     *                      error could occur;  if a database access error occurs or
-     *                      this method is called on a closed <code>CallableStatement</code>
-     * @throws SQLFeatureNotSupportedException
-     *                      if the JDBC driver does not support this method
+     * parameter; if the driver does not support national character sets; if the
+     * driver can detect that a data conversion error could occur; if a database
+     * access error occurs or this method is called on a closed
+     * <code>CallableStatement</code>
+     * @throws SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
      * @since 1.6
      */
+    @Override
     public void setNClob(String parameterName, NClob reader) throws SQLException {
         callableStatement.setNClob(parameterName, reader);
     }
 
     /**
-     * Sets the designated parameter to a <code>Reader</code> object.  The <code>reader</code> must contain  the number
-     * of characters specified by length otherwise a <code>SQLException</code> will be
-     * generated when the <code>CallableStatement</code> is executed.
-     * This method differs from the <code>setCharacterStream (int, Reader, int)</code> method
-     * because it informs the driver that the parameter value should be sent to
-     * the server as a <code>CLOB</code>.  When the <code>setCharacterStream</code> method is used, the
-     * driver may have to do extra work to determine whether the parameter
-     * data should be send to the server as a <code>LONGVARCHAR</code> or a <code>CLOB</code>
+     * Sets the designated parameter to a <code>Reader</code> object. The
+     * <code>reader</code> must contain the number of characters specified by length
+     * otherwise a <code>SQLException</code> will be generated when the
+     * <code>CallableStatement</code> is executed. This method differs from the
+     * <code>setCharacterStream (int, Reader, int)</code> method because it informs
+     * the driver that the parameter value should be sent to the server as a
+     * <code>CLOB</code>. When the <code>setCharacterStream</code> method is used,
+     * the driver may have to do extra work to determine whether the parameter data
+     * should be send to the server as a <code>LONGVARCHAR</code> or a
+     * <code>CLOB</code>
      *
      * @param parameterName the name of the parameter to be set
-     * @param reader        An object that contains the data to set the parameter value to.
-     * @param length        the number of characters in the parameter data.
+     * @param reader An object that contains the data to set the parameter value to.
+     * @param length the number of characters in the parameter data.
      * @throws SQLException if parameterName does not correspond to a named
-     *                      parameter; if the length specified is less than zero;
-     *                      a database access error occurs or
-     *                      this method is called on a closed <code>CallableStatement</code>
-     * @throws SQLFeatureNotSupportedException
-     *                      if the JDBC driver does not support
-     *                      this method
+     * parameter; if the length specified is less than zero; a database access error
+     * occurs or this method is called on a closed <code>CallableStatement</code>
+     * @throws SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
      * @since 1.6
      */
+    @Override
     public void setClob(String parameterName, Reader reader, long length) throws SQLException {
         callableStatement.setClob(parameterName, reader, length);
     }
 
     /**
-     * Sets the designated parameter to a <code>Reader</code> object.
-     * This method differs from the <code>setCharacterStream (int, Reader)</code> method
-     * because it informs the driver that the parameter value should be sent to
-     * the server as a <code>NCLOB</code>.  When the <code>setCharacterStream</code> method is used, the
-     * driver may have to do extra work to determine whether the parameter
-     * data should be send to the server as a <code>LONGNVARCHAR</code> or a <code>NCLOB</code>
-     * <P><B>Note:</B> Consult your JDBC driver documentation to determine if
-     * it might be more efficient to use a version of
-     * <code>setNClob</code> which takes a length parameter.
+     * Sets the designated parameter to a <code>Reader</code> object. This method
+     * differs from the <code>setCharacterStream (int, Reader)</code> method because
+     * it informs the driver that the parameter value should be sent to the server
+     * as a <code>NCLOB</code>. When the <code>setCharacterStream</code> method is
+     * used, the driver may have to do extra work to determine whether the parameter
+     * data should be send to the server as a <code>LONGNVARCHAR</code> or a
+     * <code>NCLOB</code>
+     * <P>
+     * <B>Note:</B> Consult your JDBC driver documentation to determine if it might
+     * be more efficient to use a version of <code>setNClob</code> which takes a
+     * length parameter.
      *
      * @param parameterName the name of the parameter
-     * @param reader        An object that contains the data to set the parameter value to.
+     * @param reader An object that contains the data to set the parameter value to.
      * @throws SQLException if parameterName does not correspond to a named
-     *                      parameter; if the driver does not support national character sets;
-     *                      if the driver can detect that a data conversion
-     *                      error could occur;  if a database access error occurs or
-     *                      this method is called on a closed <code>CallableStatement</code>
-     * @throws SQLFeatureNotSupportedException
-     *                      if the JDBC driver does not support this method
+     * parameter; if the driver does not support national character sets; if the
+     * driver can detect that a data conversion error could occur; if a database
+     * access error occurs or this method is called on a closed
+     * <code>CallableStatement</code>
+     * @throws SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
      * @since 1.6
      */
+    @Override
     public void setNClob(String parameterName, Reader reader) throws SQLException {
         callableStatement.setNClob(parameterName, reader);
     }
 
     /**
-     * Sets the designated parameter to a <code>Reader</code> object.  The <code>reader</code> must contain  the number
-     * of characters specified by length otherwise a <code>SQLException</code> will be
-     * generated when the <code>CallableStatement</code> is executed.
-     * This method differs from the <code>setCharacterStream (int, Reader, int)</code> method
-     * because it informs the driver that the parameter value should be sent to
-     * the server as a <code>NCLOB</code>.  When the <code>setCharacterStream</code> method is used, the
-     * driver may have to do extra work to determine whether the parameter
-     * data should be send to the server as a <code>LONGNVARCHAR</code> or a <code>NCLOB</code>
+     * Sets the designated parameter to a <code>Reader</code> object. The
+     * <code>reader</code> must contain the number of characters specified by length
+     * otherwise a <code>SQLException</code> will be generated when the
+     * <code>CallableStatement</code> is executed. This method differs from the
+     * <code>setCharacterStream (int, Reader, int)</code> method because it informs
+     * the driver that the parameter value should be sent to the server as a
+     * <code>NCLOB</code>. When the <code>setCharacterStream</code> method is used,
+     * the driver may have to do extra work to determine whether the parameter data
+     * should be send to the server as a <code>LONGNVARCHAR</code> or a
+     * <code>NCLOB</code>
      *
      * @param parameterName the name of the parameter to be set
-     * @param reader        An object that contains the data to set the parameter value to.
-     * @param length        the number of characters in the parameter data.
+     * @param reader An object that contains the data to set the parameter value to.
+     * @param length the number of characters in the parameter data.
      * @throws SQLException if parameterName does not correspond to a named
-     *                      parameter; if the length specified is less than zero;
-     *                      if the driver does not support national
-     *                      character sets;  if the driver can detect that a data conversion
-     *                      error could occur; if a database access error occurs or
-     *                      this method is called on a closed <code>CallableStatement</code>
-     * @throws SQLFeatureNotSupportedException
-     *                      if the JDBC driver does not support
-     *                      this method
+     * parameter; if the length specified is less than zero; if the driver does not
+     * support national character sets; if the driver can detect that a data
+     * conversion error could occur; if a database access error occurs or this
+     * method is called on a closed <code>CallableStatement</code>
+     * @throws SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
      * @since 1.6
      */
+    @Override
     public void setNClob(String parameterName, Reader reader, long length) throws SQLException {
         callableStatement.setNClob(parameterName, reader, length);
     }
 
     /**
-     * Sets the designated parameter to the given <code>String</code> object.
-     * The driver converts this to a SQL <code>NCHAR</code> or
-     * <code>NVARCHAR</code> or <code>LONGNVARCHAR</code>
+     * Sets the designated parameter to the given <code>String</code> object. The
+     * driver converts this to a SQL <code>NCHAR</code> or <code>NVARCHAR</code> or
+     * <code>LONGNVARCHAR</code>
      *
      * @param parameterName the name of the parameter to be set
-     * @param value         the parameter value
+     * @param value the parameter value
      * @throws SQLException if parameterName does not correspond to a named
-     *                      parameter; if the driver does not support national
-     *                      character sets;  if the driver can detect that a data conversion
-     *                      error could occur; if a database access error occurs or
-     *                      this method is called on a closed <code>CallableStatement</code>
-     * @throws SQLFeatureNotSupportedException
-     *                      if the JDBC driver does not support
-     *                      this method
+     * parameter; if the driver does not support national character sets; if the
+     * driver can detect that a data conversion error could occur; if a database
+     * access error occurs or this method is called on a closed
+     * <code>CallableStatement</code>
+     * @throws SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
      * @since 1.6
      */
+    @Override
     public void setNString(String parameterName, String value) throws SQLException {
         callableStatement.setNString(parameterName, value);
     }
 
     /**
-     * Sets the designated parameter to the given <code>java.sql.RowId</code> object. The
-     * driver converts this to a SQL <code>ROWID</code> when it sends it to the
-     * database.
+     * Sets the designated parameter to the given <code>java.sql.RowId</code>
+     * object. The driver converts this to a SQL <code>ROWID</code> when it sends it
+     * to the database.
      *
      * @param parameterName the name of the parameter
-     * @param x             the parameter value
+     * @param x the parameter value
      * @throws SQLException if parameterName does not correspond to a named
-     *                      parameter; if a database access error occurs or
-     *                      this method is called on a closed <code>CallableStatement</code>
-     * @throws SQLFeatureNotSupportedException
-     *                      if the JDBC driver does not support
-     *                      this method
+     * parameter; if a database access error occurs or this method is called on a
+     * closed <code>CallableStatement</code>
+     * @throws SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
      * @since 1.6
      */
+    @Override
     public void setRowId(String parameterName, RowId x) throws SQLException {
         callableStatement.setRowId(parameterName, x);
     }
 
     /**
-     * Sets the designated parameter to the given <code>java.sql.SQLXML</code> object. The driver converts this to an
-     * <code>SQL XML</code> value when it sends it to the database.
+     * Sets the designated parameter to the given <code>java.sql.SQLXML</code>
+     * object. The driver converts this to an <code>SQL XML</code> value when it
+     * sends it to the database.
      *
      * @param parameterName the name of the parameter
-     * @param xmlObject     a <code>SQLXML</code> object that maps an <code>SQL XML</code> value
+     * @param xmlObject a <code>SQLXML</code> object that maps an
+     * <code>SQL XML</code> value
      * @throws SQLException if parameterName does not correspond to a named
-     *                      parameter; if a database access error occurs;
-     *                      this method is called on a closed <code>CallableStatement</code> or
-     *                      the <code>java.xml.transform.Result</code>,
-     *                      <code>Writer</code> or <code>OutputStream</code> has not been closed for the <code>SQLXML</code> object
-     * @throws SQLFeatureNotSupportedException
-     *                      if the JDBC driver does not support
-     *                      this method
+     * parameter; if a database access error occurs; this method is called on a
+     * closed <code>CallableStatement</code> or the
+     * <code>java.xml.transform.Result</code>, <code>Writer</code> or
+     * <code>OutputStream</code> has not been closed for the <code>SQLXML</code>
+     * object
+     * @throws SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
      * @since 1.6
      */
+    @Override
     public void setSQLXML(String parameterName, SQLXML xmlObject) throws SQLException {
         callableStatement.setSQLXML(parameterName, xmlObject);
     }
 
     /**
-     * Sets the designated parameter to the given input stream.
-     * When a very large ASCII value is input to a <code>LONGVARCHAR</code>
-     * parameter, it may be more practical to send it via a
-     * <code>java.io.InputStream</code>. Data will be read from the stream
-     * as needed until end-of-file is reached.  The JDBC driver will
-     * do any necessary conversion from ASCII to the database char format.
+     * Sets the designated parameter to the given input stream. When a very large
+     * ASCII value is input to a <code>LONGVARCHAR</code> parameter, it may be more
+     * practical to send it via a <code>java.io.InputStream</code>. Data will be
+     * read from the stream as needed until end-of-file is reached. The JDBC driver
+     * will do any necessary conversion from ASCII to the database char format.
      * <p/>
-     * <P><B>Note:</B> This stream object can either be a standard
-     * Java stream object or your own subclass that implements the
-     * standard interface.
-     * <P><B>Note:</B> Consult your JDBC driver documentation to determine if
-     * it might be more efficient to use a version of
-     * <code>setAsciiStream</code> which takes a length parameter.
+     * <P>
+     * <B>Note:</B> This stream object can either be a standard Java stream object
+     * or your own subclass that implements the standard interface.
+     * <P>
+     * <B>Note:</B> Consult your JDBC driver documentation to determine if it might
+     * be more efficient to use a version of <code>setAsciiStream</code> which takes
+     * a length parameter.
      *
      * @param parameterIndex the first parameter is 1, the second is 2, ...
-     * @param x              the Java input stream that contains the ASCII parameter value
+     * @param x the Java input stream that contains the ASCII parameter value
      * @throws SQLException if parameterIndex does not correspond to a parameter
-     *                      marker in the SQL statement; if a database access error occurs or
-     *                      this method is called on a closed <code>PreparedStatement</code>
-     * @throws SQLFeatureNotSupportedException
-     *                      if the JDBC driver does not support this method
+     * marker in the SQL statement; if a database access error occurs or this method
+     * is called on a closed <code>PreparedStatement</code>
+     * @throws SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
      * @since 1.6
      */
+    @Override
     public void setAsciiStream(int parameterIndex, InputStream x) throws SQLException {
         callableStatement.setAsciiStream(parameterIndex, x);
     }
 
     /**
-     * Sets the designated parameter to the given input stream, which will have
-     * the specified number of bytes.
-     * When a very large ASCII value is input to a <code>LONGVARCHAR</code>
-     * parameter, it may be more practical to send it via a
-     * <code>java.io.InputStream</code>. Data will be read from the stream
-     * as needed until end-of-file is reached.  The JDBC driver will
-     * do any necessary conversion from ASCII to the database char format.
+     * Sets the designated parameter to the given input stream, which will have the
+     * specified number of bytes. When a very large ASCII value is input to a
+     * <code>LONGVARCHAR</code> parameter, it may be more practical to send it via a
+     * <code>java.io.InputStream</code>. Data will be read from the stream as needed
+     * until end-of-file is reached. The JDBC driver will do any necessary
+     * conversion from ASCII to the database char format.
      * <p/>
-     * <P><B>Note:</B> This stream object can either be a standard
-     * Java stream object or your own subclass that implements the
-     * standard interface.
+     * <P>
+     * <B>Note:</B> This stream object can either be a standard Java stream object
+     * or your own subclass that implements the standard interface.
      *
      * @param parameterIndex the first parameter is 1, the second is 2, ...
-     * @param x              the Java input stream that contains the ASCII parameter value
-     * @param length         the number of bytes in the stream
+     * @param x the Java input stream that contains the ASCII parameter value
+     * @param length the number of bytes in the stream
      * @throws SQLException if parameterIndex does not correspond to a parameter
-     *                      marker in the SQL statement; if a database access error occurs or
-     *                      this method is called on a closed <code>PreparedStatement</code>
+     * marker in the SQL statement; if a database access error occurs or this method
+     * is called on a closed <code>PreparedStatement</code>
      * @since 1.6
      */
+    @Override
     public void setAsciiStream(int parameterIndex, InputStream x, long length) throws SQLException {
         callableStatement.setAsciiStream(parameterIndex, x, length);
     }
 
     /**
-     * Sets the designated parameter to the given input stream.
-     * When a very large binary value is input to a <code>LONGVARBINARY</code>
-     * parameter, it may be more practical to send it via a
-     * <code>java.io.InputStream</code> object. The data will be read from the
-     * stream as needed until end-of-file is reached.
+     * Sets the designated parameter to the given input stream. When a very large
+     * binary value is input to a <code>LONGVARBINARY</code> parameter, it may be
+     * more practical to send it via a <code>java.io.InputStream</code> object. The
+     * data will be read from the stream as needed until end-of-file is reached.
      * <p/>
-     * <P><B>Note:</B> This stream object can either be a standard
-     * Java stream object or your own subclass that implements the
-     * standard interface.
-     * <P><B>Note:</B> Consult your JDBC driver documentation to determine if
-     * it might be more efficient to use a version of
-     * <code>setBinaryStream</code> which takes a length parameter.
+     * <P>
+     * <B>Note:</B> This stream object can either be a standard Java stream object
+     * or your own subclass that implements the standard interface.
+     * <P>
+     * <B>Note:</B> Consult your JDBC driver documentation to determine if it might
+     * be more efficient to use a version of <code>setBinaryStream</code> which
+     * takes a length parameter.
      *
      * @param parameterIndex the first parameter is 1, the second is 2, ...
-     * @param x              the java input stream which contains the binary parameter value
+     * @param x the java input stream which contains the binary parameter value
      * @throws SQLException if parameterIndex does not correspond to a parameter
-     *                      marker in the SQL statement; if a database access error occurs or
-     *                      this method is called on a closed <code>PreparedStatement</code>
-     * @throws SQLFeatureNotSupportedException
-     *                      if the JDBC driver does not support this method
+     * marker in the SQL statement; if a database access error occurs or this method
+     * is called on a closed <code>PreparedStatement</code>
+     * @throws SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
      * @since 1.6
      */
+    @Override
     public void setBinaryStream(int parameterIndex, InputStream x) throws SQLException {
         callableStatement.setBinaryStream(parameterIndex, x);
     }
 
     /**
-     * Sets the designated parameter to the given input stream, which will have
-     * the specified number of bytes.
-     * When a very large binary value is input to a <code>LONGVARBINARY</code>
-     * parameter, it may be more practical to send it via a
-     * <code>java.io.InputStream</code> object. The data will be read from the
+     * Sets the designated parameter to the given input stream, which will have the
+     * specified number of bytes. When a very large binary value is input to a
+     * <code>LONGVARBINARY</code> parameter, it may be more practical to send it via
+     * a <code>java.io.InputStream</code> object. The data will be read from the
      * stream as needed until end-of-file is reached.
      * <p/>
-     * <P><B>Note:</B> This stream object can either be a standard
-     * Java stream object or your own subclass that implements the
-     * standard interface.
+     * <P>
+     * <B>Note:</B> This stream object can either be a standard Java stream object
+     * or your own subclass that implements the standard interface.
      *
      * @param parameterIndex the first parameter is 1, the second is 2, ...
-     * @param x              the java input stream which contains the binary parameter value
-     * @param length         the number of bytes in the stream
+     * @param x the java input stream which contains the binary parameter value
+     * @param length the number of bytes in the stream
      * @throws SQLException if parameterIndex does not correspond to a parameter
-     *                      marker in the SQL statement; if a database access error occurs or
-     *                      this method is called on a closed <code>PreparedStatement</code>
+     * marker in the SQL statement; if a database access error occurs or this method
+     * is called on a closed <code>PreparedStatement</code>
      * @since 1.6
      */
+    @Override
     public void setBinaryStream(int parameterIndex, InputStream x, long length) throws SQLException {
         callableStatement.setBinaryStream(parameterIndex, x, length);
     }
 
     /**
-     * Sets the designated parameter to a <code>InputStream</code> object.
-     * This method differs from the <code>setBinaryStream (int, InputStream)</code>
-     * method because it informs the driver that the parameter value should be
-     * sent to the server as a <code>BLOB</code>.  When the <code>setBinaryStream</code> method is used,
-     * the driver may have to do extra work to determine whether the parameter
-     * data should be sent to the server as a <code>LONGVARBINARY</code> or a <code>BLOB</code>
+     * Sets the designated parameter to a <code>InputStream</code> object. This
+     * method differs from the <code>setBinaryStream (int, InputStream)</code>
+     * method because it informs the driver that the parameter value should be sent
+     * to the server as a <code>BLOB</code>. When the <code>setBinaryStream</code>
+     * method is used, the driver may have to do extra work to determine whether the
+     * parameter data should be sent to the server as a <code>LONGVARBINARY</code>
+     * or a <code>BLOB</code>
      * <p/>
-     * <P><B>Note:</B> Consult your JDBC driver documentation to determine if
-     * it might be more efficient to use a version of
-     * <code>setBlob</code> which takes a length parameter.
+     * <P>
+     * <B>Note:</B> Consult your JDBC driver documentation to determine if it might
+     * be more efficient to use a version of <code>setBlob</code> which takes a
+     * length parameter.
      *
-     * @param parameterIndex index of the first parameter is 1,
-     *                       the second is 2, ...
-     * @param inputStream    An object that contains the data to set the parameter
-     *                       value to.
+     * @param parameterIndex index of the first parameter is 1, the second is 2, ...
+     * @param inputStream An object that contains the data to set the parameter
+     * value to.
      * @throws SQLException if parameterIndex does not correspond to a parameter
-     *                      marker in the SQL statement; if a database access error occurs;
-     *                      this method is called on a closed <code>PreparedStatement</code> or
-     *                      if parameterIndex does not correspond
-     *                      to a parameter marker in the SQL statement,
-     * @throws SQLFeatureNotSupportedException
-     *                      if the JDBC driver does not support this method
+     * marker in the SQL statement; if a database access error occurs; this method
+     * is called on a closed <code>PreparedStatement</code> or if parameterIndex
+     * does not correspond to a parameter marker in the SQL statement,
+     * @throws SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
      * @since 1.6
      */
+    @Override
     public void setBlob(int parameterIndex, InputStream inputStream) throws SQLException {
         callableStatement.setBlob(parameterIndex, inputStream);
     }
 
     /**
-     * Sets the designated parameter to a <code>InputStream</code> object.  The inputstream must contain  the number
-     * of characters specified by length otherwise a <code>SQLException</code> will be
-     * generated when the <code>PreparedStatement</code> is executed.
-     * This method differs from the <code>setBinaryStream (int, InputStream, int)</code>
-     * method because it informs the driver that the parameter value should be
-     * sent to the server as a <code>BLOB</code>.  When the <code>setBinaryStream</code> method is used,
-     * the driver may have to do extra work to determine whether the parameter
-     * data should be sent to the server as a <code>LONGVARBINARY</code> or a <code>BLOB</code>
+     * Sets the designated parameter to a <code>InputStream</code> object. The
+     * inputstream must contain the number of characters specified by length
+     * otherwise a <code>SQLException</code> will be generated when the
+     * <code>PreparedStatement</code> is executed. This method differs from the
+     * <code>setBinaryStream (int, InputStream, int)</code> method because it
+     * informs the driver that the parameter value should be sent to the server as a
+     * <code>BLOB</code>. When the <code>setBinaryStream</code> method is used, the
+     * driver may have to do extra work to determine whether the parameter data
+     * should be sent to the server as a <code>LONGVARBINARY</code> or a
+     * <code>BLOB</code>
      *
-     * @param parameterIndex index of the first parameter is 1,
-     *                       the second is 2, ...
-     * @param inputStream    An object that contains the data to set the parameter
-     *                       value to.
-     * @param length         the number of bytes in the parameter data.
+     * @param parameterIndex index of the first parameter is 1, the second is 2, ...
+     * @param inputStream An object that contains the data to set the parameter
+     * value to.
+     * @param length the number of bytes in the parameter data.
      * @throws SQLException if parameterIndex does not correspond to a parameter
-     *                      marker in the SQL statement; if a database access error occurs;
-     *                      this method is called on a closed <code>PreparedStatement</code>;
-     *                      if the length specified
-     *                      is less than zero or if the number of bytes in the inputstream does not match
-     *                      the specfied length.
-     * @throws SQLFeatureNotSupportedException
-     *                      if the JDBC driver does not support this method
+     * marker in the SQL statement; if a database access error occurs; this method
+     * is called on a closed <code>PreparedStatement</code>; if the length specified
+     * is less than zero or if the number of bytes in the inputstream does not match
+     * the specfied length.
+     * @throws SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
      * @since 1.6
      */
+    @Override
     public void setBlob(int parameterIndex, InputStream inputStream, long length) throws SQLException {
         callableStatement.setBlob(parameterIndex, inputStream, length);
     }
 
     /**
-     * Sets the designated parameter to the given <code>Reader</code>
-     * object.
-     * When a very large UNICODE value is input to a <code>LONGVARCHAR</code>
-     * parameter, it may be more practical to send it via a
-     * <code>java.io.Reader</code> object. The data will be read from the stream
-     * as needed until end-of-file is reached.  The JDBC driver will
-     * do any necessary conversion from UNICODE to the database char format.
+     * Sets the designated parameter to the given <code>Reader</code> object. When a
+     * very large UNICODE value is input to a <code>LONGVARCHAR</code> parameter, it
+     * may be more practical to send it via a <code>java.io.Reader</code> object.
+     * The data will be read from the stream as needed until end-of-file is reached.
+     * The JDBC driver will do any necessary conversion from UNICODE to the database
+     * char format.
      * <p/>
-     * <P><B>Note:</B> This stream object can either be a standard
-     * Java stream object or your own subclass that implements the
-     * standard interface.
-     * <P><B>Note:</B> Consult your JDBC driver documentation to determine if
-     * it might be more efficient to use a version of
-     * <code>setCharacterStream</code> which takes a length parameter.
+     * <P>
+     * <B>Note:</B> This stream object can either be a standard Java stream object
+     * or your own subclass that implements the standard interface.
+     * <P>
+     * <B>Note:</B> Consult your JDBC driver documentation to determine if it might
+     * be more efficient to use a version of <code>setCharacterStream</code> which
+     * takes a length parameter.
      *
      * @param parameterIndex the first parameter is 1, the second is 2, ...
-     * @param reader         the <code>java.io.Reader</code> object that contains the
-     *                       Unicode data
+     * @param reader the <code>java.io.Reader</code> object that contains the
+     * Unicode data
      * @throws SQLException if parameterIndex does not correspond to a parameter
-     *                      marker in the SQL statement; if a database access error occurs or
-     *                      this method is called on a closed <code>PreparedStatement</code>
-     * @throws SQLFeatureNotSupportedException
-     *                      if the JDBC driver does not support this method
+     * marker in the SQL statement; if a database access error occurs or this method
+     * is called on a closed <code>PreparedStatement</code>
+     * @throws SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
      * @since 1.6
      */
+    @Override
     public void setCharacterStream(int parameterIndex, Reader reader) throws SQLException {
         callableStatement.setCharacterStream(parameterIndex, reader);
     }
 
     /**
-     * Sets the designated parameter to the given <code>Reader</code>
-     * object, which is the given number of characters long.
-     * When a very large UNICODE value is input to a <code>LONGVARCHAR</code>
-     * parameter, it may be more practical to send it via a
-     * <code>java.io.Reader</code> object. The data will be read from the stream
-     * as needed until end-of-file is reached.  The JDBC driver will
-     * do any necessary conversion from UNICODE to the database char format.
+     * Sets the designated parameter to the given <code>Reader</code> object, which
+     * is the given number of characters long. When a very large UNICODE value is
+     * input to a <code>LONGVARCHAR</code> parameter, it may be more practical to
+     * send it via a <code>java.io.Reader</code> object. The data will be read from
+     * the stream as needed until end-of-file is reached. The JDBC driver will do
+     * any necessary conversion from UNICODE to the database char format.
      * <p/>
-     * <P><B>Note:</B> This stream object can either be a standard
-     * Java stream object or your own subclass that implements the
-     * standard interface.
+     * <P>
+     * <B>Note:</B> This stream object can either be a standard Java stream object
+     * or your own subclass that implements the standard interface.
      *
      * @param parameterIndex the first parameter is 1, the second is 2, ...
-     * @param reader         the <code>java.io.Reader</code> object that contains the
-     *                       Unicode data
-     * @param length         the number of characters in the stream
+     * @param reader the <code>java.io.Reader</code> object that contains the
+     * Unicode data
+     * @param length the number of characters in the stream
      * @throws SQLException if parameterIndex does not correspond to a parameter
-     *                      marker in the SQL statement; if a database access error occurs or
-     *                      this method is called on a closed <code>PreparedStatement</code>
+     * marker in the SQL statement; if a database access error occurs or this method
+     * is called on a closed <code>PreparedStatement</code>
      * @since 1.6
      */
+    @Override
     public void setCharacterStream(int parameterIndex, Reader reader, long length) throws SQLException {
         callableStatement.setCharacterStream(parameterIndex, reader, length);
     }
 
     /**
-     * Sets the designated parameter to a <code>Reader</code> object.
-     * This method differs from the <code>setCharacterStream (int, Reader)</code> method
-     * because it informs the driver that the parameter value should be sent to
-     * the server as a <code>CLOB</code>.  When the <code>setCharacterStream</code> method is used, the
-     * driver may have to do extra work to determine whether the parameter
-     * data should be sent to the server as a <code>LONGVARCHAR</code> or a <code>CLOB</code>
+     * Sets the designated parameter to a <code>Reader</code> object. This method
+     * differs from the <code>setCharacterStream (int, Reader)</code> method because
+     * it informs the driver that the parameter value should be sent to the server
+     * as a <code>CLOB</code>. When the <code>setCharacterStream</code> method is
+     * used, the driver may have to do extra work to determine whether the parameter
+     * data should be sent to the server as a <code>LONGVARCHAR</code> or a
+     * <code>CLOB</code>
      * <p/>
-     * <P><B>Note:</B> Consult your JDBC driver documentation to determine if
-     * it might be more efficient to use a version of
-     * <code>setClob</code> which takes a length parameter.
+     * <P>
+     * <B>Note:</B> Consult your JDBC driver documentation to determine if it might
+     * be more efficient to use a version of <code>setClob</code> which takes a
+     * length parameter.
      *
      * @param parameterIndex index of the first parameter is 1, the second is 2, ...
-     * @param reader         An object that contains the data to set the parameter value to.
+     * @param reader An object that contains the data to set the parameter value to.
      * @throws SQLException if parameterIndex does not correspond to a parameter
-     *                      marker in the SQL statement; if a database access error occurs; this method is called on
-     *                      a closed <code>PreparedStatement</code>or if parameterIndex does not correspond to a parameter
-     *                      marker in the SQL statement
-     * @throws SQLFeatureNotSupportedException
-     *                      if the JDBC driver does not support this method
+     * marker in the SQL statement; if a database access error occurs; this method
+     * is called on a closed <code>PreparedStatement</code>or if parameterIndex does
+     * not correspond to a parameter marker in the SQL statement
+     * @throws SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
      * @since 1.6
      */
+    @Override
     public void setClob(int parameterIndex, Reader reader) throws SQLException {
         callableStatement.setClob(parameterIndex, reader);
     }
 
     /**
-     * Sets the designated parameter to a <code>Reader</code> object.  The reader must contain  the number
-     * of characters specified by length otherwise a <code>SQLException</code> will be
-     * generated when the <code>PreparedStatement</code> is executed.
-     * This method differs from the <code>setCharacterStream (int, Reader, int)</code> method
-     * because it informs the driver that the parameter value should be sent to
-     * the server as a <code>CLOB</code>.  When the <code>setCharacterStream</code> method is used, the
-     * driver may have to do extra work to determine whether the parameter
-     * data should be sent to the server as a <code>LONGVARCHAR</code> or a <code>CLOB</code>
+     * Sets the designated parameter to a <code>Reader</code> object. The reader
+     * must contain the number of characters specified by length otherwise a
+     * <code>SQLException</code> will be generated when the
+     * <code>PreparedStatement</code> is executed. This method differs from the
+     * <code>setCharacterStream (int, Reader, int)</code> method because it informs
+     * the driver that the parameter value should be sent to the server as a
+     * <code>CLOB</code>. When the <code>setCharacterStream</code> method is used,
+     * the driver may have to do extra work to determine whether the parameter data
+     * should be sent to the server as a <code>LONGVARCHAR</code> or a
+     * <code>CLOB</code>
      *
      * @param parameterIndex index of the first parameter is 1, the second is 2, ...
-     * @param reader         An object that contains the data to set the parameter value to.
-     * @param length         the number of characters in the parameter data.
+     * @param reader An object that contains the data to set the parameter value to.
+     * @param length the number of characters in the parameter data.
      * @throws SQLException if parameterIndex does not correspond to a parameter
-     *                      marker in the SQL statement; if a database access error occurs; this method is called on
-     *                      a closed <code>PreparedStatement</code> or if the length specified is less than zero.
-     * @throws SQLFeatureNotSupportedException
-     *                      if the JDBC driver does not support this method
+     * marker in the SQL statement; if a database access error occurs; this method
+     * is called on a closed <code>PreparedStatement</code> or if the length
+     * specified is less than zero.
+     * @throws SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
      * @since 1.6
      */
+    @Override
     public void setClob(int parameterIndex, Reader reader, long length) throws SQLException {
         callableStatement.setClob(parameterIndex, reader, length);
     }
 
     /**
      * Sets the designated parameter to a <code>Reader</code> object. The
-     * <code>Reader</code> reads the data till end-of-file is reached. The
-     * driver does the necessary conversion from Java character format to
-     * the national character set in the database.
+     * <code>Reader</code> reads the data till end-of-file is reached. The driver
+     * does the necessary conversion from Java character format to the national
+     * character set in the database.
      * <p/>
-     * <P><B>Note:</B> This stream object can either be a standard
-     * Java stream object or your own subclass that implements the
-     * standard interface.
-     * <P><B>Note:</B> Consult your JDBC driver documentation to determine if
-     * it might be more efficient to use a version of
-     * <code>setNCharacterStream</code> which takes a length parameter.
+     * <P>
+     * <B>Note:</B> This stream object can either be a standard Java stream object
+     * or your own subclass that implements the standard interface.
+     * <P>
+     * <B>Note:</B> Consult your JDBC driver documentation to determine if it might
+     * be more efficient to use a version of <code>setNCharacterStream</code> which
+     * takes a length parameter.
      *
      * @param parameterIndex of the first parameter is 1, the second is 2, ...
-     * @param value          the parameter value
+     * @param value the parameter value
      * @throws SQLException if parameterIndex does not correspond to a parameter
-     *                      marker in the SQL statement; if the driver does not support national
-     *                      character sets;  if the driver can detect that a data conversion
-     *                      error could occur; if a database access error occurs; or
-     *                      this method is called on a closed <code>PreparedStatement</code>
-     * @throws SQLFeatureNotSupportedException
-     *                      if the JDBC driver does not support this method
+     * marker in the SQL statement; if the driver does not support national
+     * character sets; if the driver can detect that a data conversion error could
+     * occur; if a database access error occurs; or this method is called on a
+     * closed <code>PreparedStatement</code>
+     * @throws SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
      * @since 1.6
      */
+    @Override
     public void setNCharacterStream(int parameterIndex, Reader value) throws SQLException {
         callableStatement.setNCharacterStream(parameterIndex, value);
     }
 
     /**
      * Sets the designated parameter to a <code>Reader</code> object. The
-     * <code>Reader</code> reads the data till end-of-file is reached. The
-     * driver does the necessary conversion from Java character format to
-     * the national character set in the database.
+     * <code>Reader</code> reads the data till end-of-file is reached. The driver
+     * does the necessary conversion from Java character format to the national
+     * character set in the database.
      *
      * @param parameterIndex of the first parameter is 1, the second is 2, ...
-     * @param value          the parameter value
-     * @param length         the number of characters in the parameter data.
+     * @param value the parameter value
+     * @param length the number of characters in the parameter data.
      * @throws SQLException if parameterIndex does not correspond to a parameter
-     *                      marker in the SQL statement; if the driver does not support national
-     *                      character sets;  if the driver can detect that a data conversion
-     *                      error could occur; if a database access error occurs; or
-     *                      this method is called on a closed <code>PreparedStatement</code>
-     * @throws SQLFeatureNotSupportedException
-     *                      if the JDBC driver does not support this method
+     * marker in the SQL statement; if the driver does not support national
+     * character sets; if the driver can detect that a data conversion error could
+     * occur; if a database access error occurs; or this method is called on a
+     * closed <code>PreparedStatement</code>
+     * @throws SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
      * @since 1.6
      */
+    @Override
     public void setNCharacterStream(int parameterIndex, Reader value, long length) throws SQLException {
         callableStatement.setNCharacterStream(parameterIndex, value, length);
     }
 
     /**
-     * Sets the designated parameter to a <code>java.sql.NClob</code> object. The driver converts this to a
-     * SQL <code>NCLOB</code> value when it sends it to the database.
+     * Sets the designated parameter to a <code>java.sql.NClob</code> object. The
+     * driver converts this to a SQL <code>NCLOB</code> value when it sends it to
+     * the database.
      *
      * @param parameterIndex of the first parameter is 1, the second is 2, ...
-     * @param value          the parameter value
+     * @param value the parameter value
      * @throws SQLException if parameterIndex does not correspond to a parameter
-     *                      marker in the SQL statement; if the driver does not support national
-     *                      character sets;  if the driver can detect that a data conversion
-     *                      error could occur; if a database access error occurs; or
-     *                      this method is called on a closed <code>PreparedStatement</code>
-     * @throws SQLFeatureNotSupportedException
-     *                      if the JDBC driver does not support this method
+     * marker in the SQL statement; if the driver does not support national
+     * character sets; if the driver can detect that a data conversion error could
+     * occur; if a database access error occurs; or this method is called on a
+     * closed <code>PreparedStatement</code>
+     * @throws SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
      * @since 1.6
      */
+    @Override
     public void setNClob(int parameterIndex, NClob value) throws SQLException {
         callableStatement.setNClob(parameterIndex, value);
     }
 
     /**
-     * Sets the designated parameter to a <code>Reader</code> object.
-     * This method differs from the <code>setCharacterStream (int, Reader)</code> method
-     * because it informs the driver that the parameter value should be sent to
-     * the server as a <code>NCLOB</code>.  When the <code>setCharacterStream</code> method is used, the
-     * driver may have to do extra work to determine whether the parameter
-     * data should be sent to the server as a <code>LONGNVARCHAR</code> or a <code>NCLOB</code>
-     * <P><B>Note:</B> Consult your JDBC driver documentation to determine if
-     * it might be more efficient to use a version of
-     * <code>setNClob</code> which takes a length parameter.
+     * Sets the designated parameter to a <code>Reader</code> object. This method
+     * differs from the <code>setCharacterStream (int, Reader)</code> method because
+     * it informs the driver that the parameter value should be sent to the server
+     * as a <code>NCLOB</code>. When the <code>setCharacterStream</code> method is
+     * used, the driver may have to do extra work to determine whether the parameter
+     * data should be sent to the server as a <code>LONGNVARCHAR</code> or a
+     * <code>NCLOB</code>
+     * <P>
+     * <B>Note:</B> Consult your JDBC driver documentation to determine if it might
+     * be more efficient to use a version of <code>setNClob</code> which takes a
+     * length parameter.
      *
      * @param parameterIndex index of the first parameter is 1, the second is 2, ...
-     * @param reader         An object that contains the data to set the parameter value to.
+     * @param reader An object that contains the data to set the parameter value to.
      * @throws SQLException if parameterIndex does not correspond to a parameter
-     *                      marker in the SQL statement;
-     *                      if the driver does not support national character sets;
-     *                      if the driver can detect that a data conversion
-     *                      error could occur;  if a database access error occurs or
-     *                      this method is called on a closed <code>PreparedStatement</code>
-     * @throws SQLFeatureNotSupportedException
-     *                      if the JDBC driver does not support this method
+     * marker in the SQL statement; if the driver does not support national
+     * character sets; if the driver can detect that a data conversion error could
+     * occur; if a database access error occurs or this method is called on a closed
+     * <code>PreparedStatement</code>
+     * @throws SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
      * @since 1.6
      */
+    @Override
     public void setNClob(int parameterIndex, Reader reader) throws SQLException {
         callableStatement.setNClob(parameterIndex, reader);
     }
 
     /**
-     * Sets the designated parameter to a <code>Reader</code> object.  The reader must contain  the number
-     * of characters specified by length otherwise a <code>SQLException</code> will be
-     * generated when the <code>PreparedStatement</code> is executed.
-     * This method differs from the <code>setCharacterStream (int, Reader, int)</code> method
-     * because it informs the driver that the parameter value should be sent to
-     * the server as a <code>NCLOB</code>.  When the <code>setCharacterStream</code> method is used, the
-     * driver may have to do extra work to determine whether the parameter
-     * data should be sent to the server as a <code>LONGNVARCHAR</code> or a <code>NCLOB</code>
+     * Sets the designated parameter to a <code>Reader</code> object. The reader
+     * must contain the number of characters specified by length otherwise a
+     * <code>SQLException</code> will be generated when the
+     * <code>PreparedStatement</code> is executed. This method differs from the
+     * <code>setCharacterStream (int, Reader, int)</code> method because it informs
+     * the driver that the parameter value should be sent to the server as a
+     * <code>NCLOB</code>. When the <code>setCharacterStream</code> method is used,
+     * the driver may have to do extra work to determine whether the parameter data
+     * should be sent to the server as a <code>LONGNVARCHAR</code> or a
+     * <code>NCLOB</code>
      *
      * @param parameterIndex index of the first parameter is 1, the second is 2, ...
-     * @param reader         An object that contains the data to set the parameter value to.
-     * @param length         the number of characters in the parameter data.
+     * @param reader An object that contains the data to set the parameter value to.
+     * @param length the number of characters in the parameter data.
      * @throws SQLException if parameterIndex does not correspond to a parameter
-     *                      marker in the SQL statement; if the length specified is less than zero;
-     *                      if the driver does not support national character sets;
-     *                      if the driver can detect that a data conversion
-     *                      error could occur;  if a database access error occurs or
-     *                      this method is called on a closed <code>PreparedStatement</code>
-     * @throws SQLFeatureNotSupportedException
-     *                      if the JDBC driver does not support this method
+     * marker in the SQL statement; if the length specified is less than zero; if
+     * the driver does not support national character sets; if the driver can detect
+     * that a data conversion error could occur; if a database access error occurs
+     * or this method is called on a closed <code>PreparedStatement</code>
+     * @throws SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
      * @since 1.6
      */
+    @Override
     public void setNClob(int parameterIndex, Reader reader, long length) throws SQLException {
         callableStatement.setNClob(parameterIndex, reader, length);
     }
 
     /**
-     * Sets the designated paramter to the given <code>String</code> object.
-     * The driver converts this to a SQL <code>NCHAR</code> or
-     * <code>NVARCHAR</code> or <code>LONGNVARCHAR</code> value
-     * (depending on the argument's
-     * size relative to the driver's limits on <code>NVARCHAR</code> values)
-     * when it sends it to the database.
+     * Sets the designated paramter to the given <code>String</code> object. The
+     * driver converts this to a SQL <code>NCHAR</code> or <code>NVARCHAR</code> or
+     * <code>LONGNVARCHAR</code> value (depending on the argument's size relative to
+     * the driver's limits on <code>NVARCHAR</code> values) when it sends it to the
+     * database.
      *
      * @param parameterIndex of the first parameter is 1, the second is 2, ...
-     * @param value          the parameter value
+     * @param value the parameter value
      * @throws SQLException if parameterIndex does not correspond to a parameter
-     *                      marker in the SQL statement; if the driver does not support national
-     *                      character sets;  if the driver can detect that a data conversion
-     *                      error could occur; if a database access error occurs; or
-     *                      this method is called on a closed <code>PreparedStatement</code>
-     * @throws SQLFeatureNotSupportedException
-     *                      if the JDBC driver does not support this method
+     * marker in the SQL statement; if the driver does not support national
+     * character sets; if the driver can detect that a data conversion error could
+     * occur; if a database access error occurs; or this method is called on a
+     * closed <code>PreparedStatement</code>
+     * @throws SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
      * @since 1.6
      */
+    @Override
     public void setNString(int parameterIndex, String value) throws SQLException {
         callableStatement.setNString(parameterIndex, value);
     }
 
     /**
-     * Sets the designated parameter to the given <code>java.sql.RowId</code> object. The
-     * driver converts this to a SQL <code>ROWID</code> value when it sends it
-     * to the database
+     * Sets the designated parameter to the given <code>java.sql.RowId</code>
+     * object. The driver converts this to a SQL <code>ROWID</code> value when it
+     * sends it to the database
      *
      * @param parameterIndex the first parameter is 1, the second is 2, ...
-     * @param x              the parameter value
+     * @param x the parameter value
      * @throws SQLException if parameterIndex does not correspond to a parameter
-     *                      marker in the SQL statement; if a database access error occurs or
-     *                      this method is called on a closed <code>PreparedStatement</code>
-     * @throws SQLFeatureNotSupportedException
-     *                      if the JDBC driver does not support this method
+     * marker in the SQL statement; if a database access error occurs or this method
+     * is called on a closed <code>PreparedStatement</code>
+     * @throws SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
      * @since 1.6
      */
+    @Override
     public void setRowId(int parameterIndex, RowId x) throws SQLException {
         callableStatement.setRowId(parameterIndex, x);
     }
 
     /**
-     * Sets the designated parameter to the given <code>java.sql.SQLXML</code> object.
-     * The driver converts this to an
-     * SQL <code>XML</code> value when it sends it to the database.
+     * Sets the designated parameter to the given <code>java.sql.SQLXML</code>
+     * object. The driver converts this to an SQL <code>XML</code> value when it
+     * sends it to the database.
      * <p/>
      *
      * @param parameterIndex index of the first parameter is 1, the second is 2, ...
-     * @param xmlObject      a <code>SQLXML</code> object that maps an SQL <code>XML</code> value
+     * @param xmlObject a <code>SQLXML</code> object that maps an SQL
+     * <code>XML</code> value
      * @throws SQLException if parameterIndex does not correspond to a parameter
-     *                      marker in the SQL statement; if a database access error occurs;
-     *                      this method is called on a closed <code>PreparedStatement</code>
-     *                      or the <code>java.xml.transform.Result</code>,
-     *                      <code>Writer</code> or <code>OutputStream</code> has not been closed for
-     *                      the <code>SQLXML</code> object
-     * @throws SQLFeatureNotSupportedException
-     *                      if the JDBC driver does not support this method
+     * marker in the SQL statement; if a database access error occurs; this method
+     * is called on a closed <code>PreparedStatement</code> or the
+     * <code>java.xml.transform.Result</code>, <code>Writer</code> or
+     * <code>OutputStream</code> has not been closed for the <code>SQLXML</code>
+     * object
+     * @throws SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
      * @since 1.6
      */
+    @Override
     public void setSQLXML(int parameterIndex, SQLXML xmlObject) throws SQLException {
         callableStatement.setSQLXML(parameterIndex, xmlObject);
     }
 
     /**
-     * Retrieves whether this <code>Statement</code> object has been closed. A <code>Statement</code> is closed if the
-     * method close has been called on it, or if it is automatically closed.
+     * Retrieves whether this <code>Statement</code> object has been closed. A
+     * <code>Statement</code> is closed if the method close has been called on it,
+     * or if it is automatically closed.
      *
-     * @return true if this <code>Statement</code> object is closed; false if it is still open
+     * @return true if this <code>Statement</code> object is closed; false if it is
+     * still open
      * @throws SQLException if a database access error occurs
      * @since 1.6
      */
+    @Override
     public boolean isClosed() throws SQLException {
         return callableStatement.isClosed();
     }
 
     /**
-     * Returns a  value indicating whether the <code>Statement</code>
-     * is poolable or not.
+     * Returns a value indicating whether the <code>Statement</code> is poolable or
+     * not.
      * <p/>
      *
      * @throws SQLException if this method is called on a closed
-     *                      <code>Statement</code>
-     *                      <p/>
-     * @return        <code>true</code> if the <code>Statement</code>
-     * is poolable; <code>false</code> otherwise
+     * <code>Statement</code>
+     * <p/>
+     * @return <code>true</code> if the <code>Statement</code> is poolable;
+     * <code>false</code> otherwise
      * <p/>
      * @see java.sql.Statement#setPoolable(boolean) setPoolable(boolean)
      * @since 1.6
-     *        <p/>
+     * <p/>
      */
+    @Override
     public boolean isPoolable() throws SQLException {
         return callableStatement.isPoolable();
     }
 
     /**
-     * Requests that a <code>Statement</code> be pooled or not pooled.  The value
-     * specified is a hint to the statement pool implementation indicating
-     * whether the applicaiton wants the statement to be pooled.  It is up to
-     * the statement pool manager as to whether the hint is used.
+     * Requests that a <code>Statement</code> be pooled or not pooled. The value
+     * specified is a hint to the statement pool implementation indicating whether
+     * the applicaiton wants the statement to be pooled. It is up to the statement
+     * pool manager as to whether the hint is used.
      * <p/>
-     * The poolable value of a statement is applicable to both internal
-     * statement caches implemented by the driver and external statement caches
-     * implemented by application servers and other applications.
+     * The poolable value of a statement is applicable to both internal statement
+     * caches implemented by the driver and external statement caches implemented by
+     * application servers and other applications.
      * <p/>
-     * By default, a <code>Statement</code> is not poolable when created, and
-     * a <code>PreparedStatement</code> and <code>CallableStatement</code>
-     * are poolable when created.
+     * By default, a <code>Statement</code> is not poolable when created, and a
+     * <code>PreparedStatement</code> and <code>CallableStatement</code> are
+     * poolable when created.
      * <p/>
      *
-     * @param poolable requests that the statement be pooled if true and
-     *                 that the statement not be pooled if false
-     *                 <p/>
+     * @param poolable requests that the statement be pooled if true and that the
+     * statement not be pooled if false
+     * <p/>
      * @throws SQLException if this method is called on a closed
-     *                      <code>Statement</code>
-     *                      <p/>
+     * <code>Statement</code>
+     * <p/>
      * @since 1.6
      */
+    @Override
     public void setPoolable(boolean poolable) throws SQLException {
         callableStatement.setPoolable(poolable);
     }
 
     /**
-     * Returns true if this either implements the interface argument or is directly or indirectly a wrapper
-     * for an object that does. Returns false otherwise. If this implements the interface then return true,
-     * else if this is a wrapper then return the result of recursively calling <code>isWrapperFor</code> on the wrapped
-     * object. If this does not implement the interface and is not a wrapper, return false.
-     * This method should be implemented as a low-cost operation compared to <code>unwrap</code> so that
-     * callers can use this method to avoid expensive <code>unwrap</code> calls that may fail. If this method
-     * returns true then calling <code>unwrap</code> with the same argument should succeed.
+     * Returns true if this either implements the interface argument or is directly
+     * or indirectly a wrapper for an object that does. Returns false otherwise. If
+     * this implements the interface then return true, else if this is a wrapper
+     * then return the result of recursively calling <code>isWrapperFor</code> on
+     * the wrapped object. If this does not implement the interface and is not a
+     * wrapper, return false. This method should be implemented as a low-cost
+     * operation compared to <code>unwrap</code> so that callers can use this method
+     * to avoid expensive <code>unwrap</code> calls that may fail. If this method
+     * returns true then calling <code>unwrap</code> with the same argument should
+     * succeed.
      *
      * @param iface a Class defining an interface.
-     * @return true if this implements the interface or directly or indirectly wraps an object that does.
-     * @throws java.sql.SQLException if an error occurs while determining whether this is a wrapper
-     *                               for an object with the given interface.
+     * @return true if this implements the interface or directly or indirectly wraps
+     * an object that does.
+     * @throws java.sql.SQLException if an error occurs while determining whether
+     * this is a wrapper for an object with the given interface.
      * @since 1.6
      */
+    @Override
     public boolean isWrapperFor(Class<?> iface) throws SQLException {
         boolean result;
         if (iface.isInstance(this)) {
@@ -1346,19 +1402,22 @@
      * Returns an object that implements the given interface to allow access to
      * non-standard methods, or standard methods not exposed by the proxy.
      * <p/>
-     * If the receiver implements the interface then the result is the receiver
-     * or a proxy for the receiver. If the receiver is a wrapper
-     * and the wrapped object implements the interface then the result is the
-     * wrapped object or a proxy for the wrapped object. Otherwise return the
-     * the result of calling <code>unwrap</code> recursively on the wrapped object
-     * or a proxy for that result. If the receiver is not a
-     * wrapper and does not implement the interface, then an <code>SQLException</code> is thrown.
+     * If the receiver implements the interface then the result is the receiver or a
+     * proxy for the receiver. If the receiver is a wrapper and the wrapped object
+     * implements the interface then the result is the wrapped object or a proxy for
+     * the wrapped object. Otherwise return the the result of calling
+     * <code>unwrap</code> recursively on the wrapped object or a proxy for that
+     * result. If the receiver is not a wrapper and does not implement the
+     * interface, then an <code>SQLException</code> is thrown.
      *
      * @param iface A Class defining an interface that the result must implement.
-     * @return an object that implements the interface. May be a proxy for the actual implementing object.
-     * @throws java.sql.SQLException If no object found that implements the interface
+     * @return an object that implements the interface. May be a proxy for the
+     * actual implementing object.
+     * @throws java.sql.SQLException If no object found that implements the
+     * interface
      * @since 1.6
      */
+    @Override
     public <T> T unwrap(Class<T> iface) throws SQLException {
         T result = null;
         if (iface.isInstance(this)) {
@@ -1370,15 +1429,16 @@
     }
 
     /**
-     * Executes the SQL query in this <code>PreparedStatement</code> object
-     * and returns the <code>ResultSet</code> object generated by the query.
+     * Executes the SQL query in this <code>PreparedStatement</code> object and
+     * returns the <code>ResultSet</code> object generated by the query.
      *
-     * @return a <code>ResultSet</code> object that contains the data produced by the
-     *         query; never <code>null</code>
-     * @throws SQLException if a database access error occurs;
-     *                      this method is called on a closed  <code>PreparedStatement</code> or the SQL
-     *                      statement does not return a <code>ResultSet</code> object
+     * @return a <code>ResultSet</code> object that contains the data produced by
+     * the query; never <code>null</code>
+     * @throws SQLException if a database access error occurs; this method is called
+     * on a closed <code>PreparedStatement</code> or the SQL statement does not
+     * return a <code>ResultSet</code> object
      */
+    @Override
     public java.sql.ResultSet executeQuery() throws java.sql.SQLException {
         ResultSet rs = callableStatement.executeQuery();
         incrementResultSetReferenceCount();
@@ -1389,17 +1449,16 @@
      * Executes the given SQL statement, which returns a single
      * <code>ResultSet</code> object.
      *
-     * @param sql an SQL statement to be sent to the database, typically a
-     *            static SQL <code>SELECT</code> statement
-     * @return a <code>ResultSet</code> object that contains the data produced
-     *         by the given query; never <code>null</code>
-     * @throws SQLException if a database access error occurs,
-     *                      this method is called on a closed <code>Statement</code> or the given
-     *                      SQL statement produces anything other than a single
-     *                      <code>ResultSet</code> object
+     * @param sql an SQL statement to be sent to the database, typically a static
+     * SQL <code>SELECT</code> statement
+     * @return a <code>ResultSet</code> object that contains the data produced by
+     * the given query; never <code>null</code>
+     * @throws SQLException if a database access error occurs, this method is called
+     * on a closed <code>Statement</code> or the given SQL statement produces
+     * anything other than a single <code>ResultSet</code> object
      */
-    public java.sql.ResultSet executeQuery(String sql) throws
-            java.sql.SQLException {
+    @Override
+    public java.sql.ResultSet executeQuery(String sql) throws java.sql.SQLException {
         ResultSet rs = callableStatement.executeQuery(sql);
         incrementResultSetReferenceCount();
         return new ResultSetWrapper40(this, rs);
@@ -1407,21 +1466,23 @@
 
     /**
      * Retrieves any auto-generated keys created as a result of executing this
-     * <code>Statement</code> object. If this <code>Statement</code> object did
-     * not generate any keys, an empty <code>ResultSet</code>
-     * object is returned.
+     * <code>Statement</code> object. If this <code>Statement</code> object did not
+     * generate any keys, an empty <code>ResultSet</code> object is returned.
      * <p/>
-     * <p><B>Note:</B>If the columns which represent the auto-generated keys were not specified,
-     * the JDBC driver implementation will determine the columns which best represent the auto-generated keys.
+     * <p>
+     * <B>Note:</B>If the columns which represent the auto-generated keys were not
+     * specified, the JDBC driver implementation will determine the columns which
+     * best represent the auto-generated keys.
      *
      * @return a <code>ResultSet</code> object containing the auto-generated key(s)
-     *         generated by the execution of this <code>Statement</code> object
-     * @throws SQLException if a database access error occurs or
-     *                      this method is called on a closed <code>Statement</code>
-     * @throws SQLFeatureNotSupportedException
-     *                      if the JDBC driver does not support this method
+     * generated by the execution of this <code>Statement</code> object
+     * @throws SQLException if a database access error occurs or this method is
+     * called on a closed <code>Statement</code>
+     * @throws SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
      * @since 1.4
      */
+    @Override
     public java.sql.ResultSet getGeneratedKeys() throws java.sql.SQLException {
         ResultSet rs = callableStatement.getGeneratedKeys();
         if (rs == null)
@@ -1431,48 +1492,56 @@
     }
 
     /**
-     * Retrieves the current result as a <code>ResultSet</code> object.
-     * This method should be called only once per result.
+     * Retrieves the current result as a <code>ResultSet</code> object. This method
+     * should be called only once per result.
      *
      * @return the current result as a <code>ResultSet</code> object or
-     *         <code>null</code> if the result is an update count or there are no more results
-     * @throws SQLException if a database access error occurs or
-     *                      this method is called on a closed <code>Statement</code>
+     * <code>null</code> if the result is an update count or there are no more
+     * results
+     * @throws SQLException if a database access error occurs or this method is
+     * called on a closed <code>Statement</code>
      * @see #execute
      */
-    public java.sql.ResultSet getResultSet() throws java.sql.SQLException {
+    @Override
+    public ResultSet getResultSet() throws java.sql.SQLException {
         ResultSet rs = callableStatement.getResultSet();
-        if (rs == null)
+        if (rs == null) {
             return null;
+        }
+
         incrementResultSetReferenceCount();
         return new ResultSetWrapper40(this, rs);
     }
 
+    @Override
+    @SuppressWarnings("unchecked")
     public <T> T getObject(int parameterIndex, Class<T> type) throws SQLException {
-        if (DataSourceObjectBuilder.isJDBC41()) {
-            Class<?>[] valueTypes = new Class<?>[]{Integer.TYPE, Class.class};
-            try {
-                return (T) executor.invokeMethod(jdbcStatement, "getObject",
-                        valueTypes, parameterIndex, type);
-            } catch (ResourceException ex) {
-                _logger.log(Level.SEVERE, "jdbc.ex_get_object", ex);
-                throw new SQLException(ex);
-            }
+        if (!isJDBC41()) {
+            throw new UnsupportedOperationException("Operation not supported in this runtime.");
         }
-        throw new UnsupportedOperationException("Operation not supported in this runtime.");
+
+        Class<?>[] valueTypes = new Class<?>[] { Integer.TYPE, Class.class };
+        try {
+            return (T) executor.invokeMethod(jdbcStatement, "getObject", valueTypes, parameterIndex, type);
+        } catch (ResourceException ex) {
+            _logger.log(SEVERE, "jdbc.ex_get_object", ex);
+            throw new SQLException(ex);
+        }
     }
 
+    @Override
+    @SuppressWarnings("unchecked")
     public <T> T getObject(String parameterName, Class<T> type) throws SQLException {
-        if (DataSourceObjectBuilder.isJDBC41()) {
-            Class<?>[] valueTypes = new Class<?>[]{String.class, Class.class};
-            try {
-                return (T) executor.invokeMethod(jdbcStatement, "getObject",
-                        valueTypes, parameterName, type);
-            } catch (ResourceException ex) {
-                _logger.log(Level.SEVERE, "jdbc.ex_get_object", ex);
-                throw new SQLException(ex);
-            }
+        if (!isJDBC41()) {
+            throw new UnsupportedOperationException("Operation not supported in this runtime.");
         }
-        throw new UnsupportedOperationException("Operation not supported in this runtime.");
+
+        Class<?>[] valueTypes = new Class<?>[] { String.class, Class.class };
+        try {
+            return (T) executor.invokeMethod(jdbcStatement, "getObject", valueTypes, parameterName, type);
+        } catch (ResourceException ex) {
+            _logger.log(SEVERE, "jdbc.ex_get_object", ex);
+            throw new SQLException(ex);
+        }
     }
 }
diff --git a/appserver/jdbc/jdbc-ra/jdbc40/src/main/java/com/sun/gjc/spi/jdbc40/ConnectionHolder40.java b/appserver/jdbc/jdbc-ra/jdbc40/src/main/java/com/sun/gjc/spi/jdbc40/ConnectionHolder40.java
index 567683c..6ceaa78 100644
--- a/appserver/jdbc/jdbc-ra/jdbc40/src/main/java/com/sun/gjc/spi/jdbc40/ConnectionHolder40.java
+++ b/appserver/jdbc/jdbc-ra/jdbc40/src/main/java/com/sun/gjc/spi/jdbc40/ConnectionHolder40.java
@@ -16,56 +16,69 @@
 
 package com.sun.gjc.spi.jdbc40;
 
-import com.sun.enterprise.util.i18n.StringManager;
-import com.sun.gjc.common.DataSourceObjectBuilder;
-import com.sun.gjc.spi.ManagedConnectionFactoryImpl;
-import com.sun.gjc.spi.ManagedConnectionImpl;
-import com.sun.gjc.spi.base.ConnectionHolder;
+import static com.sun.gjc.common.DataSourceObjectBuilder.isJDBC41;
+import static java.util.logging.Level.FINE;
+import static java.util.logging.Level.FINEST;
+import static java.util.logging.Level.INFO;
+import static java.util.logging.Level.SEVERE;
 
 import java.lang.reflect.InvocationHandler;
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
 import java.lang.reflect.Proxy;
-import java.sql.*;
+import java.sql.Array;
+import java.sql.Blob;
+import java.sql.Clob;
+import java.sql.Connection;
+import java.sql.NClob;
+import java.sql.ResultSet;
+import java.sql.SQLClientInfoException;
+import java.sql.SQLException;
+import java.sql.SQLXML;
+import java.sql.Struct;
 import java.util.Properties;
 import java.util.concurrent.Executor;
-import java.util.logging.Level;
-import jakarta.resource.ResourceException;
 
+import com.sun.enterprise.util.i18n.StringManager;
+import com.sun.gjc.spi.ManagedConnectionFactoryImpl;
+import com.sun.gjc.spi.ManagedConnectionImpl;
+import com.sun.gjc.spi.base.ConnectionHolder;
+
+import jakarta.resource.ResourceException;
+import jakarta.resource.spi.ConnectionRequestInfo;
 
 /**
- * Holds the java.sql.Connection object, which is to be
- * passed to the application program.
+ * Holds the java.sql.Connection object, which is to be passed to the
+ * application program.
  *
  * @author Jagadish Ramu
  * @version 1.0, 25-Aug-2006
  */
 public class ConnectionHolder40 extends ConnectionHolder {
 
+    protected final static StringManager localStrings = StringManager.getManager(ManagedConnectionFactoryImpl.class);
     protected Properties defaultClientInfo;
-    protected final static StringManager localStrings =
-            StringManager.getManager(ManagedConnectionFactoryImpl.class);
     protected boolean jdbc30Connection;
 
     /**
      * Connection wrapper given to application program
      *
-     * @param con           Connection that is wrapped
-     * @param mc            ManagedConnection
+     * @param con Connection that is wrapped
+     * @param mc ManagedConnection
      * @param cxRequestInfo Connection Request Information
      */
-    public ConnectionHolder40(Connection con, ManagedConnectionImpl mc,
-                              jakarta.resource.spi.ConnectionRequestInfo cxRequestInfo,
-                              boolean jdbc30Connection) {
+    public ConnectionHolder40(Connection con, ManagedConnectionImpl mc, ConnectionRequestInfo cxRequestInfo, boolean jdbc30Connection) {
         super(con, mc, cxRequestInfo);
         this.jdbc30Connection = jdbc30Connection;
-        if (!jdbc30Connection)
+        if (!jdbc30Connection) {
             init();
+        }
     }
 
     /**
      * cache the default client info which can will set back during close()<br>
-     * as this connection may be re-used by connection pool of application server<br>
+     * as this connection may be re-used by connection pool of application
+     * server<br>
      */
     protected void init() {
         try {
@@ -73,180 +86,178 @@
                 defaultClientInfo = getClientInfo();
             }
         } catch (Throwable e) {
-            _logger.log(Level.INFO, "jdbc.unable_to_get_client_info", e.getMessage());
-            if(_logger.isLoggable(Level.FINEST)) {
-                _logger.log(Level.FINEST, "jdbc.unable_to_get_client_info", e);
-            }
+            _logger.log(INFO, "jdbc.unable_to_get_client_info", e.getMessage());
+            _logger.log(FINEST, "jdbc.unable_to_get_client_info", e);
         }
     }
 
     /**
-     * Constructs an object that implements the <code>Clob</code> interface. The object
-     * returned initially contains no data.  The <code>setAsciiStream</code>,
-     * <code>setCharacterStream</code> and <code>setString</code> methods of
-     * the <code>Clob</code> interface may be used to add data to the <code>Clob</code>.
+     * Constructs an object that implements the <code>Clob</code> interface. The
+     * object returned initially contains no data. The <code>setAsciiStream</code>,
+     * <code>setCharacterStream</code> and <code>setString</code> methods of the
+     * <code>Clob</code> interface may be used to add data to the <code>Clob</code>.
      *
      * @return An object that implements the <code>Clob</code> interface
      * @throws java.sql.SQLException if an object that implements the
-     *                               <code>Clob</code> interface can not be constructed, this method is
-     *                               called on a closed connection or a database access error occurs.
-     * @throws java.sql.SQLFeatureNotSupportedException
-     *                               if the JDBC driver does not support
-     *                               this data type
+     * <code>Clob</code> interface can not be constructed, this method is called on
+     * a closed connection or a database access error occurs.
+     * @throws java.sql.SQLFeatureNotSupportedException if the JDBC driver does not
+     * support this data type
      * @since 1.6
      */
+    @Override
     public Clob createClob() throws SQLException {
         checkValidity();
         jdbcPreInvoke();
-        return con.createClob();
+        return connection.createClob();
     }
 
     /**
-     * Constructs an object that implements the <code>Blob</code> interface. The object
-     * returned initially contains no data.  The <code>setBinaryStream</code> and
-     * <code>setBytes</code> methods of the <code>Blob</code> interface may be used to add data to
-     * the <code>Blob</code>.
+     * Constructs an object that implements the <code>Blob</code> interface. The
+     * object returned initially contains no data. The <code>setBinaryStream</code>
+     * and <code>setBytes</code> methods of the <code>Blob</code> interface may be
+     * used to add data to the <code>Blob</code>.
      *
      * @return An object that implements the <code>Blob</code> interface
      * @throws java.sql.SQLException if an object that implements the
-     *                               <code>Blob</code> interface can not be constructed, this method is
-     *                               called on a closed connection or a database access error occurs.
-     * @throws java.sql.SQLFeatureNotSupportedException
-     *                               if the JDBC driver does not support
-     *                               this data type
+     * <code>Blob</code> interface can not be constructed, this method is called on
+     * a closed connection or a database access error occurs.
+     * @throws java.sql.SQLFeatureNotSupportedException if the JDBC driver does not
+     * support this data type
      * @since 1.6
      */
+    @Override
     public Blob createBlob() throws SQLException {
         checkValidity();
         jdbcPreInvoke();
-        return con.createBlob();
+        return connection.createBlob();
     }
 
     /**
-     * Constructs an object that implements the <code>NClob</code> interface. The object
-     * returned initially contains no data.  The <code>setAsciiStream</code>,
-     * <code>setCharacterStream</code> and <code>setString</code> methods of the <code>NClob</code> interface may
-     * be used to add data to the <code>NClob</code>.
+     * Constructs an object that implements the <code>NClob</code> interface. The
+     * object returned initially contains no data. The <code>setAsciiStream</code>,
+     * <code>setCharacterStream</code> and <code>setString</code> methods of the
+     * <code>NClob</code> interface may be used to add data to the
+     * <code>NClob</code>.
      *
      * @return An object that implements the <code>NClob</code> interface
      * @throws java.sql.SQLException if an object that implements the
-     *                               <code>NClob</code> interface can not be constructed, this method is
-     *                               called on a closed connection or a database access error occurs.
-     * @throws java.sql.SQLFeatureNotSupportedException
-     *                               if the JDBC driver does not support
-     *                               this data type
+     * <code>NClob</code> interface can not be constructed, this method is called on
+     * a closed connection or a database access error occurs.
+     * @throws java.sql.SQLFeatureNotSupportedException if the JDBC driver does not
+     * support this data type
      * @since 1.6
      */
+    @Override
     public NClob createNClob() throws SQLException {
         checkValidity();
         jdbcPreInvoke();
-        return con.createNClob();
+        return connection.createNClob();
     }
 
     /**
-     * Constructs an object that implements the <code>SQLXML</code> interface. The object
-     * returned initially contains no data. The <code>createXmlStreamWriter</code> object and
-     * <code>setString</code> method of the <code>SQLXML</code> interface may be used to add data to the <code>SQLXML</code>
-     * object.
+     * Constructs an object that implements the <code>SQLXML</code> interface. The
+     * object returned initially contains no data. The
+     * <code>createXmlStreamWriter</code> object and <code>setString</code> method
+     * of the <code>SQLXML</code> interface may be used to add data to the
+     * <code>SQLXML</code> object.
      *
      * @return An object that implements the <code>SQLXML</code> interface
-     * @throws java.sql.SQLException if an object that implements the <code>SQLXML</code> interface can not
-     *                               be constructed, this method is
-     *                               called on a closed connection or a database access error occurs.
-     * @throws java.sql.SQLFeatureNotSupportedException
-     *                               if the JDBC driver does not support
-     *                               this data type
+     * @throws java.sql.SQLException if an object that implements the
+     * <code>SQLXML</code> interface can not be constructed, this method is called
+     * on a closed connection or a database access error occurs.
+     * @throws java.sql.SQLFeatureNotSupportedException if the JDBC driver does not
+     * support this data type
      * @since 1.6
      */
+    @Override
     public SQLXML createSQLXML() throws SQLException {
         checkValidity();
         jdbcPreInvoke();
-        return con.createSQLXML();
+        return connection.createSQLXML();
     }
 
     /**
-     * Returns true if the connection has not been closed and is still valid.
-     * The driver shall submit a query on the connection or use some other
-     * mechanism that positively verifies the connection is still valid when
-     * this method is called.
+     * Returns true if the connection has not been closed and is still valid. The
+     * driver shall submit a query on the connection or use some other mechanism
+     * that positively verifies the connection is still valid when this method is
+     * called.
      * <p/>
      * The query submitted by the driver to validate the connection shall be
      * executed in the context of the current transaction.
      *
-     * @param timeout - The time in seconds to wait for the database operation
-     *                used to validate the connection to complete.  If
-     *                the timeout period expires before the operation
-     *                completes, this method returns false.  A value of
-     *                0 indicates a timeout is not applied to the
-     *                database operation.
-     *                <p/>
+     * @param timeout - The time in seconds to wait for the database operation used
+     * to validate the connection to complete. If the timeout period expires before
+     * the operation completes, this method returns false. A value of 0 indicates a
+     * timeout is not applied to the database operation.
+     * <p/>
      * @return true if the connection is valid, false otherwise
      * @throws java.sql.SQLException if the value supplied for <code>timeout</code>
-     *                               is less then 0
+     * is less then 0
      * @see java.sql.DatabaseMetaData#getClientInfoProperties
      * @since 1.6
-     *        <p/>
+     * <p/>
      */
+    @Override
     public boolean isValid(int timeout) throws SQLException {
         checkValidity();
-        return con.isValid(timeout);
+        return connection.isValid(timeout);
     }
 
     /**
-     * Sets the value of the client info property specified by name to the
-     * value specified by value.
+     * Sets the value of the client info property specified by name to the value
+     * specified by value.
      * <p/>
-     * Applications may use the <code>DatabaseMetaData.getClientInfoProperties</code>
-     * method to determine the client info properties supported by the driver
-     * and the maximum length that may be specified for each property.
+     * Applications may use the
+     * <code>DatabaseMetaData.getClientInfoProperties</code> method to determine the
+     * client info properties supported by the driver and the maximum length that
+     * may be specified for each property.
      * <p/>
-     * The driver stores the value specified in a suitable location in the
-     * database. For example in a special register, session parameter, or
-     * system table column. For efficiency the driver may defer setting the
-     * value in the database until the next time a statement is executed or
-     * prepared. Other than storing the client information in the appropriate
-     * place in the database, these methods shall not alter the behavior of
-     * the connection in anyway. The values supplied to these methods are
-     * used for accounting, diagnostics and debugging purposes only.
+     * The driver stores the value specified in a suitable location in the database.
+     * For example in a special register, session parameter, or system table column.
+     * For efficiency the driver may defer setting the value in the database until
+     * the next time a statement is executed or prepared. Other than storing the
+     * client information in the appropriate place in the database, these methods
+     * shall not alter the behavior of the connection in anyway. The values supplied
+     * to these methods are used for accounting, diagnostics and debugging purposes
+     * only.
      * <p/>
-     * The driver shall generate a warning if the client info name specified
-     * is not recognized by the driver.
+     * The driver shall generate a warning if the client info name specified is not
+     * recognized by the driver.
      * <p/>
-     * If the value specified to this method is greater than the maximum
-     * length for the property the driver may either truncate the value and
-     * generate a warning or generate a <code>SQLClientInfoException</code>. If the driver
-     * generates a <code>SQLClientInfoException</code>, the value specified was not set on the
+     * If the value specified to this method is greater than the maximum length for
+     * the property the driver may either truncate the value and generate a warning
+     * or generate a <code>SQLClientInfoException</code>. If the driver generates a
+     * <code>SQLClientInfoException</code>, the value specified was not set on the
      * connection.
      * <p/>
-     * The following are standard client info properties. Drivers are not
-     * required to support these properties however if the driver supports a
-     * client info property that can be described by one of the standard
-     * properties, the standard property name should be used.
+     * The following are standard client info properties. Drivers are not required
+     * to support these properties however if the driver supports a client info
+     * property that can be described by one of the standard properties, the
+     * standard property name should be used.
      * <p/>
      * <ul>
-     * <li>ApplicationName - The name of the application currently utilizing
-     * the connection</li>
-     * <li>ClientUser - The name of the user that the application using
-     * the connection is performing work for. This may
-     * not be the same as the user name that was used
-     * in establishing the connection.</li>
-     * <li>ClientHostname - The hostname of the computer the application
-     * using the connection is running on.</li>
+     * <li>ApplicationName - The name of the application currently utilizing the
+     * connection</li>
+     * <li>ClientUser - The name of the user that the application using the
+     * connection is performing work for. This may not be the same as the user name
+     * that was used in establishing the connection.</li>
+     * <li>ClientHostname - The hostname of the computer the application using the
+     * connection is running on.</li>
      * </ul>
      * <p/>
      *
      * @param name The name of the client info property to set
-     * @param value The value to set the client info property to. If the
-     *            value is null, the current value of the specified
-     *            property is cleared.
-     *            <p/>
-     * @throws java.sql.SQLClientInfoException
-     *             if the database server returns an error while
-     *             setting the client info value on the database server or this method
-     *             is called on a closed connection
-     *             <p/>
+     * @param value The value to set the client info property to. If the value is
+     * null, the current value of the specified property is cleared.
+     * <p/>
+     * @throws java.sql.SQLClientInfoException if the database server returns an
+     * error while setting the client info value on the database server or this
+     * method is called on a closed connection
+     * <p/>
      * @since 1.6
      */
+    @Override
     public void setClientInfo(String name, String value) throws SQLClientInfoException {
         try {
             checkValidity();
@@ -255,40 +266,40 @@
             sce.setStackTrace(sqe.getStackTrace());
             throw sce;
         }
-        con.setClientInfo(name, value);
+        connection.setClientInfo(name, value);
     }
 
     /**
-     * Sets the value of the connection's client info properties.  The
-     * <code>Properties</code> object contains the names and values of the client info
-     * properties to be set.  The set of client info properties contained in
-     * the properties list replaces the current set of client info properties
-     * on the connection.  If a property that is currently set on the
-     * connection is not present in the properties list, that property is
-     * cleared.  Specifying an empty properties list will clear all of the
-     * properties on the connection.  See <code>setClientInfo (String, String)</code> for
-     * more information.
+     * Sets the value of the connection's client info properties. The
+     * <code>Properties</code> object contains the names and values of the client
+     * info properties to be set. The set of client info properties contained in the
+     * properties list replaces the current set of client info properties on the
+     * connection. If a property that is currently set on the connection is not
+     * present in the properties list, that property is cleared. Specifying an empty
+     * properties list will clear all of the properties on the connection. See
+     * <code>setClientInfo (String, String)</code> for more information.
      * <p/>
      * If an error occurs in setting any of the client info properties, a
-     * <code>SQLClientInfoException</code> is thrown. The <code>SQLClientInfoException</code>
-     * contains information indicating which client info properties were not set.
-     * The state of the client information is unknown because
-     * some databases do not allow multiple client info properties to be set
-     * atomically.  For those databases, one or more properties may have been
-     * set before the error occurred.
+     * <code>SQLClientInfoException</code> is thrown. The
+     * <code>SQLClientInfoException</code> contains information indicating which
+     * client info properties were not set. The state of the client information is
+     * unknown because some databases do not allow multiple client info properties
+     * to be set atomically. For those databases, one or more properties may have
+     * been set before the error occurred.
      * <p/>
      *
      * @param properties the list of client info properties to set
-     *                   <p/>
-     * @throws java.sql.SQLClientInfoException
-     *          if the database server returns an error while
-     *          setting the clientInfo values on the database server or this method
-     *          is called on a closed connection
-     *          <p/>
-     * @see java.sql.Connection#setClientInfo(String,String) setClientInfo(String, String)
+     * <p/>
+     * @throws java.sql.SQLClientInfoException if the database server returns an
+     * error while setting the clientInfo values on the database server or this
+     * method is called on a closed connection
+     * <p/>
+     * @see java.sql.Connection#setClientInfo(String,String) setClientInfo(String,
+     * String)
      * @since 1.6
-     *        <p/>
+     * <p/>
      */
+    @Override
     public void setClientInfo(Properties properties) throws SQLClientInfoException {
         try {
             checkValidity();
@@ -297,73 +308,76 @@
             sce.setStackTrace(sqe.getStackTrace());
             throw sce;
         }
-        con.setClientInfo(properties);
+        connection.setClientInfo(properties);
     }
 
     /**
-     * Returns the value of the client info property specified by name.  This
-     * method may return null if the specified client info property has not
-     * been set and does not have a default value.  This method will also
-     * return null if the specified client info property name is not supported
-     * by the driver.
+     * Returns the value of the client info property specified by name. This method
+     * may return null if the specified client info property has not been set and
+     * does not have a default value. This method will also return null if the
+     * specified client info property name is not supported by the driver.
      * <p/>
-     * Applications may use the <code>DatabaseMetaData.getClientInfoProperties</code>
-     * method to determine the client info properties supported by the driver.
+     * Applications may use the
+     * <code>DatabaseMetaData.getClientInfoProperties</code> method to determine the
+     * client info properties supported by the driver.
      * <p/>
      *
      * @param name The name of the client info property to retrieve
-     *             <p/>
+     * <p/>
      * @return The value of the client info property specified
-     *         <p/>
+     * <p/>
      * @throws java.sql.SQLException if the database server returns an error when
-     *                               fetching the client info value from the database
-     *                               or this method is called on a closed connection
-     *                               <p/>
+     * fetching the client info value from the database or this method is called on
+     * a closed connection
+     * <p/>
      * @see java.sql.DatabaseMetaData#getClientInfoProperties
      * @since 1.6
-     *        <p/>
+     * <p/>
      */
+    @Override
     public String getClientInfo(String name) throws SQLException {
         checkValidity();
-        return con.getClientInfo(name);
+        return connection.getClientInfo(name);
     }
 
     /**
      * Returns a list containing the name and current value of each client info
-     * property supported by the driver.  The value of a client info property
-     * may be null if the property has not been set and does not have a
-     * default value.
+     * property supported by the driver. The value of a client info property may be
+     * null if the property has not been set and does not have a default value.
      * <p/>
      *
-     * @return A <code>Properties</code> object that contains the name and current value of
-     *         each of the client info properties supported by the driver.
-     *         <p/>
+     * @return A <code>Properties</code> object that contains the name and current
+     * value of each of the client info properties supported by the driver.
+     * <p/>
      * @throws java.sql.SQLException if the database server returns an error when
-     *                               fetching the client info values from the database
-     *                               or this method is called on a closed connection
-     *                               <p/>
+     * fetching the client info values from the database or this method is called on
+     * a closed connection
+     * <p/>
      * @since 1.6
      */
+    @Override
     public Properties getClientInfo() throws SQLException {
         checkValidity();
-        return con.getClientInfo();
+        return connection.getClientInfo();
     }
 
     /**
-     * Returns true if the client info properties are supported.
-     * The application server calls the <code>getClientInfo</code> method and the <code>setClientInfo</code> method
-     * only if the driver supports the client info properties.
-     * The <code>DatabaseMetaData#getClientInfoProperties</code> method is used to determine
-     * whether the driver supports the client info properties or not.
-     * Note that the <code>DatabaseMetaData</code> will be cached by <code>ManagedConnection</code>.
+     * Returns true if the client info properties are supported. The application
+     * server calls the <code>getClientInfo</code> method and the
+     * <code>setClientInfo</code> method only if the driver supports the client info
+     * properties. The <code>DatabaseMetaData#getClientInfoProperties</code> method
+     * is used to determine whether the driver supports the client info properties
+     * or not. Note that the <code>DatabaseMetaData</code> will be cached by
+     * <code>ManagedConnection</code>.
      * <p/>
      *
      * @return true if the client info properties are supported, false otherwise
      *
-     * @throws jakarta.resource.ResourceException if the access to connection is failed.
+     * @throws jakarta.resource.ResourceException if the access to connection is
+     * failed.
      *
-     * @throws java.sql.SQLException if the database server returns an error when retrieving
-     *                               a list of the client info properties.
+     * @throws java.sql.SQLException if the database server returns an error when
+     * retrieving a list of the client info properties.
      *
      * @see java.sql.DatabaseMetaData#getClientInfoProperties
      * @since 1.6
@@ -380,10 +394,10 @@
                 return isSupportClientInfo;
             } finally {
                 try {
-                rs.close();
-                } catch(SQLException ex) {
-                    if(_logger.isLoggable(Level.FINEST)) {
-                        _logger.log(Level.FINEST, "jdbc.unable_to_get_client_info", ex);
+                    rs.close();
+                } catch (SQLException ex) {
+                    if (_logger.isLoggable(FINEST)) {
+                        _logger.log(FINEST, "jdbc.unable_to_get_client_info", ex);
                     }
                     return false;
                 }
@@ -394,100 +408,113 @@
     /**
      * Factory method for creating Array objects.
      *
-     * @param typeName the SQL name of the type the elements of the array map to. The typeName is a
-     *                 database-specific name which may be the name of a built-in type, a user-defined type or a standard  SQL type supported by this database. This
-     *                 is the value returned by <code>Array.getBaseTypeName</code>
+     * @param typeName the SQL name of the type the elements of the array map to.
+     * The typeName is a database-specific name which may be the name of a built-in
+     * type, a user-defined type or a standard SQL type supported by this database.
+     * This is the value returned by <code>Array.getBaseTypeName</code>
      * @param elements the elements that populate the returned object
      * @return an Array object whose elements map to the specified SQL type
-     * @throws java.sql.SQLException if a database error occurs, the typeName is null or this method is called on a closed connection
-     * @throws java.sql.SQLFeatureNotSupportedException
-     *                               if the JDBC driver does not support this data type
+     * @throws java.sql.SQLException if a database error occurs, the typeName is
+     * null or this method is called on a closed connection
+     * @throws java.sql.SQLFeatureNotSupportedException if the JDBC driver does not
+     * support this data type
      * @since 1.6
      */
+    @Override
     public Array createArrayOf(String typeName, Object[] elements) throws SQLException {
         checkValidity();
         jdbcPreInvoke();
-        return con.createArrayOf(typeName, elements);
+        return connection.createArrayOf(typeName, elements);
     }
 
     /**
      * Factory method for creating Struct objects.
      *
-     * @param typeName   the SQL type name of the SQL structured type that this <code>Struct</code>
-     *                   object maps to. The typeName is the name of  a user-defined type that
-     *                   has been defined for this database. It is the value returned by
-     *                   <code>Struct.getSQLTypeName</code>.
+     * @param typeName the SQL type name of the SQL structured type that this
+     * <code>Struct</code> object maps to. The typeName is the name of a
+     * user-defined type that has been defined for this database. It is the value
+     * returned by <code>Struct.getSQLTypeName</code>.
      * @param attributes the attributes that populate the returned object
-     * @return a Struct object that maps to the given SQL type and is populated with the given attributes
-     * @throws java.sql.SQLException if a database error occurs, the typeName is null or this method is called on a closed connection
-     * @throws java.sql.SQLFeatureNotSupportedException
-     *                               if the JDBC driver does not support this data type
+     * @return a Struct object that maps to the given SQL type and is populated with
+     * the given attributes
+     * @throws java.sql.SQLException if a database error occurs, the typeName is
+     * null or this method is called on a closed connection
+     * @throws java.sql.SQLFeatureNotSupportedException if the JDBC driver does not
+     * support this data type
      * @since 1.6
      */
+    @Override
     public Struct createStruct(String typeName, Object[] attributes) throws SQLException {
         checkValidity();
         jdbcPreInvoke();
-        return con.createStruct(typeName, attributes);
+        return connection.createStruct(typeName, attributes);
     }
 
     /**
      * Returns an object that implements the given interface to allow access to
      * non-standard methods, or standard methods not exposed by the proxy.
      * <p/>
-     * If the receiver implements the interface then the result is the receiver
-     * or a proxy for the receiver. If the receiver is a wrapper
-     * and the wrapped object implements the interface then the result is the
-     * wrapped object or a proxy for the wrapped object. Otherwise return the
-     * the result of calling <code>unwrap</code> recursively on the wrapped object
-     * or a proxy for that result. If the receiver is not a
-     * wrapper and does not implement the interface, then an <code>SQLException</code> is thrown.
+     * If the receiver implements the interface then the result is the receiver or a
+     * proxy for the receiver. If the receiver is a wrapper and the wrapped object
+     * implements the interface then the result is the wrapped object or a proxy for
+     * the wrapped object. Otherwise return the the result of calling
+     * <code>unwrap</code> recursively on the wrapped object or a proxy for that
+     * result. If the receiver is not a wrapper and does not implement the
+     * interface, then an <code>SQLException</code> is thrown.
      *
      * @param iface A Class defining an interface that the result must implement.
-     * @return an object that implements the interface. May be a proxy for the actual implementing object.
-     * @throws java.sql.SQLException If no object found that implements the interface
+     * @return an object that implements the interface. May be a proxy for the
+     * actual implementing object.
+     * @throws java.sql.SQLException If no object found that implements the
+     * interface
      * @since 1.6
      */
+    @Override
     public <T> T unwrap(Class<T> iface) throws SQLException {
         checkValidity();
-        T result = null;
-        if (iface.isInstance(this)) { //if iface is "java.sql.Connection"
-            result = iface.cast(this);
-        } else if (iface.isInstance(con)) {
-            //if iface is not "java.sql.Connection" & implemented by native Connection
-            Class<T> listIntf[] = new Class[]{iface};
-            result = getProxyObject(con, listIntf);
-        } else {
-            //probably a proxy, delegating to native connection
-            result = con.unwrap(iface);
-            if (Connection.class.isInstance(result)) {
-                // rare case : returned object implements both iface & java.sql.Connection
-                Class<T> listIntf[] = new Class[]{iface, Connection.class};
-                result = getProxyObject(result, listIntf);
-            }
+
+        if (iface.isInstance(this)) { // if iface is "java.sql.Connection"
+            return iface.cast(this);
         }
+
+        if (iface.isInstance(connection)) {
+            // If iface is not "java.sql.Connection" & implemented by native Connection
+            @SuppressWarnings("unchecked")
+            Class<T>[] listIntf = new Class[] { iface };
+            return getProxyObject(connection, listIntf);
+        }
+
+        // Probably a proxy, delegating to native connection
+        T result = connection.unwrap(iface);
+        if (Connection.class.isInstance(result)) {
+            // rare case : returned object implements both iface & java.sql.Connection
+            @SuppressWarnings("unchecked")
+            Class<T> listIntf[] = new Class[] { iface, Connection.class };
+            result = getProxyObject(result, listIntf);
+        }
+
         return result;
     }
 
     /**
      * @param actualObject Object from jdbc vendor connection's unwrap
-     * @param ifaces       Interfaces for which proxy is needed
+     * @param ifaces Interfaces for which proxy is needed
      * @return Proxy class implmenting the interfaces
      * @throws SQLException
      */
+    @SuppressWarnings("unchecked")
     private <T> T getProxyObject(final Object actualObject, Class<T>[] ifaces) throws SQLException {
-        T result;
-        InvocationHandler ih;
+        InvocationHandler invocationHandler;
         try {
-            ih = new InvocationHandler() {
-                public Object invoke(Object proxy, Method method, Object[] args) throws SQLException,
-                        IllegalAccessException, InvocationTargetException {
+            invocationHandler = new InvocationHandler() {
+                @Override
+                public Object invoke(Object proxy, Method method, Object[] args) throws SQLException, IllegalAccessException, InvocationTargetException {
+
                     // When close() is called on proxy object, call close() on resource adapter's
                     // Connection Holder instead of physical connection.
-                    if (method.getName().equals("close")
-                            && method.getParameterTypes().length == 0) {
-                        if (_logger.isLoggable(Level.FINE)) {
-                            String msg = localStrings.getString("jdbc.close_called_on_proxy_object", actualObject);
-                            _logger.log(Level.FINE, msg);
+                    if (method.getName().equals("close") && method.getParameterTypes().length == 0) {
+                        if (_logger.isLoggable(FINE)) {
+                            _logger.log(FINE, localStrings.getString("jdbc.close_called_on_proxy_object", actualObject));
                         }
                         ConnectionHolder40.this.close();
                         return null;
@@ -500,34 +527,37 @@
         } catch (Exception e) {
             throw new SQLException(e.fillInStackTrace());
         }
-        result = (T) Proxy.newProxyInstance(actualObject.getClass().getClassLoader(), ifaces, ih);
-        return result;
+
+        return (T) Proxy.newProxyInstance(actualObject.getClass().getClassLoader(), ifaces, invocationHandler);
     }
 
     /**
-     * Returns true if this either implements the interface argument or is directly or indirectly a wrapper
-     * for an object that does. Returns false otherwise. If this implements the interface then return true,
-     * else if this is a wrapper then return the result of recursively calling <code>isWrapperFor</code> on the wrapped
-     * object. If this does not implement the interface and is not a wrapper, return false.
-     * This method should be implemented as a low-cost operation compared to <code>unwrap</code> so that
-     * callers can use this method to avoid expensive <code>unwrap</code> calls that may fail. If this method
-     * returns true then calling <code>unwrap</code> with the same argument should succeed.
+     * Returns true if this either implements the interface argument or is directly
+     * or indirectly a wrapper for an object that does. Returns false otherwise. If
+     * this implements the interface then return true, else if this is a wrapper
+     * then return the result of recursively calling <code>isWrapperFor</code> on
+     * the wrapped object. If this does not implement the interface and is not a
+     * wrapper, return false. This method should be implemented as a low-cost
+     * operation compared to <code>unwrap</code> so that callers can use this method
+     * to avoid expensive <code>unwrap</code> calls that may fail. If this method
+     * returns true then calling <code>unwrap</code> with the same argument should
+     * succeed.
      *
      * @param iface a Class defining an interface.
-     * @return true if this implements the interface or directly or indirectly wraps an object that does.
-     * @throws java.sql.SQLException if an error occurs while determining whether this is a wrapper
-     *                               for an object with the given interface.
+     * @return true if this implements the interface or directly or indirectly wraps
+     * an object that does.
+     * @throws java.sql.SQLException if an error occurs while determining whether
+     * this is a wrapper for an object with the given interface.
      * @since 1.6
      */
+    @Override
     public boolean isWrapperFor(Class<?> iface) throws SQLException {
         checkValidity();
-        boolean result;
         if (iface.isInstance(this)) {
-            result = true;
-        } else {
-            result = con.isWrapperFor(iface);
+            return true;
         }
-        return result;
+
+        return connection.isWrapperFor(iface);
     }
 
     /**
@@ -536,13 +566,13 @@
      *
      * @throws SQLException In case of a database error.
      */
+    @Override
     public void close() throws SQLException {
         if (isClosed) {
-            if (_logger.isLoggable(Level.FINE)) {
-                _logger.log(Level.FINE, "jdbc.duplicate_close_connection", this);
-            }
+            _logger.log(FINE, "jdbc.duplicate_close_connection", this);
             return;
         }
+
         if (!jdbc30Connection) {
             try {
                 checkValidity();
@@ -554,91 +584,104 @@
                     }
                 }
             } catch (Throwable e) {
-                _logger.log(Level.INFO, "jdbc.unable_to_set_client_info", e.getMessage());
-                if(_logger.isLoggable(Level.FINEST)) {
-                    _logger.log(Level.FINEST, "jdbc.unable_to_set_client_info", e);
-                }
+                _logger.log(INFO, "jdbc.unable_to_set_client_info", e.getMessage());
+                _logger.log(FINEST, "jdbc.unable_to_set_client_info", e);
             }
         }
+
         super.close();
     }
 
+    @Override
     public void setSchema(String schema) throws SQLException {
-        if(DataSourceObjectBuilder.isJDBC41()) {
-            checkValidity();
-            Class<?>[] valueTypes = new Class<?>[]{String.class};
-            try {
-                getMethodExecutor().invokeMethod(con, "setSchema", valueTypes, schema);
-            } catch (ResourceException ex) {
-                _logger.log(Level.SEVERE, "jdbc.ex_connection_holder", ex);
-                throw new SQLException(ex);
-            }
-            return;
+        if (!isJDBC41()) {
+            throw new UnsupportedOperationException("Operation not supported in this runtime.");
         }
-        throw new UnsupportedOperationException("Operation not supported in this runtime.");
+
+        checkValidity();
+
+        Class<?>[] valueTypes = new Class<?>[] { String.class };
+        try {
+            getMethodExecutor().invokeMethod(connection, "setSchema", valueTypes, schema);
+        } catch (ResourceException ex) {
+            _logger.log(SEVERE, "jdbc.ex_connection_holder", ex);
+            throw new SQLException(ex);
+        }
+
+        return;
+
     }
 
+    @Override
     public String getSchema() throws SQLException {
-        if(DataSourceObjectBuilder.isJDBC41()) {
-            checkValidity();
-            try {
-                return (String) getMethodExecutor().invokeMethod(con, "getSchema", null);
-            } catch (ResourceException ex) {
-                _logger.log(Level.SEVERE, "jdbc.ex_connection_holder", ex);
-                throw new SQLException(ex);
-            }
+        if (!isJDBC41()) {
+            throw new UnsupportedOperationException("Operation not supported in this runtime.");
         }
-        throw new UnsupportedOperationException("Operation not supported in this runtime.");
+
+        checkValidity();
+
+        try {
+            return (String) getMethodExecutor().invokeMethod(connection, "getSchema", null);
+        } catch (ResourceException ex) {
+            _logger.log(SEVERE, "jdbc.ex_connection_holder", ex);
+            throw new SQLException(ex);
+        }
     }
 
-    public void setNetworkTimeout(Executor executorObj, int milliseconds)
-            throws SQLException {
-        if (DataSourceObjectBuilder.isJDBC41()) {
-            checkValidity();
-            Class<?>[] valueTypes = new Class<?>[]{Executor.class, Integer.TYPE};
-            try {
-                getMethodExecutor().invokeMethod(con, "setNetworkTimeout", valueTypes, executorObj, milliseconds);
-            } catch (ResourceException ex) {
-                _logger.log(Level.SEVERE, "jdbc.ex_connection_holder", ex);
-                throw new SQLException(ex);
-            }
-            return;
+    @Override
+    public void setNetworkTimeout(Executor executorObj, int milliseconds) throws SQLException {
+        if (!isJDBC41()) {
+            throw new UnsupportedOperationException("Operation not supported in this runtime.");
         }
-        throw new UnsupportedOperationException("Operation not supported in this runtime.");
+
+        checkValidity();
+
+        Class<?>[] valueTypes = new Class<?>[] { Executor.class, Integer.TYPE };
+        try {
+            getMethodExecutor().invokeMethod(connection, "setNetworkTimeout", valueTypes, executorObj, milliseconds);
+        } catch (ResourceException ex) {
+            _logger.log(SEVERE, "jdbc.ex_connection_holder", ex);
+            throw new SQLException(ex);
+        }
+        return;
     }
 
+    @Override
     public int getNetworkTimeout() throws SQLException {
-        if (DataSourceObjectBuilder.isJDBC41()) {
-            checkValidity();
-            try {
-                return (Integer) getMethodExecutor().invokeMethod(con, "getNetworkTimeout", null);
-            } catch (ResourceException ex) {
-                _logger.log(Level.SEVERE, "jdbc.ex_connection_holder", ex);
-                throw new SQLException(ex);
-            }
+        if (!isJDBC41()) {
+            throw new UnsupportedOperationException("Operation not supported in this runtime.");
         }
-        throw new UnsupportedOperationException("Operation not supported in this runtime.");
+
+        checkValidity();
+
+        try {
+            return (Integer) getMethodExecutor().invokeMethod(connection, "getNetworkTimeout", null);
+        } catch (ResourceException ex) {
+            _logger.log(SEVERE, "jdbc.ex_connection_holder", ex);
+            throw new SQLException(ex);
+        }
     }
 
     /**
-     * Abort operation to mark the connection internally as a bad connection
-     * for removal and to close the connection. This ensures that at the end
-     * of the transaction, the connection is destroyed. A running thread
-     * holding a connection will run to completion before the connection is
-     * destroyed
+     * Abort operation to mark the connection internally as a bad connection for
+     * removal and to close the connection. This ensures that at the end of the
+     * transaction, the connection is destroyed. A running thread holding a
+     * connection will run to completion before the connection is destroyed
      *
      * @param executor
      * @throws SQLException
      */
+    @Override
     public void abort(Executor executor) throws SQLException {
-        if (DataSourceObjectBuilder.isJDBC41()) {
-            getManagedConnection().markForRemoval(true);
-            getManagedConnection().setAborted(true);
-            if(!getManagedConnection().isTransactionInProgress()) {
-                close();
-            }
-        } else {
+        if (!isJDBC41()) {
             throw new UnsupportedOperationException("Operation not supported in this runtime.");
         }
+
+        getManagedConnection().markForRemoval(true);
+        getManagedConnection().setAborted(true);
+        if (!getManagedConnection().isTransactionInProgress()) {
+            close();
+        }
+
     }
 }
diff --git a/appserver/jdbc/jdbc-ra/jdbc40/src/main/java/com/sun/gjc/spi/jdbc40/ConnectionWrapper40.java b/appserver/jdbc/jdbc-ra/jdbc40/src/main/java/com/sun/gjc/spi/jdbc40/ConnectionWrapper40.java
index 4b3619b..a337163 100644
--- a/appserver/jdbc/jdbc-ra/jdbc40/src/main/java/com/sun/gjc/spi/jdbc40/ConnectionWrapper40.java
+++ b/appserver/jdbc/jdbc-ra/jdbc40/src/main/java/com/sun/gjc/spi/jdbc40/ConnectionWrapper40.java
@@ -16,13 +16,24 @@
 
 package com.sun.gjc.spi.jdbc40;
 
+import static java.sql.ResultSet.CONCUR_READ_ONLY;
+import static java.sql.ResultSet.TYPE_FORWARD_ONLY;
+
+import java.sql.CallableStatement;
+import java.sql.Connection;
+import java.sql.DatabaseMetaData;
+import java.sql.PreparedStatement;
+import java.sql.SQLException;
+import java.sql.Statement;
+
 import com.sun.gjc.spi.ManagedConnectionImpl;
 import com.sun.gjc.spi.base.ConnectionWrapper;
 
-import java.sql.*;
+import jakarta.resource.spi.ConnectionRequestInfo;
 
 /**
- * Wrapper class that aids to provide wrapper for the following JDBC objects : <br>
+ * Wrapper class that aids to provide wrapper for the following JDBC objects :
+ * <br>
  * Statement, PreparedStatement, CallableStatement, DatabaseMetaData
  */
 public class ConnectionWrapper40 extends ConnectionHolder40 implements ConnectionWrapper {
@@ -30,13 +41,12 @@
     /**
      * Instantiates connection wrapper to wrap JDBC objects.
      *
-     * @param con           Connection that is wrapped
-     * @param mc            Managed Connection
+     * @param con Connection that is wrapped
+     * @param mc Managed Connection
      * @param cxRequestInfo Connection Request Info
      */
-    public ConnectionWrapper40(Connection con, ManagedConnectionImpl mc,
-                               jakarta.resource.spi.ConnectionRequestInfo cxRequestInfo,
-                               boolean jdbc30Connection) {
+    public ConnectionWrapper40(Connection con, ManagedConnectionImpl mc, ConnectionRequestInfo cxRequestInfo,
+            boolean jdbc30Connection) {
         super(con, mc, cxRequestInfo, jdbc30Connection);
     }
 
@@ -46,37 +56,36 @@
      * @return <code>Statement</code> object.
      * @throws java.sql.SQLException In case of a database error.
      */
+    @Override
     public Statement createStatement() throws SQLException {
-
         return new StatementWrapper40(this, super.createStatement());
     }
 
     /**
      * Creates a statement from the underlying Connection.
      *
-     * @param resultSetType        Type of the ResultSet
+     * @param resultSetType Type of the ResultSet
      * @param resultSetConcurrency ResultSet Concurrency.
      * @return <code>Statement</code> object.
      * @throws SQLException In case of a database error.
      */
+    @Override
     public Statement createStatement(int resultSetType, int resultSetConcurrency) throws SQLException {
-        return new StatementWrapper40(this, super.createStatement(resultSetType,
-                resultSetConcurrency));
+        return new StatementWrapper40(this, super.createStatement(resultSetType, resultSetConcurrency));
     }
 
     /**
      * Creates a statement from the underlying Connection.
      *
-     * @param resultSetType        Type of the ResultSet
+     * @param resultSetType Type of the ResultSet
      * @param resultSetConcurrency ResultSet Concurrency.
      * @param resultSetHoldability ResultSet Holdability.
      * @return <code>Statement</code> object.
      * @throws SQLException In case of a database error.
      */
-    public Statement createStatement(int resultSetType, int resultSetConcurrency,
-                                     int resultSetHoldability) throws SQLException {
-        return new StatementWrapper40(this, super.createStatement(resultSetType,
-                resultSetConcurrency, resultSetHoldability));
+    @Override
+    public Statement createStatement(int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException {
+        return new StatementWrapper40(this, super.createStatement(resultSetType, resultSetConcurrency, resultSetHoldability));
     }
 
     /**
@@ -86,195 +95,187 @@
      * @return <code>DatabaseMetaData</code> object.
      * @throws SQLException In case of a database error.
      */
+    @Override
     public DatabaseMetaData getMetaData() throws SQLException {
         return new DatabaseMetaDataWrapper40(this, super.getMetaData());
     }
 
-
     /**
-     * Creates a <code> CallableStatement </code> object for calling database
-     * stored procedures.
+     * Creates a <code> CallableStatement </code> object for calling database stored
+     * procedures.
      *
      * @param sql SQL Statement
      * @return <code> CallableStatement</code> object.
      * @throws java.sql.SQLException In case of a database error.
      */
+    @Override
     public CallableStatement prepareCall(String sql) throws SQLException {
-        return mc.prepareCachedCallableStatement(this, sql, ResultSet.TYPE_FORWARD_ONLY,
-                ResultSet.CONCUR_READ_ONLY);
+        return managedConnectionImpl.prepareCachedCallableStatement(this, sql, TYPE_FORWARD_ONLY, CONCUR_READ_ONLY);
     }
 
     /**
-     * Creates a <code> CallableStatement </code> object for calling database
-     * stored procedures.
+     * Creates a <code> CallableStatement </code> object for calling database stored
+     * procedures.
      *
-     * @param sql                  SQL Statement
-     * @param resultSetType        Type of the ResultSet
+     * @param sql SQL Statement
+     * @param resultSetType Type of the ResultSet
      * @param resultSetConcurrency ResultSet Concurrency.
      * @return <code> CallableStatement</code> object.
      * @throws SQLException In case of a database error.
      */
-    public CallableStatement prepareCall(String sql, int resultSetType,
-                                         int resultSetConcurrency) throws SQLException {
-        return mc.prepareCachedCallableStatement(this, sql, resultSetType, resultSetConcurrency);
+    @Override
+    public CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency) throws SQLException {
+        return managedConnectionImpl.prepareCachedCallableStatement(this, sql, resultSetType, resultSetConcurrency);
     }
 
     /**
-     * Creates a <code> CallableStatement </code> object for calling database
-     * stored procedures.
+     * Creates a <code> CallableStatement </code> object for calling database stored
+     * procedures.
      *
-     * @param sql                  SQL Statement
-     * @param resultSetType        Type of the ResultSet
+     * @param sql SQL Statement
+     * @param resultSetType Type of the ResultSet
      * @param resultSetConcurrency ResultSet Concurrency.
      * @param resultSetHoldability ResultSet Holdability.
      * @return <code> CallableStatement</code> object.
      * @throws SQLException In case of a database error.
      */
-     public CallableStatement prepareCall(String sql, int resultSetType,
-                                         int resultSetConcurrency,
-                                         int resultSetHoldability) throws SQLException {
-        return mc.prepareCachedCallableStatement(this, sql, resultSetType,
-                resultSetConcurrency, resultSetHoldability);
+    @Override
+    public CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException {
+        return managedConnectionImpl.prepareCachedCallableStatement(this, sql, resultSetType, resultSetConcurrency, resultSetHoldability);
     }
 
     /**
-     * Creates a <code> PreparedStatement </code> object for sending
-     * paramterized SQL statements to database
+     * Creates a <code> PreparedStatement </code> object for sending paramterized
+     * SQL statements to database
      *
      * @param sql SQL Statement
      * @return <code> PreparedStatement</code> object.
      * @throws SQLException In case of a database error.
      */
+    @Override
     public PreparedStatement prepareStatement(String sql) throws SQLException {
-        return mc.prepareCachedStatement(this, sql, ResultSet.TYPE_FORWARD_ONLY,
-                ResultSet.CONCUR_READ_ONLY);
+        return managedConnectionImpl.prepareCachedStatement(this, sql, TYPE_FORWARD_ONLY, CONCUR_READ_ONLY);
     }
 
     /**
-     * Creates a <code> PreparedStatement </code> object for sending
-     * paramterized SQL statements to database
+     * Creates a <code> PreparedStatement </code> object for sending paramterized
+     * SQL statements to database
      *
-     * @param sql               SQL Statement
-     * @param autoGeneratedKeys a flag indicating AutoGeneratedKeys need to be returned.
+     * @param sql SQL Statement
+     * @param autoGeneratedKeys a flag indicating AutoGeneratedKeys need to be
+     * returned.
      * @return <code> PreparedStatement</code> object.
      * @throws SQLException In case of a database error.
      */
-     public PreparedStatement prepareStatement(String sql, int autoGeneratedKeys) throws SQLException {
-        return mc.prepareCachedStatement(this, sql, autoGeneratedKeys);
+    @Override
+    public PreparedStatement prepareStatement(String sql, int autoGeneratedKeys) throws SQLException {
+        return managedConnectionImpl.prepareCachedStatement(this, sql, autoGeneratedKeys);
     }
 
     /**
-     * Creates a <code> PreparedStatement </code> object for sending
-     * paramterized SQL statements to database
+     * Creates a <code> PreparedStatement </code> object for sending paramterized
+     * SQL statements to database
      *
-     * @param sql           SQL Statement
-     * @param columnIndexes an array of column indexes indicating the columns that should be
-     *                      returned from the inserted row or rows.
+     * @param sql SQL Statement
+     * @param columnIndexes an array of column indexes indicating the columns that
+     * should be returned from the inserted row or rows.
      * @return <code> PreparedStatement</code> object.
      * @throws SQLException In case of a database error.
      */
-     public PreparedStatement prepareStatement(String sql, int[] columnIndexes) throws SQLException {
-        return mc.prepareCachedStatement(this, sql, columnIndexes);
+    @Override
+    public PreparedStatement prepareStatement(String sql, int[] columnIndexes) throws SQLException {
+        return managedConnectionImpl.prepareCachedStatement(this, sql, columnIndexes);
     }
 
     /**
-     * Creates a <code> PreparedStatement </code> object for sending
-     * paramterized SQL statements to database
+     * Creates a <code> PreparedStatement </code> object for sending paramterized
+     * SQL statements to database
      *
-     * @param sql                  SQL Statement
-     * @param resultSetType        Type of the ResultSet
+     * @param sql SQL Statement
+     * @param resultSetType Type of the ResultSet
      * @param resultSetConcurrency ResultSet Concurrency.
      * @return <code> PreparedStatement</code> object.
      * @throws SQLException In case of a database error.
      */
-     public PreparedStatement prepareStatement(String sql, int resultSetType,
-                                              int resultSetConcurrency) throws SQLException {
-        return mc.prepareCachedStatement(this, sql, resultSetType, resultSetConcurrency);
+    @Override
+    public PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency) throws SQLException {
+        return managedConnectionImpl.prepareCachedStatement(this, sql, resultSetType, resultSetConcurrency);
     }
 
     /**
-     * Creates a <code> PreparedStatement </code> object for sending
-     * paramterized SQL statements to database
+     * Creates a <code> PreparedStatement </code> object for sending paramterized
+     * SQL statements to database
      *
-     * @param sql                  SQL Statement
-     * @param resultSetType        Type of the ResultSet
+     * @param sql SQL Statement
+     * @param resultSetType Type of the ResultSet
      * @param resultSetConcurrency ResultSet Concurrency.
      * @param resultSetHoldability ResultSet Holdability.
      * @return <code> PreparedStatement</code> object.
      * @throws SQLException In case of a database error.
      */
-     public PreparedStatement prepareStatement(String sql, int resultSetType,
-                                              int resultSetConcurrency,
-                                              int resultSetHoldability) throws SQLException {
-        return mc.prepareCachedStatement(this, sql, resultSetType,
-                resultSetConcurrency, resultSetHoldability);
+    @Override
+    public PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException {
+        return managedConnectionImpl.prepareCachedStatement(this, sql, resultSetType, resultSetConcurrency, resultSetHoldability);
     }
 
     /**
-     * Creates a <code> PreparedStatement </code> object for sending
-     * paramterized SQL statements to database
+     * Creates a <code> PreparedStatement </code> object for sending paramterized
+     * SQL statements to database
      *
-     * @param sql         SQL Statement
+     * @param sql SQL Statement
      * @param columnNames Name of bound columns.
      * @return <code> PreparedStatement</code> object.
      * @throws SQLException In case of a database error.
      */
-     public PreparedStatement prepareStatement(String sql, String[] columnNames) throws SQLException {
+    @Override
+    public PreparedStatement prepareStatement(String sql, String[] columnNames) throws SQLException {
         checkValidity();
         jdbcPreInvoke();
-        return mc.prepareCachedStatement(this, sql, columnNames);
+        return managedConnectionImpl.prepareCachedStatement(this, sql, columnNames);
     }
 
-      public PreparedStatementWrapper40 prepareCachedStatement(String sql,
-              int resultSetType, int resultSetConcurrency, boolean enableCaching)
-              throws SQLException {
-           return new PreparedStatementWrapper40(this, super.prepareStatement(sql,
-                   resultSetType, resultSetConcurrency), enableCaching);
-       }
+    @Override
+    public PreparedStatementWrapper40 prepareCachedStatement(String sql, int resultSetType, int resultSetConcurrency, boolean enableCaching) throws SQLException {
+        return new PreparedStatementWrapper40(
+            this,
+            super.prepareStatement(sql, resultSetType, resultSetConcurrency),
+            enableCaching);
+    }
 
-       public PreparedStatementWrapper40 prepareCachedStatement(String sql,
-              String[] columnNames, boolean enableCaching)
-              throws SQLException {
-           return new PreparedStatementWrapper40(this,
-                   super.prepareStatement(sql, columnNames), enableCaching);
-       }
+    @Override
+    public PreparedStatementWrapper40 prepareCachedStatement(String sql, String[] columnNames, boolean enableCaching) throws SQLException {
+        return new PreparedStatementWrapper40(this, super.prepareStatement(sql, columnNames), enableCaching);
+    }
 
-        public PreparedStatementWrapper40 prepareCachedStatement(String sql,
-                int resultSetType, int resultSetConcurrency, int resultSetHoldability,
-                boolean enableCaching) throws SQLException {
-            return new PreparedStatementWrapper40(this,
-                    super.prepareCall(sql, resultSetType, resultSetConcurrency, resultSetHoldability),
-                    enableCaching);
-        }
+    @Override
+    public PreparedStatementWrapper40 prepareCachedStatement(String sql, int resultSetType, int resultSetConcurrency, int resultSetHoldability, boolean enableCaching) throws SQLException {
+        return new PreparedStatementWrapper40(
+            this,
+            super.prepareCall(sql, resultSetType, resultSetConcurrency, resultSetHoldability),
+            enableCaching);
+    }
 
-        public PreparedStatementWrapper40 prepareCachedStatement(String sql,
-              int[] columnIndexes, boolean enableCaching)
-              throws SQLException {
-           return new PreparedStatementWrapper40(this,
-                   super.prepareStatement(sql, columnIndexes), enableCaching);
-       }
+    @Override
+    public PreparedStatementWrapper40 prepareCachedStatement(String sql, int[] columnIndexes, boolean enableCaching) throws SQLException {
+        return new PreparedStatementWrapper40(this, super.prepareStatement(sql, columnIndexes), enableCaching);
+    }
 
-        public PreparedStatementWrapper40 prepareCachedStatement(String sql,
-              int autoGeneratedKeys, boolean enableCaching)
-              throws SQLException {
-           return new PreparedStatementWrapper40(this,
-                   super.prepareStatement(sql, autoGeneratedKeys), enableCaching);
-       }
+    @Override
+    public PreparedStatementWrapper40 prepareCachedStatement(String sql, int autoGeneratedKeys, boolean enableCaching) throws SQLException {
+        return new PreparedStatementWrapper40(this, super.prepareStatement(sql, autoGeneratedKeys), enableCaching);
+    }
 
-        public CallableStatementWrapper40 callableCachedStatement(String sql,
-               int resultSetType, int resultSetConcurrency, boolean enableCaching)
-               throws SQLException {
-           return new CallableStatementWrapper40(this, super.prepareCall(sql,
-                   resultSetType, resultSetConcurrency), enableCaching);
-       }
+    @Override
+    public CallableStatementWrapper40 callableCachedStatement(String sql, int resultSetType, int resultSetConcurrency, boolean enableCaching) throws SQLException {
+        return new CallableStatementWrapper40(this, super.prepareCall(sql, resultSetType, resultSetConcurrency), enableCaching);
+    }
 
-        public CallableStatementWrapper40 callableCachedStatement(String sql,
-               int resultSetType, int resultSetConcurrency,
-               int resultSetHoldability, boolean enableCaching)
-               throws SQLException {
-           return new CallableStatementWrapper40(this, super.prepareCall(sql,
-                   resultSetType, resultSetConcurrency, resultSetHoldability),
-                   enableCaching);
-       }
+    @Override
+    public CallableStatementWrapper40 callableCachedStatement(String sql, int resultSetType, int resultSetConcurrency, int resultSetHoldability, boolean enableCaching) throws SQLException {
+        return new CallableStatementWrapper40(
+            this,
+            super.prepareCall(sql, resultSetType, resultSetConcurrency, resultSetHoldability),
+            enableCaching);
+    }
 
 }
diff --git a/appserver/jdbc/jdbc-ra/jdbc40/src/main/java/com/sun/gjc/spi/jdbc40/DataSource40.java b/appserver/jdbc/jdbc-ra/jdbc40/src/main/java/com/sun/gjc/spi/jdbc40/DataSource40.java
index 00c0878..3f5e3f9 100644
--- a/appserver/jdbc/jdbc-ra/jdbc40/src/main/java/com/sun/gjc/spi/jdbc40/DataSource40.java
+++ b/appserver/jdbc/jdbc-ra/jdbc40/src/main/java/com/sun/gjc/spi/jdbc40/DataSource40.java
@@ -16,38 +16,41 @@
 
 package com.sun.gjc.spi.jdbc40;
 
+import static com.sun.gjc.common.DataSourceObjectBuilder.isJDBC41;
+import static java.util.logging.Level.SEVERE;
+import static java.util.logging.Level.WARNING;
+
+import java.sql.SQLException;
+import java.sql.SQLFeatureNotSupportedException;
+import java.sql.Wrapper;
+import java.util.logging.Logger;
+
 import com.sun.enterprise.util.i18n.StringManager;
-import com.sun.gjc.common.DataSourceObjectBuilder;
 import com.sun.gjc.spi.ManagedConnectionFactoryImpl;
 import com.sun.gjc.spi.base.AbstractDataSource;
 
 import jakarta.resource.ResourceException;
 import jakarta.resource.spi.ConnectionManager;
-import java.util.logging.Level;
-import java.sql.*;
-import java.util.logging.Logger;
 
 /**
- * Holds the <code>java.sql.Connection</code> object, which is to be
- * passed to the application program.
+ * Holds the <code>java.sql.Connection</code> object, which is to be passed to
+ * the application program.
  *
  * @author Binod P.G
  * @version 1.0, 02/07/31
  */
 public class DataSource40 extends AbstractDataSource {
 
-
-    protected final static StringManager localStrings =
-            StringManager.getManager(ManagedConnectionFactoryImpl.class);
+    private static final long serialVersionUID = 1L;
+    protected final static StringManager localStrings = StringManager.getManager(ManagedConnectionFactoryImpl.class);
 
     /**
      * Constructs <code>DataSource</code> object. This is created by the
      * <code>ManagedConnectionFactory</code> object.
      *
-     * @param mcf <code>ManagedConnectionFactory</code> object
-     *            creating this object.
-     * @param cm  <code>ConnectionManager</code> object either associated
-     *            with Application server or Resource Adapter.
+     * @param mcf <code>ManagedConnectionFactory</code> object creating this object.
+     * @param cm <code>ConnectionManager</code> object either associated with
+     * Application server or Resource Adapter.
      */
     public DataSource40(ManagedConnectionFactoryImpl mcf, ConnectionManager cm) {
         super(mcf, cm);
@@ -57,23 +60,26 @@
      * Returns an object that implements the given interface to allow access to
      * non-standard methods, or standard methods not exposed by the proxy.
      * <p/>
-     * If the receiver implements the interface then the result is the receiver
-     * or a proxy for the receiver. If the receiver is a wrapper
-     * and the wrapped object implements the interface then the result is the
-     * wrapped object or a proxy for the wrapped object. Otherwise return the
-     * the result of calling <code>unwrap</code> recursively on the wrapped object
-     * or a proxy for that result. If the receiver is not a
-     * wrapper and does not implement the interface, then an <code>SQLException</code> is thrown.
+     * If the receiver implements the interface then the result is the receiver or a
+     * proxy for the receiver. If the receiver is a wrapper and the wrapped object
+     * implements the interface then the result is the wrapped object or a proxy for
+     * the wrapped object. Otherwise return the the result of calling
+     * <code>unwrap</code> recursively on the wrapped object or a proxy for that
+     * result. If the receiver is not a wrapper and does not implement the
+     * interface, then an <code>SQLException</code> is thrown.
      *
      * @param iface A Class defining an interface that the result must implement.
-     * @return an object that implements the interface. May be a proxy for the actual implementing object.
-     * @throws java.sql.SQLException If no object found that implements the interface
+     * @return an object that implements the interface. May be a proxy for the
+     * actual implementing object.
+     * @throws java.sql.SQLException If no object found that implements the
+     * interface
      * @since 1.6
      */
+    @Override
     public <T> T unwrap(Class<T> iface) throws SQLException {
         T result;
         try {
-            Object cds = mcf.getDataSource();
+            Object cds = managedConnectionFactoryImpl.getDataSource();
 
             if (iface.isInstance(cds)) {
                 result = iface.cast(cds);
@@ -84,54 +90,62 @@
                 throw new SQLException(msg);
             }
         } catch (ResourceException e) {
-            _logger.log(Level.WARNING, "jdbc.exc_unwrap", e);
+            _logger.log(WARNING, "jdbc.exc_unwrap", e);
             throw new SQLException(e);
         }
+
         return result;
     }
 
     /**
-     * Returns true if this either implements the interface argument or is directly or indirectly a wrapper
-     * for an object that does. Returns false otherwise. If this implements the interface then return true,
-     * else if this is a wrapper then return the result of recursively calling <code>isWrapperFor</code> on the wrapped
-     * object. If this does not implement the interface and is not a wrapper, return false.
-     * This method should be implemented as a low-cost operation compared to <code>unwrap</code> so that
-     * callers can use this method to avoid expensive <code>unwrap</code> calls that may fail. If this method
-     * returns true then calling <code>unwrap</code> with the same argument should succeed.
+     * Returns true if this either implements the interface argument or is directly
+     * or indirectly a wrapper for an object that does. Returns false otherwise. If
+     * this implements the interface then return true, else if this is a wrapper
+     * then return the result of recursively calling <code>isWrapperFor</code> on
+     * the wrapped object. If this does not implement the interface and is not a
+     * wrapper, return false. This method should be implemented as a low-cost
+     * operation compared to <code>unwrap</code> so that callers can use this method
+     * to avoid expensive <code>unwrap</code> calls that may fail. If this method
+     * returns true then calling <code>unwrap</code> with the same argument should
+     * succeed.
      *
      * @param iface a Class defining an interface.
-     * @return true if this implements the interface or directly or indirectly wraps an object that does.
-     * @throws java.sql.SQLException if an error occurs while determining whether this is a wrapper
-     *                               for an object with the given interface.
+     * @return true if this implements the interface or directly or indirectly wraps
+     * an object that does.
+     * @throws java.sql.SQLException if an error occurs while determining whether
+     * this is a wrapper for an object with the given interface.
      * @since 1.6
      */
+    @Override
     public boolean isWrapperFor(Class<?> iface) throws SQLException {
         boolean result = false;
         try {
-            Object cds = mcf.getDataSource();
+            Object cds = managedConnectionFactoryImpl.getDataSource();
 
             if (iface.isInstance(cds)) {
                 result = true;
             } else if (cds instanceof java.sql.Wrapper) {
-                result = ((java.sql.Wrapper) cds).isWrapperFor(iface);
+                result = ((Wrapper) cds).isWrapperFor(iface);
             }
         } catch (ResourceException e) {
-            _logger.log(Level.WARNING, "jdbc.exc_is_wrapper", e);
+            _logger.log(WARNING, "jdbc.exc_is_wrapper", e);
             throw new SQLException(e);
         }
         return result;
     }
 
+    @Override
     public Logger getParentLogger() throws SQLFeatureNotSupportedException {
-        if(DataSourceObjectBuilder.isJDBC41()) {
-            try {
-                return (Logger) executor.invokeMethod(mcf.getDataSource().getClass(),
-                    "getParentLogger", null);
-            } catch (ResourceException ex) {
-                _logger.log(Level.SEVERE, "jdbc.ex_get_parent_logger", ex);
-                throw new SQLFeatureNotSupportedException(ex);
-            }
+        if (!isJDBC41()) {
+            throw new UnsupportedOperationException("Operation not supported in this runtime.");
         }
-        throw new UnsupportedOperationException("Operation not supported in this runtime.");
+
+        try {
+            return (Logger) executor.invokeMethod(managedConnectionFactoryImpl.getDataSource().getClass(), "getParentLogger", null);
+        } catch (ResourceException ex) {
+            _logger.log(SEVERE, "jdbc.ex_get_parent_logger", ex);
+            throw new SQLFeatureNotSupportedException(ex);
+        }
+
     }
 }
diff --git a/appserver/jdbc/jdbc-ra/jdbc40/src/main/java/com/sun/gjc/spi/jdbc40/DatabaseMetaDataWrapper40.java b/appserver/jdbc/jdbc-ra/jdbc40/src/main/java/com/sun/gjc/spi/jdbc40/DatabaseMetaDataWrapper40.java
index 36e6c0d..5ac0227 100644
--- a/appserver/jdbc/jdbc-ra/jdbc40/src/main/java/com/sun/gjc/spi/jdbc40/DatabaseMetaDataWrapper40.java
+++ b/appserver/jdbc/jdbc-ra/jdbc40/src/main/java/com/sun/gjc/spi/jdbc40/DatabaseMetaDataWrapper40.java
@@ -16,11 +16,16 @@
 
 package com.sun.gjc.spi.jdbc40;
 
+import java.sql.Connection;
+import java.sql.DatabaseMetaData;
+import java.sql.ResultSet;
+import java.sql.RowIdLifetime;
+import java.sql.SQLException;
+import java.util.logging.Level;
+
 import com.sun.gjc.common.DataSourceObjectBuilder;
 import com.sun.gjc.spi.base.DatabaseMetaDataWrapper;
 
-import java.sql.*;
-import java.util.logging.Level;
 import jakarta.resource.ResourceException;
 
 /**
@@ -31,7 +36,7 @@
     /**
      * Creates a new instance of DatabaseMetaDataWrapper40 for JDBC 4.0
      *
-     * @param con      Connection that is wrapped
+     * @param con Connection that is wrapped
      * @param metaData DatabaseMetaData that is wrapped
      */
     public DatabaseMetaDataWrapper40(Connection con, DatabaseMetaData metaData) {
@@ -39,256 +44,270 @@
     }
 
     /**
-     * Indicates whether or not this data source supports the SQL <code>ROWID</code> type,
-     * and if so  the lifetime for which a <code>RowId</code> object remains valid.
+     * Indicates whether or not this data source supports the SQL <code>ROWID</code>
+     * type, and if so the lifetime for which a <code>RowId</code> object remains
+     * valid.
      * <p/>
      * The returned int values have the following relationship:
+     *
      * <pre>
-     *     ROWID_UNSUPPORTED < ROWID_VALID_OTHER < ROWID_VALID_TRANSACTION
-     *         < ROWID_VALID_SESSION < ROWID_VALID_FOREVER
+     * ROWID_UNSUPPORTED < ROWID_VALID_OTHER < ROWID_VALID_TRANSACTION < ROWID_VALID_SESSION < ROWID_VALID_FOREVER
      * </pre>
+     *
      * so conditional logic such as
+     *
      * <pre>
      *     if (metadata.getRowIdLifetime() > DatabaseMetaData.ROWID_VALID_TRANSACTION)
      * </pre>
-     * can be used. Valid Forever means valid across all Sessions, and valid for
-     * a Session means valid across all its contained Transactions.
+     *
+     * can be used. Valid Forever means valid across all Sessions, and valid for a
+     * Session means valid across all its contained Transactions.
      *
      * @return the status indicating the lifetime of a <code>RowId</code>
      * @throws SQLException if a database access error occurs
      * @since 1.6
      */
+    @Override
     public RowIdLifetime getRowIdLifetime() throws SQLException {
         return databaseMetaData.getRowIdLifetime();
     }
 
     /**
-     * Retrieves the schema names available in this database.  The results
-     * are ordered by <code>TABLE_CATALOG</code> and
-     * <code>TABLE_SCHEM</code>.
+     * Retrieves the schema names available in this database. The results are
+     * ordered by <code>TABLE_CATALOG</code> and <code>TABLE_SCHEM</code>.
      * <p/>
-     * <P>The schema columns are:
+     * <P>
+     * The schema columns are:
      * <OL>
      * <LI><B>TABLE_SCHEM</B> String => schema name
      * <LI><B>TABLE_CATALOG</B> String => catalog name (may be <code>null</code>)
      * </OL>
      *
-     * @param catalog       a catalog name; must match the catalog name as it is stored
-     *                      in the database;"" retrieves those without a catalog; null means catalog
-     *                      name should not be used to narrow down the search.
+     * @param catalog a catalog name; must match the catalog name as it is stored in
+     * the database;"" retrieves those without a catalog; null means catalog name
+     * should not be used to narrow down the search.
      * @param schemaPattern a schema name; must match the schema name as it is
-     *                      stored in the database; null means
-     *                      schema name should not be used to narrow down the search.
-     * @return a <code>ResultSet</code> object in which each row is a
-     *         schema description
+     * stored in the database; null means schema name should not be used to narrow
+     * down the search.
+     * @return a <code>ResultSet</code> object in which each row is a schema
+     * description
      * @throws SQLException if a database access error occurs
      * @see #getSearchStringEscape
      * @since 1.6
      */
+    @Override
     public ResultSet getSchemas(String catalog, String schemaPattern) throws SQLException {
         return databaseMetaData.getSchemas(catalog, schemaPattern);
     }
 
     /**
-     * Retrieves whether this database supports invoking user-defined or vendor functions
-     * using the stored procedure escape syntax.
+     * Retrieves whether this database supports invoking user-defined or vendor
+     * functions using the stored procedure escape syntax.
      *
      * @return <code>true</code> if so; <code>false</code> otherwise
      * @throws SQLException if a database access error occurs
      * @since 1.6
      */
+    @Override
     public boolean supportsStoredFunctionsUsingCallSyntax() throws SQLException {
         return databaseMetaData.supportsStoredFunctionsUsingCallSyntax();
     }
 
     /**
-     * Retrieves whether a <code>SQLException</code> while autoCommit is <code>true</code> inidcates
-     * that all open ResultSets are closed, even ones that are holdable.  When a <code>SQLException</code> occurs while
-     * autocommit is <code>true</code>, it is vendor specific whether the JDBC driver responds with a commit operation, a
-     * rollback operation, or by doing neither a commit nor a rollback.  A potential result of this difference
-     * is in whether or not holdable ResultSets are closed.
+     * Retrieves whether a <code>SQLException</code> while autoCommit is
+     * <code>true</code> inidcates that all open ResultSets are closed, even ones
+     * that are holdable. When a <code>SQLException</code> occurs while autocommit
+     * is <code>true</code>, it is vendor specific whether the JDBC driver responds
+     * with a commit operation, a rollback operation, or by doing neither a commit
+     * nor a rollback. A potential result of this difference is in whether or not
+     * holdable ResultSets are closed.
      *
      * @return <code>true</code> if so; <code>false</code> otherwise
      * @throws SQLException if a database access error occurs
      * @since 1.6
      */
+    @Override
     public boolean autoCommitFailureClosesAllResultSets() throws SQLException {
         return databaseMetaData.autoCommitFailureClosesAllResultSets();
     }
 
     /**
-     * Retrieves a list of the client info properties
-     * that the driver supports.  The result set contains the following columns
+     * Retrieves a list of the client info properties that the driver supports. The
+     * result set contains the following columns
      * <p/>
      * <ol>
      * <li><b>NAME</b> String=> The name of the client info property<br>
      * <li><b>MAX_LEN</b> int=> The maximum length of the value for the property<br>
      * <li><b>DEFAULT_VALUE</b> String=> The default value of the property<br>
-     * <li><b>DESCRIPTION</b> String=> A description of the property.  This will typically
-     * contain information as to where this property is
-     * stored in the database.
+     * <li><b>DESCRIPTION</b> String=> A description of the property. This will
+     * typically contain information as to where this property is stored in the
+     * database.
      * </ol>
      * <p/>
      * The <code>ResultSet</code> is sorted by the NAME column
      * <p/>
      *
      * @throws SQLException if a database access error occurs
-     *                      <p/>
+     * <p/>
      * @return A <code>ResultSet</code> object; each row is a supported client info
      * property
      * <p/>
      * @since 1.6
      */
+    @Override
     public ResultSet getClientInfoProperties() throws SQLException {
         return databaseMetaData.getClientInfoProperties();
     }
 
     /**
-     * Retrieves a description of the  system and user functions available
-     * in the given catalog.
+     * Retrieves a description of the system and user functions available in the
+     * given catalog.
      * <p/>
-     * Only system and user function descriptions matching the schema and
-     * function name criteria are returned.  They are ordered by
-     * <code>FUNCTION_CAT</code>, <code>FUNCTION_SCHEM</code>,
-     * <code>FUNCTION_NAME</code> and
+     * Only system and user function descriptions matching the schema and function
+     * name criteria are returned. They are ordered by <code>FUNCTION_CAT</code>,
+     * <code>FUNCTION_SCHEM</code>, <code>FUNCTION_NAME</code> and
      * <code>SPECIFIC_ NAME</code>.
      * <p/>
-     * <P>Each function description has the the following columns:
+     * <P>
+     * Each function description has the the following columns:
      * <OL>
      * <LI><B>FUNCTION_CAT</B> String => function catalog (may be <code>null</code>)
-     * <LI><B>FUNCTION_SCHEM</B> String => function schema (may be <code>null</code>)
-     * <LI><B>FUNCTION_NAME</B> String => function name.  This is the name
-     * used to invoke the function
+     * <LI><B>FUNCTION_SCHEM</B> String => function schema (may be
+     * <code>null</code>)
+     * <LI><B>FUNCTION_NAME</B> String => function name. This is the name used to
+     * invoke the function
      * <LI><B>REMARKS</B> String => explanatory comment on the function
      * <LI><B>FUNCTION_TYPE</B> short => kind of function:
      * <UL>
-     * <LI>functionResultUnknown - Cannot determine if a return value
-     * or table will be returned
-     * <LI> functionNoTable- Does not return a table
-     * <LI> functionReturnsTable - Returns a table
+     * <LI>functionResultUnknown - Cannot determine if a return value or table will
+     * be returned
+     * <LI>functionNoTable- Does not return a table
+     * <LI>functionReturnsTable - Returns a table
      * </UL>
-     * <LI><B>SPECIFIC_NAME</B> String  => the name which uniquely identifies
-     * this function within its schema.  This is a user specified, or DBMS
-     * generated, name that may be different then the <code>FUNCTION_NAME</code>
-     * for example with overload functions
+     * <LI><B>SPECIFIC_NAME</B> String => the name which uniquely identifies this
+     * function within its schema. This is a user specified, or DBMS generated, name
+     * that may be different then the <code>FUNCTION_NAME</code> for example with
+     * overload functions
      * </OL>
      * <p/>
      * A user may not have permission to execute any of the functions that are
      * returned by <code>getFunctions</code>
      *
-     * @param catalog             a catalog name; must match the catalog name as it
-     *                            is stored in the database; "" retrieves those without a catalog;
-     *                            <code>null</code> means that the catalog name should not be used to narrow
-     *                            the search
-     * @param schemaPattern       a schema name pattern; must match the schema name
-     *                            as it is stored in the database; "" retrieves those without a schema;
-     *                            <code>null</code> means that the schema name should not be used to narrow
-     *                            the search
-     * @param functionNamePattern a function name pattern; must match the
-     *                            function name as it is stored in the database
+     * @param catalog a catalog name; must match the catalog name as it is stored in
+     * the database; "" retrieves those without a catalog; <code>null</code> means
+     * that the catalog name should not be used to narrow the search
+     * @param schemaPattern a schema name pattern; must match the schema name as it
+     * is stored in the database; "" retrieves those without a schema;
+     * <code>null</code> means that the schema name should not be used to narrow the
+     * search
+     * @param functionNamePattern a function name pattern; must match the function
+     * name as it is stored in the database
      * @return <code>ResultSet</code> - each row is a function description
      * @throws SQLException if a database access error occurs
      * @see #getSearchStringEscape
      * @since 1.6
      */
+    @Override
     public ResultSet getFunctions(String catalog, String schemaPattern, String functionNamePattern) throws SQLException {
         return databaseMetaData.getFunctions(catalog, schemaPattern, functionNamePattern);
     }
 
     /**
-     * Retrieves a description of the given catalog's system or user
-     * function parameters and return type.
+     * Retrieves a description of the given catalog's system or user function
+     * parameters and return type.
      * <p/>
-     * <P>Only descriptions matching the schema,  function and
-     * parameter name criteria are returned. They are ordered by
-     * <code>FUNCTION_CAT</code>, <code>FUNCTION_SCHEM</code>,
-     * <code>FUNCTION_NAME</code> and
-     * <code>SPECIFIC_ NAME</code>. Within this, the return value,
-     * if any, is first. Next are the parameter descriptions in call
-     * order. The column descriptions follow in column number order.
+     * <P>
+     * Only descriptions matching the schema, function and parameter name criteria
+     * are returned. They are ordered by <code>FUNCTION_CAT</code>,
+     * <code>FUNCTION_SCHEM</code>, <code>FUNCTION_NAME</code> and
+     * <code>SPECIFIC_ NAME</code>. Within this, the return value, if any, is first.
+     * Next are the parameter descriptions in call order. The column descriptions
+     * follow in column number order.
      * <p/>
-     * <P>Each row in the <code>ResultSet</code>
-     * is a parameter description, column description or
-     * return type description with the following fields:
+     * <P>
+     * Each row in the <code>ResultSet</code> is a parameter description, column
+     * description or return type description with the following fields:
      * <OL>
      * <LI><B>FUNCTION_CAT</B> String => function catalog (may be <code>null</code>)
-     * <LI><B>FUNCTION_SCHEM</B> String => function schema (may be <code>null</code>)
-     * <LI><B>FUNCTION_NAME</B> String => function name.  This is the name
-     * used to invoke the function
+     * <LI><B>FUNCTION_SCHEM</B> String => function schema (may be
+     * <code>null</code>)
+     * <LI><B>FUNCTION_NAME</B> String => function name. This is the name used to
+     * invoke the function
      * <LI><B>COLUMN_NAME</B> String => column/parameter name
      * <LI><B>COLUMN_TYPE</B> Short => kind of column/parameter:
      * <UL>
-     * <LI> functionColumnUnknown - nobody knows
-     * <LI> functionColumnIn - IN parameter
-     * <LI> functionColumnInOut - INOUT parameter
-     * <LI> functionColumnOut - OUT parameter
-     * <LI> functionColumnReturn - function return value
-     * <LI> functionColumnResult - Indicates that the parameter or column
-     * is a column in the <code>ResultSet</code>
+     * <LI>functionColumnUnknown - nobody knows
+     * <LI>functionColumnIn - IN parameter
+     * <LI>functionColumnInOut - INOUT parameter
+     * <LI>functionColumnOut - OUT parameter
+     * <LI>functionColumnReturn - function return value
+     * <LI>functionColumnResult - Indicates that the parameter or column is a column
+     * in the <code>ResultSet</code>
      * </UL>
      * <LI><B>DATA_TYPE</B> int => SQL type from java.sql.Types
-     * <LI><B>TYPE_NAME</B> String => SQL type name, for a UDT type the
-     * type name is fully qualified
+     * <LI><B>TYPE_NAME</B> String => SQL type name, for a UDT type the type name is
+     * fully qualified
      * <LI><B>PRECISION</B> int => precision
      * <LI><B>LENGTH</B> int => length in bytes of data
-     * <LI><B>SCALE</B> short => scale -  null is returned for data types where
-     * SCALE is not applicable.
+     * <LI><B>SCALE</B> short => scale - null is returned for data types where SCALE
+     * is not applicable.
      * <LI><B>RADIX</B> short => radix
      * <LI><B>NULLABLE</B> short => can it contain NULL.
      * <UL>
-     * <LI> functionNoNulls - does not allow NULL values
-     * <LI> functionNullable - allows NULL values
-     * <LI> functionNullableUnknown - nullability unknown
+     * <LI>functionNoNulls - does not allow NULL values
+     * <LI>functionNullable - allows NULL values
+     * <LI>functionNullableUnknown - nullability unknown
      * </UL>
      * <LI><B>REMARKS</B> String => comment describing column/parameter
-     * <LI><B>CHAR_OCTET_LENGTH</B> int  => the maximum length of binary
-     * and character based parameters or columns.  For any other datatype the returned value
-     * is a NULL
-     * <LI><B>ORDINAL_POSITION</B> int  => the ordinal position, starting
-     * from 1, for the input and output parameters. A value of 0
-     * is returned if this row describes the function's return value.
-     * For result set columns, it is the
+     * <LI><B>CHAR_OCTET_LENGTH</B> int => the maximum length of binary and
+     * character based parameters or columns. For any other datatype the returned
+     * value is a NULL
+     * <LI><B>ORDINAL_POSITION</B> int => the ordinal position, starting from 1, for
+     * the input and output parameters. A value of 0 is returned if this row
+     * describes the function's return value. For result set columns, it is the
      * ordinal position of the column in the result set starting from 1.
-     * <LI><B>IS_NULLABLE</B> String  => ISO rules are used to determine
-     * the nullability for a parameter or column.
+     * <LI><B>IS_NULLABLE</B> String => ISO rules are used to determine the
+     * nullability for a parameter or column.
      * <UL>
-     * <LI> YES           --- if the parameter or column can include NULLs
-     * <LI> NO            --- if the parameter or column  cannot include NULLs
-     * <LI> empty string  --- if the nullability for the
-     * parameter  or column is unknown
+     * <LI>YES --- if the parameter or column can include NULLs
+     * <LI>NO --- if the parameter or column cannot include NULLs
+     * <LI>empty string --- if the nullability for the parameter or column is
+     * unknown
      * </UL>
-     * <LI><B>SPECIFIC_NAME</B> String  => the name which uniquely identifies
-     * this function within its schema.  This is a user specified, or DBMS
-     * generated, name that may be different then the <code>FUNCTION_NAME</code>
-     * for example with overload functions
+     * <LI><B>SPECIFIC_NAME</B> String => the name which uniquely identifies this
+     * function within its schema. This is a user specified, or DBMS generated, name
+     * that may be different then the <code>FUNCTION_NAME</code> for example with
+     * overload functions
      * </OL>
      * <p/>
-     * <p>The PRECISION column represents the specified column size for the given
-     * parameter or column.
-     * For numeric data, this is the maximum precision.  For character data, this is the length in characters.
-     * For datetime datatypes, this is the length in characters of the String representation (assuming the
-     * maximum allowed precision of the fractional seconds component). For binary data, this is the length in bytes.  For the ROWID datatype,
-     * this is the length in bytes. Null is returned for data types where the
-     * column size is not applicable.
+     * <p>
+     * The PRECISION column represents the specified column size for the given
+     * parameter or column. For numeric data, this is the maximum precision. For
+     * character data, this is the length in characters. For datetime datatypes,
+     * this is the length in characters of the String representation (assuming the
+     * maximum allowed precision of the fractional seconds component). For binary
+     * data, this is the length in bytes. For the ROWID datatype, this is the length
+     * in bytes. Null is returned for data types where the column size is not
+     * applicable.
      *
-     * @param catalog             a catalog name; must match the catalog name as it
-     *                            is stored in the database; "" retrieves those without a catalog;
-     *                            <code>null</code> means that the catalog name should not be used to narrow
-     *                            the search
-     * @param schemaPattern       a schema name pattern; must match the schema name
-     *                            as it is stored in the database; "" retrieves those without a schema;
-     *                            <code>null</code> means that the schema name should not be used to narrow
-     *                            the search
-     * @param functionNamePattern a procedure name pattern; must match the
-     *                            function name as it is stored in the database
-     * @param columnNamePattern   a parameter name pattern; must match the
-     *                            parameter or column name as it is stored in the database
-     * @return <code>ResultSet</code> - each row describes a
-     *         user function parameter, column  or return type
+     * @param catalog a catalog name; must match the catalog name as it is stored in
+     * the database; "" retrieves those without a catalog; <code>null</code> means
+     * that the catalog name should not be used to narrow the search
+     * @param schemaPattern a schema name pattern; must match the schema name as it
+     * is stored in the database; "" retrieves those without a schema;
+     * <code>null</code> means that the schema name should not be used to narrow the
+     * search
+     * @param functionNamePattern a procedure name pattern; must match the function
+     * name as it is stored in the database
+     * @param columnNamePattern a parameter name pattern; must match the parameter
+     * or column name as it is stored in the database
+     * @return <code>ResultSet</code> - each row describes a user function
+     * parameter, column or return type
      * @throws SQLException if a database access error occurs
      * @see #getSearchStringEscape
      * @since 1.6
      */
+    @Override
     public ResultSet getFunctionColumns(String catalog, String schemaPattern, String functionNamePattern, String columnNamePattern) throws SQLException {
         return databaseMetaData.getFunctionColumns(catalog, schemaPattern, functionNamePattern, columnNamePattern);
     }
@@ -297,19 +316,22 @@
      * Returns an object that implements the given interface to allow access to
      * non-standard methods, or standard methods not exposed by the proxy.
      * <p/>
-     * If the receiver implements the interface then the result is the receiver
-     * or a proxy for the receiver. If the receiver is a wrapper
-     * and the wrapped object implements the interface then the result is the
-     * wrapped object or a proxy for the wrapped object. Otherwise return the
-     * the result of calling <code>unwrap</code> recursively on the wrapped object
-     * or a proxy for that result. If the receiver is not a
-     * wrapper and does not implement the interface, then an <code>SQLException</code> is thrown.
+     * If the receiver implements the interface then the result is the receiver or a
+     * proxy for the receiver. If the receiver is a wrapper and the wrapped object
+     * implements the interface then the result is the wrapped object or a proxy for
+     * the wrapped object. Otherwise return the the result of calling
+     * <code>unwrap</code> recursively on the wrapped object or a proxy for that
+     * result. If the receiver is not a wrapper and does not implement the
+     * interface, then an <code>SQLException</code> is thrown.
      *
      * @param iface A Class defining an interface that the result must implement.
-     * @return an object that implements the interface. May be a proxy for the actual implementing object.
-     * @throws java.sql.SQLException If no object found that implements the interface
+     * @return an object that implements the interface. May be a proxy for the
+     * actual implementing object.
+     * @throws java.sql.SQLException If no object found that implements the
+     * interface
      * @since 1.6
      */
+    @Override
     public <T> T unwrap(Class<T> iface) throws SQLException {
         T result;
         if (iface.isInstance(this)) {
@@ -321,20 +343,25 @@
     }
 
     /**
-     * Returns true if this either implements the interface argument or is directly or indirectly a wrapper
-     * for an object that does. Returns false otherwise. If this implements the interface then return true,
-     * else if this is a wrapper then return the result of recursively calling <code>isWrapperFor</code> on the wrapped
-     * object. If this does not implement the interface and is not a wrapper, return false.
-     * This method should be implemented as a low-cost operation compared to <code>unwrap</code> so that
-     * callers can use this method to avoid expensive <code>unwrap</code> calls that may fail. If this method
-     * returns true then calling <code>unwrap</code> with the same argument should succeed.
+     * Returns true if this either implements the interface argument or is directly
+     * or indirectly a wrapper for an object that does. Returns false otherwise. If
+     * this implements the interface then return true, else if this is a wrapper
+     * then return the result of recursively calling <code>isWrapperFor</code> on
+     * the wrapped object. If this does not implement the interface and is not a
+     * wrapper, return false. This method should be implemented as a low-cost
+     * operation compared to <code>unwrap</code> so that callers can use this method
+     * to avoid expensive <code>unwrap</code> calls that may fail. If this method
+     * returns true then calling <code>unwrap</code> with the same argument should
+     * succeed.
      *
      * @param iface a Class defining an interface.
-     * @return true if this implements the interface or directly or indirectly wraps an object that does.
-     * @throws java.sql.SQLException if an error occurs while determining whether this is a wrapper
-     *                               for an object with the given interface.
+     * @return true if this implements the interface or directly or indirectly wraps
+     * an object that does.
+     * @throws java.sql.SQLException if an error occurs while determining whether
+     * this is a wrapper for an object with the given interface.
      * @since 1.6
      */
+    @Override
     public boolean isWrapperFor(Class<?> iface) throws SQLException {
         boolean result;
         if (iface.isInstance(this)) {
@@ -345,15 +372,14 @@
         return result;
     }
 
-    public ResultSet getPseudoColumns(String catalog, String schemaPattern,
-            String tableNamePattern, String columnNamePattern) throws SQLException {
+    @Override
+    public ResultSet getPseudoColumns(String catalog, String schemaPattern, String tableNamePattern, String columnNamePattern)
+            throws SQLException {
         if (DataSourceObjectBuilder.isJDBC41()) {
-            Class<?>[] valueTypes =
-                    new Class<?>[]{String.class, String.class, String.class, String.class};
+            Class<?>[] valueTypes = new Class<?>[] { String.class, String.class, String.class, String.class };
             try {
-                return (ResultSet) getMethodExecutor().invokeMethod(databaseMetaData,
-                        "getPseudoColumns", valueTypes, catalog, schemaPattern,
-                        tableNamePattern, columnNamePattern);
+                return (ResultSet) getMethodExecutor().invokeMethod(databaseMetaData, "getPseudoColumns", valueTypes, catalog,
+                        schemaPattern, tableNamePattern, columnNamePattern);
             } catch (ResourceException ex) {
                 _logger.log(Level.SEVERE, "jdbc.ex_dmd_wrapper", ex);
                 throw new SQLException(ex);
@@ -362,11 +388,11 @@
         throw new UnsupportedOperationException("Operation not supported in this runtime.");
     }
 
+    @Override
     public boolean generatedKeyAlwaysReturned() throws SQLException {
         if (DataSourceObjectBuilder.isJDBC41()) {
             try {
-                return (Boolean) getMethodExecutor().invokeMethod(databaseMetaData,
-                        "generatedKeyAlwaysReturned", null);
+                return (Boolean) getMethodExecutor().invokeMethod(databaseMetaData, "generatedKeyAlwaysReturned", null);
             } catch (ResourceException ex) {
                 _logger.log(Level.SEVERE, "jdbc.ex_dmd_wrapper", ex);
                 throw new SQLException(ex);
diff --git a/appserver/jdbc/jdbc-ra/jdbc40/src/main/java/com/sun/gjc/spi/jdbc40/Jdbc40ObjectsFactory.java b/appserver/jdbc/jdbc-ra/jdbc40/src/main/java/com/sun/gjc/spi/jdbc40/Jdbc40ObjectsFactory.java
index ae9f258..860d230 100644
--- a/appserver/jdbc/jdbc-ra/jdbc40/src/main/java/com/sun/gjc/spi/jdbc40/Jdbc40ObjectsFactory.java
+++ b/appserver/jdbc/jdbc-ra/jdbc40/src/main/java/com/sun/gjc/spi/jdbc40/Jdbc40ObjectsFactory.java
@@ -16,52 +16,58 @@
 
 package com.sun.gjc.spi.jdbc40;
 
+import static java.lang.reflect.Modifier.isAbstract;
+
+import java.lang.reflect.Method;
+import java.sql.Connection;
+import java.util.logging.Level;
+
+import javax.sql.DataSource;
+
 import com.sun.gjc.spi.JdbcObjectsFactory;
 import com.sun.gjc.spi.ManagedConnectionFactoryImpl;
 import com.sun.gjc.spi.ManagedConnectionImpl;
 import com.sun.gjc.spi.base.ConnectionHolder;
-
 import com.sun.gjc.util.SQLTraceDelegator;
-import java.lang.reflect.Method;
-import java.lang.reflect.Modifier;
-import java.sql.Connection;
-import java.util.logging.Level;
 
+import jakarta.resource.spi.ConnectionManager;
 
 /**
  * Factory to create jdbc40 connection & datasource
  */
 public class Jdbc40ObjectsFactory extends JdbcObjectsFactory {
-    //indicates whether JDBC 3.0 Connection (and hence JDBC 3.0 DataSource) is used
+
+    private static final long serialVersionUID = 1L;
+
+    // indicates whether JDBC 3.0 Connection (and hence JDBC 3.0 DataSource) is used
     private boolean jdbc30Connection;
-    //indicates whether detection of JDBC 3.0 Datasource in JDK 1.6 is done or not
+
+    // indicates whether detection of JDBC 3.0 Datasource in JDK 1.6 is done or not
     private boolean initJDBC30Connection;
 
     /**
      * To get an instance of ConnectionHolder40.<br>
      * Will return a ConnectionHolder40 with or without wrapper<br>
      *
-     * @param conObject         Connection
-     * @param mcObject          ManagedConnection
-     * @param criObject         Connection Request Info
+     * @param conObject Connection
+     * @param mcObject ManagedConnection
+     * @param criObject Connection Request Info
      * @param statementWrapping Whether to wrap statement objects or not.
      * @return ConnectionHolder
      */
-    public ConnectionHolder getConnection(Connection conObject,
-                                          ManagedConnectionImpl mcObject,
-                                          jakarta.resource.spi.ConnectionRequestInfo criObject,
-                                          boolean statementWrapping,
-                                          SQLTraceDelegator sqlTraceDelegator) {
+    @Override
+    public ConnectionHolder getConnection(Connection conObject, ManagedConnectionImpl mcObject,
+            jakarta.resource.spi.ConnectionRequestInfo criObject, boolean statementWrapping, SQLTraceDelegator sqlTraceDelegator) {
         ConnectionHolder connection = null;
         if (!initJDBC30Connection) {
             detectJDBC30Connection(conObject, mcObject);
         }
+
         if (statementWrapping) {
             if (sqlTraceDelegator != null) {
-                Class connIntf[] = new Class[]{java.sql.Connection.class};
+                Class<?>[] connIntf = new Class[] { Connection.class };
                 Connection proxiedConn = getProxiedConnection(conObject, connIntf, sqlTraceDelegator);
-                connection = new ProfiledConnectionWrapper40(proxiedConn, mcObject,
-                        criObject, jdbc30Connection, sqlTraceDelegator);
+                connection = new ProfiledConnectionWrapper40(proxiedConn, mcObject, criObject, jdbc30Connection, sqlTraceDelegator);
             } else {
                 connection = new ConnectionWrapper40(conObject, mcObject, criObject, jdbc30Connection);
             }
@@ -75,11 +81,11 @@
      * Returns a DataSource instance for JDBC 4.0
      *
      * @param mcfObject Managed Connection Factory
-     * @param cmObject  Connection Manager
+     * @param cmObject Connection Manager
      * @return DataSource
      */
-    public javax.sql.DataSource getDataSourceInstance(ManagedConnectionFactoryImpl mcfObject,
-                                                      jakarta.resource.spi.ConnectionManager cmObject) {
+    @Override
+    public DataSource getDataSourceInstance(ManagedConnectionFactoryImpl mcfObject, ConnectionManager cmObject) {
         return new DataSource40(mcfObject, cmObject);
     }
 
@@ -96,21 +102,17 @@
     }
 
     public void detectJDBC30Connection(Connection con, ManagedConnectionImpl mcObject) {
-
         String dataSourceProperty = mcObject.getManagedConnectionFactory().getJdbc30DataSource();
         if (dataSourceProperty != null) {
             setJdbc30Connection(Boolean.valueOf(dataSourceProperty));
             initJDBC30Connection = true;
         } else {
             try {
-                Class paramClasses[] = new Class[]{Class.class};
+                Class<?>[] paramClasses = new Class[] { Class.class };
 
                 Method isWrapperMethod = con.getClass().getMethod("isWrapperFor", paramClasses);
-                int modifiers = isWrapperMethod.getModifiers();
-                setJdbc30Connection(Modifier.isAbstract(modifiers));
-            } catch (NoSuchMethodException e) {
-                setJdbc30Connection(true);
-            } catch (AbstractMethodError e) {
+                setJdbc30Connection(isAbstract(isWrapperMethod.getModifiers()));
+            } catch (NoSuchMethodException | AbstractMethodError e) {
                 setJdbc30Connection(true);
             } catch (Throwable t) {
                 setJdbc30Connection(true);
diff --git a/appserver/jdbc/jdbc-ra/jdbc40/src/main/java/com/sun/gjc/spi/jdbc40/PreparedStatementWrapper40.java b/appserver/jdbc/jdbc-ra/jdbc40/src/main/java/com/sun/gjc/spi/jdbc40/PreparedStatementWrapper40.java
index 287b366..84f1fb9 100644
--- a/appserver/jdbc/jdbc-ra/jdbc40/src/main/java/com/sun/gjc/spi/jdbc40/PreparedStatementWrapper40.java
+++ b/appserver/jdbc/jdbc-ra/jdbc40/src/main/java/com/sun/gjc/spi/jdbc40/PreparedStatementWrapper40.java
@@ -16,12 +16,18 @@
 
 package com.sun.gjc.spi.jdbc40;
 
-import com.sun.gjc.spi.base.PreparedStatementWrapper;
-
 import java.io.InputStream;
 import java.io.Reader;
-import java.sql.*;
+import java.sql.Connection;
+import java.sql.NClob;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.RowId;
+import java.sql.SQLException;
+import java.sql.SQLFeatureNotSupportedException;
+import java.sql.SQLXML;
 
+import com.sun.gjc.spi.base.PreparedStatementWrapper;
 
 /**
  * Wrapper for JDBC 4.0 PreparedStatement
@@ -31,523 +37,550 @@
     /**
      * Creates a new instance of PreparedStatement Wrapper for JDBC 3.0<br>
      *
-     * @param con       ConnectionWrapper<br>
+     * @param con ConnectionWrapper<br>
      * @param statement PreparedStatement that is wrapped<br>
      */
-    public PreparedStatementWrapper40(Connection con,
-                                      PreparedStatement statement, boolean statementCaching)
-            throws SQLException {
+    public PreparedStatementWrapper40(Connection con, PreparedStatement statement, boolean statementCaching) throws SQLException {
         super(con, statement, statementCaching);
     }
 
     /**
-     * Sets the designated parameter to the given <code>java.sql.RowId</code> object. The
-     * driver converts this to a SQL <code>ROWID</code> value when it sends it
-     * to the database
+     * Sets the designated parameter to the given <code>java.sql.RowId</code>
+     * object. The driver converts this to a SQL <code>ROWID</code> value when it
+     * sends it to the database
      *
      * @param parameterIndex the first parameter is 1, the second is 2, ...
-     * @param x              the parameter value
+     * @param x the parameter value
      * @throws SQLException if parameterIndex does not correspond to a parameter
-     *                      marker in the SQL statement; if a database access error occurs or
-     *                      this method is called on a closed <code>PreparedStatement</code>
-     * @throws SQLFeatureNotSupportedException
-     *                      if the JDBC driver does not support this method
+     * marker in the SQL statement; if a database access error occurs or this method
+     * is called on a closed <code>PreparedStatement</code>
+     * @throws SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
      * @since 1.6
      */
+    @Override
     public void setRowId(int parameterIndex, RowId x) throws SQLException {
         preparedStatement.setRowId(parameterIndex, x);
     }
 
     /**
-     * Sets the designated paramter to the given <code>String</code> object.
-     * The driver converts this to a SQL <code>NCHAR</code> or
-     * <code>NVARCHAR</code> or <code>LONGNVARCHAR</code> value
-     * (depending on the argument's
-     * size relative to the driver's limits on <code>NVARCHAR</code> values)
-     * when it sends it to the database.
+     * Sets the designated paramter to the given <code>String</code> object. The
+     * driver converts this to a SQL <code>NCHAR</code> or <code>NVARCHAR</code> or
+     * <code>LONGNVARCHAR</code> value (depending on the argument's size relative to
+     * the driver's limits on <code>NVARCHAR</code> values) when it sends it to the
+     * database.
      *
      * @param parameterIndex of the first parameter is 1, the second is 2, ...
-     * @param value          the parameter value
+     * @param value the parameter value
      * @throws SQLException if parameterIndex does not correspond to a parameter
-     *                      marker in the SQL statement; if the driver does not support national
-     *                      character sets;  if the driver can detect that a data conversion
-     *                      error could occur; if a database access error occurs; or
-     *                      this method is called on a closed <code>PreparedStatement</code>
-     * @throws SQLFeatureNotSupportedException
-     *                      if the JDBC driver does not support this method
+     * marker in the SQL statement; if the driver does not support national
+     * character sets; if the driver can detect that a data conversion error could
+     * occur; if a database access error occurs; or this method is called on a
+     * closed <code>PreparedStatement</code>
+     * @throws SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
      * @since 1.6
      */
+    @Override
     public void setNString(int parameterIndex, String value) throws SQLException {
         preparedStatement.setNString(parameterIndex, value);
     }
 
     /**
      * Sets the designated parameter to a <code>Reader</code> object. The
-     * <code>Reader</code> reads the data till end-of-file is reached. The
-     * driver does the necessary conversion from Java character format to
-     * the national character set in the database.
+     * <code>Reader</code> reads the data till end-of-file is reached. The driver
+     * does the necessary conversion from Java character format to the national
+     * character set in the database.
      *
      * @param parameterIndex of the first parameter is 1, the second is 2, ...
-     * @param value          the parameter value
-     * @param length         the number of characters in the parameter data.
+     * @param value the parameter value
+     * @param length the number of characters in the parameter data.
      * @throws SQLException if parameterIndex does not correspond to a parameter
-     *                      marker in the SQL statement; if the driver does not support national
-     *                      character sets;  if the driver can detect that a data conversion
-     *                      error could occur; if a database access error occurs; or
-     *                      this method is called on a closed <code>PreparedStatement</code>
-     * @throws SQLFeatureNotSupportedException
-     *                      if the JDBC driver does not support this method
+     * marker in the SQL statement; if the driver does not support national
+     * character sets; if the driver can detect that a data conversion error could
+     * occur; if a database access error occurs; or this method is called on a
+     * closed <code>PreparedStatement</code>
+     * @throws SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
      * @since 1.6
      */
+    @Override
     public void setNCharacterStream(int parameterIndex, Reader value, long length) throws SQLException {
         preparedStatement.setNCharacterStream(parameterIndex, value, length);
     }
 
     /**
-     * Sets the designated parameter to a <code>java.sql.NClob</code> object. The driver converts this to a
-     * SQL <code>NCLOB</code> value when it sends it to the database.
+     * Sets the designated parameter to a <code>java.sql.NClob</code> object. The
+     * driver converts this to a SQL <code>NCLOB</code> value when it sends it to
+     * the database.
      *
      * @param parameterIndex of the first parameter is 1, the second is 2, ...
-     * @param value          the parameter value
+     * @param value the parameter value
      * @throws SQLException if parameterIndex does not correspond to a parameter
-     *                      marker in the SQL statement; if the driver does not support national
-     *                      character sets;  if the driver can detect that a data conversion
-     *                      error could occur; if a database access error occurs; or
-     *                      this method is called on a closed <code>PreparedStatement</code>
-     * @throws SQLFeatureNotSupportedException
-     *                      if the JDBC driver does not support this method
+     * marker in the SQL statement; if the driver does not support national
+     * character sets; if the driver can detect that a data conversion error could
+     * occur; if a database access error occurs; or this method is called on a
+     * closed <code>PreparedStatement</code>
+     * @throws SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
      * @since 1.6
      */
+    @Override
     public void setNClob(int parameterIndex, NClob value) throws SQLException {
         preparedStatement.setNClob(parameterIndex, value);
     }
 
     /**
-     * Sets the designated parameter to a <code>Reader</code> object.  The reader must contain  the number
-     * of characters specified by length otherwise a <code>SQLException</code> will be
-     * generated when the <code>PreparedStatement</code> is executed.
-     * This method differs from the <code>setCharacterStream (int, Reader, int)</code> method
-     * because it informs the driver that the parameter value should be sent to
-     * the server as a <code>CLOB</code>.  When the <code>setCharacterStream</code> method is used, the
-     * driver may have to do extra work to determine whether the parameter
-     * data should be sent to the server as a <code>LONGVARCHAR</code> or a <code>CLOB</code>
+     * Sets the designated parameter to a <code>Reader</code> object. The reader
+     * must contain the number of characters specified by length otherwise a
+     * <code>SQLException</code> will be generated when the
+     * <code>PreparedStatement</code> is executed. This method differs from the
+     * <code>setCharacterStream (int, Reader, int)</code> method because it informs
+     * the driver that the parameter value should be sent to the server as a
+     * <code>CLOB</code>. When the <code>setCharacterStream</code> method is used,
+     * the driver may have to do extra work to determine whether the parameter data
+     * should be sent to the server as a <code>LONGVARCHAR</code> or a
+     * <code>CLOB</code>
      *
      * @param parameterIndex index of the first parameter is 1, the second is 2, ...
-     * @param reader         An object that contains the data to set the parameter value to.
-     * @param length         the number of characters in the parameter data.
+     * @param reader An object that contains the data to set the parameter value to.
+     * @param length the number of characters in the parameter data.
      * @throws SQLException if parameterIndex does not correspond to a parameter
-     *                      marker in the SQL statement; if a database access error occurs; this method is called on
-     *                      a closed <code>PreparedStatement</code> or if the length specified is less than zero.
-     * @throws SQLFeatureNotSupportedException
-     *                      if the JDBC driver does not support this method
+     * marker in the SQL statement; if a database access error occurs; this method
+     * is called on a closed <code>PreparedStatement</code> or if the length
+     * specified is less than zero.
+     * @throws SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
      * @since 1.6
      */
+    @Override
     public void setClob(int parameterIndex, Reader reader, long length) throws SQLException {
         preparedStatement.setClob(parameterIndex, reader, length);
     }
 
     /**
-     * Sets the designated parameter to a <code>InputStream</code> object.  The inputstream must contain  the number
-     * of characters specified by length otherwise a <code>SQLException</code> will be
-     * generated when the <code>PreparedStatement</code> is executed.
-     * This method differs from the <code>setBinaryStream (int, InputStream, int)</code>
-     * method because it informs the driver that the parameter value should be
-     * sent to the server as a <code>BLOB</code>.  When the <code>setBinaryStream</code> method is used,
-     * the driver may have to do extra work to determine whether the parameter
-     * data should be sent to the server as a <code>LONGVARBINARY</code> or a <code>BLOB</code>
+     * Sets the designated parameter to a <code>InputStream</code> object. The
+     * inputstream must contain the number of characters specified by length
+     * otherwise a <code>SQLException</code> will be generated when the
+     * <code>PreparedStatement</code> is executed. This method differs from the
+     * <code>setBinaryStream (int, InputStream, int)</code> method because it
+     * informs the driver that the parameter value should be sent to the server as a
+     * <code>BLOB</code>. When the <code>setBinaryStream</code> method is used, the
+     * driver may have to do extra work to determine whether the parameter data
+     * should be sent to the server as a <code>LONGVARBINARY</code> or a
+     * <code>BLOB</code>
      *
-     * @param parameterIndex index of the first parameter is 1,
-     *                       the second is 2, ...
-     * @param inputStream    An object that contains the data to set the parameter
-     *                       value to.
-     * @param length         the number of bytes in the parameter data.
+     * @param parameterIndex index of the first parameter is 1, the second is 2, ...
+     * @param inputStream An object that contains the data to set the parameter
+     * value to.
+     * @param length the number of bytes in the parameter data.
      * @throws SQLException if parameterIndex does not correspond to a parameter
-     *                      marker in the SQL statement; if a database access error occurs;
-     *                      this method is called on a closed <code>PreparedStatement</code>;
-     *                      if the length specified
-     *                      is less than zero or if the number of bytes in the inputstream does not match
-     *                      the specfied length.
-     * @throws SQLFeatureNotSupportedException
-     *                      if the JDBC driver does not support this method
+     * marker in the SQL statement; if a database access error occurs; this method
+     * is called on a closed <code>PreparedStatement</code>; if the length specified
+     * is less than zero or if the number of bytes in the inputstream does not match
+     * the specfied length.
+     * @throws SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
      * @since 1.6
      */
+    @Override
     public void setBlob(int parameterIndex, InputStream inputStream, long length) throws SQLException {
         preparedStatement.setBlob(parameterIndex, inputStream, length);
     }
 
     /**
-     * Sets the designated parameter to a <code>Reader</code> object.  The reader must contain  the number
-     * of characters specified by length otherwise a <code>SQLException</code> will be
-     * generated when the <code>PreparedStatement</code> is executed.
-     * This method differs from the <code>setCharacterStream (int, Reader, int)</code> method
-     * because it informs the driver that the parameter value should be sent to
-     * the server as a <code>NCLOB</code>.  When the <code>setCharacterStream</code> method is used, the
-     * driver may have to do extra work to determine whether the parameter
-     * data should be sent to the server as a <code>LONGNVARCHAR</code> or a <code>NCLOB</code>
+     * Sets the designated parameter to a <code>Reader</code> object. The reader
+     * must contain the number of characters specified by length otherwise a
+     * <code>SQLException</code> will be generated when the
+     * <code>PreparedStatement</code> is executed. This method differs from the
+     * <code>setCharacterStream (int, Reader, int)</code> method because it informs
+     * the driver that the parameter value should be sent to the server as a
+     * <code>NCLOB</code>. When the <code>setCharacterStream</code> method is used,
+     * the driver may have to do extra work to determine whether the parameter data
+     * should be sent to the server as a <code>LONGNVARCHAR</code> or a
+     * <code>NCLOB</code>
      *
      * @param parameterIndex index of the first parameter is 1, the second is 2, ...
-     * @param reader         An object that contains the data to set the parameter value to.
-     * @param length         the number of characters in the parameter data.
+     * @param reader An object that contains the data to set the parameter value to.
+     * @param length the number of characters in the parameter data.
      * @throws SQLException if parameterIndex does not correspond to a parameter
-     *                      marker in the SQL statement; if the length specified is less than zero;
-     *                      if the driver does not support national character sets;
-     *                      if the driver can detect that a data conversion
-     *                      error could occur;  if a database access error occurs or
-     *                      this method is called on a closed <code>PreparedStatement</code>
-     * @throws SQLFeatureNotSupportedException
-     *                      if the JDBC driver does not support this method
+     * marker in the SQL statement; if the length specified is less than zero; if
+     * the driver does not support national character sets; if the driver can detect
+     * that a data conversion error could occur; if a database access error occurs
+     * or this method is called on a closed <code>PreparedStatement</code>
+     * @throws SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
      * @since 1.6
      */
+    @Override
     public void setNClob(int parameterIndex, Reader reader, long length) throws SQLException {
         preparedStatement.setNClob(parameterIndex, reader, length);
     }
 
     /**
-     * Sets the designated parameter to the given <code>java.sql.SQLXML</code> object.
-     * The driver converts this to an
-     * SQL <code>XML</code> value when it sends it to the database.
+     * Sets the designated parameter to the given <code>java.sql.SQLXML</code>
+     * object. The driver converts this to an SQL <code>XML</code> value when it
+     * sends it to the database.
      * <p/>
      *
      * @param parameterIndex index of the first parameter is 1, the second is 2, ...
-     * @param xmlObject      a <code>SQLXML</code> object that maps an SQL <code>XML</code> value
+     * @param xmlObject a <code>SQLXML</code> object that maps an SQL
+     * <code>XML</code> value
      * @throws SQLException if parameterIndex does not correspond to a parameter
-     *                      marker in the SQL statement; if a database access error occurs;
-     *                      this method is called on a closed <code>PreparedStatement</code>
-     *                      or the <code>java.xml.transform.Result</code>,
-     *                      <code>Writer</code> or <code>OutputStream</code> has not been closed for
-     *                      the <code>SQLXML</code> object
-     * @throws SQLFeatureNotSupportedException
-     *                      if the JDBC driver does not support this method
+     * marker in the SQL statement; if a database access error occurs; this method
+     * is called on a closed <code>PreparedStatement</code> or the
+     * <code>java.xml.transform.Result</code>, <code>Writer</code> or
+     * <code>OutputStream</code> has not been closed for the <code>SQLXML</code>
+     * object
+     * @throws SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
      * @since 1.6
      */
+    @Override
     public void setSQLXML(int parameterIndex, SQLXML xmlObject) throws SQLException {
         preparedStatement.setSQLXML(parameterIndex, xmlObject);
     }
 
     /**
-     * Sets the designated parameter to the given input stream, which will have
-     * the specified number of bytes.
-     * When a very large ASCII value is input to a <code>LONGVARCHAR</code>
-     * parameter, it may be more practical to send it via a
-     * <code>java.io.InputStream</code>. Data will be read from the stream
-     * as needed until end-of-file is reached.  The JDBC driver will
-     * do any necessary conversion from ASCII to the database char format.
+     * Sets the designated parameter to the given input stream, which will have the
+     * specified number of bytes. When a very large ASCII value is input to a
+     * <code>LONGVARCHAR</code> parameter, it may be more practical to send it via a
+     * <code>java.io.InputStream</code>. Data will be read from the stream as needed
+     * until end-of-file is reached. The JDBC driver will do any necessary
+     * conversion from ASCII to the database char format.
      * <p/>
-     * <P><B>Note:</B> This stream object can either be a standard
-     * Java stream object or your own subclass that implements the
-     * standard interface.
+     * <P>
+     * <B>Note:</B> This stream object can either be a standard Java stream object
+     * or your own subclass that implements the standard interface.
      *
      * @param parameterIndex the first parameter is 1, the second is 2, ...
-     * @param x              the Java input stream that contains the ASCII parameter value
-     * @param length         the number of bytes in the stream
+     * @param x the Java input stream that contains the ASCII parameter value
+     * @param length the number of bytes in the stream
      * @throws SQLException if parameterIndex does not correspond to a parameter
-     *                      marker in the SQL statement; if a database access error occurs or
-     *                      this method is called on a closed <code>PreparedStatement</code>
+     * marker in the SQL statement; if a database access error occurs or this method
+     * is called on a closed <code>PreparedStatement</code>
      * @since 1.6
      */
+    @Override
     public void setAsciiStream(int parameterIndex, InputStream x, long length) throws SQLException {
         preparedStatement.setAsciiStream(parameterIndex, x, length);
     }
 
     /**
-     * Sets the designated parameter to the given input stream, which will have
-     * the specified number of bytes.
-     * When a very large binary value is input to a <code>LONGVARBINARY</code>
-     * parameter, it may be more practical to send it via a
-     * <code>java.io.InputStream</code> object. The data will be read from the
+     * Sets the designated parameter to the given input stream, which will have the
+     * specified number of bytes. When a very large binary value is input to a
+     * <code>LONGVARBINARY</code> parameter, it may be more practical to send it via
+     * a <code>java.io.InputStream</code> object. The data will be read from the
      * stream as needed until end-of-file is reached.
      * <p/>
-     * <P><B>Note:</B> This stream object can either be a standard
-     * Java stream object or your own subclass that implements the
-     * standard interface.
+     * <P>
+     * <B>Note:</B> This stream object can either be a standard Java stream object
+     * or your own subclass that implements the standard interface.
      *
      * @param parameterIndex the first parameter is 1, the second is 2, ...
-     * @param x              the java input stream which contains the binary parameter value
-     * @param length         the number of bytes in the stream
+     * @param x the java input stream which contains the binary parameter value
+     * @param length the number of bytes in the stream
      * @throws SQLException if parameterIndex does not correspond to a parameter
-     *                      marker in the SQL statement; if a database access error occurs or
-     *                      this method is called on a closed <code>PreparedStatement</code>
+     * marker in the SQL statement; if a database access error occurs or this method
+     * is called on a closed <code>PreparedStatement</code>
      * @since 1.6
      */
+    @Override
     public void setBinaryStream(int parameterIndex, InputStream x, long length) throws SQLException {
         preparedStatement.setBinaryStream(parameterIndex, x, length);
     }
 
     /**
-     * Sets the designated parameter to the given <code>Reader</code>
-     * object, which is the given number of characters long.
-     * When a very large UNICODE value is input to a <code>LONGVARCHAR</code>
-     * parameter, it may be more practical to send it via a
-     * <code>java.io.Reader</code> object. The data will be read from the stream
-     * as needed until end-of-file is reached.  The JDBC driver will
-     * do any necessary conversion from UNICODE to the database char format.
+     * Sets the designated parameter to the given <code>Reader</code> object, which
+     * is the given number of characters long. When a very large UNICODE value is
+     * input to a <code>LONGVARCHAR</code> parameter, it may be more practical to
+     * send it via a <code>java.io.Reader</code> object. The data will be read from
+     * the stream as needed until end-of-file is reached. The JDBC driver will do
+     * any necessary conversion from UNICODE to the database char format.
      * <p/>
-     * <P><B>Note:</B> This stream object can either be a standard
-     * Java stream object or your own subclass that implements the
-     * standard interface.
+     * <P>
+     * <B>Note:</B> This stream object can either be a standard Java stream object
+     * or your own subclass that implements the standard interface.
      *
      * @param parameterIndex the first parameter is 1, the second is 2, ...
-     * @param reader         the <code>java.io.Reader</code> object that contains the
-     *                       Unicode data
-     * @param length         the number of characters in the stream
+     * @param reader the <code>java.io.Reader</code> object that contains the
+     * Unicode data
+     * @param length the number of characters in the stream
      * @throws SQLException if parameterIndex does not correspond to a parameter
-     *                      marker in the SQL statement; if a database access error occurs or
-     *                      this method is called on a closed <code>PreparedStatement</code>
+     * marker in the SQL statement; if a database access error occurs or this method
+     * is called on a closed <code>PreparedStatement</code>
      * @since 1.6
      */
+    @Override
     public void setCharacterStream(int parameterIndex, Reader reader, long length) throws SQLException {
         preparedStatement.setCharacterStream(parameterIndex, reader, length);
     }
 
     /**
-     * Sets the designated parameter to the given input stream.
-     * When a very large ASCII value is input to a <code>LONGVARCHAR</code>
-     * parameter, it may be more practical to send it via a
-     * <code>java.io.InputStream</code>. Data will be read from the stream
-     * as needed until end-of-file is reached.  The JDBC driver will
-     * do any necessary conversion from ASCII to the database char format.
+     * Sets the designated parameter to the given input stream. When a very large
+     * ASCII value is input to a <code>LONGVARCHAR</code> parameter, it may be more
+     * practical to send it via a <code>java.io.InputStream</code>. Data will be
+     * read from the stream as needed until end-of-file is reached. The JDBC driver
+     * will do any necessary conversion from ASCII to the database char format.
      * <p/>
-     * <P><B>Note:</B> This stream object can either be a standard
-     * Java stream object or your own subclass that implements the
-     * standard interface.
-     * <P><B>Note:</B> Consult your JDBC driver documentation to determine if
-     * it might be more efficient to use a version of
-     * <code>setAsciiStream</code> which takes a length parameter.
+     * <P>
+     * <B>Note:</B> This stream object can either be a standard Java stream object
+     * or your own subclass that implements the standard interface.
+     * <P>
+     * <B>Note:</B> Consult your JDBC driver documentation to determine if it might
+     * be more efficient to use a version of <code>setAsciiStream</code> which takes
+     * a length parameter.
      *
      * @param parameterIndex the first parameter is 1, the second is 2, ...
-     * @param x              the Java input stream that contains the ASCII parameter value
+     * @param x the Java input stream that contains the ASCII parameter value
      * @throws SQLException if parameterIndex does not correspond to a parameter
-     *                      marker in the SQL statement; if a database access error occurs or
-     *                      this method is called on a closed <code>PreparedStatement</code>
-     * @throws SQLFeatureNotSupportedException
-     *                      if the JDBC driver does not support this method
+     * marker in the SQL statement; if a database access error occurs or this method
+     * is called on a closed <code>PreparedStatement</code>
+     * @throws SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
      * @since 1.6
      */
+    @Override
     public void setAsciiStream(int parameterIndex, InputStream x) throws SQLException {
         preparedStatement.setAsciiStream(parameterIndex, x);
     }
 
     /**
-     * Sets the designated parameter to the given input stream.
-     * When a very large binary value is input to a <code>LONGVARBINARY</code>
-     * parameter, it may be more practical to send it via a
-     * <code>java.io.InputStream</code> object. The data will be read from the
-     * stream as needed until end-of-file is reached.
+     * Sets the designated parameter to the given input stream. When a very large
+     * binary value is input to a <code>LONGVARBINARY</code> parameter, it may be
+     * more practical to send it via a <code>java.io.InputStream</code> object. The
+     * data will be read from the stream as needed until end-of-file is reached.
      * <p/>
-     * <P><B>Note:</B> This stream object can either be a standard
-     * Java stream object or your own subclass that implements the
-     * standard interface.
-     * <P><B>Note:</B> Consult your JDBC driver documentation to determine if
-     * it might be more efficient to use a version of
-     * <code>setBinaryStream</code> which takes a length parameter.
+     * <P>
+     * <B>Note:</B> This stream object can either be a standard Java stream object
+     * or your own subclass that implements the standard interface.
+     * <P>
+     * <B>Note:</B> Consult your JDBC driver documentation to determine if it might
+     * be more efficient to use a version of <code>setBinaryStream</code> which
+     * takes a length parameter.
      *
      * @param parameterIndex the first parameter is 1, the second is 2, ...
-     * @param x              the java input stream which contains the binary parameter value
+     * @param x the java input stream which contains the binary parameter value
      * @throws SQLException if parameterIndex does not correspond to a parameter
-     *                      marker in the SQL statement; if a database access error occurs or
-     *                      this method is called on a closed <code>PreparedStatement</code>
-     * @throws SQLFeatureNotSupportedException
-     *                      if the JDBC driver does not support this method
+     * marker in the SQL statement; if a database access error occurs or this method
+     * is called on a closed <code>PreparedStatement</code>
+     * @throws SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
      * @since 1.6
      */
+    @Override
     public void setBinaryStream(int parameterIndex, InputStream x) throws SQLException {
         preparedStatement.setBinaryStream(parameterIndex, x);
     }
 
     /**
-     * Sets the designated parameter to the given <code>Reader</code>
-     * object.
-     * When a very large UNICODE value is input to a <code>LONGVARCHAR</code>
-     * parameter, it may be more practical to send it via a
-     * <code>java.io.Reader</code> object. The data will be read from the stream
-     * as needed until end-of-file is reached.  The JDBC driver will
-     * do any necessary conversion from UNICODE to the database char format.
+     * Sets the designated parameter to the given <code>Reader</code> object. When a
+     * very large UNICODE value is input to a <code>LONGVARCHAR</code> parameter, it
+     * may be more practical to send it via a <code>java.io.Reader</code> object.
+     * The data will be read from the stream as needed until end-of-file is reached.
+     * The JDBC driver will do any necessary conversion from UNICODE to the database
+     * char format.
      * <p/>
-     * <P><B>Note:</B> This stream object can either be a standard
-     * Java stream object or your own subclass that implements the
-     * standard interface.
-     * <P><B>Note:</B> Consult your JDBC driver documentation to determine if
-     * it might be more efficient to use a version of
-     * <code>setCharacterStream</code> which takes a length parameter.
+     * <P>
+     * <B>Note:</B> This stream object can either be a standard Java stream object
+     * or your own subclass that implements the standard interface.
+     * <P>
+     * <B>Note:</B> Consult your JDBC driver documentation to determine if it might
+     * be more efficient to use a version of <code>setCharacterStream</code> which
+     * takes a length parameter.
      *
      * @param parameterIndex the first parameter is 1, the second is 2, ...
-     * @param reader         the <code>java.io.Reader</code> object that contains the
-     *                       Unicode data
+     * @param reader the <code>java.io.Reader</code> object that contains the
+     * Unicode data
      * @throws SQLException if parameterIndex does not correspond to a parameter
-     *                      marker in the SQL statement; if a database access error occurs or
-     *                      this method is called on a closed <code>PreparedStatement</code>
-     * @throws SQLFeatureNotSupportedException
-     *                      if the JDBC driver does not support this method
+     * marker in the SQL statement; if a database access error occurs or this method
+     * is called on a closed <code>PreparedStatement</code>
+     * @throws SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
      * @since 1.6
      */
+    @Override
     public void setCharacterStream(int parameterIndex, Reader reader) throws SQLException {
         preparedStatement.setCharacterStream(parameterIndex, reader);
     }
 
     /**
      * Sets the designated parameter to a <code>Reader</code> object. The
-     * <code>Reader</code> reads the data till end-of-file is reached. The
-     * driver does the necessary conversion from Java character format to
-     * the national character set in the database.
+     * <code>Reader</code> reads the data till end-of-file is reached. The driver
+     * does the necessary conversion from Java character format to the national
+     * character set in the database.
      * <p/>
-     * <P><B>Note:</B> This stream object can either be a standard
-     * Java stream object or your own subclass that implements the
-     * standard interface.
-     * <P><B>Note:</B> Consult your JDBC driver documentation to determine if
-     * it might be more efficient to use a version of
-     * <code>setNCharacterStream</code> which takes a length parameter.
+     * <P>
+     * <B>Note:</B> This stream object can either be a standard Java stream object
+     * or your own subclass that implements the standard interface.
+     * <P>
+     * <B>Note:</B> Consult your JDBC driver documentation to determine if it might
+     * be more efficient to use a version of <code>setNCharacterStream</code> which
+     * takes a length parameter.
      *
      * @param parameterIndex of the first parameter is 1, the second is 2, ...
-     * @param value          the parameter value
+     * @param value the parameter value
      * @throws SQLException if parameterIndex does not correspond to a parameter
-     *                      marker in the SQL statement; if the driver does not support national
-     *                      character sets;  if the driver can detect that a data conversion
-     *                      error could occur; if a database access error occurs; or
-     *                      this method is called on a closed <code>PreparedStatement</code>
-     * @throws SQLFeatureNotSupportedException
-     *                      if the JDBC driver does not support this method
+     * marker in the SQL statement; if the driver does not support national
+     * character sets; if the driver can detect that a data conversion error could
+     * occur; if a database access error occurs; or this method is called on a
+     * closed <code>PreparedStatement</code>
+     * @throws SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
      * @since 1.6
      */
+    @Override
     public void setNCharacterStream(int parameterIndex, Reader value) throws SQLException {
         preparedStatement.setNCharacterStream(parameterIndex, value);
     }
 
     /**
-     * Sets the designated parameter to a <code>Reader</code> object.
-     * This method differs from the <code>setCharacterStream (int, Reader)</code> method
-     * because it informs the driver that the parameter value should be sent to
-     * the server as a <code>CLOB</code>.  When the <code>setCharacterStream</code> method is used, the
-     * driver may have to do extra work to determine whether the parameter
-     * data should be sent to the server as a <code>LONGVARCHAR</code> or a <code>CLOB</code>
+     * Sets the designated parameter to a <code>Reader</code> object. This method
+     * differs from the <code>setCharacterStream (int, Reader)</code> method because
+     * it informs the driver that the parameter value should be sent to the server
+     * as a <code>CLOB</code>. When the <code>setCharacterStream</code> method is
+     * used, the driver may have to do extra work to determine whether the parameter
+     * data should be sent to the server as a <code>LONGVARCHAR</code> or a
+     * <code>CLOB</code>
      * <p/>
-     * <P><B>Note:</B> Consult your JDBC driver documentation to determine if
-     * it might be more efficient to use a version of
-     * <code>setClob</code> which takes a length parameter.
+     * <P>
+     * <B>Note:</B> Consult your JDBC driver documentation to determine if it might
+     * be more efficient to use a version of <code>setClob</code> which takes a
+     * length parameter.
      *
      * @param parameterIndex index of the first parameter is 1, the second is 2, ...
-     * @param reader         An object that contains the data to set the parameter value to.
+     * @param reader An object that contains the data to set the parameter value to.
      * @throws SQLException if parameterIndex does not correspond to a parameter
-     *                      marker in the SQL statement; if a database access error occurs; this method is called on
-     *                      a closed <code>PreparedStatement</code>or if parameterIndex does not correspond to a parameter
-     *                      marker in the SQL statement
-     * @throws SQLFeatureNotSupportedException
-     *                      if the JDBC driver does not support this method
+     * marker in the SQL statement; if a database access error occurs; this method
+     * is called on a closed <code>PreparedStatement</code>or if parameterIndex does
+     * not correspond to a parameter marker in the SQL statement
+     * @throws SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
      * @since 1.6
      */
+    @Override
     public void setClob(int parameterIndex, Reader reader) throws SQLException {
         preparedStatement.setClob(parameterIndex, reader);
     }
 
     /**
-     * Sets the designated parameter to a <code>InputStream</code> object.
-     * This method differs from the <code>setBinaryStream (int, InputStream)</code>
-     * method because it informs the driver that the parameter value should be
-     * sent to the server as a <code>BLOB</code>.  When the <code>setBinaryStream</code> method is used,
-     * the driver may have to do extra work to determine whether the parameter
-     * data should be sent to the server as a <code>LONGVARBINARY</code> or a <code>BLOB</code>
+     * Sets the designated parameter to a <code>InputStream</code> object. This
+     * method differs from the <code>setBinaryStream (int, InputStream)</code>
+     * method because it informs the driver that the parameter value should be sent
+     * to the server as a <code>BLOB</code>. When the <code>setBinaryStream</code>
+     * method is used, the driver may have to do extra work to determine whether the
+     * parameter data should be sent to the server as a <code>LONGVARBINARY</code>
+     * or a <code>BLOB</code>
      * <p/>
-     * <P><B>Note:</B> Consult your JDBC driver documentation to determine if
-     * it might be more efficient to use a version of
-     * <code>setBlob</code> which takes a length parameter.
+     * <P>
+     * <B>Note:</B> Consult your JDBC driver documentation to determine if it might
+     * be more efficient to use a version of <code>setBlob</code> which takes a
+     * length parameter.
      *
-     * @param parameterIndex index of the first parameter is 1,
-     *                       the second is 2, ...
-     * @param inputStream    An object that contains the data to set the parameter
-     *                       value to.
+     * @param parameterIndex index of the first parameter is 1, the second is 2, ...
+     * @param inputStream An object that contains the data to set the parameter
+     * value to.
      * @throws SQLException if parameterIndex does not correspond to a parameter
-     *                      marker in the SQL statement; if a database access error occurs;
-     *                      this method is called on a closed <code>PreparedStatement</code> or
-     *                      if parameterIndex does not correspond
-     *                      to a parameter marker in the SQL statement,
-     * @throws SQLFeatureNotSupportedException
-     *                      if the JDBC driver does not support this method
+     * marker in the SQL statement; if a database access error occurs; this method
+     * is called on a closed <code>PreparedStatement</code> or if parameterIndex
+     * does not correspond to a parameter marker in the SQL statement,
+     * @throws SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
      * @since 1.6
      */
+    @Override
     public void setBlob(int parameterIndex, InputStream inputStream) throws SQLException {
         preparedStatement.setBlob(parameterIndex, inputStream);
     }
 
     /**
-     * Sets the designated parameter to a <code>Reader</code> object.
-     * This method differs from the <code>setCharacterStream (int, Reader)</code> method
-     * because it informs the driver that the parameter value should be sent to
-     * the server as a <code>NCLOB</code>.  When the <code>setCharacterStream</code> method is used, the
-     * driver may have to do extra work to determine whether the parameter
-     * data should be sent to the server as a <code>LONGNVARCHAR</code> or a <code>NCLOB</code>
-     * <P><B>Note:</B> Consult your JDBC driver documentation to determine if
-     * it might be more efficient to use a version of
-     * <code>setNClob</code> which takes a length parameter.
+     * Sets the designated parameter to a <code>Reader</code> object. This method
+     * differs from the <code>setCharacterStream (int, Reader)</code> method because
+     * it informs the driver that the parameter value should be sent to the server
+     * as a <code>NCLOB</code>. When the <code>setCharacterStream</code> method is
+     * used, the driver may have to do extra work to determine whether the parameter
+     * data should be sent to the server as a <code>LONGNVARCHAR</code> or a
+     * <code>NCLOB</code>
+     * <P>
+     * <B>Note:</B> Consult your JDBC driver documentation to determine if it might
+     * be more efficient to use a version of <code>setNClob</code> which takes a
+     * length parameter.
      *
      * @param parameterIndex index of the first parameter is 1, the second is 2, ...
-     * @param reader         An object that contains the data to set the parameter value to.
+     * @param reader An object that contains the data to set the parameter value to.
      * @throws SQLException if parameterIndex does not correspond to a parameter
-     *                      marker in the SQL statement;
-     *                      if the driver does not support national character sets;
-     *                      if the driver can detect that a data conversion
-     *                      error could occur;  if a database access error occurs or
-     *                      this method is called on a closed <code>PreparedStatement</code>
-     * @throws SQLFeatureNotSupportedException
-     *                      if the JDBC driver does not support this method
+     * marker in the SQL statement; if the driver does not support national
+     * character sets; if the driver can detect that a data conversion error could
+     * occur; if a database access error occurs or this method is called on a closed
+     * <code>PreparedStatement</code>
+     * @throws SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
      * @since 1.6
      */
+    @Override
     public void setNClob(int parameterIndex, Reader reader) throws SQLException {
         preparedStatement.setNClob(parameterIndex, reader);
     }
 
     /**
-     * Retrieves whether this <code>Statement</code> object has been closed. A <code>Statement</code> is closed if the
-     * method close has been called on it, or if it is automatically closed.
+     * Retrieves whether this <code>Statement</code> object has been closed. A
+     * <code>Statement</code> is closed if the method close has been called on it,
+     * or if it is automatically closed.
      *
-     * @return true if this <code>Statement</code> object is closed; false if it is still open
+     * @return true if this <code>Statement</code> object is closed; false if it is
+     * still open
      * @throws SQLException if a database access error occurs
      * @since 1.6
      */
+    @Override
     public boolean isClosed() throws SQLException {
         return preparedStatement.isClosed();
     }
 
     /**
-     * Requests that a <code>Statement</code> be pooled or not pooled.  The value
-     * specified is a hint to the statement pool implementation indicating
-     * whether the applicaiton wants the statement to be pooled.  It is up to
-     * the statement pool manager as to whether the hint is used.
+     * Requests that a <code>Statement</code> be pooled or not pooled. The value
+     * specified is a hint to the statement pool implementation indicating whether
+     * the applicaiton wants the statement to be pooled. It is up to the statement
+     * pool manager as to whether the hint is used.
      * <p/>
-     * The poolable value of a statement is applicable to both internal
-     * statement caches implemented by the driver and external statement caches
-     * implemented by application servers and other applications.
+     * The poolable value of a statement is applicable to both internal statement
+     * caches implemented by the driver and external statement caches implemented by
+     * application servers and other applications.
      * <p/>
-     * By default, a <code>Statement</code> is not poolable when created, and
-     * a <code>PreparedStatement</code> and <code>CallableStatement</code>
-     * are poolable when created.
+     * By default, a <code>Statement</code> is not poolable when created, and a
+     * <code>PreparedStatement</code> and <code>CallableStatement</code> are
+     * poolable when created.
      * <p/>
      *
-     * @param poolable requests that the statement be pooled if true and
-     *                 that the statement not be pooled if false
-     *                 <p/>
+     * @param poolable requests that the statement be pooled if true and that the
+     * statement not be pooled if false
+     * <p/>
      * @throws SQLException if this method is called on a closed
-     *                      <code>Statement</code>
-     *                      <p/>
+     * <code>Statement</code>
+     * <p/>
      * @since 1.6
      */
+    @Override
     public void setPoolable(boolean poolable) throws SQLException {
         preparedStatement.setPoolable(poolable);
     }
 
     /**
-     * Returns a  value indicating whether the <code>Statement</code>
-     * is poolable or not.
+     * Returns a value indicating whether the <code>Statement</code> is poolable or
+     * not.
      * <p/>
      *
      * @throws SQLException if this method is called on a closed
-     *                      <code>Statement</code>
-     *                      <p/>
-     * @return        <code>true</code> if the <code>Statement</code>
-     * is poolable; <code>false</code> otherwise
+     * <code>Statement</code>
+     * <p/>
+     * @return <code>true</code> if the <code>Statement</code> is poolable;
+     * <code>false</code> otherwise
      * <p/>
      * @see java.sql.Statement#setPoolable(boolean) setPoolable(boolean)
      * @since 1.6
-     *        <p/>
+     * <p/>
      */
+    @Override
     public boolean isPoolable() throws SQLException {
         return preparedStatement.isPoolable();
     }
@@ -556,131 +589,143 @@
      * Returns an object that implements the given interface to allow access to
      * non-standard methods, or standard methods not exposed by the proxy.
      * <p/>
-     * If the receiver implements the interface then the result is the receiver
-     * or a proxy for the receiver. If the receiver is a wrapper
-     * and the wrapped object implements the interface then the result is the
-     * wrapped object or a proxy for the wrapped object. Otherwise return the
-     * the result of calling <code>unwrap</code> recursively on the wrapped object
-     * or a proxy for that result. If the receiver is not a
-     * wrapper and does not implement the interface, then an <code>SQLException</code> is thrown.
+     * If the receiver implements the interface then the result is the receiver or a
+     * proxy for the receiver. If the receiver is a wrapper and the wrapped object
+     * implements the interface then the result is the wrapped object or a proxy for
+     * the wrapped object. Otherwise return the the result of calling
+     * <code>unwrap</code> recursively on the wrapped object or a proxy for that
+     * result. If the receiver is not a wrapper and does not implement the
+     * interface, then an <code>SQLException</code> is thrown.
      *
      * @param iface A Class defining an interface that the result must implement.
-     * @return an object that implements the interface. May be a proxy for the actual implementing object.
-     * @throws java.sql.SQLException If no object found that implements the interface
+     * @return an object that implements the interface. May be a proxy for the
+     * actual implementing object.
+     * @throws java.sql.SQLException If no object found that implements the
+     * interface
      * @since 1.6
      */
+    @Override
     public <T> T unwrap(Class<T> iface) throws SQLException {
-        T result;
         if (iface.isInstance(this)) {
-            result = iface.cast(this);
-        } else {
-            result = preparedStatement.unwrap(iface);
+            return iface.cast(this);
         }
-        return result;
+
+        return preparedStatement.unwrap(iface);
     }
 
     /**
-     * Returns true if this either implements the interface argument or is directly or indirectly a wrapper
-     * for an object that does. Returns false otherwise. If this implements the interface then return true,
-     * else if this is a wrapper then return the result of recursively calling <code>isWrapperFor</code> on the wrapped
-     * object. If this does not implement the interface and is not a wrapper, return false.
-     * This method should be implemented as a low-cost operation compared to <code>unwrap</code> so that
-     * callers can use this method to avoid expensive <code>unwrap</code> calls that may fail. If this method
-     * returns true then calling <code>unwrap</code> with the same argument should succeed.
+     * Returns true if this either implements the interface argument or is directly
+     * or indirectly a wrapper for an object that does. Returns false otherwise. If
+     * this implements the interface then return true, else if this is a wrapper
+     * then return the result of recursively calling <code>isWrapperFor</code> on
+     * the wrapped object. If this does not implement the interface and is not a
+     * wrapper, return false. This method should be implemented as a low-cost
+     * operation compared to <code>unwrap</code> so that callers can use this method
+     * to avoid expensive <code>unwrap</code> calls that may fail. If this method
+     * returns true then calling <code>unwrap</code> with the same argument should
+     * succeed.
      *
      * @param iface a Class defining an interface.
-     * @return true if this implements the interface or directly or indirectly wraps an object that does.
-     * @throws java.sql.SQLException if an error occurs while determining whether this is a wrapper
-     *                               for an object with the given interface.
+     * @return true if this implements the interface or directly or indirectly wraps
+     * an object that does.
+     * @throws java.sql.SQLException if an error occurs while determining whether
+     * this is a wrapper for an object with the given interface.
      * @since 1.6
      */
+    @Override
     public boolean isWrapperFor(Class<?> iface) throws SQLException {
-        boolean result;
         if (iface.isInstance(this)) {
-            result = true;
-        } else {
-            result = preparedStatement.isWrapperFor(iface);
+            return true;
         }
-        return result;
+
+        return preparedStatement.isWrapperFor(iface);
     }
 
     /**
-     * Executes the SQL query in this <code>PreparedStatement</code> object
-     * and returns the <code>ResultSet</code> object generated by the query.
+     * Executes the SQL query in this <code>PreparedStatement</code> object and
+     * returns the <code>ResultSet</code> object generated by the query.
      *
-     * @return a <code>ResultSet</code> object that contains the data produced by the
-     *         query; never <code>null</code>
-     * @throws SQLException if a database access error occurs;
-     *                      this method is called on a closed  <code>PreparedStatement</code> or the SQL
-     *                      statement does not return a <code>ResultSet</code> object
+     * @return a <code>ResultSet</code> object that contains the data produced by
+     * the query; never <code>null</code>
+     * @throws SQLException if a database access error occurs; this method is called
+     * on a closed <code>PreparedStatement</code> or the SQL statement does not
+     * return a <code>ResultSet</code> object
      */
-    public java.sql.ResultSet executeQuery() throws java.sql.SQLException {
-        ResultSet rs = preparedStatement.executeQuery();
+    @Override
+    public ResultSet executeQuery() throws SQLException {
+        ResultSet resultSet = preparedStatement.executeQuery();
         incrementResultSetReferenceCount();
-        return new ResultSetWrapper40(this, rs);
+        return new ResultSetWrapper40(this, resultSet);
     }
 
     /**
      * Executes the given SQL statement, which returns a single
      * <code>ResultSet</code> object.
      *
-     * @param sql an SQL statement to be sent to the database, typically a
-     *            static SQL <code>SELECT</code> statement
-     * @return a <code>ResultSet</code> object that contains the data produced
-     *         by the given query; never <code>null</code>
-     * @throws SQLException if a database access error occurs,
-     *                      this method is called on a closed <code>Statement</code> or the given
-     *                      SQL statement produces anything other than a single
-     *                      <code>ResultSet</code> object
+     * @param sql an SQL statement to be sent to the database, typically a static
+     * SQL <code>SELECT</code> statement
+     * @return a <code>ResultSet</code> object that contains the data produced by
+     * the given query; never <code>null</code>
+     * @throws SQLException if a database access error occurs, this method is called
+     * on a closed <code>Statement</code> or the given SQL statement produces
+     * anything other than a single <code>ResultSet</code> object
      */
-    public java.sql.ResultSet executeQuery(String sql) throws
-            java.sql.SQLException {
-        ResultSet rs = preparedStatement.executeQuery(sql);
+    @Override
+    public ResultSet executeQuery(String sql) throws SQLException {
+        ResultSet resultSet = preparedStatement.executeQuery(sql);
         incrementResultSetReferenceCount();
-        return new ResultSetWrapper40(this, rs);
+        return new ResultSetWrapper40(this, resultSet);
     }
 
     /**
      * Retrieves any auto-generated keys created as a result of executing this
-     * <code>Statement</code> object. If this <code>Statement</code> object did
-     * not generate any keys, an empty <code>ResultSet</code>
-     * object is returned.
+     * <code>Statement</code> object. If this <code>Statement</code> object did not
+     * generate any keys, an empty <code>ResultSet</code> object is returned.
      * <p/>
-     * <p><B>Note:</B>If the columns which represent the auto-generated keys were not specified,
-     * the JDBC driver implementation will determine the columns which best represent the auto-generated keys.
+     * <p>
+     * <B>Note:</B>If the columns which represent the auto-generated keys were not
+     * specified, the JDBC driver implementation will determine the columns which
+     * best represent the auto-generated keys.
      *
      * @return a <code>ResultSet</code> object containing the auto-generated key(s)
-     *         generated by the execution of this <code>Statement</code> object
-     * @throws SQLException if a database access error occurs or
-     *                      this method is called on a closed <code>Statement</code>
-     * @throws java.sql.SQLFeatureNotSupportedException
-     *                      if the JDBC driver does not support this method
+     * generated by the execution of this <code>Statement</code> object
+     * @throws SQLException if a database access error occurs or this method is
+     * called on a closed <code>Statement</code>
+     * @throws java.sql.SQLFeatureNotSupportedException if the JDBC driver does not
+     * support this method
      * @since 1.4
      */
-    public java.sql.ResultSet getGeneratedKeys() throws java.sql.SQLException {
-        ResultSet rs = preparedStatement.getGeneratedKeys();
-        if (rs == null)
+    @Override
+    public ResultSet getGeneratedKeys() throws SQLException {
+        ResultSet resultSet = preparedStatement.getGeneratedKeys();
+        if (resultSet == null) {
             return null;
+        }
+
         incrementResultSetReferenceCount();
-        return new ResultSetWrapper40(this, rs);
+        return new ResultSetWrapper40(this, resultSet);
     }
 
     /**
-     * Retrieves the current result as a <code>ResultSet</code> object.
-     * This method should be called only once per result.
+     * Retrieves the current result as a <code>ResultSet</code> object. This method
+     * should be called only once per result.
      *
      * @return the current result as a <code>ResultSet</code> object or
-     *         <code>null</code> if the result is an update count or there are no more results
-     * @throws SQLException if a database access error occurs or
-     *                      this method is called on a closed <code>Statement</code>
+     * <code>null</code> if the result is an update count or there are no more
+     * results
+     * @throws SQLException if a database access error occurs or this method is
+     * called on a closed <code>Statement</code>
      * @see #execute
      */
-    public java.sql.ResultSet getResultSet() throws java.sql.SQLException {
-        ResultSet rs = preparedStatement.getResultSet();
-        if (rs == null)
+    @Override
+    public ResultSet getResultSet() throws SQLException {
+        ResultSet resultSet = preparedStatement.getResultSet();
+        if (resultSet == null) {
             return null;
+        }
+
         incrementResultSetReferenceCount();
-        return new ResultSetWrapper40(this, rs);
+        return new ResultSetWrapper40(this, resultSet);
     }
 
 }
diff --git a/appserver/jdbc/jdbc-ra/jdbc40/src/main/java/com/sun/gjc/spi/jdbc40/ProfiledConnectionWrapper40.java b/appserver/jdbc/jdbc-ra/jdbc40/src/main/java/com/sun/gjc/spi/jdbc40/ProfiledConnectionWrapper40.java
index 64f49be..3a1d222 100644
--- a/appserver/jdbc/jdbc-ra/jdbc40/src/main/java/com/sun/gjc/spi/jdbc40/ProfiledConnectionWrapper40.java
+++ b/appserver/jdbc/jdbc-ra/jdbc40/src/main/java/com/sun/gjc/spi/jdbc40/ProfiledConnectionWrapper40.java
@@ -16,9 +16,9 @@
 
 package com.sun.gjc.spi.jdbc40;
 
-import com.sun.gjc.spi.ManagedConnectionImpl;
-import com.sun.gjc.spi.base.ConnectionWrapper;
-import com.sun.gjc.util.SQLTraceDelegator;
+import static java.sql.ResultSet.CONCUR_READ_ONLY;
+import static java.sql.ResultSet.TYPE_FORWARD_ONLY;
+
 import java.lang.reflect.InvocationHandler;
 import java.lang.reflect.Method;
 import java.lang.reflect.Proxy;
@@ -26,11 +26,17 @@
 import java.sql.Connection;
 import java.sql.DatabaseMetaData;
 import java.sql.PreparedStatement;
-import java.sql.ResultSet;
 import java.sql.SQLException;
 import java.sql.Statement;
+
 import org.glassfish.api.jdbc.SQLTraceRecord;
 
+import com.sun.gjc.spi.ManagedConnectionImpl;
+import com.sun.gjc.spi.base.ConnectionWrapper;
+import com.sun.gjc.util.SQLTraceDelegator;
+
+import jakarta.resource.spi.ConnectionRequestInfo;
+
 /**
  * Wrapper class that aids to provide wrapper for Statement, PreparedStatement,
  * CallableStatement, DatabaseMetaData. Along with providing a wrapper, this
@@ -44,13 +50,12 @@
 
     /**
      * Instantiates connection wrapper to wrap JDBC objects.
+     *
      * @param con Connection that is wrapped
-     * @param mc  Managed Connection
-     * @param cxRequestInfo  Connection Request Info
+     * @param mc Managed Connection
+     * @param cxRequestInfo Connection Request Info
      */
-    public ProfiledConnectionWrapper40(Connection con, ManagedConnectionImpl mc,
-            jakarta.resource.spi.ConnectionRequestInfo cxRequestInfo,
-            boolean jdbc30Connection, SQLTraceDelegator delegator) {
+    public ProfiledConnectionWrapper40(Connection con, ManagedConnectionImpl mc, ConnectionRequestInfo cxRequestInfo, boolean jdbc30Connection, SQLTraceDelegator delegator) {
         super(con, mc, cxRequestInfo, jdbc30Connection);
         this.sqlTraceDelegator = delegator;
     }
@@ -61,14 +66,13 @@
      * @return <code>Statement</code> object.
      * @throws java.sql.SQLException In case of a database error.
      */
+    @Override
     public Statement createStatement() throws SQLException {
         Statement output = null;
-        Class intf[] = new Class[]{java.sql.Statement.class};
         try {
-            output = (java.sql.Statement) getProxyObject(
-                    new StatementWrapper40(this, super.createStatement()), intf);
+            output = (Statement) getProxyObject(new StatementWrapper40(this, super.createStatement()), new Class<?>[] { Statement.class });
         } catch (Exception e) {
-            //TODO SQLexception or any other type?
+            // TODO SQLexception or any other type?
             throw new SQLException(e);
         }
         return output;
@@ -77,43 +81,43 @@
     /**
      * Creates a statement from the underlying Connection.
      *
-     * @param resultSetType        Type of the ResultSet
+     * @param resultSetType Type of the ResultSet
      * @param resultSetConcurrency ResultSet Concurrency.
      * @return <code>Statement</code> object.
      * @throws SQLException In case of a database error.
      */
+    @Override
     public Statement createStatement(int resultSetType, int resultSetConcurrency) throws SQLException {
         Statement output = null;
-        Class intf[] = new Class[]{java.sql.Statement.class};
-        try{
-            output = (java.sql.Statement)getProxyObject(
-                    new StatementWrapper40(this,
-                    super.createStatement(resultSetType, resultSetConcurrency)), intf);
-        }catch(Exception e){
+        try {
+            output = (Statement)
+                getProxyObject(
+                    new StatementWrapper40(this, super.createStatement(resultSetType, resultSetConcurrency)), new Class<?>[] { Statement.class });
+        } catch (Exception e) {
             throw new SQLException(e);
         }
+
         return output;
     }
 
     /**
      * Creates a statement from the underlying Connection.
      *
-     * @param resultSetType        Type of the ResultSet
+     * @param resultSetType Type of the ResultSet
      * @param resultSetConcurrency ResultSet Concurrency.
      * @param resultSetHoldability ResultSet Holdability.
      * @return <code>Statement</code> object.
      * @throws SQLException In case of a database error.
      */
-    public Statement createStatement(int resultSetType, int resultSetConcurrency,
-            int resultSetHoldability) throws SQLException {
+    @Override
+    public Statement createStatement(int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException {
         Statement output = null;
-        Class intf[] = new Class[]{java.sql.Statement.class};
-        try{
-            output = (java.sql.Statement)getProxyObject(
-                    new StatementWrapper40(this,
-                    super.createStatement(resultSetType, resultSetConcurrency, resultSetHoldability)),
-                    intf);
-        }catch(Exception e){
+        Class<?>[] intf = new Class[] { Statement.class };
+        try {
+            output = (Statement)
+                getProxyObject(
+                    new StatementWrapper40(this, super.createStatement(resultSetType, resultSetConcurrency, resultSetHoldability)), intf);
+        } catch (Exception e) {
             throw new SQLException(e);
         }
         return output;
@@ -126,279 +130,269 @@
      * @return <code>DatabaseMetaData</code> object.
      * @throws SQLException In case of a database error.
      */
+    @Override
     public DatabaseMetaData getMetaData() throws SQLException {
         return new DatabaseMetaDataWrapper40(this, super.getMetaData());
     }
 
     /**
-     * Creates a <code> CallableStatement </code> object for calling database
-     * stored procedures.
+     * Creates a <code> CallableStatement </code> object for calling database stored
+     * procedures.
      *
      * @param sql SQL Statement
      * @return <code> CallableStatement</code> object.
      * @throws java.sql.SQLException In case of a database error.
      */
+    @Override
     public CallableStatement prepareCall(String sql) throws SQLException {
         CallableStatement output = null;
-        Class intf[] = new Class[]{java.sql.CallableStatement.class};
-        try{
-            output = (java.sql.CallableStatement)getProxyObject(
-                    mc.prepareCachedCallableStatement(this,sql, ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY),
-                    intf);
-        }catch(Exception e){
+        Class<?>[] intf = new Class[] { java.sql.CallableStatement.class };
+        try {
+            output = (CallableStatement)
+                getProxyObject(
+                    managedConnectionImpl.prepareCachedCallableStatement(this, sql, TYPE_FORWARD_ONLY, CONCUR_READ_ONLY), intf);
+        } catch (Exception e) {
             throw new SQLException(e);
         }
         return output;
     }
 
     /**
-     * Creates a <code> CallableStatement </code> object for calling database
-     * stored procedures.
+     * Creates a <code> CallableStatement </code> object for calling database stored
+     * procedures.
      *
-     * @param sql                  SQL Statement
-     * @param resultSetType        Type of the ResultSet
+     * @param sql SQL Statement
+     * @param resultSetType Type of the ResultSet
      * @param resultSetConcurrency ResultSet Concurrency.
      * @return <code> CallableStatement</code> object.
      * @throws SQLException In case of a database error.
      */
-    public CallableStatement prepareCall(String sql, int resultSetType,
-            int resultSetConcurrency) throws SQLException {
+    @Override
+    public CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency) throws SQLException {
         CallableStatement output = null;
-        Class intf[] = new Class[]{java.sql.CallableStatement.class};
-        try{
-            output = (java.sql.CallableStatement)getProxyObject(
-                    mc.prepareCachedCallableStatement(this, sql, resultSetType, resultSetConcurrency),
-                    intf);
-        }catch(Exception e){
+        Class<?>[] intf = new Class[] { java.sql.CallableStatement.class };
+        try {
+            output = (CallableStatement)
+                getProxyObject(
+                    managedConnectionImpl.prepareCachedCallableStatement(this, sql, resultSetType, resultSetConcurrency), intf);
+        } catch (Exception e) {
             throw new SQLException(e);
         }
         return output;
     }
 
     /**
-     * Creates a <code> CallableStatement </code> object for calling database
-     * stored procedures.
+     * Creates a <code> CallableStatement </code> object for calling database stored
+     * procedures.
      *
-     * @param sql                  SQL Statement
-     * @param resultSetType        Type of the ResultSet
+     * @param sql SQL Statement
+     * @param resultSetType Type of the ResultSet
      * @param resultSetConcurrency ResultSet Concurrency.
      * @param resultSetHoldability ResultSet Holdability.
      * @return <code> CallableStatement</code> object.
      * @throws SQLException In case of a database error.
      */
-    public CallableStatement prepareCall(String sql, int resultSetType,
-            int resultSetConcurrency,
-            int resultSetHoldability) throws SQLException {
+    @Override
+    public CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException {
         CallableStatement output = null;
-        Class intf[] = new Class[]{java.sql.CallableStatement.class};
-        try{
-            output = (java.sql.CallableStatement)getProxyObject(
-                    mc.prepareCachedCallableStatement(this, sql, resultSetType, resultSetConcurrency, resultSetHoldability),
-                    intf);
-        }catch(Exception e){
+        Class<?>[] intf = new Class[] { CallableStatement.class };
+        try {
+            output = (CallableStatement)
+                getProxyObject(
+                    managedConnectionImpl.prepareCachedCallableStatement(this, sql, resultSetType, resultSetConcurrency, resultSetHoldability), intf);
+        } catch (Exception e) {
             throw new SQLException(e);
         }
         return output;
     }
 
     /**
-     * Creates a <code> PreparedStatement </code> object for sending
-     * paramterized SQL statements to database
+     * Creates a <code> PreparedStatement </code> object for sending paramterized
+     * SQL statements to database
      *
      * @param sql SQL Statement
      * @return <code> PreparedStatement</code> object.
      * @throws SQLException In case of a database error.
      */
+    @Override
     public PreparedStatement prepareStatement(String sql) throws SQLException {
         PreparedStatement output = null;
-        Class intf[] = new Class[]{java.sql.PreparedStatement.class};
+        Class<?>[] intf = new Class[] { PreparedStatement.class };
 
-        try{
-            output = (PreparedStatement)getProxyObject(
-                    mc.prepareCachedStatement(this, sql,
-                    ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY),
-                    intf);
-        }catch(Exception e){
+        try {
+            output = (PreparedStatement)
+                getProxyObject(
+                    managedConnectionImpl.prepareCachedStatement(this, sql, TYPE_FORWARD_ONLY, CONCUR_READ_ONLY), intf);
+        } catch (Exception e) {
             throw new SQLException(e);
         }
         return output;
     }
 
     /**
-     * Creates a <code> PreparedStatement </code> object for sending
-     * paramterized SQL statements to database
+     * Creates a <code> PreparedStatement </code> object for sending paramterized
+     * SQL statements to database
      *
-     * @param sql               SQL Statement
-     * @param autoGeneratedKeys a flag indicating AutoGeneratedKeys need to be returned.
+     * @param sql SQL Statement
+     * @param autoGeneratedKeys a flag indicating AutoGeneratedKeys need to be
+     * returned.
      * @return <code> PreparedStatement</code> object.
      * @throws SQLException In case of a database error.
      */
+    @Override
     public PreparedStatement prepareStatement(String sql, int autoGeneratedKeys) throws SQLException {
         PreparedStatement output = null;
-        Class intf[] = new Class[]{java.sql.PreparedStatement.class};
-        try{
-            output = (PreparedStatement)getProxyObject(
-                    mc.prepareCachedStatement(this, sql, autoGeneratedKeys), intf);
-        }catch(Exception e){
+        Class<?>[] intf = new Class[] { PreparedStatement.class };
+        try {
+            output = (PreparedStatement)
+                getProxyObject(managedConnectionImpl.prepareCachedStatement(this, sql, autoGeneratedKeys), intf);
+        } catch (Exception e) {
             throw new SQLException(e);
         }
         return output;
     }
 
     /**
-     * Creates a <code> PreparedStatement </code> object for sending
-     * paramterized SQL statements to database
+     * Creates a <code> PreparedStatement </code> object for sending paramterized
+     * SQL statements to database
      *
-     * @param sql           SQL Statement
-     * @param columnIndexes an array of column indexes indicating the columns that should be
-     *                      returned from the inserted row or rows.
+     * @param sql SQL Statement
+     * @param columnIndexes an array of column indexes indicating the columns that
+     * should be returned from the inserted row or rows.
      * @return <code> PreparedStatement</code> object.
      * @throws SQLException In case of a database error.
      */
+    @Override
     public PreparedStatement prepareStatement(String sql, int[] columnIndexes) throws SQLException {
-            PreparedStatement output = null;
-        Class intf[] = new Class[]{java.sql.PreparedStatement.class};
-        try{
-            output = (PreparedStatement)getProxyObject(
-                    mc.prepareCachedStatement(this, sql, columnIndexes), intf);
-        }catch(Exception e){
+        PreparedStatement output = null;
+        Class<?>[] intf = new Class[] { PreparedStatement.class };
+        try {
+            output = (PreparedStatement)
+                getProxyObject(managedConnectionImpl.prepareCachedStatement(this, sql, columnIndexes), intf);
+        } catch (Exception e) {
             throw new SQLException(e);
         }
         return output;
     }
 
     /**
-     * Creates a <code> PreparedStatement </code> object for sending
-     * paramterized SQL statements to database
+     * Creates a <code> PreparedStatement </code> object for sending paramterized
+     * SQL statements to database
      *
-     * @param sql                  SQL Statement
-     * @param resultSetType        Type of the ResultSet
+     * @param sql SQL Statement
+     * @param resultSetType Type of the ResultSet
      * @param resultSetConcurrency ResultSet Concurrency.
      * @return <code> PreparedStatement</code> object.
      * @throws SQLException In case of a database error.
      */
-    public PreparedStatement prepareStatement(String sql, int resultSetType,
-            int resultSetConcurrency) throws SQLException {
+    @Override
+    public PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency) throws SQLException {
         PreparedStatement output = null;
-        Class intf[] = new Class[]{java.sql.PreparedStatement.class};
-        try{
-            output = (PreparedStatement)getProxyObject(
-                    mc.prepareCachedStatement(this, sql, resultSetType, resultSetConcurrency),
-                    intf);
-        }catch(Exception e){
+        Class<?>[] intf = new Class[] { PreparedStatement.class };
+        try {
+            output = (PreparedStatement)
+                getProxyObject(managedConnectionImpl.prepareCachedStatement(this, sql, resultSetType, resultSetConcurrency), intf);
+        } catch (Exception e) {
             throw new SQLException(e);
         }
         return output;
     }
 
     /**
-     * Creates a <code> PreparedStatement </code> object for sending
-     * paramterized SQL statements to database
+     * Creates a <code> PreparedStatement </code> object for sending paramterized
+     * SQL statements to database
      *
-     * @param sql                  SQL Statement
-     * @param resultSetType        Type of the ResultSet
+     * @param sql SQL Statement
+     * @param resultSetType Type of the ResultSet
      * @param resultSetConcurrency ResultSet Concurrency.
      * @param resultSetHoldability ResultSet Holdability.
      * @return <code> PreparedStatement</code> object.
      * @throws SQLException In case of a database error.
      */
-    public PreparedStatement prepareStatement(String sql, int resultSetType,
-            int resultSetConcurrency,
-            int resultSetHoldability) throws SQLException {
+    @Override
+    public PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency, int resultSetHoldability)
+            throws SQLException {
         PreparedStatement output = null;
-        Class intf[] = new Class[]{java.sql.PreparedStatement.class};
-        try{
-            output = (PreparedStatement)getProxyObject(
-                    mc.prepareCachedStatement(this, sql, resultSetType, resultSetConcurrency, resultSetHoldability),
-                    intf);
-        }catch(Exception e){
+        Class<?>[] intf = new Class[] { PreparedStatement.class };
+        try {
+            output = (PreparedStatement)
+                getProxyObject(
+                    managedConnectionImpl.prepareCachedStatement(this, sql, resultSetType, resultSetConcurrency, resultSetHoldability), intf);
+        } catch (Exception e) {
             throw new SQLException(e);
         }
         return output;
     }
 
     /**
-     * Creates a <code> PreparedStatement </code> object for sending
-     * paramterized SQL statements to database
+     * Creates a <code> PreparedStatement </code> object for sending paramterized
+     * SQL statements to database
      *
-     * @param sql         SQL Statement
+     * @param sql SQL Statement
      * @param columnNames Name of bound columns.
      * @return <code> PreparedStatement</code> object.
      * @throws SQLException In case of a database error.
      */
+    @Override
     public PreparedStatement prepareStatement(String sql, String[] columnNames) throws SQLException {
         checkValidity();
         jdbcPreInvoke();
         PreparedStatement output = null;
-        Class intf[] = new Class[]{java.sql.PreparedStatement.class};
-        try{
-            output = (PreparedStatement)getProxyObject(mc.prepareCachedStatement(this, sql, columnNames),
-                    intf);
-        }catch(Exception e){
+        Class<?>[] intf = new Class[] { PreparedStatement.class };
+        try {
+            output = (PreparedStatement)
+                getProxyObject(managedConnectionImpl.prepareCachedStatement(this, sql, columnNames), intf);
+        } catch (Exception e) {
             throw new SQLException(e);
         }
         return output;
 
     }
 
-    public PreparedStatementWrapper40 prepareCachedStatement(String sql,
-            int resultSetType, int resultSetConcurrency, boolean enableCaching)
-            throws SQLException {
-        return new PreparedStatementWrapper40(this, super.prepareStatement(sql,
-                resultSetType, resultSetConcurrency), enableCaching);
+    @Override
+    public PreparedStatementWrapper40 prepareCachedStatement(String sql, int resultSetType, int resultSetConcurrency, boolean enableCaching) throws SQLException {
+        return new PreparedStatementWrapper40(this, super.prepareStatement(sql, resultSetType, resultSetConcurrency), enableCaching);
     }
 
-    public PreparedStatementWrapper40 prepareCachedStatement(String sql,
-            String[] columnNames, boolean enableCaching)
-            throws SQLException {
-        return new PreparedStatementWrapper40(this,
-                super.prepareStatement(sql, columnNames), enableCaching);
+    @Override
+    public PreparedStatementWrapper40 prepareCachedStatement(String sql, String[] columnNames, boolean enableCaching) throws SQLException {
+        return new PreparedStatementWrapper40(this, super.prepareStatement(sql, columnNames), enableCaching);
     }
 
-    public PreparedStatementWrapper40 prepareCachedStatement(String sql,
-            int resultSetType, int resultSetConcurrency, int resultSetHoldability,
+    @Override
+    public PreparedStatementWrapper40 prepareCachedStatement(String sql, int resultSetType, int resultSetConcurrency, int resultSetHoldability, boolean enableCaching) throws SQLException {
+        return new PreparedStatementWrapper40(this, super.prepareCall(sql, resultSetType, resultSetConcurrency, resultSetHoldability),
+                enableCaching);
+    }
+
+    @Override
+    public PreparedStatementWrapper40 prepareCachedStatement(String sql, int[] columnIndexes, boolean enableCaching) throws SQLException {
+        return new PreparedStatementWrapper40(this, super.prepareStatement(sql, columnIndexes), enableCaching);
+    }
+
+    @Override
+    public PreparedStatementWrapper40 prepareCachedStatement(String sql, int autoGeneratedKeys, boolean enableCaching) throws SQLException {
+        return new PreparedStatementWrapper40(this, super.prepareStatement(sql, autoGeneratedKeys), enableCaching);
+    }
+
+    @Override
+    public CallableStatementWrapper40 callableCachedStatement(String sql, int resultSetType, int resultSetConcurrency,
             boolean enableCaching) throws SQLException {
-        return new PreparedStatementWrapper40(this,
-                super.prepareCall(sql, resultSetType, resultSetConcurrency, resultSetHoldability),
+        return new CallableStatementWrapper40(this, super.prepareCall(sql, resultSetType, resultSetConcurrency), enableCaching);
+    }
+
+    @Override
+    public CallableStatementWrapper40 callableCachedStatement(String sql, int resultSetType, int resultSetConcurrency, int resultSetHoldability, boolean enableCaching) throws SQLException {
+        return new CallableStatementWrapper40(this, super.prepareCall(sql, resultSetType, resultSetConcurrency, resultSetHoldability),
                 enableCaching);
     }
 
-    public PreparedStatementWrapper40 prepareCachedStatement(String sql,
-            int[] columnIndexes, boolean enableCaching)
-            throws SQLException {
-        return new PreparedStatementWrapper40(this,
-                super.prepareStatement(sql, columnIndexes), enableCaching);
-    }
-
-    public PreparedStatementWrapper40 prepareCachedStatement(String sql,
-            int autoGeneratedKeys, boolean enableCaching)
-            throws SQLException {
-        return new PreparedStatementWrapper40(this,
-                super.prepareStatement(sql, autoGeneratedKeys), enableCaching);
-    }
-
-    public CallableStatementWrapper40 callableCachedStatement(String sql,
-            int resultSetType, int resultSetConcurrency, boolean enableCaching)
-            throws SQLException {
-        return new CallableStatementWrapper40(this, super.prepareCall(sql,
-                resultSetType, resultSetConcurrency), enableCaching);
-    }
-
-    public CallableStatementWrapper40 callableCachedStatement(String sql,
-            int resultSetType, int resultSetConcurrency,
-            int resultSetHoldability, boolean enableCaching)
-            throws SQLException {
-        return new CallableStatementWrapper40(this, super.prepareCall(sql,
-                resultSetType, resultSetConcurrency, resultSetHoldability),
-                enableCaching);
-    }
-
-    //TODO refactor this method and move to a higher level
-    private <T> T getProxyObject(final Object actualObject, Class<T>[] ifaces) throws Exception {
-
-        T result;
+    // TODO refactor this method and move to a higher level
+    @SuppressWarnings("unchecked")
+    private <T> T getProxyObject(final Object actualObject, Class<?>[] ifaces) throws Exception {
         InvocationHandler ih = new InvocationHandler() {
 
+            @Override
             public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                 SQLTraceRecord record = new SQLTraceRecord();
                 record.setMethodName(method.getName());
@@ -411,8 +405,8 @@
                 return method.invoke(actualObject, args);
             }
         };
-        result = (T) Proxy.newProxyInstance(actualObject.getClass().getClassLoader(), ifaces, ih);
-        return result;
+
+        return (T) Proxy.newProxyInstance(actualObject.getClass().getClassLoader(), ifaces, ih);
     }
 
 }
diff --git a/appserver/jdbc/jdbc-ra/jdbc40/src/main/java/com/sun/gjc/spi/jdbc40/ResultSetWrapper40.java b/appserver/jdbc/jdbc-ra/jdbc40/src/main/java/com/sun/gjc/spi/jdbc40/ResultSetWrapper40.java
index 9a479f3..c54f7ed 100644
--- a/appserver/jdbc/jdbc-ra/jdbc40/src/main/java/com/sun/gjc/spi/jdbc40/ResultSetWrapper40.java
+++ b/appserver/jdbc/jdbc-ra/jdbc40/src/main/java/com/sun/gjc/spi/jdbc40/ResultSetWrapper40.java
@@ -16,16 +16,23 @@
 
 package com.sun.gjc.spi.jdbc40;
 
-import com.sun.enterprise.util.i18n.StringManager;
-import com.sun.gjc.common.DataSourceObjectBuilder;
-import com.sun.gjc.spi.ManagedConnectionFactoryImpl;
-import com.sun.gjc.spi.base.ResultSetWrapper;
+import static com.sun.gjc.common.DataSourceObjectBuilder.isJDBC41;
+import static java.util.logging.Level.SEVERE;
 
 import java.io.InputStream;
 import java.io.Reader;
+import java.sql.NClob;
+import java.sql.ResultSet;
+import java.sql.RowId;
+import java.sql.SQLException;
+import java.sql.SQLFeatureNotSupportedException;
+import java.sql.SQLXML;
+import java.sql.Statement;
 
-import java.sql.*;
-import java.util.logging.Level;
+import com.sun.enterprise.util.i18n.StringManager;
+import com.sun.gjc.spi.ManagedConnectionFactoryImpl;
+import com.sun.gjc.spi.base.ResultSetWrapper;
+
 import jakarta.resource.ResourceException;
 
 /**
@@ -33,104 +40,108 @@
  */
 public class ResultSetWrapper40 extends ResultSetWrapper {
 
-    protected final static StringManager localStrings =
-            StringManager.getManager(ManagedConnectionFactoryImpl.class);
+    protected final static StringManager localStrings = StringManager.getManager(ManagedConnectionFactoryImpl.class);
 
     /**
      * Creates a new instance of ResultSetWrapper for JDBC 4.0
      *
-     * @param stmt Statement that is to be wrapped<br>
-     * @param rs   ResultSet that is to be wraped<br>*
+     * @param statement Statement that is to be wrapped<br>
+     * @param resultSet ResultSet that is to be wraped<br>
+     * *
      */
-    public ResultSetWrapper40(Statement stmt, ResultSet rs) {
-        super(stmt, rs);
+    public ResultSetWrapper40(Statement statement, ResultSet resultSet) {
+        super(statement, resultSet);
     }
 
     /**
      * Retrieves the value of the designated column in the current row of this
-     * <code>ResultSet</code> object as a <code>java.sql.RowId</code> object in the Java
-     * programming language.
+     * <code>ResultSet</code> object as a <code>java.sql.RowId</code> object in the
+     * Java programming language.
      *
      * @param columnIndex the first column is 1, the second 2, ...
-     * @return the column value; if the value is a SQL <code>NULL</code> the
-     *         value returned is <code>null</code>
-     * @throws SQLException if the columnIndex is not valid;
-     *                      if a database access error occurs
-     *                      or this method is called on a closed result set
-     * @throws SQLFeatureNotSupportedException
-     *                      if the JDBC driver does not support
-     *                      this method
+     * @return the column value; if the value is a SQL <code>NULL</code> the value
+     * returned is <code>null</code>
+     * @throws SQLException if the columnIndex is not valid; if a database access
+     * error occurs or this method is called on a closed result set
+     * @throws SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
      * @since 1.6
      */
+    @Override
     public RowId getRowId(int columnIndex) throws SQLException {
         return resultSet.getRowId(columnIndex);
     }
 
     /**
      * Retrieves the value of the designated column in the current row of this
-     * <code>ResultSet</code> object as a <code>java.sql.RowId</code> object in the Java
-     * programming language.
+     * <code>ResultSet</code> object as a <code>java.sql.RowId</code> object in the
+     * Java programming language.
      *
-     * @param columnLabel the label for the column specified with the SQL AS clause.  If the SQL AS clause was not
-     *                    specified, then the label is the name of the column
-     * @return the column value ; if the value is a SQL <code>NULL</code> the
-     *         value returned is <code>null</code>
-     * @throws SQLException if the columnLabel is not valid;
-     *                      if a database access error occurs
-     *                      or this method is called on a closed result set
-     * @throws SQLFeatureNotSupportedException
-     *                      if the JDBC driver does not support
-     *                      this method
+     * @param columnLabel the label for the column specified with the SQL AS clause.
+     * If the SQL AS clause was not specified, then the label is the name of the
+     * column
+     * @return the column value ; if the value is a SQL <code>NULL</code> the value
+     * returned is <code>null</code>
+     * @throws SQLException if the columnLabel is not valid; if a database access
+     * error occurs or this method is called on a closed result set
+     * @throws SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
      * @since 1.6
      */
+    @Override
     public RowId getRowId(String columnLabel) throws SQLException {
         return resultSet.getRowId(columnLabel);
     }
 
+    @SuppressWarnings("unchecked")
+    @Override
     public <T> T getObject(int columnIndex, Class<T> type) throws SQLException {
-        if (DataSourceObjectBuilder.isJDBC41()) {
-            Class<?>[] valueTypes = new Class<?>[]{Integer.TYPE, Class.class};
-            try {
-                return (T) getMethodExecutor().invokeMethod(resultSet, "getObject", valueTypes, columnIndex, type);
-            } catch (ResourceException ex) {
-                _logger.log(Level.SEVERE, "jdbc.ex_get_object", ex);
-                throw new SQLException(ex);
-            }
+        if (!isJDBC41()) {
+            throw new UnsupportedOperationException("Operation not supported in this runtime.");
         }
-        throw new UnsupportedOperationException("Operation not supported in this runtime.");
+
+        Class<?>[] valueTypes = new Class<?>[] { Integer.TYPE, Class.class };
+        try {
+            return (T) getMethodExecutor().invokeMethod(resultSet, "getObject", valueTypes, columnIndex, type);
+        } catch (ResourceException ex) {
+            _logger.log(SEVERE, "jdbc.ex_get_object", ex);
+            throw new SQLException(ex);
+        }
     }
 
+    @SuppressWarnings("unchecked")
+    @Override
     public <T> T getObject(String columnLabel, Class<T> type) throws SQLException {
-        if (DataSourceObjectBuilder.isJDBC41()) {
-            Class<?>[] valueTypes = new Class<?>[]{String.class, Class.class};
-            try {
-                return (T) getMethodExecutor().invokeMethod(resultSet, "getObject", valueTypes, columnLabel, type);
-            } catch (ResourceException ex) {
-                _logger.log(Level.SEVERE, "jdbc.ex_get_object", ex);
-                throw new SQLException(ex);
-            }
+        if (!isJDBC41()) {
+            throw new UnsupportedOperationException("Operation not supported in this runtime.");
         }
-        throw new UnsupportedOperationException("Operation not supported in this runtime.");
+
+        Class<?>[] valueTypes = new Class<?>[] { String.class, Class.class };
+        try {
+            return (T) getMethodExecutor().invokeMethod(resultSet, "getObject", valueTypes, columnLabel, type);
+        } catch (ResourceException ex) {
+            _logger.log(SEVERE, "jdbc.ex_get_object", ex);
+            throw new SQLException(ex);
+        }
     }
 
     /**
      * Updates the designated column with a <code>RowId</code> value. The updater
      * methods are used to update column values in the current row or the insert
-     * row. The updater methods do not update the underlying database; instead
-     * the <code>updateRow</code> or <code>insertRow</code> methods are called
-     * to update the database.
+     * row. The updater methods do not update the underlying database; instead the
+     * <code>updateRow</code> or <code>insertRow</code> methods are called to update
+     * the database.
      *
      * @param columnIndex the first column is 1, the second 2, ...
-     * @param x           the column value
-     * @throws SQLException if the columnIndex is not valid;
-     *                      if a database access error occurs;
-     *                      the result set concurrency is <code>CONCUR_READ_ONLY</code>
-     *                      or this method is called on a closed result set
-     * @throws SQLFeatureNotSupportedException
-     *                      if the JDBC driver does not support
-     *                      this method
+     * @param x the column value
+     * @throws SQLException if the columnIndex is not valid; if a database access
+     * error occurs; the result set concurrency is <code>CONCUR_READ_ONLY</code> or
+     * this method is called on a closed result set
+     * @throws SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
      * @since 1.6
      */
+    @Override
     public void updateRowId(int columnIndex, RowId x) throws SQLException {
         resultSet.updateRowId(columnIndex, x);
     }
@@ -138,22 +149,22 @@
     /**
      * Updates the designated column with a <code>RowId</code> value. The updater
      * methods are used to update column values in the current row or the insert
-     * row. The updater methods do not update the underlying database; instead
-     * the <code>updateRow</code> or <code>insertRow</code> methods are called
-     * to update the database.
+     * row. The updater methods do not update the underlying database; instead the
+     * <code>updateRow</code> or <code>insertRow</code> methods are called to update
+     * the database.
      *
-     * @param columnLabel the label for the column specified with the SQL AS clause.  If the SQL AS clause was
-     *                    not specified, then the label is the name of the column
-     * @param x           the column value
-     * @throws SQLException if the columnLabel is not valid;
-     *                      if a database access error occurs;
-     *                      the result set concurrency is <code>CONCUR_READ_ONLY</code>
-     *                      or this method is called on a closed result set
-     * @throws SQLFeatureNotSupportedException
-     *                      if the JDBC driver does not support
-     *                      this method
+     * @param columnLabel the label for the column specified with the SQL AS clause.
+     * If the SQL AS clause was not specified, then the label is the name of the
+     * column
+     * @param x the column value
+     * @throws SQLException if the columnLabel is not valid; if a database access
+     * error occurs; the result set concurrency is <code>CONCUR_READ_ONLY</code> or
+     * this method is called on a closed result set
+     * @throws SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
      * @since 1.6
      */
+    @Override
     public void updateRowId(String columnLabel, RowId x) throws SQLException {
         resultSet.updateRowId(columnLabel, x);
     }
@@ -161,476 +172,457 @@
     /**
      * Retrieves the holdability of this <code>ResultSet</code> object
      *
-     * @return either <code>ResultSet.HOLD_CURSORS_OVER_COMMIT</code> or <code>ResultSet.CLOSE_CURSORS_AT_COMMIT</code>
-     * @throws SQLException if a database access error occurs
-     *                      or this method is called on a closed result set
+     * @return either <code>ResultSet.HOLD_CURSORS_OVER_COMMIT</code> or
+     * <code>ResultSet.CLOSE_CURSORS_AT_COMMIT</code>
+     * @throws SQLException if a database access error occurs or this method is
+     * called on a closed result set
      * @since 1.6
      */
+    @Override
     public int getHoldability() throws SQLException {
         return resultSet.getHoldability();
     }
 
     /**
-     * Retrieves whether this <code>ResultSet</code> object has been closed. A <code>ResultSet</code> is closed if the
-     * method close has been called on it, or if it is automatically closed.
+     * Retrieves whether this <code>ResultSet</code> object has been closed. A
+     * <code>ResultSet</code> is closed if the method close has been called on it,
+     * or if it is automatically closed.
      *
-     * @return true if this <code>ResultSet</code> object is closed; false if it is still open
+     * @return true if this <code>ResultSet</code> object is closed; false if it is
+     * still open
      * @throws SQLException if a database access error occurs
      * @since 1.6
      */
+    @Override
     public boolean isClosed() throws SQLException {
         return resultSet.isClosed();
     }
 
     /**
-     * Updates the designated column with a <code>String</code> value.
-     * It is intended for use when updating <code>NCHAR</code>,<code>NVARCHAR</code>
-     * and <code>LONGNVARCHAR</code> columns.
-     * The updater methods are used to update column values in the
-     * current row or the insert row.  The updater methods do not
-     * update the underlying database; instead the <code>updateRow</code> or
+     * Updates the designated column with a <code>String</code> value. It is
+     * intended for use when updating <code>NCHAR</code>,<code>NVARCHAR</code> and
+     * <code>LONGNVARCHAR</code> columns. The updater methods are used to update
+     * column values in the current row or the insert row. The updater methods do
+     * not update the underlying database; instead the <code>updateRow</code> or
      * <code>insertRow</code> methods are called to update the database.
      *
      * @param columnIndex the first column is 1, the second 2, ...
-     * @param nString     the value for the column to be updated
-     * @throws SQLException if the columnIndex is not valid;
-     *                      if the driver does not support national
-     *                      character sets;  if the driver can detect that a data conversion
-     *                      error could occur; this method is called on a closed result set;
-     *                      the result set concurrency is <code>CONCUR_READ_ONLY</code>
-     *                      or if a database access error occurs
-     * @throws SQLFeatureNotSupportedException
-     *                      if the JDBC driver does not support
-     *                      this method
+     * @param nString the value for the column to be updated
+     * @throws SQLException if the columnIndex is not valid; if the driver does not
+     * support national character sets; if the driver can detect that a data
+     * conversion error could occur; this method is called on a closed result set;
+     * the result set concurrency is <code>CONCUR_READ_ONLY</code> or if a database
+     * access error occurs
+     * @throws SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
      * @since 1.6
      */
+    @Override
     public void updateNString(int columnIndex, String nString) throws SQLException {
         resultSet.updateNString(columnIndex, nString);
     }
 
     /**
-     * Updates the designated column with a <code>String</code> value.
-     * It is intended for use when updating <code>NCHAR</code>,<code>NVARCHAR</code>
-     * and <code>LONGNVARCHAR</code> columns.
-     * The updater methods are used to update column values in the
-     * current row or the insert row.  The updater methods do not
-     * update the underlying database; instead the <code>updateRow</code> or
+     * Updates the designated column with a <code>String</code> value. It is
+     * intended for use when updating <code>NCHAR</code>,<code>NVARCHAR</code> and
+     * <code>LONGNVARCHAR</code> columns. The updater methods are used to update
+     * column values in the current row or the insert row. The updater methods do
+     * not update the underlying database; instead the <code>updateRow</code> or
      * <code>insertRow</code> methods are called to update the database.
      *
-     * @param columnLabel the label for the column specified with the SQL AS clause.  If the SQL AS clause was not
-     *                    specified, then the label is the name of the column
-     * @param nString     the value for the column to be updated
-     * @throws SQLException if the columnLabel is not valid;
-     *                      if the driver does not support national
-     *                      character sets;  if the driver can detect that a data conversion
-     *                      error could occur; this method is called on a closed result set;
-     *                      the result set concurrency is <CODE>CONCUR_READ_ONLY</code>
-     *                      or if a database access error occurs
-     * @throws SQLFeatureNotSupportedException
-     *                      if the JDBC driver does not support
-     *                      this method
+     * @param columnLabel the label for the column specified with the SQL AS clause.
+     * If the SQL AS clause was not specified, then the label is the name of the
+     * column
+     * @param nString the value for the column to be updated
+     * @throws SQLException if the columnLabel is not valid; if the driver does not
+     * support national character sets; if the driver can detect that a data
+     * conversion error could occur; this method is called on a closed result set;
+     * the result set concurrency is <CODE>CONCUR_READ_ONLY</code> or if a database
+     * access error occurs
+     * @throws SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
      * @since 1.6
      */
+    @Override
     public void updateNString(String columnLabel, String nString) throws SQLException {
         resultSet.updateNString(columnLabel, nString);
     }
 
     /**
-     * Updates the designated column with a <code>java.sql.NClob</code> value.
-     * The updater methods are used to update column values in the
-     * current row or the insert row.  The updater methods do not
-     * update the underlying database; instead the <code>updateRow</code> or
-     * <code>insertRow</code> methods are called to update the database.
+     * Updates the designated column with a <code>java.sql.NClob</code> value. The
+     * updater methods are used to update column values in the current row or the
+     * insert row. The updater methods do not update the underlying database;
+     * instead the <code>updateRow</code> or <code>insertRow</code> methods are
+     * called to update the database.
      *
      * @param columnIndex the first column is 1, the second 2, ...
-     * @param nClob       the value for the column to be updated
-     * @throws SQLException if the columnIndex is not valid;
-     *                      if the driver does not support national
-     *                      character sets;  if the driver can detect that a data conversion
-     *                      error could occur; this method is called on a closed result set;
-     *                      if a database access error occurs or
-     *                      the result set concurrency is <code>CONCUR_READ_ONLY</code>
-     * @throws SQLFeatureNotSupportedException
-     *                      if the JDBC driver does not support
-     *                      this method
+     * @param nClob the value for the column to be updated
+     * @throws SQLException if the columnIndex is not valid; if the driver does not
+     * support national character sets; if the driver can detect that a data
+     * conversion error could occur; this method is called on a closed result set;
+     * if a database access error occurs or the result set concurrency is
+     * <code>CONCUR_READ_ONLY</code>
+     * @throws SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
      * @since 1.6
      */
+    @Override
     public void updateNClob(int columnIndex, NClob nClob) throws SQLException {
         resultSet.updateNClob(columnIndex, nClob);
     }
 
     /**
-     * Updates the designated column with a <code>java.sql.NClob</code> value.
-     * The updater methods are used to update column values in the
-     * current row or the insert row.  The updater methods do not
-     * update the underlying database; instead the <code>updateRow</code> or
-     * <code>insertRow</code> methods are called to update the database.
+     * Updates the designated column with a <code>java.sql.NClob</code> value. The
+     * updater methods are used to update column values in the current row or the
+     * insert row. The updater methods do not update the underlying database;
+     * instead the <code>updateRow</code> or <code>insertRow</code> methods are
+     * called to update the database.
      *
-     * @param columnLabel the label for the column specified with the SQL AS clause.  If the SQL AS clause was not
-     *                    specified, then the label is the name of the column
-     * @param nClob       the value for the column to be updated
-     * @throws SQLException if the columnLabel is not valid;
-     *                      if the driver does not support national
-     *                      character sets;  if the driver can detect that a data conversion
-     *                      error could occur; this method is called on a closed result set;
-     *                      if a database access error occurs or
-     *                      the result set concurrency is <code>CONCUR_READ_ONLY</code>
-     * @throws SQLFeatureNotSupportedException
-     *                      if the JDBC driver does not support
-     *                      this method
+     * @param columnLabel the label for the column specified with the SQL AS clause.
+     * If the SQL AS clause was not specified, then the label is the name of the
+     * column
+     * @param nClob the value for the column to be updated
+     * @throws SQLException if the columnLabel is not valid; if the driver does not
+     * support national character sets; if the driver can detect that a data
+     * conversion error could occur; this method is called on a closed result set;
+     * if a database access error occurs or the result set concurrency is
+     * <code>CONCUR_READ_ONLY</code>
+     * @throws SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
      * @since 1.6
      */
+    @Override
     public void updateNClob(String columnLabel, NClob nClob) throws SQLException {
         resultSet.updateNClob(columnLabel, nClob);
     }
 
     /**
-     * Retrieves the value of the designated column in the current row
-     * of this <code>ResultSet</code> object as a <code>NClob</code> object
-     * in the Java programming language.
+     * Retrieves the value of the designated column in the current row of this
+     * <code>ResultSet</code> object as a <code>NClob</code> object in the Java
+     * programming language.
      *
      * @param columnIndex the first column is 1, the second is 2, ...
-     * @return a <code>NClob</code> object representing the SQL
-     *         <code>NCLOB</code> value in the specified column
-     * @throws SQLException if the columnIndex is not valid;
-     *                      if the driver does not support national
-     *                      character sets;  if the driver can detect that a data conversion
-     *                      error could occur; this method is called on a closed result set
-     *                      or if a database access error occurs
-     * @throws SQLFeatureNotSupportedException
-     *                      if the JDBC driver does not support
-     *                      this method
+     * @return a <code>NClob</code> object representing the SQL <code>NCLOB</code>
+     * value in the specified column
+     * @throws SQLException if the columnIndex is not valid; if the driver does not
+     * support national character sets; if the driver can detect that a data
+     * conversion error could occur; this method is called on a closed result set or
+     * if a database access error occurs
+     * @throws SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
      * @since 1.6
      */
+    @Override
     public NClob getNClob(int columnIndex) throws SQLException {
         return resultSet.getNClob(columnIndex);
     }
 
     /**
-     * Retrieves the value of the designated column in the current row
-     * of this <code>ResultSet</code> object as a <code>NClob</code> object
-     * in the Java programming language.
+     * Retrieves the value of the designated column in the current row of this
+     * <code>ResultSet</code> object as a <code>NClob</code> object in the Java
+     * programming language.
      *
-     * @param columnLabel the label for the column specified with the SQL AS clause.  If the SQL AS clause was not
-     *                    specified, then the label is the name of the column
+     * @param columnLabel the label for the column specified with the SQL AS clause.
+     * If the SQL AS clause was not specified, then the label is the name of the
+     * column
      * @return a <code>NClob</code> object representing the SQL <code>NCLOB</code>
-     *         value in the specified column
-     * @throws SQLException if the columnLabel is not valid;
-     *                      if the driver does not support national
-     *                      character sets;  if the driver can detect that a data conversion
-     *                      error could occur; this method is called on a closed result set
-     *                      or if a database access error occurs
-     * @throws SQLFeatureNotSupportedException
-     *                      if the JDBC driver does not support
-     *                      this method
+     * value in the specified column
+     * @throws SQLException if the columnLabel is not valid; if the driver does not
+     * support national character sets; if the driver can detect that a data
+     * conversion error could occur; this method is called on a closed result set or
+     * if a database access error occurs
+     * @throws SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
      * @since 1.6
      */
+    @Override
     public NClob getNClob(String columnLabel) throws SQLException {
         return resultSet.getNClob(columnLabel);
     }
 
     /**
-     * Retrieves the value of the designated column in  the current row of
-     * this <code>ResultSet</code> as a
-     * <code>java.sql.SQLXML</code> object in the Java programming language.
+     * Retrieves the value of the designated column in the current row of this
+     * <code>ResultSet</code> as a <code>java.sql.SQLXML</code> object in the Java
+     * programming language.
      *
      * @param columnIndex the first column is 1, the second is 2, ...
      * @return a <code>SQLXML</code> object that maps an <code>SQL XML</code> value
-     * @throws SQLException if the columnIndex is not valid;
-     *                      if a database access error occurs
-     *                      or this method is called on a closed result set
-     * @throws SQLFeatureNotSupportedException
-     *                      if the JDBC driver does not support
-     *                      this method
+     * @throws SQLException if the columnIndex is not valid; if a database access
+     * error occurs or this method is called on a closed result set
+     * @throws SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
      * @since 1.6
      */
+    @Override
     public SQLXML getSQLXML(int columnIndex) throws SQLException {
         return resultSet.getSQLXML(columnIndex);
     }
 
     /**
-     * Retrieves the value of the designated column in  the current row of
-     * this <code>ResultSet</code> as a
-     * <code>java.sql.SQLXML</code> object in the Java programming language.
+     * Retrieves the value of the designated column in the current row of this
+     * <code>ResultSet</code> as a <code>java.sql.SQLXML</code> object in the Java
+     * programming language.
      *
-     * @param columnLabel the label for the column specified with the SQL AS clause.  If the SQL AS clause was not
-     *                    specified, then the label is the name of the column
+     * @param columnLabel the label for the column specified with the SQL AS clause.
+     * If the SQL AS clause was not specified, then the label is the name of the
+     * column
      * @return a <code>SQLXML</code> object that maps an <code>SQL XML</code> value
-     * @throws SQLException if the columnLabel is not valid;
-     *                      if a database access error occurs
-     *                      or this method is called on a closed result set
-     * @throws SQLFeatureNotSupportedException
-     *                      if the JDBC driver does not support
-     *                      this method
+     * @throws SQLException if the columnLabel is not valid; if a database access
+     * error occurs or this method is called on a closed result set
+     * @throws SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
      * @since 1.6
      */
+    @Override
     public SQLXML getSQLXML(String columnLabel) throws SQLException {
         return resultSet.getSQLXML(columnLabel);
     }
 
     /**
-     * Updates the designated column with a <code>java.sql.SQLXML</code> value.
-     * The updater
-     * methods are used to update column values in the current row or the insert
-     * row. The updater methods do not update the underlying database; instead
-     * the <code>updateRow</code> or <code>insertRow</code> methods are called
-     * to update the database.
+     * Updates the designated column with a <code>java.sql.SQLXML</code> value. The
+     * updater methods are used to update column values in the current row or the
+     * insert row. The updater methods do not update the underlying database;
+     * instead the <code>updateRow</code> or <code>insertRow</code> methods are
+     * called to update the database.
      * <p/>
      *
      * @param columnIndex the first column is 1, the second 2, ...
-     * @param xmlObject   the value for the column to be updated
-     * @throws SQLException if the columnIndex is not valid;
-     *                      if a database access error occurs; this method
-     *                      is called on a closed result set;
-     *                      the <code>java.xml.transform.Result</code>,
-     *                      <code>Writer</code> or <code>OutputStream</code> has not been closed
-     *                      for the <code>SQLXML</code> object;
-     *                      if there is an error processing the XML value or
-     *                      the result set concurrency is <code>CONCUR_READ_ONLY</code>.  The <code>getCause</code> method
-     *                      of the exception may provide a more detailed exception, for example, if the
-     *                      stream does not contain valid XML.
-     * @throws SQLFeatureNotSupportedException
-     *                      if the JDBC driver does not support
-     *                      this method
+     * @param xmlObject the value for the column to be updated
+     * @throws SQLException if the columnIndex is not valid; if a database access
+     * error occurs; this method is called on a closed result set; the
+     * <code>java.xml.transform.Result</code>, <code>Writer</code> or
+     * <code>OutputStream</code> has not been closed for the <code>SQLXML</code>
+     * object; if there is an error processing the XML value or the result set
+     * concurrency is <code>CONCUR_READ_ONLY</code>. The <code>getCause</code>
+     * method of the exception may provide a more detailed exception, for example,
+     * if the stream does not contain valid XML.
+     * @throws SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
      * @since 1.6
      */
+    @Override
     public void updateSQLXML(int columnIndex, SQLXML xmlObject) throws SQLException {
         resultSet.updateSQLXML(columnIndex, xmlObject);
     }
 
     /**
-     * Updates the designated column with a <code>java.sql.SQLXML</code> value.
-     * The updater
-     * methods are used to update column values in the current row or the insert
-     * row. The updater methods do not update the underlying database; instead
-     * the <code>updateRow</code> or <code>insertRow</code> methods are called
-     * to update the database.
+     * Updates the designated column with a <code>java.sql.SQLXML</code> value. The
+     * updater methods are used to update column values in the current row or the
+     * insert row. The updater methods do not update the underlying database;
+     * instead the <code>updateRow</code> or <code>insertRow</code> methods are
+     * called to update the database.
      * <p/>
      *
-     * @param columnLabel the label for the column specified with the SQL AS clause.  If the SQL AS clause was not
-     *                    specified, then the label is the name of the column
-     * @param xmlObject   the column value
-     * @throws SQLException if the columnLabel is not valid;
-     *                      if a database access error occurs; this method
-     *                      is called on a closed result set;
-     *                      the <code>java.xml.transform.Result</code>,
-     *                      <code>Writer</code> or <code>OutputStream</code> has not been closed
-     *                      for the <code>SQLXML</code> object;
-     *                      if there is an error processing the XML value or
-     *                      the result set concurrency is <code>CONCUR_READ_ONLY</code>.  The <code>getCause</code> method
-     *                      of the exception may provide a more detailed exception, for example, if the
-     *                      stream does not contain valid XML.
-     * @throws SQLFeatureNotSupportedException
-     *                      if the JDBC driver does not support
-     *                      this method
+     * @param columnLabel the label for the column specified with the SQL AS clause.
+     * If the SQL AS clause was not specified, then the label is the name of the
+     * column
+     * @param xmlObject the column value
+     * @throws SQLException if the columnLabel is not valid; if a database access
+     * error occurs; this method is called on a closed result set; the
+     * <code>java.xml.transform.Result</code>, <code>Writer</code> or
+     * <code>OutputStream</code> has not been closed for the <code>SQLXML</code>
+     * object; if there is an error processing the XML value or the result set
+     * concurrency is <code>CONCUR_READ_ONLY</code>. The <code>getCause</code>
+     * method of the exception may provide a more detailed exception, for example,
+     * if the stream does not contain valid XML.
+     * @throws SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
      * @since 1.6
      */
+    @Override
     public void updateSQLXML(String columnLabel, SQLXML xmlObject) throws SQLException {
         resultSet.updateSQLXML(columnLabel, xmlObject);
     }
 
     /**
-     * Retrieves the value of the designated column in the current row
-     * of this <code>ResultSet</code> object as
-     * a <code>String</code> in the Java programming language.
-     * It is intended for use when
-     * accessing  <code>NCHAR</code>,<code>NVARCHAR</code>
-     * and <code>LONGNVARCHAR</code> columns.
+     * Retrieves the value of the designated column in the current row of this
+     * <code>ResultSet</code> object as a <code>String</code> in the Java
+     * programming language. It is intended for use when accessing
+     * <code>NCHAR</code>,<code>NVARCHAR</code> and <code>LONGNVARCHAR</code>
+     * columns.
      *
      * @param columnIndex the first column is 1, the second is 2, ...
-     * @return the column value; if the value is SQL <code>NULL</code>, the
-     *         value returned is <code>null</code>
-     * @throws SQLException if the columnIndex is not valid;
-     *                      if a database access error occurs
-     *                      or this method is called on a closed result set
-     * @throws SQLFeatureNotSupportedException
-     *                      if the JDBC driver does not support
-     *                      this method
+     * @return the column value; if the value is SQL <code>NULL</code>, the value
+     * returned is <code>null</code>
+     * @throws SQLException if the columnIndex is not valid; if a database access
+     * error occurs or this method is called on a closed result set
+     * @throws SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
      * @since 1.6
      */
+    @Override
     public String getNString(int columnIndex) throws SQLException {
         return resultSet.getNString(columnIndex);
     }
 
     /**
-     * Retrieves the value of the designated column in the current row
-     * of this <code>ResultSet</code> object as
-     * a <code>String</code> in the Java programming language.
-     * It is intended for use when
-     * accessing  <code>NCHAR</code>,<code>NVARCHAR</code>
-     * and <code>LONGNVARCHAR</code> columns.
+     * Retrieves the value of the designated column in the current row of this
+     * <code>ResultSet</code> object as a <code>String</code> in the Java
+     * programming language. It is intended for use when accessing
+     * <code>NCHAR</code>,<code>NVARCHAR</code> and <code>LONGNVARCHAR</code>
+     * columns.
      *
-     * @param columnLabel the label for the column specified with the SQL AS clause.  If the SQL AS clause was not
-     *                    specified, then the label is the name of the column
-     * @return the column value; if the value is SQL <code>NULL</code>, the
-     *         value returned is <code>null</code>
-     * @throws SQLException if the columnLabel is not valid;
-     *                      if a database access error occurs
-     *                      or this method is called on a closed result set
-     * @throws SQLFeatureNotSupportedException
-     *                      if the JDBC driver does not support
-     *                      this method
+     * @param columnLabel the label for the column specified with the SQL AS clause.
+     * If the SQL AS clause was not specified, then the label is the name of the
+     * column
+     * @return the column value; if the value is SQL <code>NULL</code>, the value
+     * returned is <code>null</code>
+     * @throws SQLException if the columnLabel is not valid; if a database access
+     * error occurs or this method is called on a closed result set
+     * @throws SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
      * @since 1.6
      */
+    @Override
     public String getNString(String columnLabel) throws SQLException {
         return resultSet.getNString(columnLabel);
     }
 
     /**
-     * Retrieves the value of the designated column in the current row
-     * of this <code>ResultSet</code> object as a
-     * <code>java.io.Reader</code> object.
-     * It is intended for use when
-     * accessing  <code>NCHAR</code>,<code>NVARCHAR</code>
-     * and <code>LONGNVARCHAR</code> columns.
+     * Retrieves the value of the designated column in the current row of this
+     * <code>ResultSet</code> object as a <code>java.io.Reader</code> object. It is
+     * intended for use when accessing <code>NCHAR</code>,<code>NVARCHAR</code> and
+     * <code>LONGNVARCHAR</code> columns.
      *
      * @param columnIndex the first column is 1, the second is 2, ...
-     * @return a <code>java.io.Reader</code> object that contains the column
-     *         value; if the value is SQL <code>NULL</code>, the value returned is
-     *         <code>null</code> in the Java programming language.
-     * @throws SQLException if the columnIndex is not valid;
-     *                      if a database access error occurs
-     *                      or this method is called on a closed result set
-     * @throws SQLFeatureNotSupportedException
-     *                      if the JDBC driver does not support
-     *                      this method
+     * @return a <code>java.io.Reader</code> object that contains the column value;
+     * if the value is SQL <code>NULL</code>, the value returned is
+     * <code>null</code> in the Java programming language.
+     * @throws SQLException if the columnIndex is not valid; if a database access
+     * error occurs or this method is called on a closed result set
+     * @throws SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
      * @since 1.6
      */
+    @Override
     public Reader getNCharacterStream(int columnIndex) throws SQLException {
         return resultSet.getNCharacterStream(columnIndex);
     }
 
     /**
-     * Retrieves the value of the designated column in the current row
-     * of this <code>ResultSet</code> object as a
-     * <code>java.io.Reader</code> object.
-     * It is intended for use when
-     * accessing  <code>NCHAR</code>,<code>NVARCHAR</code>
-     * and <code>LONGNVARCHAR</code> columns.
+     * Retrieves the value of the designated column in the current row of this
+     * <code>ResultSet</code> object as a <code>java.io.Reader</code> object. It is
+     * intended for use when accessing <code>NCHAR</code>,<code>NVARCHAR</code> and
+     * <code>LONGNVARCHAR</code> columns.
      *
-     * @param columnLabel the label for the column specified with the SQL AS clause.  If the SQL AS clause was not
-     *                    specified, then the label is the name of the column
-     * @return a <code>java.io.Reader</code> object that contains the column
-     *         value; if the value is SQL <code>NULL</code>, the value returned is
-     *         <code>null</code> in the Java programming language
-     * @throws SQLException if the columnLabel is not valid;
-     *                      if a database access error occurs
-     *                      or this method is called on a closed result set
-     * @throws SQLFeatureNotSupportedException
-     *                      if the JDBC driver does not support
-     *                      this method
+     * @param columnLabel the label for the column specified with the SQL AS clause.
+     * If the SQL AS clause was not specified, then the label is the name of the
+     * column
+     * @return a <code>java.io.Reader</code> object that contains the column value;
+     * if the value is SQL <code>NULL</code>, the value returned is
+     * <code>null</code> in the Java programming language
+     * @throws SQLException if the columnLabel is not valid; if a database access
+     * error occurs or this method is called on a closed result set
+     * @throws SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
      * @since 1.6
      */
+    @Override
     public Reader getNCharacterStream(String columnLabel) throws SQLException {
         return resultSet.getNCharacterStream(columnLabel);
     }
 
     /**
      * Updates the designated column with a character stream value, which will have
-     * the specified number of bytes.   The
-     * driver does the necessary conversion from Java character format to
-     * the national character set in the database.
-     * It is intended for use when
-     * updating  <code>NCHAR</code>,<code>NVARCHAR</code>
-     * and <code>LONGNVARCHAR</code> columns.
+     * the specified number of bytes. The driver does the necessary conversion from
+     * Java character format to the national character set in the database. It is
+     * intended for use when updating <code>NCHAR</code>,<code>NVARCHAR</code> and
+     * <code>LONGNVARCHAR</code> columns.
      * <p/>
-     * The updater methods are used to update column values in the
-     * current row or the insert row.  The updater methods do not
-     * update the underlying database; instead the <code>updateRow</code> or
-     * <code>insertRow</code> methods are called to update the database.
+     * The updater methods are used to update column values in the current row or
+     * the insert row. The updater methods do not update the underlying database;
+     * instead the <code>updateRow</code> or <code>insertRow</code> methods are
+     * called to update the database.
      *
      * @param columnIndex the first column is 1, the second is 2, ...
-     * @param x           the new column value
-     * @param length      the length of the stream
-     * @throws SQLException if the columnIndex is not valid;
-     *                      if a database access error occurs;
-     *                      the result set concurrency is <code>CONCUR_READ_ONLY</code> or this method is called on a closed result set
-     * @throws SQLFeatureNotSupportedException
-     *                      if the JDBC driver does not support
-     *                      this method
+     * @param x the new column value
+     * @param length the length of the stream
+     * @throws SQLException if the columnIndex is not valid; if a database access
+     * error occurs; the result set concurrency is <code>CONCUR_READ_ONLY</code> or
+     * this method is called on a closed result set
+     * @throws SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
      * @since 1.6
      */
+    @Override
     public void updateNCharacterStream(int columnIndex, Reader x, long length) throws SQLException {
         resultSet.updateNCharacterStream(columnIndex, x, length);
     }
 
     /**
      * Updates the designated column with a character stream value, which will have
-     * the specified number of bytes.  The
-     * driver does the necessary conversion from Java character format to
-     * the national character set in the database.
-     * It is intended for use when
-     * updating  <code>NCHAR</code>,<code>NVARCHAR</code>
-     * and <code>LONGNVARCHAR</code> columns.
+     * the specified number of bytes. The driver does the necessary conversion from
+     * Java character format to the national character set in the database. It is
+     * intended for use when updating <code>NCHAR</code>,<code>NVARCHAR</code> and
+     * <code>LONGNVARCHAR</code> columns.
      * <p/>
-     * The updater methods are used to update column values in the
-     * current row or the insert row.  The updater methods do not
-     * update the underlying database; instead the <code>updateRow</code> or
-     * <code>insertRow</code> methods are called to update the database.
+     * The updater methods are used to update column values in the current row or
+     * the insert row. The updater methods do not update the underlying database;
+     * instead the <code>updateRow</code> or <code>insertRow</code> methods are
+     * called to update the database.
      *
-     * @param columnLabel the label for the column specified with the SQL AS clause.  If the SQL AS clause was not
-     *                    specified, then the label is the name of the column
-     * @param reader      the <code>java.io.Reader</code> object containing
-     *                    the new column value
-     * @param length      the length of the stream
-     * @throws SQLException if the columnLabel is not valid;
-     *                      if a database access error occurs;
-     *                      the result set concurrency is <code>CONCUR_READ_ONLY</code> or this method is called on a closed result set
-     * @throws SQLFeatureNotSupportedException
-     *                      if the JDBC driver does not support
-     *                      this method
+     * @param columnLabel the label for the column specified with the SQL AS clause.
+     * If the SQL AS clause was not specified, then the label is the name of the
+     * column
+     * @param reader the <code>java.io.Reader</code> object containing the new
+     * column value
+     * @param length the length of the stream
+     * @throws SQLException if the columnLabel is not valid; if a database access
+     * error occurs; the result set concurrency is <code>CONCUR_READ_ONLY</code> or
+     * this method is called on a closed result set
+     * @throws SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
      * @since 1.6
      */
+    @Override
     public void updateNCharacterStream(String columnLabel, Reader reader, long length) throws SQLException {
         resultSet.updateNCharacterStream(columnLabel, reader, length);
     }
 
     /**
-     * Updates the designated column with an ascii stream value, which will have
-     * the specified number of bytes.
+     * Updates the designated column with an ascii stream value, which will have the
+     * specified number of bytes.
      * <p/>
-     * The updater methods are used to update column values in the
-     * current row or the insert row.  The updater methods do not
-     * update the underlying database; instead the <code>updateRow</code> or
-     * <code>insertRow</code> methods are called to update the database.
+     * The updater methods are used to update column values in the current row or
+     * the insert row. The updater methods do not update the underlying database;
+     * instead the <code>updateRow</code> or <code>insertRow</code> methods are
+     * called to update the database.
      *
      * @param columnIndex the first column is 1, the second is 2, ...
-     * @param x           the new column value
-     * @param length      the length of the stream
-     * @throws SQLException if the columnIndex is not valid;
-     *                      if a database access error occurs;
-     *                      the result set concurrency is <code>CONCUR_READ_ONLY</code>
-     *                      or this method is called on a closed result set
-     * @throws SQLFeatureNotSupportedException
-     *                      if the JDBC driver does not support
-     *                      this method
+     * @param x the new column value
+     * @param length the length of the stream
+     * @throws SQLException if the columnIndex is not valid; if a database access
+     * error occurs; the result set concurrency is <code>CONCUR_READ_ONLY</code> or
+     * this method is called on a closed result set
+     * @throws SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
      * @since 1.6
      */
+    @Override
     public void updateAsciiStream(int columnIndex, InputStream x, long length) throws SQLException {
         resultSet.updateAsciiStream(columnIndex, x, length);
     }
 
     /**
-     * Updates the designated column with a binary stream value, which will have
-     * the specified number of bytes.
+     * Updates the designated column with a binary stream value, which will have the
+     * specified number of bytes.
      * <p/>
-     * The updater methods are used to update column values in the
-     * current row or the insert row.  The updater methods do not
-     * update the underlying database; instead the <code>updateRow</code> or
-     * <code>insertRow</code> methods are called to update the database.
+     * The updater methods are used to update column values in the current row or
+     * the insert row. The updater methods do not update the underlying database;
+     * instead the <code>updateRow</code> or <code>insertRow</code> methods are
+     * called to update the database.
      *
      * @param columnIndex the first column is 1, the second is 2, ...
-     * @param x           the new column value
-     * @param length      the length of the stream
-     * @throws SQLException if the columnIndex is not valid;
-     *                      if a database access error occurs;
-     *                      the result set concurrency is <code>CONCUR_READ_ONLY</code>
-     *                      or this method is called on a closed result set
-     * @throws SQLFeatureNotSupportedException
-     *                      if the JDBC driver does not support
-     *                      this method
+     * @param x the new column value
+     * @param length the length of the stream
+     * @throws SQLException if the columnIndex is not valid; if a database access
+     * error occurs; the result set concurrency is <code>CONCUR_READ_ONLY</code> or
+     * this method is called on a closed result set
+     * @throws SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
      * @since 1.6
      */
+    @Override
     public void updateBinaryStream(int columnIndex, InputStream x, long length) throws SQLException {
         resultSet.updateBinaryStream(columnIndex, x, length);
     }
@@ -639,75 +631,74 @@
      * Updates the designated column with a character stream value, which will have
      * the specified number of bytes.
      * <p/>
-     * The updater methods are used to update column values in the
-     * current row or the insert row.  The updater methods do not
-     * update the underlying database; instead the <code>updateRow</code> or
-     * <code>insertRow</code> methods are called to update the database.
+     * The updater methods are used to update column values in the current row or
+     * the insert row. The updater methods do not update the underlying database;
+     * instead the <code>updateRow</code> or <code>insertRow</code> methods are
+     * called to update the database.
      *
      * @param columnIndex the first column is 1, the second is 2, ...
-     * @param x           the new column value
-     * @param length      the length of the stream
-     * @throws SQLException if the columnIndex is not valid;
-     *                      if a database access error occurs;
-     *                      the result set concurrency is <code>CONCUR_READ_ONLY</code>
-     *                      or this method is called on a closed result set
-     * @throws SQLFeatureNotSupportedException
-     *                      if the JDBC driver does not support
-     *                      this method
+     * @param x the new column value
+     * @param length the length of the stream
+     * @throws SQLException if the columnIndex is not valid; if a database access
+     * error occurs; the result set concurrency is <code>CONCUR_READ_ONLY</code> or
+     * this method is called on a closed result set
+     * @throws SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
      * @since 1.6
      */
+    @Override
     public void updateCharacterStream(int columnIndex, Reader x, long length) throws SQLException {
         resultSet.updateCharacterStream(columnIndex, x, length);
     }
 
     /**
-     * Updates the designated column with an ascii stream value, which will have
-     * the specified number of bytes.
+     * Updates the designated column with an ascii stream value, which will have the
+     * specified number of bytes.
      * <p/>
-     * The updater methods are used to update column values in the
-     * current row or the insert row.  The updater methods do not
-     * update the underlying database; instead the <code>updateRow</code> or
-     * <code>insertRow</code> methods are called to update the database.
+     * The updater methods are used to update column values in the current row or
+     * the insert row. The updater methods do not update the underlying database;
+     * instead the <code>updateRow</code> or <code>insertRow</code> methods are
+     * called to update the database.
      *
-     * @param columnLabel the label for the column specified with the SQL AS clause.  If the SQL AS clause was not
-     *                    specified, then the label is the name of the column
-     * @param x           the new column value
-     * @param length      the length of the stream
-     * @throws SQLException if the columnLabel is not valid;
-     *                      if a database access error occurs;
-     *                      the result set concurrency is <code>CONCUR_READ_ONLY</code>
-     *                      or this method is called on a closed result set
-     * @throws SQLFeatureNotSupportedException
-     *                      if the JDBC driver does not support
-     *                      this method
+     * @param columnLabel the label for the column specified with the SQL AS clause.
+     * If the SQL AS clause was not specified, then the label is the name of the
+     * column
+     * @param x the new column value
+     * @param length the length of the stream
+     * @throws SQLException if the columnLabel is not valid; if a database access
+     * error occurs; the result set concurrency is <code>CONCUR_READ_ONLY</code> or
+     * this method is called on a closed result set
+     * @throws SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
      * @since 1.6
      */
+    @Override
     public void updateAsciiStream(String columnLabel, InputStream x, long length) throws SQLException {
         resultSet.updateAsciiStream(columnLabel, x, length);
     }
 
     /**
-     * Updates the designated column with a binary stream value, which will have
-     * the specified number of bytes.
+     * Updates the designated column with a binary stream value, which will have the
+     * specified number of bytes.
      * <p/>
-     * The updater methods are used to update column values in the
-     * current row or the insert row.  The updater methods do not
-     * update the underlying database; instead the <code>updateRow</code> or
-     * <code>insertRow</code> methods are called to update the database.
+     * The updater methods are used to update column values in the current row or
+     * the insert row. The updater methods do not update the underlying database;
+     * instead the <code>updateRow</code> or <code>insertRow</code> methods are
+     * called to update the database.
      *
-     * @param columnLabel the label for the column specified with the SQL AS clause.  If the SQL AS clause was not
-     *                    specified, then the label is the name of the column
-     * @param x           the new column value
-     * @param length      the length of the stream
-     * @throws SQLException if the columnLabel is not valid;
-     *                      if a database access error occurs;
-     *                      the result set concurrency is <code>CONCUR_READ_ONLY</code>
-     *                      or this method is called on a closed result set
-     * @throws SQLFeatureNotSupportedException
-     *                      if the JDBC driver does not support
-     *                      this method
+     * @param columnLabel the label for the column specified with the SQL AS clause.
+     * If the SQL AS clause was not specified, then the label is the name of the
+     * column
+     * @param x the new column value
+     * @param length the length of the stream
+     * @throws SQLException if the columnLabel is not valid; if a database access
+     * error occurs; the result set concurrency is <code>CONCUR_READ_ONLY</code> or
+     * this method is called on a closed result set
+     * @throws SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
      * @since 1.6
      */
+    @Override
     public void updateBinaryStream(String columnLabel, InputStream x, long length) throws SQLException {
         resultSet.updateBinaryStream(columnLabel, x, length);
     }
@@ -716,572 +707,565 @@
      * Updates the designated column with a character stream value, which will have
      * the specified number of bytes.
      * <p/>
-     * The updater methods are used to update column values in the
-     * current row or the insert row.  The updater methods do not
-     * update the underlying database; instead the <code>updateRow</code> or
-     * <code>insertRow</code> methods are called to update the database.
+     * The updater methods are used to update column values in the current row or
+     * the insert row. The updater methods do not update the underlying database;
+     * instead the <code>updateRow</code> or <code>insertRow</code> methods are
+     * called to update the database.
      *
-     * @param columnLabel the label for the column specified with the SQL AS clause.  If the SQL AS clause was not
-     *                    specified, then the label is the name of the column
-     * @param reader      the <code>java.io.Reader</code> object containing
-     *                    the new column value
-     * @param length      the length of the stream
-     * @throws SQLException if the columnLabel is not valid;
-     *                      if a database access error occurs;
-     *                      the result set concurrency is <code>CONCUR_READ_ONLY</code>
-     *                      or this method is called on a closed result set
-     * @throws SQLFeatureNotSupportedException
-     *                      if the JDBC driver does not support
-     *                      this method
+     * @param columnLabel the label for the column specified with the SQL AS clause.
+     * If the SQL AS clause was not specified, then the label is the name of the
+     * column
+     * @param reader the <code>java.io.Reader</code> object containing the new
+     * column value
+     * @param length the length of the stream
+     * @throws SQLException if the columnLabel is not valid; if a database access
+     * error occurs; the result set concurrency is <code>CONCUR_READ_ONLY</code> or
+     * this method is called on a closed result set
+     * @throws SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
      * @since 1.6
      */
+    @Override
     public void updateCharacterStream(String columnLabel, Reader reader, long length) throws SQLException {
         resultSet.updateCharacterStream(columnLabel, reader, length);
     }
 
     /**
-     * Updates the designated column using the given input stream, which
-     * will have the specified number of bytes.
+     * Updates the designated column using the given input stream, which will have
+     * the specified number of bytes.
      * <p/>
      * <p/>
-     * The updater methods are used to update column values in the
-     * current row or the insert row.  The updater methods do not
-     * update the underlying database; instead the <code>updateRow</code> or
-     * <code>insertRow</code> methods are called to update the database.
+     * The updater methods are used to update column values in the current row or
+     * the insert row. The updater methods do not update the underlying database;
+     * instead the <code>updateRow</code> or <code>insertRow</code> methods are
+     * called to update the database.
      *
      * @param columnIndex the first column is 1, the second is 2, ...
      * @param inputStream An object that contains the data to set the parameter
-     *                    value to.
-     * @param length      the number of bytes in the parameter data.
-     * @throws SQLException if the columnIndex is not valid;
-     *                      if a database access error occurs;
-     *                      the result set concurrency is <code>CONCUR_READ_ONLY</code>
-     *                      or this method is called on a closed result set
-     * @throws SQLFeatureNotSupportedException
-     *                      if the JDBC driver does not support
-     *                      this method
+     * value to.
+     * @param length the number of bytes in the parameter data.
+     * @throws SQLException if the columnIndex is not valid; if a database access
+     * error occurs; the result set concurrency is <code>CONCUR_READ_ONLY</code> or
+     * this method is called on a closed result set
+     * @throws SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
      * @since 1.6
      */
+    @Override
     public void updateBlob(int columnIndex, InputStream inputStream, long length) throws SQLException {
         resultSet.updateBlob(columnIndex, inputStream, length);
     }
 
     /**
-     * Updates the designated column using the given input stream, which
-     * will have the specified number of bytes.
+     * Updates the designated column using the given input stream, which will have
+     * the specified number of bytes.
      * <p/>
      * <p/>
-     * The updater methods are used to update column values in the
-     * current row or the insert row.  The updater methods do not
-     * update the underlying database; instead the <code>updateRow</code> or
-     * <code>insertRow</code> methods are called to update the database.
+     * The updater methods are used to update column values in the current row or
+     * the insert row. The updater methods do not update the underlying database;
+     * instead the <code>updateRow</code> or <code>insertRow</code> methods are
+     * called to update the database.
      *
-     * @param columnLabel the label for the column specified with the SQL AS clause.  If the SQL AS clause was not
-     *                    specified, then the label is the name of the column
+     * @param columnLabel the label for the column specified with the SQL AS clause.
+     * If the SQL AS clause was not specified, then the label is the name of the
+     * column
      * @param inputStream An object that contains the data to set the parameter
-     *                    value to.
-     * @param length      the number of bytes in the parameter data.
-     * @throws SQLException if the columnLabel is not valid;
-     *                      if a database access error occurs;
-     *                      the result set concurrency is <code>CONCUR_READ_ONLY</code>
-     *                      or this method is called on a closed result set
-     * @throws SQLFeatureNotSupportedException
-     *                      if the JDBC driver does not support
-     *                      this method
+     * value to.
+     * @param length the number of bytes in the parameter data.
+     * @throws SQLException if the columnLabel is not valid; if a database access
+     * error occurs; the result set concurrency is <code>CONCUR_READ_ONLY</code> or
+     * this method is called on a closed result set
+     * @throws SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
      * @since 1.6
      */
+    @Override
     public void updateBlob(String columnLabel, InputStream inputStream, long length) throws SQLException {
         resultSet.updateBlob(columnLabel, inputStream, length);
     }
 
     /**
-     * Updates the designated column using the given <code>Reader</code>
-     * object, which is the given number of characters long.
-     * When a very large UNICODE value is input to a <code>LONGVARCHAR</code>
-     * parameter, it may be more practical to send it via a
-     * <code>java.io.Reader</code> object. The JDBC driver will
-     * do any necessary conversion from UNICODE to the database char format.
+     * Updates the designated column using the given <code>Reader</code> object,
+     * which is the given number of characters long. When a very large UNICODE value
+     * is input to a <code>LONGVARCHAR</code> parameter, it may be more practical to
+     * send it via a <code>java.io.Reader</code> object. The JDBC driver will do any
+     * necessary conversion from UNICODE to the database char format.
      * <p/>
      * <p/>
-     * The updater methods are used to update column values in the
-     * current row or the insert row.  The updater methods do not
-     * update the underlying database; instead the <code>updateRow</code> or
-     * <code>insertRow</code> methods are called to update the database.
+     * The updater methods are used to update column values in the current row or
+     * the insert row. The updater methods do not update the underlying database;
+     * instead the <code>updateRow</code> or <code>insertRow</code> methods are
+     * called to update the database.
      *
      * @param columnIndex the first column is 1, the second is 2, ...
-     * @param reader      An object that contains the data to set the parameter value to.
-     * @param length      the number of characters in the parameter data.
-     * @throws SQLException if the columnIndex is not valid;
-     *                      if a database access error occurs;
-     *                      the result set concurrency is <code>CONCUR_READ_ONLY</code>
-     *                      or this method is called on a closed result set
-     * @throws SQLFeatureNotSupportedException
-     *                      if the JDBC driver does not support
-     *                      this method
+     * @param reader An object that contains the data to set the parameter value to.
+     * @param length the number of characters in the parameter data.
+     * @throws SQLException if the columnIndex is not valid; if a database access
+     * error occurs; the result set concurrency is <code>CONCUR_READ_ONLY</code> or
+     * this method is called on a closed result set
+     * @throws SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
      * @since 1.6
      */
+    @Override
     public void updateClob(int columnIndex, Reader reader, long length) throws SQLException {
         resultSet.updateClob(columnIndex, reader, length);
     }
 
     /**
-     * Updates the designated column using the given <code>Reader</code>
-     * object, which is the given number of characters long.
-     * When a very large UNICODE value is input to a <code>LONGVARCHAR</code>
-     * parameter, it may be more practical to send it via a
-     * <code>java.io.Reader</code> object.  The JDBC driver will
-     * do any necessary conversion from UNICODE to the database char format.
+     * Updates the designated column using the given <code>Reader</code> object,
+     * which is the given number of characters long. When a very large UNICODE value
+     * is input to a <code>LONGVARCHAR</code> parameter, it may be more practical to
+     * send it via a <code>java.io.Reader</code> object. The JDBC driver will do any
+     * necessary conversion from UNICODE to the database char format.
      * <p/>
      * <p/>
-     * The updater methods are used to update column values in the
-     * current row or the insert row.  The updater methods do not
-     * update the underlying database; instead the <code>updateRow</code> or
-     * <code>insertRow</code> methods are called to update the database.
+     * The updater methods are used to update column values in the current row or
+     * the insert row. The updater methods do not update the underlying database;
+     * instead the <code>updateRow</code> or <code>insertRow</code> methods are
+     * called to update the database.
      *
-     * @param columnLabel the label for the column specified with the SQL AS clause.  If the SQL AS clause was
-     *                    not specified, then the label is the name of the column
-     * @param reader      An object that contains the data to set the parameter value to.
-     * @param length      the number of characters in the parameter data.
-     * @throws SQLException if the columnLabel is not valid;
-     *                      if a database access error occurs;
-     *                      the result set concurrency is <code>CONCUR_READ_ONLY</code>
-     *                      or this method is called on a closed result set
-     * @throws SQLFeatureNotSupportedException
-     *                      if the JDBC driver does not support
-     *                      this method
+     * @param columnLabel the label for the column specified with the SQL AS clause.
+     * If the SQL AS clause was not specified, then the label is the name of the
+     * column
+     * @param reader An object that contains the data to set the parameter value to.
+     * @param length the number of characters in the parameter data.
+     * @throws SQLException if the columnLabel is not valid; if a database access
+     * error occurs; the result set concurrency is <code>CONCUR_READ_ONLY</code> or
+     * this method is called on a closed result set
+     * @throws SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
      * @since 1.6
      */
+    @Override
     public void updateClob(String columnLabel, Reader reader, long length) throws SQLException {
         resultSet.updateClob(columnLabel, reader, length);
     }
 
     /**
-     * Updates the designated column using the given <code>Reader</code>
-     * object, which is the given number of characters long.
-     * When a very large UNICODE value is input to a <code>LONGVARCHAR</code>
-     * parameter, it may be more practical to send it via a
-     * <code>java.io.Reader</code> object. The JDBC driver will
-     * do any necessary conversion from UNICODE to the database char format.
+     * Updates the designated column using the given <code>Reader</code> object,
+     * which is the given number of characters long. When a very large UNICODE value
+     * is input to a <code>LONGVARCHAR</code> parameter, it may be more practical to
+     * send it via a <code>java.io.Reader</code> object. The JDBC driver will do any
+     * necessary conversion from UNICODE to the database char format.
      * <p/>
      * <p/>
-     * The updater methods are used to update column values in the
-     * current row or the insert row.  The updater methods do not
-     * update the underlying database; instead the <code>updateRow</code> or
-     * <code>insertRow</code> methods are called to update the database.
+     * The updater methods are used to update column values in the current row or
+     * the insert row. The updater methods do not update the underlying database;
+     * instead the <code>updateRow</code> or <code>insertRow</code> methods are
+     * called to update the database.
      *
      * @param columnIndex the first column is 1, the second 2, ...
-     * @param reader      An object that contains the data to set the parameter value to.
-     * @param length      the number of characters in the parameter data.
-     * @throws SQLException if the columnIndex is not valid;
-     *                      if the driver does not support national
-     *                      character sets;  if the driver can detect that a data conversion
-     *                      error could occur; this method is called on a closed result set,
-     *                      if a database access error occurs or
-     *                      the result set concurrency is <code>CONCUR_READ_ONLY</code>
-     * @throws SQLFeatureNotSupportedException
-     *                      if the JDBC driver does not support
-     *                      this method
+     * @param reader An object that contains the data to set the parameter value to.
+     * @param length the number of characters in the parameter data.
+     * @throws SQLException if the columnIndex is not valid; if the driver does not
+     * support national character sets; if the driver can detect that a data
+     * conversion error could occur; this method is called on a closed result set,
+     * if a database access error occurs or the result set concurrency is
+     * <code>CONCUR_READ_ONLY</code>
+     * @throws SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
      * @since 1.6
      */
+    @Override
     public void updateNClob(int columnIndex, Reader reader, long length) throws SQLException {
         resultSet.updateNClob(columnIndex, reader, length);
     }
 
     /**
-     * Updates the designated column using the given <code>Reader</code>
-     * object, which is the given number of characters long.
-     * When a very large UNICODE value is input to a <code>LONGVARCHAR</code>
-     * parameter, it may be more practical to send it via a
-     * <code>java.io.Reader</code> object. The JDBC driver will
-     * do any necessary conversion from UNICODE to the database char format.
+     * Updates the designated column using the given <code>Reader</code> object,
+     * which is the given number of characters long. When a very large UNICODE value
+     * is input to a <code>LONGVARCHAR</code> parameter, it may be more practical to
+     * send it via a <code>java.io.Reader</code> object. The JDBC driver will do any
+     * necessary conversion from UNICODE to the database char format.
      * <p/>
      * <p/>
-     * The updater methods are used to update column values in the
-     * current row or the insert row.  The updater methods do not
-     * update the underlying database; instead the <code>updateRow</code> or
-     * <code>insertRow</code> methods are called to update the database.
+     * The updater methods are used to update column values in the current row or
+     * the insert row. The updater methods do not update the underlying database;
+     * instead the <code>updateRow</code> or <code>insertRow</code> methods are
+     * called to update the database.
      *
-     * @param columnLabel the label for the column specified with the SQL AS clause.  If the SQL AS clause was not
-     *                    specified, then the label is the name of the column
-     * @param reader      An object that contains the data to set the parameter value to.
-     * @param length      the number of characters in the parameter data.
-     * @throws SQLException if the columnLabel is not valid;
-     *                      if the driver does not support national
-     *                      character sets;  if the driver can detect that a data conversion
-     *                      error could occur; this method is called on a closed result set;
-     *                      if a database access error occurs or
-     *                      the result set concurrency is <code>CONCUR_READ_ONLY</code>
-     * @throws SQLFeatureNotSupportedException
-     *                      if the JDBC driver does not support
-     *                      this method
+     * @param columnLabel the label for the column specified with the SQL AS clause.
+     * If the SQL AS clause was not specified, then the label is the name of the
+     * column
+     * @param reader An object that contains the data to set the parameter value to.
+     * @param length the number of characters in the parameter data.
+     * @throws SQLException if the columnLabel is not valid; if the driver does not
+     * support national character sets; if the driver can detect that a data
+     * conversion error could occur; this method is called on a closed result set;
+     * if a database access error occurs or the result set concurrency is
+     * <code>CONCUR_READ_ONLY</code>
+     * @throws SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
      * @since 1.6
      */
+    @Override
     public void updateNClob(String columnLabel, Reader reader, long length) throws SQLException {
         resultSet.updateNClob(columnLabel, reader, length);
     }
 
     /**
-     * Updates the designated column with a character stream value.
-     * The data will be read from the stream
-     * as needed until end-of-stream is reached.  The
-     * driver does the necessary conversion from Java character format to
-     * the national character set in the database.
-     * It is intended for use when
-     * updating  <code>NCHAR</code>,<code>NVARCHAR</code>
-     * and <code>LONGNVARCHAR</code> columns.
+     * Updates the designated column with a character stream value. The data will be
+     * read from the stream as needed until end-of-stream is reached. The driver
+     * does the necessary conversion from Java character format to the national
+     * character set in the database. It is intended for use when updating
+     * <code>NCHAR</code>,<code>NVARCHAR</code> and <code>LONGNVARCHAR</code>
+     * columns.
      * <p/>
-     * The updater methods are used to update column values in the
-     * current row or the insert row.  The updater methods do not
-     * update the underlying database; instead the <code>updateRow</code> or
-     * <code>insertRow</code> methods are called to update the database.
+     * The updater methods are used to update column values in the current row or
+     * the insert row. The updater methods do not update the underlying database;
+     * instead the <code>updateRow</code> or <code>insertRow</code> methods are
+     * called to update the database.
      * <p/>
-     * <P><B>Note:</B> Consult your JDBC driver documentation to determine if
-     * it might be more efficient to use a version of
-     * <code>updateNCharacterStream</code> which takes a length parameter.
+     * <P>
+     * <B>Note:</B> Consult your JDBC driver documentation to determine if it might
+     * be more efficient to use a version of <code>updateNCharacterStream</code>
+     * which takes a length parameter.
      *
      * @param columnIndex the first column is 1, the second is 2, ...
-     * @param x           the new column value
-     * @throws SQLException if the columnIndex is not valid;
-     *                      if a database access error occurs;
-     *                      the result set concurrency is <code>CONCUR_READ_ONLY</code> or this method is called on a closed result set
-     * @throws SQLFeatureNotSupportedException
-     *                      if the JDBC driver does not support
-     *                      this method
+     * @param x the new column value
+     * @throws SQLException if the columnIndex is not valid; if a database access
+     * error occurs; the result set concurrency is <code>CONCUR_READ_ONLY</code> or
+     * this method is called on a closed result set
+     * @throws SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
      * @since 1.6
      */
+    @Override
     public void updateNCharacterStream(int columnIndex, Reader x) throws SQLException {
         resultSet.updateNCharacterStream(columnIndex, x);
     }
 
     /**
-     * Updates the designated column with a character stream value.
-     * The data will be read from the stream
-     * as needed until end-of-stream is reached.  The
-     * driver does the necessary conversion from Java character format to
-     * the national character set in the database.
-     * It is intended for use when
-     * updating  <code>NCHAR</code>,<code>NVARCHAR</code>
-     * and <code>LONGNVARCHAR</code> columns.
+     * Updates the designated column with a character stream value. The data will be
+     * read from the stream as needed until end-of-stream is reached. The driver
+     * does the necessary conversion from Java character format to the national
+     * character set in the database. It is intended for use when updating
+     * <code>NCHAR</code>,<code>NVARCHAR</code> and <code>LONGNVARCHAR</code>
+     * columns.
      * <p/>
-     * The updater methods are used to update column values in the
-     * current row or the insert row.  The updater methods do not
-     * update the underlying database; instead the <code>updateRow</code> or
-     * <code>insertRow</code> methods are called to update the database.
+     * The updater methods are used to update column values in the current row or
+     * the insert row. The updater methods do not update the underlying database;
+     * instead the <code>updateRow</code> or <code>insertRow</code> methods are
+     * called to update the database.
      * <p/>
-     * <P><B>Note:</B> Consult your JDBC driver documentation to determine if
-     * it might be more efficient to use a version of
-     * <code>updateNCharacterStream</code> which takes a length parameter.
+     * <P>
+     * <B>Note:</B> Consult your JDBC driver documentation to determine if it might
+     * be more efficient to use a version of <code>updateNCharacterStream</code>
+     * which takes a length parameter.
      *
-     * @param columnLabel the label for the column specified with the SQL AS clause.  If the SQL AS clause was not
-     *                    specified, then the label is the name of the column
-     * @param reader      the <code>java.io.Reader</code> object containing
-     *                    the new column value
-     * @throws SQLException if the columnLabel is not valid;
-     *                      if a database access error occurs;
-     *                      the result set concurrency is <code>CONCUR_READ_ONLY</code> or this method is called on a closed result set
-     * @throws SQLFeatureNotSupportedException
-     *                      if the JDBC driver does not support
-     *                      this method
+     * @param columnLabel the label for the column specified with the SQL AS clause.
+     * If the SQL AS clause was not specified, then the label is the name of the
+     * column
+     * @param reader the <code>java.io.Reader</code> object containing the new
+     * column value
+     * @throws SQLException if the columnLabel is not valid; if a database access
+     * error occurs; the result set concurrency is <code>CONCUR_READ_ONLY</code> or
+     * this method is called on a closed result set
+     * @throws SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
      * @since 1.6
      */
+    @Override
     public void updateNCharacterStream(String columnLabel, Reader reader) throws SQLException {
         resultSet.updateNCharacterStream(columnLabel, reader);
     }
 
     /**
-     * Updates the designated column with an ascii stream value.
-     * The data will be read from the stream
-     * as needed until end-of-stream is reached.
+     * Updates the designated column with an ascii stream value. The data will be
+     * read from the stream as needed until end-of-stream is reached.
      * <p/>
-     * The updater methods are used to update column values in the
-     * current row or the insert row.  The updater methods do not
-     * update the underlying database; instead the <code>updateRow</code> or
-     * <code>insertRow</code> methods are called to update the database.
+     * The updater methods are used to update column values in the current row or
+     * the insert row. The updater methods do not update the underlying database;
+     * instead the <code>updateRow</code> or <code>insertRow</code> methods are
+     * called to update the database.
      * <p/>
-     * <P><B>Note:</B> Consult your JDBC driver documentation to determine if
-     * it might be more efficient to use a version of
-     * <code>updateAsciiStream</code> which takes a length parameter.
+     * <P>
+     * <B>Note:</B> Consult your JDBC driver documentation to determine if it might
+     * be more efficient to use a version of <code>updateAsciiStream</code> which
+     * takes a length parameter.
      *
      * @param columnIndex the first column is 1, the second is 2, ...
-     * @param x           the new column value
-     * @throws SQLException if the columnIndex is not valid;
-     *                      if a database access error occurs;
-     *                      the result set concurrency is <code>CONCUR_READ_ONLY</code>
-     *                      or this method is called on a closed result set
-     * @throws SQLFeatureNotSupportedException
-     *                      if the JDBC driver does not support
-     *                      this method
+     * @param x the new column value
+     * @throws SQLException if the columnIndex is not valid; if a database access
+     * error occurs; the result set concurrency is <code>CONCUR_READ_ONLY</code> or
+     * this method is called on a closed result set
+     * @throws SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
      * @since 1.6
      */
+    @Override
     public void updateAsciiStream(int columnIndex, InputStream x) throws SQLException {
         resultSet.updateAsciiStream(columnIndex, x);
     }
 
     /**
-     * Updates the designated column with a binary stream value.
-     * The data will be read from the stream
-     * as needed until end-of-stream is reached.
+     * Updates the designated column with a binary stream value. The data will be
+     * read from the stream as needed until end-of-stream is reached.
      * <p/>
-     * The updater methods are used to update column values in the
-     * current row or the insert row.  The updater methods do not
-     * update the underlying database; instead the <code>updateRow</code> or
-     * <code>insertRow</code> methods are called to update the database.
+     * The updater methods are used to update column values in the current row or
+     * the insert row. The updater methods do not update the underlying database;
+     * instead the <code>updateRow</code> or <code>insertRow</code> methods are
+     * called to update the database.
      * <p/>
-     * <P><B>Note:</B> Consult your JDBC driver documentation to determine if
-     * it might be more efficient to use a version of
-     * <code>updateBinaryStream</code> which takes a length parameter.
+     * <P>
+     * <B>Note:</B> Consult your JDBC driver documentation to determine if it might
+     * be more efficient to use a version of <code>updateBinaryStream</code> which
+     * takes a length parameter.
      *
      * @param columnIndex the first column is 1, the second is 2, ...
-     * @param x           the new column value
-     * @throws SQLException if the columnIndex is not valid;
-     *                      if a database access error occurs;
-     *                      the result set concurrency is <code>CONCUR_READ_ONLY</code>
-     *                      or this method is called on a closed result set
-     * @throws SQLFeatureNotSupportedException
-     *                      if the JDBC driver does not support
-     *                      this method
+     * @param x the new column value
+     * @throws SQLException if the columnIndex is not valid; if a database access
+     * error occurs; the result set concurrency is <code>CONCUR_READ_ONLY</code> or
+     * this method is called on a closed result set
+     * @throws SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
      * @since 1.6
      */
+    @Override
     public void updateBinaryStream(int columnIndex, InputStream x) throws SQLException {
         resultSet.updateBinaryStream(columnIndex, x);
     }
 
     /**
-     * Updates the designated column with a character stream value.
-     * The data will be read from the stream
-     * as needed until end-of-stream is reached.
+     * Updates the designated column with a character stream value. The data will be
+     * read from the stream as needed until end-of-stream is reached.
      * <p/>
-     * The updater methods are used to update column values in the
-     * current row or the insert row.  The updater methods do not
-     * update the underlying database; instead the <code>updateRow</code> or
-     * <code>insertRow</code> methods are called to update the database.
+     * The updater methods are used to update column values in the current row or
+     * the insert row. The updater methods do not update the underlying database;
+     * instead the <code>updateRow</code> or <code>insertRow</code> methods are
+     * called to update the database.
      * <p/>
-     * <P><B>Note:</B> Consult your JDBC driver documentation to determine if
-     * it might be more efficient to use a version of
-     * <code>updateCharacterStream</code> which takes a length parameter.
+     * <P>
+     * <B>Note:</B> Consult your JDBC driver documentation to determine if it might
+     * be more efficient to use a version of <code>updateCharacterStream</code>
+     * which takes a length parameter.
      *
      * @param columnIndex the first column is 1, the second is 2, ...
-     * @param x           the new column value
-     * @throws SQLException if the columnIndex is not valid;
-     *                      if a database access error occurs;
-     *                      the result set concurrency is <code>CONCUR_READ_ONLY</code>
-     *                      or this method is called on a closed result set
-     * @throws SQLFeatureNotSupportedException
-     *                      if the JDBC driver does not support
-     *                      this method
+     * @param x the new column value
+     * @throws SQLException if the columnIndex is not valid; if a database access
+     * error occurs; the result set concurrency is <code>CONCUR_READ_ONLY</code> or
+     * this method is called on a closed result set
+     * @throws SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
      * @since 1.6
      */
+    @Override
     public void updateCharacterStream(int columnIndex, Reader x) throws SQLException {
         resultSet.updateCharacterStream(columnIndex, x);
     }
 
     /**
-     * Updates the designated column with an ascii stream value.
-     * The data will be read from the stream
-     * as needed until end-of-stream is reached.
+     * Updates the designated column with an ascii stream value. The data will be
+     * read from the stream as needed until end-of-stream is reached.
      * <p/>
-     * The updater methods are used to update column values in the
-     * current row or the insert row.  The updater methods do not
-     * update the underlying database; instead the <code>updateRow</code> or
-     * <code>insertRow</code> methods are called to update the database.
+     * The updater methods are used to update column values in the current row or
+     * the insert row. The updater methods do not update the underlying database;
+     * instead the <code>updateRow</code> or <code>insertRow</code> methods are
+     * called to update the database.
      * <p/>
-     * <P><B>Note:</B> Consult your JDBC driver documentation to determine if
-     * it might be more efficient to use a version of
-     * <code>updateAsciiStream</code> which takes a length parameter.
+     * <P>
+     * <B>Note:</B> Consult your JDBC driver documentation to determine if it might
+     * be more efficient to use a version of <code>updateAsciiStream</code> which
+     * takes a length parameter.
      *
-     * @param columnLabel the label for the column specified with the SQL AS clause.  If the SQL AS clause was not
-     *                    specified, then the label is the name of the column
-     * @param x           the new column value
-     * @throws SQLException if the columnLabel is not valid;
-     *                      if a database access error occurs;
-     *                      the result set concurrency is <code>CONCUR_READ_ONLY</code>
-     *                      or this method is called on a closed result set
-     * @throws SQLFeatureNotSupportedException
-     *                      if the JDBC driver does not support
-     *                      this method
+     * @param columnLabel the label for the column specified with the SQL AS clause.
+     * If the SQL AS clause was not specified, then the label is the name of the
+     * column
+     * @param x the new column value
+     * @throws SQLException if the columnLabel is not valid; if a database access
+     * error occurs; the result set concurrency is <code>CONCUR_READ_ONLY</code> or
+     * this method is called on a closed result set
+     * @throws SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
      * @since 1.6
      */
+    @Override
     public void updateAsciiStream(String columnLabel, InputStream x) throws SQLException {
         resultSet.updateAsciiStream(columnLabel, x);
     }
 
     /**
-     * Updates the designated column with a binary stream value.
-     * The data will be read from the stream
-     * as needed until end-of-stream is reached.
+     * Updates the designated column with a binary stream value. The data will be
+     * read from the stream as needed until end-of-stream is reached.
      * <p/>
-     * The updater methods are used to update column values in the
-     * current row or the insert row.  The updater methods do not
-     * update the underlying database; instead the <code>updateRow</code> or
-     * <code>insertRow</code> methods are called to update the database.
+     * The updater methods are used to update column values in the current row or
+     * the insert row. The updater methods do not update the underlying database;
+     * instead the <code>updateRow</code> or <code>insertRow</code> methods are
+     * called to update the database.
      * <p/>
-     * <P><B>Note:</B> Consult your JDBC driver documentation to determine if
-     * it might be more efficient to use a version of
-     * <code>updateBinaryStream</code> which takes a length parameter.
+     * <P>
+     * <B>Note:</B> Consult your JDBC driver documentation to determine if it might
+     * be more efficient to use a version of <code>updateBinaryStream</code> which
+     * takes a length parameter.
      *
-     * @param columnLabel the label for the column specified with the SQL AS clause.  If the SQL AS clause was not
-     *                    specified, then the label is the name of the column
-     * @param x           the new column value
-     * @throws SQLException if the columnLabel is not valid;
-     *                      if a database access error occurs;
-     *                      the result set concurrency is <code>CONCUR_READ_ONLY</code>
-     *                      or this method is called on a closed result set
-     * @throws SQLFeatureNotSupportedException
-     *                      if the JDBC driver does not support
-     *                      this method
+     * @param columnLabel the label for the column specified with the SQL AS clause.
+     * If the SQL AS clause was not specified, then the label is the name of the
+     * column
+     * @param x the new column value
+     * @throws SQLException if the columnLabel is not valid; if a database access
+     * error occurs; the result set concurrency is <code>CONCUR_READ_ONLY</code> or
+     * this method is called on a closed result set
+     * @throws SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
      * @since 1.6
      */
+    @Override
     public void updateBinaryStream(String columnLabel, InputStream x) throws SQLException {
         resultSet.updateBinaryStream(columnLabel, x);
     }
 
     /**
-     * Updates the designated column with a character stream value.
-     * The data will be read from the stream
-     * as needed until end-of-stream is reached.
+     * Updates the designated column with a character stream value. The data will be
+     * read from the stream as needed until end-of-stream is reached.
      * <p/>
-     * The updater methods are used to update column values in the
-     * current row or the insert row.  The updater methods do not
-     * update the underlying database; instead the <code>updateRow</code> or
-     * <code>insertRow</code> methods are called to update the database.
+     * The updater methods are used to update column values in the current row or
+     * the insert row. The updater methods do not update the underlying database;
+     * instead the <code>updateRow</code> or <code>insertRow</code> methods are
+     * called to update the database.
      * <p/>
-     * <P><B>Note:</B> Consult your JDBC driver documentation to determine if
-     * it might be more efficient to use a version of
-     * <code>updateCharacterStream</code> which takes a length parameter.
+     * <P>
+     * <B>Note:</B> Consult your JDBC driver documentation to determine if it might
+     * be more efficient to use a version of <code>updateCharacterStream</code>
+     * which takes a length parameter.
      *
-     * @param columnLabel the label for the column specified with the SQL AS clause.  If the SQL AS clause was not
-     *                    specified, then the label is the name of the column
-     * @param reader      the <code>java.io.Reader</code> object containing
-     *                    the new column value
-     * @throws SQLException if the columnLabel is not valid; if a database access error occurs;
-     *                      the result set concurrency is <code>CONCUR_READ_ONLY</code>
-     *                      or this method is called on a closed result set
-     * @throws SQLFeatureNotSupportedException
-     *                      if the JDBC driver does not support
-     *                      this method
+     * @param columnLabel the label for the column specified with the SQL AS clause.
+     * If the SQL AS clause was not specified, then the label is the name of the
+     * column
+     * @param reader the <code>java.io.Reader</code> object containing the new
+     * column value
+     * @throws SQLException if the columnLabel is not valid; if a database access
+     * error occurs; the result set concurrency is <code>CONCUR_READ_ONLY</code> or
+     * this method is called on a closed result set
+     * @throws SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
      * @since 1.6
      */
+    @Override
     public void updateCharacterStream(String columnLabel, Reader reader) throws SQLException {
         resultSet.updateCharacterStream(columnLabel, reader);
     }
 
     /**
-     * Updates the designated column using the given input stream. The data will be read from the stream
-     * as needed until end-of-stream is reached.
+     * Updates the designated column using the given input stream. The data will be
+     * read from the stream as needed until end-of-stream is reached.
      * <p/>
-     * The updater methods are used to update column values in the
-     * current row or the insert row.  The updater methods do not
-     * update the underlying database; instead the <code>updateRow</code> or
-     * <code>insertRow</code> methods are called to update the database.
+     * The updater methods are used to update column values in the current row or
+     * the insert row. The updater methods do not update the underlying database;
+     * instead the <code>updateRow</code> or <code>insertRow</code> methods are
+     * called to update the database.
      * <p/>
-     * <P><B>Note:</B> Consult your JDBC driver documentation to determine if
-     * it might be more efficient to use a version of
-     * <code>updateBlob</code> which takes a length parameter.
+     * <P>
+     * <B>Note:</B> Consult your JDBC driver documentation to determine if it might
+     * be more efficient to use a version of <code>updateBlob</code> which takes a
+     * length parameter.
      *
      * @param columnIndex the first column is 1, the second is 2, ...
      * @param inputStream An object that contains the data to set the parameter
-     *                    value to.
-     * @throws SQLException if the columnIndex is not valid; if a database access error occurs;
-     *                      the result set concurrency is <code>CONCUR_READ_ONLY</code>
-     *                      or this method is called on a closed result set
-     * @throws SQLFeatureNotSupportedException
-     *                      if the JDBC driver does not support
-     *                      this method
+     * value to.
+     * @throws SQLException if the columnIndex is not valid; if a database access
+     * error occurs; the result set concurrency is <code>CONCUR_READ_ONLY</code> or
+     * this method is called on a closed result set
+     * @throws SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
      * @since 1.6
      */
+    @Override
     public void updateBlob(int columnIndex, InputStream inputStream) throws SQLException {
         resultSet.updateBlob(columnIndex, inputStream);
     }
 
     /**
-     * Updates the designated column using the given input stream. The data will be read from the stream
-     * as needed until end-of-stream is reached.
+     * Updates the designated column using the given input stream. The data will be
+     * read from the stream as needed until end-of-stream is reached.
      * <p/>
-     * The updater methods are used to update column values in the
-     * current row or the insert row.  The updater methods do not
-     * update the underlying database; instead the <code>updateRow</code> or
-     * <code>insertRow</code> methods are called to update the database.
+     * The updater methods are used to update column values in the current row or
+     * the insert row. The updater methods do not update the underlying database;
+     * instead the <code>updateRow</code> or <code>insertRow</code> methods are
+     * called to update the database.
      * <p/>
-     * <P><B>Note:</B> Consult your JDBC driver documentation to determine if
-     * it might be more efficient to use a version of
-     * <code>updateBlob</code> which takes a length parameter.
+     * <P>
+     * <B>Note:</B> Consult your JDBC driver documentation to determine if it might
+     * be more efficient to use a version of <code>updateBlob</code> which takes a
+     * length parameter.
      *
-     * @param columnLabel the label for the column specified with the SQL AS clause.  If the SQL AS clause was not
-     *                    specified, then the label is the name of the column
+     * @param columnLabel the label for the column specified with the SQL AS clause.
+     * If the SQL AS clause was not specified, then the label is the name of the
+     * column
      * @param inputStream An object that contains the data to set the parameter
-     *                    value to.
-     * @throws SQLException if the columnLabel is not valid; if a database access error occurs;
-     *                      the result set concurrency is <code>CONCUR_READ_ONLY</code>
-     *                      or this method is called on a closed result set
-     * @throws SQLFeatureNotSupportedException
-     *                      if the JDBC driver does not support
-     *                      this method
+     * value to.
+     * @throws SQLException if the columnLabel is not valid; if a database access
+     * error occurs; the result set concurrency is <code>CONCUR_READ_ONLY</code> or
+     * this method is called on a closed result set
+     * @throws SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
      * @since 1.6
      */
+    @Override
     public void updateBlob(String columnLabel, InputStream inputStream) throws SQLException {
         resultSet.updateBlob(columnLabel, inputStream);
     }
 
     /**
-     * Updates the designated column using the given <code>Reader</code>
-     * object.
-     * The data will be read from the stream
-     * as needed until end-of-stream is reached.  The JDBC driver will
-     * do any necessary conversion from UNICODE to the database char format.
+     * Updates the designated column using the given <code>Reader</code> object. The
+     * data will be read from the stream as needed until end-of-stream is reached.
+     * The JDBC driver will do any necessary conversion from UNICODE to the database
+     * char format.
      * <p/>
      * <p/>
-     * The updater methods are used to update column values in the
-     * current row or the insert row.  The updater methods do not
-     * update the underlying database; instead the <code>updateRow</code> or
-     * <code>insertRow</code> methods are called to update the database.
+     * The updater methods are used to update column values in the current row or
+     * the insert row. The updater methods do not update the underlying database;
+     * instead the <code>updateRow</code> or <code>insertRow</code> methods are
+     * called to update the database.
      * <p/>
-     * <P><B>Note:</B> Consult your JDBC driver documentation to determine if
-     * it might be more efficient to use a version of
-     * <code>updateClob</code> which takes a length parameter.
+     * <P>
+     * <B>Note:</B> Consult your JDBC driver documentation to determine if it might
+     * be more efficient to use a version of <code>updateClob</code> which takes a
+     * length parameter.
      *
      * @param columnIndex the first column is 1, the second is 2, ...
-     * @param reader      An object that contains the data to set the parameter value to.
-     * @throws SQLException if the columnIndex is not valid;
-     *                      if a database access error occurs;
-     *                      the result set concurrency is <code>CONCUR_READ_ONLY</code>
-     *                      or this method is called on a closed result set
-     * @throws SQLFeatureNotSupportedException
-     *                      if the JDBC driver does not support
-     *                      this method
+     * @param reader An object that contains the data to set the parameter value to.
+     * @throws SQLException if the columnIndex is not valid; if a database access
+     * error occurs; the result set concurrency is <code>CONCUR_READ_ONLY</code> or
+     * this method is called on a closed result set
+     * @throws SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
      * @since 1.6
      */
+    @Override
     public void updateClob(int columnIndex, Reader reader) throws SQLException {
         resultSet.updateClob(columnIndex, reader);
     }
 
     /**
-     * Updates the designated column using the given <code>Reader</code>
-     * object.
-     * The data will be read from the stream
-     * as needed until end-of-stream is reached.  The JDBC driver will
-     * do any necessary conversion from UNICODE to the database char format.
+     * Updates the designated column using the given <code>Reader</code> object. The
+     * data will be read from the stream as needed until end-of-stream is reached.
+     * The JDBC driver will do any necessary conversion from UNICODE to the database
+     * char format.
      * <p/>
      * <p/>
-     * The updater methods are used to update column values in the
-     * current row or the insert row.  The updater methods do not
-     * update the underlying database; instead the <code>updateRow</code> or
-     * <code>insertRow</code> methods are called to update the database.
+     * The updater methods are used to update column values in the current row or
+     * the insert row. The updater methods do not update the underlying database;
+     * instead the <code>updateRow</code> or <code>insertRow</code> methods are
+     * called to update the database.
      * <p/>
-     * <P><B>Note:</B> Consult your JDBC driver documentation to determine if
-     * it might be more efficient to use a version of
-     * <code>updateClob</code> which takes a length parameter.
+     * <P>
+     * <B>Note:</B> Consult your JDBC driver documentation to determine if it might
+     * be more efficient to use a version of <code>updateClob</code> which takes a
+     * length parameter.
      *
-     * @param columnLabel the label for the column specified with the SQL AS clause.  If the SQL AS clause was not
-     *                    specified, then the label is the name of the column
-     * @param reader      An object that contains the data to set the parameter value to.
-     * @throws SQLException if the columnLabel is not valid; if a database access error occurs;
-     *                      the result set concurrency is <code>CONCUR_READ_ONLY</code>
-     *                      or this method is called on a closed result set
-     * @throws SQLFeatureNotSupportedException
-     *                      if the JDBC driver does not support
-     *                      this method
+     * @param columnLabel the label for the column specified with the SQL AS clause.
+     * If the SQL AS clause was not specified, then the label is the name of the
+     * column
+     * @param reader An object that contains the data to set the parameter value to.
+     * @throws SQLException if the columnLabel is not valid; if a database access
+     * error occurs; the result set concurrency is <code>CONCUR_READ_ONLY</code> or
+     * this method is called on a closed result set
+     * @throws SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
      * @since 1.6
      */
+    @Override
     public void updateClob(String columnLabel, Reader reader) throws SQLException {
         resultSet.updateClob(columnLabel, reader);
     }
@@ -1289,67 +1273,68 @@
     /**
      * Updates the designated column using the given <code>Reader</code>
      * <p/>
-     * The data will be read from the stream
-     * as needed until end-of-stream is reached.  The JDBC driver will
-     * do any necessary conversion from UNICODE to the database char format.
+     * The data will be read from the stream as needed until end-of-stream is
+     * reached. The JDBC driver will do any necessary conversion from UNICODE to the
+     * database char format.
      * <p/>
      * <p/>
-     * The updater methods are used to update column values in the
-     * current row or the insert row.  The updater methods do not
-     * update the underlying database; instead the <code>updateRow</code> or
-     * <code>insertRow</code> methods are called to update the database.
+     * The updater methods are used to update column values in the current row or
+     * the insert row. The updater methods do not update the underlying database;
+     * instead the <code>updateRow</code> or <code>insertRow</code> methods are
+     * called to update the database.
      * <p/>
-     * <P><B>Note:</B> Consult your JDBC driver documentation to determine if
-     * it might be more efficient to use a version of
-     * <code>updateNClob</code> which takes a length parameter.
+     * <P>
+     * <B>Note:</B> Consult your JDBC driver documentation to determine if it might
+     * be more efficient to use a version of <code>updateNClob</code> which takes a
+     * length parameter.
      *
      * @param columnIndex the first column is 1, the second 2, ...
-     * @param reader      An object that contains the data to set the parameter value to.
-     * @throws SQLException if the columnIndex is not valid;
-     *                      if the driver does not support national
-     *                      character sets;  if the driver can detect that a data conversion
-     *                      error could occur; this method is called on a closed result set,
-     *                      if a database access error occurs or
-     *                      the result set concurrency is <code>CONCUR_READ_ONLY</code>
-     * @throws SQLFeatureNotSupportedException
-     *                      if the JDBC driver does not support
-     *                      this method
+     * @param reader An object that contains the data to set the parameter value to.
+     * @throws SQLException if the columnIndex is not valid; if the driver does not
+     * support national character sets; if the driver can detect that a data
+     * conversion error could occur; this method is called on a closed result set,
+     * if a database access error occurs or the result set concurrency is
+     * <code>CONCUR_READ_ONLY</code>
+     * @throws SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
      * @since 1.6
      */
+    @Override
     public void updateNClob(int columnIndex, Reader reader) throws SQLException {
         resultSet.updateNClob(columnIndex, reader);
     }
 
     /**
-     * Updates the designated column using the given <code>Reader</code>
-     * object.
-     * The data will be read from the stream
-     * as needed until end-of-stream is reached.  The JDBC driver will
-     * do any necessary conversion from UNICODE to the database char format.
+     * Updates the designated column using the given <code>Reader</code> object. The
+     * data will be read from the stream as needed until end-of-stream is reached.
+     * The JDBC driver will do any necessary conversion from UNICODE to the database
+     * char format.
      * <p/>
      * <p/>
-     * The updater methods are used to update column values in the
-     * current row or the insert row.  The updater methods do not
-     * update the underlying database; instead the <code>updateRow</code> or
-     * <code>insertRow</code> methods are called to update the database.
+     * The updater methods are used to update column values in the current row or
+     * the insert row. The updater methods do not update the underlying database;
+     * instead the <code>updateRow</code> or <code>insertRow</code> methods are
+     * called to update the database.
      * <p/>
-     * <P><B>Note:</B> Consult your JDBC driver documentation to determine if
-     * it might be more efficient to use a version of
-     * <code>updateNClob</code> which takes a length parameter.
+     * <P>
+     * <B>Note:</B> Consult your JDBC driver documentation to determine if it might
+     * be more efficient to use a version of <code>updateNClob</code> which takes a
+     * length parameter.
      *
-     * @param columnLabel the label for the column specified with the SQL AS clause.  If the SQL AS clause was not
-     *                    specified, then the label is the name of the column
-     * @param reader      An object that contains the data to set the parameter value to.
-     * @throws SQLException if the columnLabel is not valid; if the driver does not support national
-     *                      character sets;  if the driver can detect that a data conversion
-     *                      error could occur; this method is called on a closed result set;
-     *                      if a database access error occurs or
-     *                      the result set concurrency is <code>CONCUR_READ_ONLY</code>
-     * @throws SQLFeatureNotSupportedException
-     *                      if the JDBC driver does not support
-     *                      this method
+     * @param columnLabel the label for the column specified with the SQL AS clause.
+     * If the SQL AS clause was not specified, then the label is the name of the
+     * column
+     * @param reader An object that contains the data to set the parameter value to.
+     * @throws SQLException if the columnLabel is not valid; if the driver does not
+     * support national character sets; if the driver can detect that a data
+     * conversion error could occur; this method is called on a closed result set;
+     * if a database access error occurs or the result set concurrency is
+     * <code>CONCUR_READ_ONLY</code>
+     * @throws SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
      * @since 1.6
      */
+    @Override
     public void updateNClob(String columnLabel, Reader reader) throws SQLException {
         resultSet.updateNClob(columnLabel, reader);
     }
@@ -1358,51 +1343,55 @@
      * Returns an object that implements the given interface to allow access to
      * non-standard methods, or standard methods not exposed by the proxy.
      * <p/>
-     * If the receiver implements the interface then the result is the receiver
-     * or a proxy for the receiver. If the receiver is a wrapper
-     * and the wrapped object implements the interface then the result is the
-     * wrapped object or a proxy for the wrapped object. Otherwise return the
-     * the result of calling <code>unwrap</code> recursively on the wrapped object
-     * or a proxy for that result. If the receiver is not a
-     * wrapper and does not implement the interface, then an <code>SQLException</code> is thrown.
+     * If the receiver implements the interface then the result is the receiver or a
+     * proxy for the receiver. If the receiver is a wrapper and the wrapped object
+     * implements the interface then the result is the wrapped object or a proxy for
+     * the wrapped object. Otherwise return the the result of calling
+     * <code>unwrap</code> recursively on the wrapped object or a proxy for that
+     * result. If the receiver is not a wrapper and does not implement the
+     * interface, then an <code>SQLException</code> is thrown.
      *
      * @param iface A Class defining an interface that the result must implement.
-     * @return an object that implements the interface. May be a proxy for the actual implementing object.
-     * @throws java.sql.SQLException If no object found that implements the interface
+     * @return an object that implements the interface. May be a proxy for the
+     * actual implementing object.
+     * @throws java.sql.SQLException If no object found that implements the
+     * interface
      * @since 1.6
      */
+    @Override
     public <T> T unwrap(Class<T> iface) throws SQLException {
-        T result;
         if (iface.isInstance(this)) {
-            result = iface.cast(this);
-        } else {
-            result = resultSet.unwrap(iface);
+            return iface.cast(this);
         }
-        return result;
+
+        return resultSet.unwrap(iface);
     }
 
     /**
-     * Returns true if this either implements the interface argument or is directly or indirectly a wrapper
-     * for an object that does. Returns false otherwise. If this implements the interface then return true,
-     * else if this is a wrapper then return the result of recursively calling <code>isWrapperFor</code> on the wrapped
-     * object. If this does not implement the interface and is not a wrapper, return false.
-     * This method should be implemented as a low-cost operation compared to <code>unwrap</code> so that
-     * callers can use this method to avoid expensive <code>unwrap</code> calls that may fail. If this method
-     * returns true then calling <code>unwrap</code> with the same argument should succeed.
+     * Returns true if this either implements the interface argument or is directly
+     * or indirectly a wrapper for an object that does. Returns false otherwise. If
+     * this implements the interface then return true, else if this is a wrapper
+     * then return the result of recursively calling <code>isWrapperFor</code> on
+     * the wrapped object. If this does not implement the interface and is not a
+     * wrapper, return false. This method should be implemented as a low-cost
+     * operation compared to <code>unwrap</code> so that callers can use this method
+     * to avoid expensive <code>unwrap</code> calls that may fail. If this method
+     * returns true then calling <code>unwrap</code> with the same argument should
+     * succeed.
      *
      * @param iface a Class defining an interface.
-     * @return true if this implements the interface or directly or indirectly wraps an object that does.
-     * @throws java.sql.SQLException if an error occurs while determining whether this is a wrapper
-     *                               for an object with the given interface.
+     * @return true if this implements the interface or directly or indirectly wraps
+     * an object that does.
+     * @throws java.sql.SQLException if an error occurs while determining whether
+     * this is a wrapper for an object with the given interface.
      * @since 1.6
      */
+    @Override
     public boolean isWrapperFor(Class<?> iface) throws SQLException {
-        boolean result;
         if (iface.isInstance(this)) {
-            result = true;
-        } else {
-            result = resultSet.isWrapperFor(iface);
+            return true;
         }
-        return result;
+
+        return resultSet.isWrapperFor(iface);
     }
 }
diff --git a/appserver/jdbc/jdbc-ra/jdbc40/src/main/java/com/sun/gjc/spi/jdbc40/StatementWrapper40.java b/appserver/jdbc/jdbc-ra/jdbc40/src/main/java/com/sun/gjc/spi/jdbc40/StatementWrapper40.java
index 266a7e5..0be14f1 100644
--- a/appserver/jdbc/jdbc-ra/jdbc40/src/main/java/com/sun/gjc/spi/jdbc40/StatementWrapper40.java
+++ b/appserver/jdbc/jdbc-ra/jdbc40/src/main/java/com/sun/gjc/spi/jdbc40/StatementWrapper40.java
@@ -16,24 +16,26 @@
 
 package com.sun.gjc.spi.jdbc40;
 
+import java.sql.Connection;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Statement;
+
 import com.sun.enterprise.util.i18n.StringManager;
 import com.sun.gjc.spi.ManagedConnectionFactoryImpl;
 import com.sun.gjc.spi.base.StatementWrapper;
 
-import java.sql.*;
-
 /**
  * Wrapper for JDBC 4.0 Statement
  */
 public class StatementWrapper40 extends StatementWrapper {
 
-    protected final static StringManager localStrings =
-            StringManager.getManager(ManagedConnectionFactoryImpl.class);
+    protected final static StringManager localStrings = StringManager.getManager(ManagedConnectionFactoryImpl.class);
 
     /**
      * Creates a new instance of StatementWrapper for JDBC 3.0<br>
      *
-     * @param con       ConnectionWrapper <br>
+     * @param con ConnectionWrapper <br>
      * @param statement Statement that is to be wrapped<br>
      */
     public StatementWrapper40(Connection con, Statement statement) {
@@ -41,59 +43,64 @@
     }
 
     /**
-     * Retrieves whether this <code>Statement</code> object has been closed. A <code>Statement</code> is closed if the
-     * method close has been called on it, or if it is automatically closed.
+     * Retrieves whether this <code>Statement</code> object has been closed. A
+     * <code>Statement</code> is closed if the method close has been called on it,
+     * or if it is automatically closed.
      *
-     * @return true if this <code>Statement</code> object is closed; false if it is still open
+     * @return true if this <code>Statement</code> object is closed; false if it is
+     * still open
      * @throws SQLException if a database access error occurs
      * @since 1.6
      */
+    @Override
     public boolean isClosed() throws SQLException {
         return jdbcStatement.isClosed();
     }
 
     /**
-     * Requests that a <code>Statement</code> be pooled or not pooled.  The value
-     * specified is a hint to the statement pool implementation indicating
-     * whether the applicaiton wants the statement to be pooled.  It is up to
-     * the statement pool manager as to whether the hint is used.
+     * Requests that a <code>Statement</code> be pooled or not pooled. The value
+     * specified is a hint to the statement pool implementation indicating whether
+     * the application wants the statement to be pooled. It is up to the statement
+     * pool manager as to whether the hint is used.
      * <p/>
-     * The poolable value of a statement is applicable to both internal
-     * statement caches implemented by the driver and external statement caches
-     * implemented by application servers and other applications.
+     * The poolable value of a statement is applicable to both internal statement
+     * caches implemented by the driver and external statement caches implemented by
+     * application servers and other applications.
      * <p/>
-     * By default, a <code>Statement</code> is not poolable when created, and
-     * a <code>PreparedStatement</code> and <code>CallableStatement</code>
-     * are poolable when created.
+     * By default, a <code>Statement</code> is not poolable when created, and a
+     * <code>PreparedStatement</code> and <code>CallableStatement</code> are
+     * poolable when created.
      * <p/>
      *
-     * @param poolable requests that the statement be pooled if true and
-     *                 that the statement not be pooled if false
-     *                 <p/>
+     * @param poolable requests that the statement be pooled if true and that the
+     * statement not be pooled if false
+     * <p/>
      * @throws SQLException if this method is called on a closed
-     *                      <code>Statement</code>
-     *                      <p/>
+     * <code>Statement</code>
+     * <p/>
      * @since 1.6
      */
+    @Override
     public void setPoolable(boolean poolable) throws SQLException {
         jdbcStatement.setPoolable(poolable);
     }
 
     /**
-     * Returns a  value indicating whether the <code>Statement</code>
-     * is poolable or not.
+     * Returns a value indicating whether the <code>Statement</code> is poolable or
+     * not.
      * <p/>
      *
      * @throws SQLException if this method is called on a closed
-     *                      <code>Statement</code>
-     *                      <p/>
-     * @return        <code>true</code> if the <code>Statement</code>
-     * is poolable; <code>false</code> otherwise
+     * <code>Statement</code>
+     * <p/>
+     * @return <code>true</code> if the <code>Statement</code> is poolable;
+     * <code>false</code> otherwise
      * <p/>
      * @see java.sql.Statement#setPoolable(boolean) setPoolable(boolean)
      * @since 1.6
-     *        <p/>
+     * <p/>
      */
+    @Override
     public boolean isPoolable() throws SQLException {
         return jdbcStatement.isPoolable();
     }
@@ -102,19 +109,22 @@
      * Returns an object that implements the given interface to allow access to
      * non-standard methods, or standard methods not exposed by the proxy.
      * <p/>
-     * If the receiver implements the interface then the result is the receiver
-     * or a proxy for the receiver. If the receiver is a wrapper
-     * and the wrapped object implements the interface then the result is the
-     * wrapped object or a proxy for the wrapped object. Otherwise return the
-     * the result of calling <code>unwrap</code> recursively on the wrapped object
-     * or a proxy for that result. If the receiver is not a
-     * wrapper and does not implement the interface, then an <code>SQLException</code> is thrown.
+     * If the receiver implements the interface then the result is the receiver or a
+     * proxy for the receiver. If the receiver is a wrapper and the wrapped object
+     * implements the interface then the result is the wrapped object or a proxy for
+     * the wrapped object. Otherwise return the the result of calling
+     * <code>unwrap</code> recursively on the wrapped object or a proxy for that
+     * result. If the receiver is not a wrapper and does not implement the
+     * interface, then an <code>SQLException</code> is thrown.
      *
      * @param iface A Class defining an interface that the result must implement.
-     * @return an object that implements the interface. May be a proxy for the actual implementing object.
-     * @throws java.sql.SQLException If no object found that implements the interface
+     * @return an object that implements the interface. May be a proxy for the
+     * actual implementing object.
+     * @throws java.sql.SQLException If no object found that implements the
+     * interface
      * @since 1.6
      */
+    @Override
     public <T> T unwrap(Class<T> iface) throws SQLException {
         T result;
         if (iface.isInstance(this)) {
@@ -126,88 +136,96 @@
     }
 
     /**
-     * Returns true if this either implements the interface argument or is directly or indirectly a wrapper
-     * for an object that does. Returns false otherwise. If this implements the interface then return true,
-     * else if this is a wrapper then return the result of recursively calling <code>isWrapperFor</code> on the wrapped
-     * object. If this does not implement the interface and is not a wrapper, return false.
-     * This method should be implemented as a low-cost operation compared to <code>unwrap</code> so that
-     * callers can use this method to avoid expensive <code>unwrap</code> calls that may fail. If this method
-     * returns true then calling <code>unwrap</code> with the same argument should succeed.
+     * Returns true if this either implements the interface argument or is directly
+     * or indirectly a wrapper for an object that does. Returns false otherwise. If
+     * this implements the interface then return true, else if this is a wrapper
+     * then return the result of recursively calling <code>isWrapperFor</code> on
+     * the wrapped object. If this does not implement the interface and is not a
+     * wrapper, return false. This method should be implemented as a low-cost
+     * operation compared to <code>unwrap</code> so that callers can use this method
+     * to avoid expensive <code>unwrap</code> calls that may fail. If this method
+     * returns true then calling <code>unwrap</code> with the same argument should
+     * succeed.
      *
      * @param iface a Class defining an interface.
-     * @return true if this implements the interface or directly or indirectly wraps an object that does.
-     * @throws java.sql.SQLException if an error occurs while determining whether this is a wrapper
-     *                               for an object with the given interface.
+     * @return true if this implements the interface or directly or indirectly wraps
+     * an object that does.
+     * @throws java.sql.SQLException if an error occurs while determining whether
+     * this is a wrapper for an object with the given interface.
      * @since 1.6
      */
+    @Override
     public boolean isWrapperFor(Class<?> iface) throws SQLException {
-
-        boolean result;
         if (iface.isInstance(this)) {
-            result = true;
-        } else {
-            result = jdbcStatement.isWrapperFor(iface);
+            return true;
         }
-        return result;
+
+        return jdbcStatement.isWrapperFor(iface);
     }
 
     /**
      * Retrieves any auto-generated keys created as a result of executing this
-     * <code>Statement</code> object. If this <code>Statement</code> object did
-     * not generate any keys, an empty <code>ResultSet</code>
-     * object is returned.
+     * <code>Statement</code> object. If this <code>Statement</code> object did not
+     * generate any keys, an empty <code>ResultSet</code> object is returned.
      * <p/>
-     * <p><B>Note:</B>If the columns which represent the auto-generated keys were not specified,
-     * the JDBC driver implementation will determine the columns which best represent the auto-generated keys.
+     * <p>
+     * <B>Note:</B>If the columns which represent the auto-generated keys were not
+     * specified, the JDBC driver implementation will determine the columns which
+     * best represent the auto-generated keys.
      *
      * @return a <code>ResultSet</code> object containing the auto-generated key(s)
-     *         generated by the execution of this <code>Statement</code> object
-     * @throws SQLException if a database access error occurs or
-     *                      this method is called on a closed <code>Statement</code>
-     * @throws java.sql.SQLFeatureNotSupportedException
-     *                      if the JDBC driver does not support this method
+     * generated by the execution of this <code>Statement</code> object
+     * @throws SQLException if a database access error occurs or this method is
+     * called on a closed <code>Statement</code>
+     * @throws java.sql.SQLFeatureNotSupportedException if the JDBC driver does not
+     * support this method
      * @since 1.4
      */
-    public java.sql.ResultSet getGeneratedKeys() throws java.sql.SQLException {
-        ResultSet rs = jdbcStatement.getGeneratedKeys();
-        if (rs == null)
+    @Override
+    public ResultSet getGeneratedKeys() throws SQLException {
+        ResultSet resultSet = jdbcStatement.getGeneratedKeys();
+        if (resultSet == null) {
             return null;
-        return new ResultSetWrapper40(this, rs);
+        }
+
+        return new ResultSetWrapper40(this, resultSet);
     }
 
     /**
-     * Retrieves the current result as a <code>ResultSet</code> object.
-     * This method should be called only once per result.
+     * Retrieves the current result as a <code>ResultSet</code> object. This method
+     * should be called only once per result.
      *
      * @return the current result as a <code>ResultSet</code> object or
-     *         <code>null</code> if the result is an update count or there are no more results
-     * @throws SQLException if a database access error occurs or
-     *                      this method is called on a closed <code>Statement</code>
+     * <code>null</code> if the result is an update count or there are no more
+     * results
+     * @throws SQLException if a database access error occurs or this method is
+     * called on a closed <code>Statement</code>
      * @see #execute
      */
-    public java.sql.ResultSet getResultSet() throws java.sql.SQLException {
-        ResultSet rs = jdbcStatement.getResultSet();
-        if (rs == null)
+    @Override
+    public ResultSet getResultSet() throws SQLException {
+        ResultSet resultSet = jdbcStatement.getResultSet();
+        if (resultSet == null) {
             return null;
-        return new ResultSetWrapper40(this, rs);
+        }
+
+        return new ResultSetWrapper40(this, resultSet);
     }
 
     /**
      * Executes the given SQL statement, which returns a single
      * <code>ResultSet</code> object.
      *
-     * @param sql an SQL statement to be sent to the database, typically a
-     *            static SQL <code>SELECT</code> statement
-     * @return a <code>ResultSet</code> object that contains the data produced
-     *         by the given query; never <code>null</code>
-     * @throws SQLException if a database access error occurs,
-     *                      this method is called on a closed <code>Statement</code> or the given
-     *                      SQL statement produces anything other than a single
-     *                      <code>ResultSet</code> object
+     * @param sql an SQL statement to be sent to the database, typically a static
+     * SQL <code>SELECT</code> statement
+     * @return a <code>ResultSet</code> object that contains the data produced by
+     * the given query; never <code>null</code>
+     * @throws SQLException if a database access error occurs, this method is called
+     * on a closed <code>Statement</code> or the given SQL statement produces
+     * anything other than a single <code>ResultSet</code> object
      */
-    public java.sql.ResultSet executeQuery(final String sql) throws
-            java.sql.SQLException {
-        ResultSet rs = jdbcStatement.executeQuery(sql);
-        return new ResultSetWrapper40(this, rs);
+    @Override
+    public ResultSet executeQuery(final String sql) throws SQLException {
+        return new ResultSetWrapper40(this, jdbcStatement.executeQuery(sql));
     }
 }
