diff --git a/src/interfaces/jdbc/build.xml b/src/interfaces/jdbc/build.xml
index 845a7e36323ff443dc66413eb6aebd27edcde3a4..80f9ca9b637f5642f195a027a439ddd2bf9799b5 100644
--- a/src/interfaces/jdbc/build.xml
+++ b/src/interfaces/jdbc/build.xml
@@ -6,7 +6,7 @@
 
   This file now requires Ant 1.4.1.  2002-04-18
 
-  $Header: /cvsroot/pgsql/src/interfaces/jdbc/Attic/build.xml,v 1.27 2002/07/30 13:22:02 davec Exp $
+  $Header: /cvsroot/pgsql/src/interfaces/jdbc/Attic/build.xml,v 1.28 2002/08/14 20:35:39 barry Exp $
 
 -->
 
@@ -46,6 +46,25 @@
     </condition>
     <available property="datasource" classname="javax.sql.DataSource"/>
     <available property="junit" classname="junit.framework.Test" />
+    <condition property="jdbc2tests">
+      <and>
+        <isset property="jdbc2"/>
+        <isset property="junit"/>
+      </and>
+    </condition>
+    <condition property="jdbc2optionaltests">
+      <and>
+        <isset property="jdbc2"/>
+        <isset property="datasource"/>
+        <isset property="junit"/>
+      </and>
+    </condition>
+    <condition property="jdbc3tests">
+      <and>
+        <isset property="jdbc3"/>
+        <isset property="junit"/>
+      </and>
+    </condition>
   </target>
 
 
@@ -89,18 +108,10 @@
       <exclude name="${package}/jdbc2/**" unless="jdbc2"/>
       <exclude name="${package}/jdbc3/**" unless="jdbc3"/>
 
-      <exclude name="${package}/largeobject/PGblob.java" if="jdbc1" />
-      <exclude name="${package}/largeobject/PGclob.java" if="jdbc1" />
-
+      <exclude name="${package}/jdbc2/optional/**" unless="jdbc2" />
       <exclude name="${package}/jdbc2/optional/**" unless="datasource" />
 
-      <exclude name="${package}/PostgresqlDataSource.java" />
-      <exclude name="${package}/xa/**" />
-
-      <exclude name="${package}/test/**" unless="junit" />
-      <exclude name="${package}/test/jdbc2/**" if="jdbc1" />
-      <exclude name="${package}/test/jdbc2/optional/**" unless="datasource" />
-      <exclude name="${package}/test/JDBC2Tests.java" if="jdbc1" />
+      <exclude name="${package}/test/**"/>
     </javac>
   </target>
 
@@ -128,8 +139,15 @@
     </condition>
 
     <!-- determine the connection class -->
-    <property name="connectclass" value="org.postgresql.jdbc1.Jdbc1Connection" />
-    <available property="connectclass" value="org.postgresql.jdbc2.Jdbc2Connection" classname="java.lang.ThreadLocal" />
+    <condition property="connectclass" value="org.postgresql.jdbc1.Jdbc1Connection">
+        <equals arg1="${jdbc1}" arg2="true"/>
+    </condition>
+    <condition property="connectclass" value="org.postgresql.jdbc2.Jdbc2Connection">
+        <equals arg1="${jdbc2}" arg2="true"/>
+    </condition>
+    <condition property="connectclass" value="org.postgresql.jdbc3.Jdbc3Connection">
+        <equals arg1="${jdbc3}" arg2="true"/>
+    </condition>
 
     <!-- Some defaults -->
     <filter token="MAJORVERSION" value="${major}" />
@@ -222,14 +240,31 @@
   <property name="junit.ui" value="textui" />
 
 
-  <target name="test" depends="jar" if="junit">
+  <target name="test" depends="testjdbc2,testjdbc2optional,testjdbc3">
+   </target>
+
+  <target name="testjdbc2" depends="jar" if="jdbc2tests">
     <javac srcdir="${srcdir}" destdir="${builddir}" debug="${debug}">
-      <include name="${package}/test/jdbc2/**" if="jdbc2" />
-      <include name="${package}/test/jdbc2/**" if="jdbc3" />
+      <include name="${package}/test/jdbc2/*" />
     </javac>
+   <java fork="yes" classname="junit.${junit.ui}.TestRunner" taskname="junit" failonerror="true">
+      <arg value="org.postgresql.test.jdbc2.Jdbc2TestSuite" />
+      <sysproperty key="database" value="${database}" />
+      <sysproperty key="username" value="${username}" />
+      <sysproperty key="password" value="${password}" />
+      <classpath>
+        <pathelement location="${builddir}" />
+        <pathelement path="${java.class.path}" />
+      </classpath>
+    </java>
+  </target>
 
+  <target name="testjdbc2optional" depends="jar" if="jdbc2optionaltests">
+    <javac srcdir="${srcdir}" destdir="${builddir}" debug="${debug}">
+      <include name="${package}/test/jdbc2/optional/**" />
+    </javac>
     <java fork="yes" classname="junit.${junit.ui}.TestRunner" taskname="junit" failonerror="true">
-      <arg value="org.postgresql.test.JDBC2Tests" />
+      <arg value="org.postgresql.test.jdbc2.optional.OptionalTestSuite" />
       <sysproperty key="database" value="${database}" />
       <sysproperty key="username" value="${username}" />
       <sysproperty key="password" value="${password}" />
@@ -240,4 +275,21 @@
     </java>
   </target>
 
+  <target name="testjdbc3" depends="jar" if="jdbc3tests">
+    <javac srcdir="${srcdir}" destdir="${builddir}" debug="${debug}">
+      <include name="${package}/test/jdbc3/*" />
+    </javac>
+    <java fork="yes" classname="junit.${junit.ui}.TestRunner" taskname="junit" failonerror="true">
+      <arg value="org.postgresql.test.jdbc3.Jdbc3TestSuite" />
+      <sysproperty key="database" value="${database}" />
+      <sysproperty key="username" value="${username}" />
+      <sysproperty key="password" value="${password}" />
+      <classpath>
+        <pathelement location="${builddir}" />
+        <pathelement path="${java.class.path}" />
+      </classpath>
+    </java>
+  </target>
+
+
 </project>
diff --git a/src/interfaces/jdbc/org/postgresql/PostgresqlDataSource.java b/src/interfaces/jdbc/org/postgresql/PostgresqlDataSource.java
deleted file mode 100644
index 3b37f790cf58b301db2afa0a3b2fe36f68e0229c..0000000000000000000000000000000000000000
--- a/src/interfaces/jdbc/org/postgresql/PostgresqlDataSource.java
+++ /dev/null
@@ -1,605 +0,0 @@
-/*
-* Redistribution and use of this software and associated documentation
-* ("Software"), with or without modification, are permitted provided
-* that the following conditions are met:
-*
-* 1. Redistributions of source code must retain copyright
-*	 statements and notices.  Redistributions must also contain a
-*	 copy of this document.
-*
-* 2. Redistributions in binary form must reproduce the
-*	 above copyright notice, this list of conditions and the
-*	 following disclaimer in the documentation and/or other
-*	 materials provided with the distribution.
-*
-* 3. The name "Exolab" must not be used to endorse or promote
-*	 products derived from this Software without prior written
-*	 permission of Exoffice Technologies.  For written permission,
-*	 please contact info@exolab.org.
-*
-* 4. Products derived from this Software may not be called "Exolab"
-*	 nor may "Exolab" appear in their names without prior written
-*	 permission of Exoffice Technologies. Exolab is a registered
-*	 trademark of Exoffice Technologies.
-*
-* 5. Due credit should be given to the Exolab Project
-*	 (http://www.exolab.org/).
-*
-* THIS SOFTWARE IS PROVIDED BY EXOFFICE TECHNOLOGIES AND CONTRIBUTORS
-* ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT
-* NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
-* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.	IN NO EVENT SHALL
-* EXOFFICE TECHNOLOGIES OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
-* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
-* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
-* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
-* OF THE POSSIBILITY OF SUCH DAMAGE.
-*
-* Copyright 1999 (C) Exoffice Technologies Inc. All Rights Reserved.
-*
-* $Id: PostgresqlDataSource.java,v 1.5 2001/11/19 23:16:45 momjian Exp $
-*/
-
-
-package org.postgresql;
-
-
-import java.io.PrintWriter;
-import java.io.Serializable;
-import java.util.Properties;
-import java.util.Hashtable;
-import java.sql.Connection;
-import java.sql.SQLException;
-import java.sql.DriverManager;
-import java.rmi.Remote;
-import javax.sql.DataSource;
-import javax.naming.Referenceable;
-import javax.naming.Reference;
-import javax.naming.StringRefAddr;
-import javax.naming.RefAddr;
-import javax.naming.Context;
-import javax.naming.Name;
-import javax.naming.NamingException;
-import javax.naming.spi.ObjectFactory;
-// FIXME
-//import postgresql.util.PSQLException;
-//import postgresql.xa.XADataSourceImpl;
-import org.postgresql.util.PSQLException;
-import org.postgresql.xa.XADataSourceImpl;
-//---------
-
-/*
- * Implements a JDBC 2.0 {@link javax.sql.DataSource} for the
- * PostgreSQL driver with JNDI persistance support. XA and pooled
- * connection support is also available, but the application must
- * used the designated DataSource interface to obtain them.
- * <p>
- * The supported data source properties are:
- * <pre>
- * description		   (optional)
- * databaseName		   (required)
- * loginTimeout		   (optional)
- * user				   (optional)
- * password			   (optional)
- * serverName		   (optional)
- * portNumber		   (optional)
- * transactionTimeout  (optional for XA connections)
- * </pre>
- * This data source may be serialized and stored in a JNDI
- * directory. Example of how to create a new data source and
- * register it with JNDI:
- * <pre>
- * PostgresqlDataSource ds;
- * InitialContext		ctx;
- *
- * ds = new PostgresqlDataSource();
- * ds.setDatabaseName( "test" );
- * ds.setUser( "me" );
- * ds.setPassword( "secret" );
- * ctx = new InitialContext();
- * ctx.rebind( "/comp/jdbc/test", ds );
- * </pre>
- * Example for obtaining the data source from JNDI and
- * opening a new connections:
- * <pre>
- * InitialContext		ctx;
- * DataSource			ds;
- *
- * ctx = new InitialContext();
- * ds = (DataSource) ctx.lookup( "/comp/jdbc/test" );
- * ds.getConnection();
- * </pre>
- *
- *
- * @author <a href="arkin@exoffice.com">Assaf Arkin</a>
- * @version 1.0
- * @see XADataSourceImpl
- * @see DataSource
- * @see Connection
- */
-public class PostgresqlDataSource
-			extends XADataSourceImpl
-			implements DataSource, Referenceable,
-			ObjectFactory, Serializable
-{
-
-
-	/*
-	 * Holds the timeout for opening a new connection, specified
-	 * in seconds. The default is obtained from the JDBC driver.
-	 */
-	private int _loginTimeout;
-
-	/*
-	 * Holds the user's account name.
-	 */
-	private String _user;
-
-	/*
-	 * Holds the database password.
-	 */
-	private String _password;
-
-	/*
-	 * Holds the name of the particular database on the server.
-	 */
-	private String _databaseName;
-
-	/*
-	 * Description of this datasource.
-	 */
-	private String _description = "PostgreSQL DataSource";
-
-	/*
-	 * Holds the database server name. If null, this is
-	 * assumed to be the localhost.
-	 */
-	private String _serverName;
-
-	/*
-	 * Holds the port number where a server is listening.
-	 * The default value will open a connection with an
-	 * unspecified port.
-	 */
-	private int _portNumber = DEFAULT_PORT;
-
-	/*
-	 * The default port number. Since we open the connection
-	 * without specifying the port if it's the default one,
-	 * this value can be meaningless.
-	 */
-	private static final int DEFAULT_PORT = 0;
-
-	/*
-	 * Holds the log writer to which all messages should be
-	 * printed. The default writer is obtained from the driver
-	 * manager, but it can be specified at the datasource level
-	 * and will be passed to the driver. May be null.
-	 */
-	private transient PrintWriter _logWriter;
-
-	/*
-	 * Each datasource maintains it's own driver, in case of
-	 * driver-specific setup (e.g. pools, log writer).
-	 */
-	// FIXME
-	//	  private transient postgresql.Driver _driver;
-	private transient org.postgresql.Driver _driver;
-
-	public PostgresqlDataSource()
-	{
-		_logWriter = DriverManager.getLogWriter();
-		_loginTimeout = DriverManager.getLoginTimeout();
-	}
-
-
-	public Connection getConnection()
-	throws SQLException
-	{
-		// Uses the username and password specified for the datasource.
-		return getConnection( _user, _password );
-	}
-
-
-	public synchronized Connection getConnection( String user, String password )
-	throws SQLException
-	{
-		Connection conn;
-		Properties info;
-		String url;
-
-		if ( _driver == null )
-		{
-			try
-			{
-				// Constructs a driver for use just by this data source
-				// which will produce TwoPhaseConnection-s. This driver
-				// is not registered with the driver manager.
-				// FIXME
-				//		_driver = new postgresql.Driver();
-				_driver = new org.postgresql.Driver();
-
-				//FIXME
-				//		_driver.setLogWriter( _logWriter );
-				// Method seems to be unavailable. Just commented it out.
-			}
-			catch ( SQLException except )
-			{
-				if ( _logWriter != null )
-					_logWriter.println( "DataSource: Failed to initialize JDBC driver: " + except );
-				throw except;
-			}
-		}
-
-		// Use info to supply properties that are not in the URL.
-		info = new Properties();
-		info.put( "loginTimeout", Integer.toString( _loginTimeout ) );
-
-		// DriverManager will do that and not rely on the URL alone.
-		if ( user == null )
-		{
-			user = _user;
-			password = _password;
-		}
-		if ( user == null || password == null )
-			throw new PSQLException( "postgresql.ds.userpswd" );
-		info.put( "user", user );
-		info.put( "password", password );
-
-		if ( _serverName != null )
-			info.put( "PGHOST", _serverName );
-		if ( _portNumber != DEFAULT_PORT )
-			info.put( "PGPORT", Integer.toString( _portNumber ) );
-		if ( _databaseName != null )
-			info.put( "PGDBNAME", _databaseName );
-
-		// Construct the URL suitable for this driver.
-		url = "jdbc:postgresql:";
-
-		// Attempt to establish a connection. Report a successful
-		// attempt or a failure.
-		try
-		{
-			conn = _driver.connect( url, info );
-			// FIXME
-			//		if ( ! ( conn instanceof postgresql.jdbc2.Connection ) ) {
-			if ( ! ( conn instanceof org.postgresql.jdbc2.Connection ) )
-			{
-				if ( _logWriter != null )
-					_logWriter.println( "DataSource: JDBC 1 connections not supported" );
-				throw new PSQLException( "postgresql.ds.onlyjdbc2" );
-			}
-		}
-		catch ( SQLException except )
-		{
-			if ( _logWriter != null )
-				_logWriter.println( "DataSource: getConnection failed " + except );
-			throw except;
-		}
-		if ( conn != null && _logWriter != null )
-			_logWriter.println( "DataSource: getConnection returning " + conn );
-		return conn;
-	}
-
-
-	public PrintWriter getLogWriter()
-	{
-		return _logWriter;
-	}
-
-
-	public synchronized void setLogWriter( PrintWriter writer )
-	{
-		// Once a log writer has been set, we cannot set it since some
-		// thread might be conditionally accessing it right now without
-		// synchronizing.
-		if ( writer != null )
-		{
-			if ( _driver != null )
-				// FIXME
-				//		_driver.setLogWriter( writer );
-				// Method seems to be unavailable. Commented it out.
-				_logWriter = writer;
-		}
-	}
-
-
-	public void setLoginTimeout( int seconds )
-	{
-		_loginTimeout = seconds;
-	}
-
-
-	public synchronized int getLoginTimeout()
-	{
-		return _loginTimeout;
-	}
-
-
-	/*
-	 * Sets the name of the particular database on the server.
-	 * The standard name for this property is <tt>databaseName</tt>.
-	 *
-	 * @param databaseName The name of the particular database on the server
-	 */
-	public synchronized void setDatabaseName( String databaseName )
-	{
-		if ( databaseName == null )
-			throw new NullPointerException( "DataSource: Argument 'databaseName' is null" );
-		_databaseName = databaseName;
-	}
-
-
-	/*
-	 * Returns the name of the particular database on the server.
-	 * The standard name for this property is <tt>databaseName</tt>.
-	 *
-	 * @return The name of the particular database on the server
-	 */
-	public String getDatabaseName()
-	{
-		return _databaseName;
-	}
-
-
-	/*
-	 * Sets the description of this datasource.
-	 * The standard name for this property is <tt>description</tt>.
-	 *
-	 * @param description The description of this datasource
-	 */
-	public synchronized void setDescription( String description )
-	{
-		if ( description == null )
-			throw new NullPointerException( "DataSource: Argument 'description' is null" );
-		_description = description;
-	}
-
-
-	/*
-	 * Returns the description of this datasource.
-	 * The standard name for this property is <tt>description</tt>.
-	 *
-	 * @return The description of this datasource
-	 */
-	public String getDescription()
-	{
-		return _description;
-	}
-
-
-	/*
-	 * Sets the database password.
-	 * The standard name for this property is <tt>password</tt>.
-	 *
-	 * @param password The database password
-	 */
-	public synchronized void setPassword( String password )
-	{
-		_password = password;
-	}
-
-
-	/*
-	 * Returns the database password.
-	 * The standard name for this property is <tt>password</tt>.
-	 *
-	 * @return The database password
-	 */
-	public String getPassword()
-	{
-		return _password;
-	}
-
-
-	/*
-	 * Sets the port number where a server is listening.
-	 * The standard name for this property is <tt>portNumber</tt>.
-	 *
-	 * @param portNumber The port number where a server is listening
-	 */
-	public synchronized void setPortNumber( int portNumber )
-	{
-		_portNumber = portNumber;
-	}
-
-
-	/*
-	 * Returns the port number where a server is listening.
-	 * The standard name for this property is <tt>portNumber</tt>.
-	 *
-	 * @return The port number where a server is listening
-	 */
-	public int getPortNumber()
-	{
-		return _portNumber;
-	}
-
-
-	/*
-	 * Sets the database server name.
-
-	 * The standard name for this property is <tt>serverName</tt>.
-	 *
-	 * @param serverName The database server name
-	 */
-	public synchronized void setServerName( String serverName )
-	{
-		_serverName = serverName;
-	}
-
-
-	/*
-	 * Returns the database server name.
-	 * The standard name for this property is <tt>serverName</tt>.
-	 *
-	 * @return The database server name
-	 */
-	public String getServerName()
-	{
-		return _serverName;
-	}
-
-
-	/*
-	 * Sets the user's account name.
-	 * The standard name for this property is <tt>user</tt>.
-	 *
-	 * @param user The user's account name
-	 */
-	public synchronized void setUser( String user )
-	{
-		_user = user;
-	}
-
-
-	/*
-	 * Returns the user's account name.
-	 * The standard name for this property is <tt>user</tt>.
-	 *
-	 * @return The user's account name
-	 */
-	public String getUser()
-	{
-		return _user;
-	}
-
-
-	/*
-	 * Returns true if this datasource and the other are equal.
-	 * The two datasources are equal if and only if they will produce
-	 * the exact same connections. Connection properties like database
-	 * name, user name, etc are comapred. Setup properties like
-	 * description, log writer, etc are not compared.
-	 */
-	public synchronized boolean equals( Object other )
-	{
-		if ( other == this )
-			return true;
-		if ( other == null || ! ( other instanceof PostgresqlDataSource ) )
-			return false;
-
-		PostgresqlDataSource with;
-
-		with = (PostgresqlDataSource) other;
-		if ( _databaseName != null && _databaseName.equals( with._databaseName ) )
-			if ( _portNumber == with._portNumber &&
-					( ( _serverName == null && with._serverName == null ) ||
-					  ( _serverName != null && _serverName.equals( with._serverName ) ) ) )
-				if ( ( _user == null && with._user == null ) ||
-						( _user != null && _password != null && _user.equals( with._user ) &&
-						  _password.equals( with._password ) ) )
-					return true;
-		return false;
-	}
-
-
-	public String toString()
-	{
-		if ( _description != null )
-			return _description;
-		else
-		{
-			String url;
-
-			url = "jdbc:postgresql:";
-			if ( _serverName != null )
-			{
-				if ( _portNumber == DEFAULT_PORT )
-					url = url + "//" + _serverName + "/";
-				else
-					url = url + "//" + _serverName + ":" + _portNumber + "/";
-			}
-			else if ( _portNumber != DEFAULT_PORT )
-				url = url + "//localhost:" + _portNumber + "/";
-			if ( _databaseName != null )
-				url = url + _databaseName;
-			return "DataSource " + url;
-		}
-	}
-
-
-	public synchronized Reference getReference()
-	{
-		Reference ref;
-
-		// We use same object as factory.
-		ref = new Reference( getClass().getName(), getClass().getName(), null );
-		// Mandatory properties
-		ref.add( new StringRefAddr( "description", _description ) );
-		ref.add( new StringRefAddr( "databaseName", _databaseName ) );
-		ref.add( new StringRefAddr( "loginTimeout", Integer.toString( _loginTimeout ) ) );
-		// Optional properties
-		if ( _user != null )
-			ref.add( new StringRefAddr( "user", _user ) );
-		if ( _password != null )
-			ref.add( new StringRefAddr( "password", _password ) );
-		if ( _serverName != null )
-			ref.add( new StringRefAddr( "serverName", _serverName ) );
-		if ( _portNumber != DEFAULT_PORT )
-			ref.add( new StringRefAddr( "portNumber", Integer.toString( _portNumber ) ) );
-		ref.add( new StringRefAddr( "transactionTimeout", Integer.toString( getTransactionTimeout() ) ) );
-		return ref;
-	}
-
-
-	public Object getObjectInstance( Object refObj, Name name, Context nameCtx, Hashtable env )
-	throws NamingException
-	{
-		Reference ref;
-
-		// Can only reconstruct from a reference.
-		if ( refObj instanceof Reference )
-		{
-			ref = (Reference) refObj;
-			// Make sure reference is of datasource class.
-			if ( ref.getClassName().equals( getClass().getName() ) )
-			{
-
-				PostgresqlDataSource ds;
-				RefAddr addr;
-
-				try
-				{
-					ds = (PostgresqlDataSource) Class.forName( ref.getClassName() ).newInstance();
-				}
-				catch ( Exception except )
-				{
-					throw new NamingException( except.toString() );
-				}
-				// Mandatory properties
-				ds._description = (String) ref.get( "description" ).getContent();
-				ds._databaseName = (String) ref.get( "databaseName" ).getContent();
-				ds._loginTimeout = Integer.parseInt( (String) ref.get( "loginTimeout" ).getContent() );
-				// Optional properties
-				addr = ref.get( "user" );
-				if ( addr != null )
-					ds._user = (String) addr.getContent();
-				addr = ref.get( "password" );
-				if ( addr != null )
-					ds._password = (String) addr.getContent();
-				addr = ref.get( "serverName" );
-				if ( addr != null )
-					ds._serverName = (String) addr.getContent();
-				addr = ref.get( "portNumber" );
-				if ( addr != null )
-					ds._portNumber = Integer.parseInt( (String) addr.getContent() );
-				addr = ref.get( "transactionTimeout" );
-				if ( addr != null )
-					setTransactionTimeout( Integer.parseInt( (String) addr.getContent() ) );
-				return ds;
-
-			}
-			else
-				throw new NamingException( "DataSource: Reference not constructed from class " + getClass().getName() );
-		}
-		else if ( refObj instanceof Remote )
-			return refObj;
-		else
-			return null;
-	}
-}
-
diff --git a/src/interfaces/jdbc/org/postgresql/jdbc1/AbstractJdbc1DatabaseMetaData.java b/src/interfaces/jdbc/org/postgresql/jdbc1/AbstractJdbc1DatabaseMetaData.java
index 3fd64c8c36301c0b7ecd17fd7fb42907e9681e1a..6a8d20d669287bb5feaa2e07010d65281bdfc182 100644
--- a/src/interfaces/jdbc/org/postgresql/jdbc1/AbstractJdbc1DatabaseMetaData.java
+++ b/src/interfaces/jdbc/org/postgresql/jdbc1/AbstractJdbc1DatabaseMetaData.java
@@ -8,6 +8,7 @@ import org.postgresql.util.PSQLException;
 
 public abstract class AbstractJdbc1DatabaseMetaData 
 {
+
 	protected AbstractJdbc1Connection connection; // The connection association
 
 	// These define various OID's. Hopefully they will stay constant.
diff --git a/src/interfaces/jdbc/org/postgresql/jdbc1/AbstractJdbc1ResultSet.java b/src/interfaces/jdbc/org/postgresql/jdbc1/AbstractJdbc1ResultSet.java
index 3bb278a8e9d8168e744a697795355a2451634994..e3e75c1e19d868a1c851ac4441dc7ff2971baa42 100644
--- a/src/interfaces/jdbc/org/postgresql/jdbc1/AbstractJdbc1ResultSet.java
+++ b/src/interfaces/jdbc/org/postgresql/jdbc1/AbstractJdbc1ResultSet.java
@@ -13,13 +13,14 @@ import org.postgresql.largeobject.*;
 import org.postgresql.util.PGbytea;
 import org.postgresql.util.PSQLException;
 
-/* $Header: /cvsroot/pgsql/src/interfaces/jdbc/org/postgresql/jdbc1/Attic/AbstractJdbc1ResultSet.java,v 1.2 2002/07/25 22:45:27 barry Exp $
+/* $Header: /cvsroot/pgsql/src/interfaces/jdbc/org/postgresql/jdbc1/Attic/AbstractJdbc1ResultSet.java,v 1.3 2002/08/14 20:35:39 barry Exp $
  * This class defines methods of the jdbc1 specification.  This class is
  * extended by org.postgresql.jdbc2.AbstractJdbc2ResultSet which adds the jdbc2
  * methods.  The real ResultSet class (for jdbc1) is org.postgresql.jdbc1.Jdbc1ResultSet
  */
 public abstract class AbstractJdbc1ResultSet
 {
+
 	protected Vector rows;			// The results
         protected Statement statement;
 	protected Field fields[];		// The field descriptions
diff --git a/src/interfaces/jdbc/org/postgresql/jdbc1/AbstractJdbc1ResultSetMetaData.java b/src/interfaces/jdbc/org/postgresql/jdbc1/AbstractJdbc1ResultSetMetaData.java
index 2a598d3c3947fe62cd4d4c35b2158224ed07b2d9..bed9cc27e19dc541916225e2db3a1a85d51a4061 100644
--- a/src/interfaces/jdbc/org/postgresql/jdbc1/AbstractJdbc1ResultSetMetaData.java
+++ b/src/interfaces/jdbc/org/postgresql/jdbc1/AbstractJdbc1ResultSetMetaData.java
@@ -10,6 +10,7 @@ import java.sql.Types;
 
 public abstract class AbstractJdbc1ResultSetMetaData 
 {
+
 	protected Vector rows;
 	protected Field[] fields;
 
diff --git a/src/interfaces/jdbc/org/postgresql/largeobject/PGblob.java b/src/interfaces/jdbc/org/postgresql/jdbc2/AbstractJdbc2Blob.java
similarity index 62%
rename from src/interfaces/jdbc/org/postgresql/largeobject/PGblob.java
rename to src/interfaces/jdbc/org/postgresql/jdbc2/AbstractJdbc2Blob.java
index 87c1ac247742538964273fa212d6c5ceba150bfc..cb6c5b01dc89831ee1439381208023c9acb9298b 100644
--- a/src/interfaces/jdbc/org/postgresql/largeobject/PGblob.java
+++ b/src/interfaces/jdbc/org/postgresql/jdbc2/AbstractJdbc2Blob.java
@@ -1,10 +1,4 @@
-package org.postgresql.largeobject;
-
-// IMPORTANT NOTE: This file implements the JDBC 2 version of the driver.
-// If you make any modifications to this file, you must make sure that the
-// changes are also made (if relevent) to the related JDBC 1 class in the
-// org.postgresql.jdbc1 package.
-
+package org.postgresql.jdbc2;
 
 import java.lang.*;
 import java.io.*;
@@ -13,22 +7,15 @@ import java.text.*;
 import java.util.*;
 import java.sql.*;
 import org.postgresql.Field;
-import org.postgresql.largeobject.*;
+import org.postgresql.PGConnection;
 import org.postgresql.largeobject.*;
 
-/*
- * This implements the Blob interface, which is basically another way to
- * access a LargeObject.
- *
- * $Id: PGblob.java,v 1.4 2002/07/23 03:59:55 barry Exp $
- *
- */
-public class PGblob implements java.sql.Blob
+public abstract class AbstractJdbc2Blob
 {
 	private int oid;
 	private LargeObject lo;
 
-	public PGblob(org.postgresql.PGConnection conn, int oid) throws SQLException
+	public AbstractJdbc2Blob(PGConnection conn, int oid) throws SQLException
 	{
 		this.oid = oid;
 		LargeObjectManager lom = conn.getLargeObjectAPI();
diff --git a/src/interfaces/jdbc/org/postgresql/largeobject/PGclob.java b/src/interfaces/jdbc/org/postgresql/jdbc2/AbstractJdbc2Clob.java
similarity index 64%
rename from src/interfaces/jdbc/org/postgresql/largeobject/PGclob.java
rename to src/interfaces/jdbc/org/postgresql/jdbc2/AbstractJdbc2Clob.java
index 71c3f8a2f0c40e9884b02a38eda3c1df4f24583e..c185bb4f4f34d5e75bfee4cbaf2e17f9d9090fcf 100644
--- a/src/interfaces/jdbc/org/postgresql/largeobject/PGclob.java
+++ b/src/interfaces/jdbc/org/postgresql/jdbc2/AbstractJdbc2Clob.java
@@ -1,9 +1,4 @@
-package org.postgresql.largeobject;
-
-// IMPORTANT NOTE: This file implements the JDBC 2 version of the driver.
-// If you make any modifications to this file, you must make sure that the
-// changes are also made (if relevent) to the related JDBC 1 class in the
-// org.postgresql.jdbc1 package.
+package org.postgresql.jdbc2;
 
 
 import java.lang.*;
@@ -13,22 +8,15 @@ import java.text.*;
 import java.util.*;
 import java.sql.*;
 import org.postgresql.Field;
-import org.postgresql.largeobject.*;
+import org.postgresql.PGConnection;
 import org.postgresql.largeobject.*;
 
-/*
- * This implements the Blob interface, which is basically another way to
- * access a LargeObject.
- *
- * $Id: PGclob.java,v 1.4 2002/07/23 03:59:55 barry Exp $
- *
- */
-public class PGclob implements java.sql.Clob
+public class AbstractJdbc2Clob
 {
 	private int oid;
 	private LargeObject lo;
 
-	public PGclob(org.postgresql.PGConnection conn, int oid) throws SQLException
+	public AbstractJdbc2Clob(PGConnection conn, int oid) throws SQLException
 	{
 		this.oid = oid;
 		LargeObjectManager lom = conn.getLargeObjectAPI();
diff --git a/src/interfaces/jdbc/org/postgresql/jdbc2/AbstractJdbc2ResultSet.java b/src/interfaces/jdbc/org/postgresql/jdbc2/AbstractJdbc2ResultSet.java
index 1a6379bf59279fb2d19ae84c2e09c8b030452f99..3b493de2f4d428e904db2e8ca4f8ec6fac8dd2f1 100644
--- a/src/interfaces/jdbc/org/postgresql/jdbc2/AbstractJdbc2ResultSet.java
+++ b/src/interfaces/jdbc/org/postgresql/jdbc2/AbstractJdbc2ResultSet.java
@@ -15,12 +15,13 @@ import org.postgresql.util.PGbytea;
 import org.postgresql.util.PSQLException;
 
 
-/* $Header: /cvsroot/pgsql/src/interfaces/jdbc/org/postgresql/jdbc2/Attic/AbstractJdbc2ResultSet.java,v 1.3 2002/07/25 22:45:28 barry Exp $
+/* $Header: /cvsroot/pgsql/src/interfaces/jdbc/org/postgresql/jdbc2/Attic/AbstractJdbc2ResultSet.java,v 1.4 2002/08/14 20:35:39 barry Exp $
  * This class defines methods of the jdbc2 specification.  This class extends
  * org.postgresql.jdbc1.AbstractJdbc1ResultSet which provides the jdbc1
  * methods.  The real Statement class (for jdbc2) is org.postgresql.jdbc2.Jdbc2ResultSet
  */
-public class AbstractJdbc2ResultSet extends org.postgresql.jdbc1.AbstractJdbc1ResultSet {
+public abstract class AbstractJdbc2ResultSet extends org.postgresql.jdbc1.AbstractJdbc1ResultSet {
+
   protected String sqlQuery = null;
 
   //needed for updateable result set support
@@ -237,9 +238,7 @@ public class AbstractJdbc2ResultSet extends org.postgresql.jdbc1.AbstractJdbc1Re
   }
 
 
-  public Blob getBlob(int i) throws SQLException {
-    return new org.postgresql.largeobject.PGblob(connection, getInt(i));
-  }
+  public abstract Blob getBlob(int i) throws SQLException;
 
 
   public java.io.Reader getCharacterStream(String columnName) throws SQLException {
@@ -276,9 +275,7 @@ public class AbstractJdbc2ResultSet extends org.postgresql.jdbc1.AbstractJdbc1Re
   }
 
 
-  public Clob getClob(int i) throws SQLException {
-    return new org.postgresql.largeobject.PGclob(connection, getInt(i));
-  }
+  public abstract Clob getClob(int i) throws SQLException;
 
 
   public int getConcurrency() throws SQLException {
@@ -919,7 +916,7 @@ public class AbstractJdbc2ResultSet extends org.postgresql.jdbc1.AbstractJdbc1Re
         selectStatement.setObject( i, ((PrimaryKey) primaryKeys.get(j)).getValue() );
       }
 
-      Jdbc2ResultSet rs = (Jdbc2ResultSet) selectStatement.executeQuery();
+      AbstractJdbc2ResultSet rs = (AbstractJdbc2ResultSet) selectStatement.executeQuery();
 
       if ( rs.first() ) {
         rowBuffer = rs.rowBuffer;
diff --git a/src/interfaces/jdbc/org/postgresql/jdbc2/Array.java b/src/interfaces/jdbc/org/postgresql/jdbc2/Array.java
index 99cbf0ea8ce6b405e3b9c4cd15d4c1b315923cff..6be102691bc2b3cf028fb36e829e5c66ac462bd1 100644
--- a/src/interfaces/jdbc/org/postgresql/jdbc2/Array.java
+++ b/src/interfaces/jdbc/org/postgresql/jdbc2/Array.java
@@ -124,33 +124,33 @@ public class Array implements java.sql.Array
 			case Types.BIT:
 				retVal = new boolean[ count ];
 				for ( ; count > 0; count-- )
-					((boolean[])retVal)[i++] = Jdbc2ResultSet.toBoolean( arrayContents[(int)index++] );
+					((boolean[])retVal)[i++] = AbstractJdbc2ResultSet.toBoolean( arrayContents[(int)index++] );
 				break;
 			case Types.SMALLINT:
 			case Types.INTEGER:
 				retVal = new int[ count ];
 				for ( ; count > 0; count-- )
-					((int[])retVal)[i++] = Jdbc2ResultSet.toInt( arrayContents[(int)index++] );
+					((int[])retVal)[i++] = AbstractJdbc2ResultSet.toInt( arrayContents[(int)index++] );
 				break;
 			case Types.BIGINT:
 				retVal = new long[ count ];
 				for ( ; count > 0; count-- )
-					((long[])retVal)[i++] = Jdbc2ResultSet.toLong( arrayContents[(int)index++] );
+					((long[])retVal)[i++] = AbstractJdbc2ResultSet.toLong( arrayContents[(int)index++] );
 				break;
 			case Types.NUMERIC:
 				retVal = new BigDecimal[ count ];
 				for ( ; count > 0; count-- )
-					((BigDecimal[])retVal)[i++] = Jdbc2ResultSet.toBigDecimal( arrayContents[(int)index++], 0 );
+					((BigDecimal[])retVal)[i++] = AbstractJdbc2ResultSet.toBigDecimal( arrayContents[(int)index++], 0 );
 				break;
 			case Types.REAL:
 				retVal = new float[ count ];
 				for ( ; count > 0; count-- )
-					((float[])retVal)[i++] = Jdbc2ResultSet.toFloat( arrayContents[(int)index++] );
+					((float[])retVal)[i++] = AbstractJdbc2ResultSet.toFloat( arrayContents[(int)index++] );
 				break;
 			case Types.DOUBLE:
 				retVal = new double[ count ];
 				for ( ; count > 0; count-- )
-					((double[])retVal)[i++] = Jdbc2ResultSet.toDouble( arrayContents[(int)index++] );
+					((double[])retVal)[i++] = AbstractJdbc2ResultSet.toDouble( arrayContents[(int)index++] );
 				break;
 			case Types.CHAR:
 			case Types.VARCHAR:
@@ -161,18 +161,18 @@ public class Array implements java.sql.Array
 			case Types.DATE:
 				retVal = new java.sql.Date[ count ];
 				for ( ; count > 0; count-- )
-					((java.sql.Date[])retVal)[i++] = Jdbc2ResultSet.toDate( arrayContents[(int)index++] );
+					((java.sql.Date[])retVal)[i++] = AbstractJdbc2ResultSet.toDate( arrayContents[(int)index++] );
 				break;
 			case Types.TIME:
 				retVal = new java.sql.Time[ count ];
 				for ( ; count > 0; count-- )
-					((java.sql.Time[])retVal)[i++] = Jdbc2ResultSet.toTime( arrayContents[(int)index++], rs, getBaseTypeName() );
+					((java.sql.Time[])retVal)[i++] = AbstractJdbc2ResultSet.toTime( arrayContents[(int)index++], rs, getBaseTypeName() );
 				break;
 			case Types.TIMESTAMP:
 				retVal = new Timestamp[ count ];
 				StringBuffer sbuf = null;
 				for ( ; count > 0; count-- )
-					((java.sql.Timestamp[])retVal)[i++] = Jdbc2ResultSet.toTimestamp( arrayContents[(int)index++], rs, getBaseTypeName() );
+					((java.sql.Timestamp[])retVal)[i++] = AbstractJdbc2ResultSet.toTimestamp( arrayContents[(int)index++], rs, getBaseTypeName() );
 				break;
 
 				// Other datatypes not currently supported.  If you are really using other types ask
@@ -340,7 +340,7 @@ public class Array implements java.sql.Array
 			default:
 				throw org.postgresql.Driver.notImplemented();
 		}
-		return ((Jdbc2Connection)conn).getResultSet(null, fields, rows, "OK", 1 );
+		return ((AbstractJdbc2Connection)conn).getResultSet(null, fields, rows, "OK", 1 );
 	}
 
 	public String toString()
diff --git a/src/interfaces/jdbc/org/postgresql/jdbc2/Jdbc2Blob.java b/src/interfaces/jdbc/org/postgresql/jdbc2/Jdbc2Blob.java
new file mode 100644
index 0000000000000000000000000000000000000000..5f5d28a5e523f73ead7caa43b058586829b21e2a
--- /dev/null
+++ b/src/interfaces/jdbc/org/postgresql/jdbc2/Jdbc2Blob.java
@@ -0,0 +1,12 @@
+package org.postgresql.jdbc2;
+
+
+public class Jdbc2Blob extends AbstractJdbc2Blob implements java.sql.Blob
+{
+
+	public Jdbc2Blob(org.postgresql.PGConnection conn, int oid) throws java.sql.SQLException
+	{
+		super(conn, oid);
+	}
+
+}
diff --git a/src/interfaces/jdbc/org/postgresql/jdbc2/Jdbc2CallableStatement.java b/src/interfaces/jdbc/org/postgresql/jdbc2/Jdbc2CallableStatement.java
index c8bc1b79073d63054bb0268da19bed908d22c264..46ff83a1e0c6e8fdaa2b3dedcba74924f8341e34 100644
--- a/src/interfaces/jdbc/org/postgresql/jdbc2/Jdbc2CallableStatement.java
+++ b/src/interfaces/jdbc/org/postgresql/jdbc2/Jdbc2CallableStatement.java
@@ -3,7 +3,7 @@ package org.postgresql.jdbc2;
 
 import java.sql.*;
 
-public class Jdbc2CallableStatement extends AbstractJdbc2Statement implements java.sql.CallableStatement
+public class Jdbc2CallableStatement extends org.postgresql.jdbc2.AbstractJdbc2Statement implements java.sql.CallableStatement
 {
 
 	public Jdbc2CallableStatement(Jdbc2Connection connection, String sql) throws SQLException
diff --git a/src/interfaces/jdbc/org/postgresql/jdbc2/Jdbc2Clob.java b/src/interfaces/jdbc/org/postgresql/jdbc2/Jdbc2Clob.java
new file mode 100644
index 0000000000000000000000000000000000000000..71de2f5433d1f3d7cfbfaa5075b29e1dcabbafd1
--- /dev/null
+++ b/src/interfaces/jdbc/org/postgresql/jdbc2/Jdbc2Clob.java
@@ -0,0 +1,12 @@
+package org.postgresql.jdbc2;
+
+
+public class Jdbc2Clob extends AbstractJdbc2Clob implements java.sql.Clob
+{
+
+	public Jdbc2Clob(org.postgresql.PGConnection conn, int oid) throws java.sql.SQLException
+	{
+		super(conn, oid);
+	}
+
+}
diff --git a/src/interfaces/jdbc/org/postgresql/jdbc2/Jdbc2DatabaseMetaData.java b/src/interfaces/jdbc/org/postgresql/jdbc2/Jdbc2DatabaseMetaData.java
index 2e7171913e7c8eb38480e5df52823ee144cc6bca..7dbf8a0f17c612548fd7abb0d2810f0465ba00d6 100644
--- a/src/interfaces/jdbc/org/postgresql/jdbc2/Jdbc2DatabaseMetaData.java
+++ b/src/interfaces/jdbc/org/postgresql/jdbc2/Jdbc2DatabaseMetaData.java
@@ -1,7 +1,7 @@
 package org.postgresql.jdbc2;
 
 
-public class Jdbc2DatabaseMetaData extends AbstractJdbc2DatabaseMetaData implements java.sql.DatabaseMetaData
+public class Jdbc2DatabaseMetaData extends org.postgresql.jdbc2.AbstractJdbc2DatabaseMetaData implements java.sql.DatabaseMetaData
 {
 	public Jdbc2DatabaseMetaData(Jdbc2Connection conn)
 	{
diff --git a/src/interfaces/jdbc/org/postgresql/jdbc2/Jdbc2PreparedStatement.java b/src/interfaces/jdbc/org/postgresql/jdbc2/Jdbc2PreparedStatement.java
index 0472007d3dd91cea4f851913fb9d022c2176bb61..15fd8d9a756070387be5204c358443059a97ee50 100644
--- a/src/interfaces/jdbc/org/postgresql/jdbc2/Jdbc2PreparedStatement.java
+++ b/src/interfaces/jdbc/org/postgresql/jdbc2/Jdbc2PreparedStatement.java
@@ -3,7 +3,7 @@ package org.postgresql.jdbc2;
 
 import java.sql.*;
 
-public class Jdbc2PreparedStatement extends AbstractJdbc2Statement implements java.sql.PreparedStatement
+public class Jdbc2PreparedStatement extends org.postgresql.jdbc2.AbstractJdbc2Statement implements java.sql.PreparedStatement
 {
 
 	public Jdbc2PreparedStatement(Jdbc2Connection connection, String sql) throws SQLException
diff --git a/src/interfaces/jdbc/org/postgresql/jdbc2/Jdbc2ResultSet.java b/src/interfaces/jdbc/org/postgresql/jdbc2/Jdbc2ResultSet.java
index c6415f0f7ae2784b33580f7f313847f9807f6d4d..1e9805be1d60d53c71df7fba2f4d7db4796190c0 100644
--- a/src/interfaces/jdbc/org/postgresql/jdbc2/Jdbc2ResultSet.java
+++ b/src/interfaces/jdbc/org/postgresql/jdbc2/Jdbc2ResultSet.java
@@ -5,7 +5,7 @@ import java.sql.*;
 import java.util.Vector;
 import org.postgresql.Field;
 
-/* $Header: /cvsroot/pgsql/src/interfaces/jdbc/org/postgresql/jdbc2/Attic/Jdbc2ResultSet.java,v 1.3 2002/07/26 05:29:35 barry Exp $
+/* $Header: /cvsroot/pgsql/src/interfaces/jdbc/org/postgresql/jdbc2/Attic/Jdbc2ResultSet.java,v 1.4 2002/08/14 20:35:39 barry Exp $
  * This class implements the java.sql.ResultSet interface for JDBC2.
  * However most of the implementation is really done in 
  * org.postgresql.jdbc2.AbstractJdbc2ResultSet or one of it's parents
@@ -23,5 +23,13 @@ public class Jdbc2ResultSet extends org.postgresql.jdbc2.AbstractJdbc2ResultSet
 		return new Jdbc2ResultSetMetaData(rows, fields);
 	}
 
+        public java.sql.Clob getClob(int i) throws SQLException {
+          return new org.postgresql.jdbc2.Jdbc2Clob(connection, getInt(i));
+        }
+
+        public java.sql.Blob getBlob(int i) throws SQLException {
+          return new org.postgresql.jdbc2.Jdbc2Blob(connection, getInt(i));
+        }
+
 }
 
diff --git a/src/interfaces/jdbc/org/postgresql/jdbc3/AbstractJdbc3Blob.java b/src/interfaces/jdbc/org/postgresql/jdbc3/AbstractJdbc3Blob.java
new file mode 100644
index 0000000000000000000000000000000000000000..d293c7acf055124855e509a9d3294c5df1fcdb72
--- /dev/null
+++ b/src/interfaces/jdbc/org/postgresql/jdbc3/AbstractJdbc3Blob.java
@@ -0,0 +1,90 @@
+package org.postgresql.jdbc3;
+
+
+import java.sql.*;
+
+public abstract class AbstractJdbc3Blob extends org.postgresql.jdbc2.AbstractJdbc2Blob
+{
+
+	public AbstractJdbc3Blob(org.postgresql.PGConnection conn, int oid) throws SQLException
+	{
+		super(conn, oid);
+	}
+
+    /**
+     * Writes the given array of bytes to the <code>BLOB</code> value that
+     * this <code>Blob</code> object represents, starting at position 
+     * <code>pos</code>, and returns the number of bytes written.
+     *
+     * @param pos the position in the <code>BLOB</code> object at which
+     *        to start writing
+     * @param bytes the array of bytes to be written to the <code>BLOB</code>
+     *        value that this <code>Blob</code> object represents
+     * @return the number of bytes written
+     * @exception SQLException if there is an error accessing the
+     *            <code>BLOB</code> value
+     * @see #getBytes
+     * @since 1.4
+     */
+    public int setBytes(long pos, byte[] bytes) throws SQLException {
+      throw org.postgresql.Driver.notImplemented();
+    }
+
+    /**
+     * Writes all or part of the given <code>byte</code> array to the
+     * <code>BLOB</code> value that this <code>Blob</code> object represents
+     * and returns the number of bytes written.
+     * Writing starts at position <code>pos</code> in the <code>BLOB</code>
+     * value; <code>len</code> bytes from the given byte array are written.
+     *
+     * @param pos the position in the <code>BLOB</code> object at which
+     *        to start writing
+     * @param bytes the array of bytes to be written to this <code>BLOB</code>
+     *        object
+     * @param offset the offset into the array <code>bytes</code> at which
+     *        to start reading the bytes to be set
+     * @param len the number of bytes to be written to the <code>BLOB</code>
+     *        value from the array of bytes <code>bytes</code>
+     * @return the number of bytes written
+     * @exception SQLException if there is an error accessing the
+     *            <code>BLOB</code> value
+     * @see #getBytes
+     * @since 1.4
+     */
+    public int setBytes(long pos, byte[] bytes, int offset, int len) throws SQLException {
+      throw org.postgresql.Driver.notImplemented();
+    }
+
+    /**
+     * Retrieves a stream that can be used to write to the <code>BLOB</code> 
+     * value that this <code>Blob</code> object represents.  The stream begins
+     * at position <code>pos</code>.
+     *
+     * @param pos the position in the <code>BLOB</code> value at which
+     *        to start writing
+     * @return a <code>java.io.OutputStream</code> object to which data can 
+     *         be written
+     * @exception SQLException if there is an error accessing the
+     *            <code>BLOB</code> value
+     * @see #getBinaryStream
+     * @since 1.4
+     */
+    public java.io.OutputStream setBinaryStream(long pos) throws SQLException {
+      throw org.postgresql.Driver.notImplemented();
+    }
+
+    /**
+     * Truncates the <code>BLOB</code> value that this <code>Blob</code>
+     * object represents to be <code>len</code> bytes in length.
+     *
+     * @param len the length, in bytes, to which the <code>BLOB</code> value
+     *        that this <code>Blob</code> object represents should be truncated
+     * @exception SQLException if there is an error accessing the
+     *            <code>BLOB</code> value
+     * @since 1.4
+     */
+    public void truncate(long len) throws SQLException {
+      throw org.postgresql.Driver.notImplemented();
+    }
+
+}
diff --git a/src/interfaces/jdbc/org/postgresql/jdbc3/AbstractJdbc3Clob.java b/src/interfaces/jdbc/org/postgresql/jdbc3/AbstractJdbc3Clob.java
new file mode 100644
index 0000000000000000000000000000000000000000..525530b537d3d3b0a61cf106df557ac2f17ecde2
--- /dev/null
+++ b/src/interfaces/jdbc/org/postgresql/jdbc3/AbstractJdbc3Clob.java
@@ -0,0 +1,107 @@
+package org.postgresql.jdbc3;
+
+
+import java.sql.*;
+
+public abstract class AbstractJdbc3Clob extends org.postgresql.jdbc2.AbstractJdbc2Clob
+{
+
+	public AbstractJdbc3Clob(org.postgresql.PGConnection conn, int oid) throws SQLException
+	{
+		super(conn, oid);
+	}
+
+    /**
+     * Writes the given Java <code>String</code> to the <code>CLOB</code>
+     * value that this <code>Clob</code> object designates at the position 
+     * <code>pos</code>.
+     *
+     * @param pos the position at which to start writing to the <code>CLOB</code>
+     *         value that this <code>Clob</code> object represents
+     * @param str the string to be written to the <code>CLOB</code>
+     *        value that this <code>Clob</code> designates
+     * @return the number of characters written
+     * @exception SQLException if there is an error accessing the 
+     *            <code>CLOB</code> value
+     *
+     * @since 1.4
+     */
+    public int setString(long pos, String str) throws SQLException {
+      throw org.postgresql.Driver.notImplemented();
+    }
+
+    /**
+     * Writes <code>len</code> characters of <code>str</code>, starting 
+     * at character <code>offset</code>, to the <code>CLOB</code> value
+     * that this <code>Clob</code> represents.
+     *
+     * @param pos the position at which to start writing to this
+     *        <code>CLOB</code> object
+     * @param str the string to be written to the <code>CLOB</code> 
+     *        value that this <code>Clob</code> object represents
+     * @param offset the offset into <code>str</code> to start reading
+     *        the characters to be written
+     * @param len the number of characters to be written
+     * @return the number of characters written
+     * @exception SQLException if there is an error accessing the 
+     *            <code>CLOB</code> value
+     *
+     * @since 1.4
+     */
+    public int setString(long pos, String str, int offset, int len) throws SQLException {
+      throw org.postgresql.Driver.notImplemented();
+    }
+
+    /**
+     * Retrieves a stream to be used to write Ascii characters to the
+     * <code>CLOB</code> value that this <code>Clob</code> object represents, 
+     * starting at position <code>pos</code>.
+     *
+     * @param pos the position at which to start writing to this
+     *        <code>CLOB</code> object
+     * @return the stream to which ASCII encoded characters can be written
+     * @exception SQLException if there is an error accessing the 
+     *            <code>CLOB</code> value
+     * @see #getAsciiStream
+     *
+     * @since 1.4
+     */
+    public java.io.OutputStream setAsciiStream(long pos) throws SQLException {
+      throw org.postgresql.Driver.notImplemented();
+    }
+
+    /**
+     * Retrieves a stream to be used to write a stream of Unicode characters 
+     * to the <code>CLOB</code> value that this <code>Clob</code> object
+     * represents, at position <code>pos</code>.
+     *
+     * @param  pos the position at which to start writing to the
+     *        <code>CLOB</code> value
+     *
+     * @return a stream to which Unicode encoded characters can be written
+     * @exception SQLException if there is an error accessing the 
+     *            <code>CLOB</code> value
+     * @see #getCharacterStream
+     *
+     * @since 1.4
+     */
+    public java.io.Writer setCharacterStream(long pos) throws SQLException {
+      throw org.postgresql.Driver.notImplemented();
+    }
+
+    /**
+     * Truncates the <code>CLOB</code> value that this <code>Clob</code> 
+     * designates to have a length of <code>len</code> 
+     * characters.
+     * @param len the length, in bytes, to which the <code>CLOB</code> value
+     *        should be truncated
+     * @exception SQLException if there is an error accessing the 
+     *            <code>CLOB</code> value
+     *
+     * @since 1.4
+     */
+    public void truncate(long len) throws SQLException {
+      throw org.postgresql.Driver.notImplemented();
+    }
+
+}
diff --git a/src/interfaces/jdbc/org/postgresql/jdbc3/AbstractJdbc3Connection.java b/src/interfaces/jdbc/org/postgresql/jdbc3/AbstractJdbc3Connection.java
new file mode 100644
index 0000000000000000000000000000000000000000..5988eddb4db4756b62fac75b845b6db5ff1bc1f8
--- /dev/null
+++ b/src/interfaces/jdbc/org/postgresql/jdbc3/AbstractJdbc3Connection.java
@@ -0,0 +1,369 @@
+package org.postgresql.jdbc3;
+
+import java.sql.*;
+
+/* $Header: /cvsroot/pgsql/src/interfaces/jdbc/org/postgresql/jdbc3/Attic/AbstractJdbc3Connection.java,v 1.1 2002/08/14 20:35:39 barry Exp $
+ * This class defines methods of the jdbc3 specification.  This class extends
+ * org.postgresql.jdbc2.AbstractJdbc2Connection which provides the jdbc2
+ * methods.  The real Connection class (for jdbc3) is org.postgresql.jdbc3.Jdbc3Connection
+ */
+public abstract class AbstractJdbc3Connection extends org.postgresql.jdbc2.AbstractJdbc2Connection
+{
+
+    /**
+     * Changes the holdability of <code>ResultSet</code> objects
+     * created using this <code>Connection</code> object to the given
+     * holdability.
+     *
+     * @param holdability a <code>ResultSet</code> holdability constant; one of
+     *        <code>ResultSet.HOLD_CURSORS_OVER_COMMIT</code> or
+     *        <code>ResultSet.CLOSE_CURSORS_AT_COMMIT</code>
+     * @throws SQLException if a database access occurs, the given parameter
+     *         is not a <code>ResultSet</code> constant indicating holdability,
+     *         or the given holdability is not supported
+     * @see #getHoldability
+     * @see ResultSet
+     * @since 1.4
+     */
+    public void setHoldability(int holdability) throws SQLException {
+      throw org.postgresql.Driver.notImplemented();
+    }
+
+    /**
+     * Retrieves the current holdability of <code>ResultSet</code> objects
+     * created using this <code>Connection</code> object.
+     *
+     * @return the holdability, one of
+     *        <code>ResultSet.HOLD_CURSORS_OVER_COMMIT</code> or
+     *        <code>ResultSet.CLOSE_CURSORS_AT_COMMIT</code>
+     * @throws SQLException if a database access occurs
+     * @see #setHoldability
+     * @see ResultSet
+     * @since 1.4
+     */
+    public int getHoldability() throws SQLException {
+      throw org.postgresql.Driver.notImplemented();
+    }
+ 
+    /**
+     * Creates an unnamed savepoint in the current transaction and 
+     * returns the new <code>Savepoint</code> object that represents it.
+     *
+     * @return the new <code>Savepoint</code> object
+     * @exception SQLException if a database access error occurs
+     *            or this <code>Connection</code> object is currently in
+     *            auto-commit mode
+     * @see Savepoint
+     * @since 1.4
+     */
+    public Savepoint setSavepoint() throws SQLException {
+      throw org.postgresql.Driver.notImplemented();
+    }
+ 
+    /**
+     * Creates a savepoint with the given name in the current transaction
+     * and returns the new <code>Savepoint</code> object that represents it.
+     *
+     * @param name a <code>String</code> containing the name of the savepoint
+     * @return the new <code>Savepoint</code> object
+     * @exception SQLException if a database access error occurs
+     *            or this <code>Connection</code> object is currently in
+     *            auto-commit mode
+     * @see Savepoint
+     * @since 1.4
+     */
+    public Savepoint setSavepoint(String name) throws SQLException {
+      throw org.postgresql.Driver.notImplemented();
+    }
+ 
+    /**
+     * Undoes all changes made after the given <code>Savepoint</code> object
+     * was set. 
+     * <P>
+     * This method should be used only when auto-commit has been disabled.
+     *
+     * @param savepoint the <code>Savepoint</code> object to roll back to
+     * @exception SQLException if a database access error occurs,
+     *            the <code>Savepoint</code> object is no longer valid,
+     *            or this <code>Connection</code> object is currently in
+     *            auto-commit mode
+     * @see Savepoint
+     * @see #rollback
+     * @since 1.4
+     */
+    public void rollback(Savepoint savepoint) throws SQLException {
+      throw org.postgresql.Driver.notImplemented();
+    }
+ 
+
+    /**
+     * Removes the given <code>Savepoint</code> object from the current 
+     * transaction. Any reference to the savepoint after it have been removed 
+     * will cause an <code>SQLException</code> to be thrown.
+     *
+     * @param savepoint the <code>Savepoint</code> object to be removed
+     * @exception SQLException if a database access error occurs or
+     *            the given <code>Savepoint</code> object is not a valid 
+     *            savepoint in the current transaction
+     * @since 1.4
+     */
+    public void releaseSavepoint(Savepoint savepoint) throws SQLException {
+      throw org.postgresql.Driver.notImplemented();
+    }
+ 
+
+    /**
+     * Creates a <code>Statement</code> object that will generate
+     * <code>ResultSet</code> objects with the given type, concurrency,
+     * and holdability.
+     * This method is the same as the <code>createStatement</code> method
+     * above, but it allows the default result set
+     * type, concurrency, and holdability to be overridden.
+     *
+     * @param resultSetType one of the following <code>ResultSet</code> 
+     *        constants:
+     *         <code>ResultSet.TYPE_FORWARD_ONLY</code>, 
+     *         <code>ResultSet.TYPE_SCROLL_INSENSITIVE</code>, or
+     *         <code>ResultSet.TYPE_SCROLL_SENSITIVE</code>
+     * @param resultSetConcurrency one of the following <code>ResultSet</code> 
+     *        constants:
+     *         <code>ResultSet.CONCUR_READ_ONLY</code> or
+     *         <code>ResultSet.CONCUR_UPDATABLE</code>
+     * @param resultSetHoldability one of the following <code>ResultSet</code> 
+     *        constants:
+     *         <code>ResultSet.HOLD_CURSORS_OVER_COMMIT</code> or
+     *         <code>ResultSet.CLOSE_CURSORS_AT_COMMIT</code>
+     * @return a new <code>Statement</code> object that will generate
+     *         <code>ResultSet</code> objects with the given type,
+     *         concurrency, and holdability
+     * @exception SQLException if a database access error occurs
+     *            or the given parameters are not <code>ResultSet</code> 
+     *            constants indicating type, concurrency, and holdability
+     * @see ResultSet
+     * @since 1.4
+     */
+    public Statement createStatement(int resultSetType, int resultSetConcurrency, 
+			      int resultSetHoldability) throws SQLException {
+      throw org.postgresql.Driver.notImplemented();
+    }
+ 
+
+    /**
+     * Creates a <code>PreparedStatement</code> object that will generate
+     * <code>ResultSet</code> objects with the given type, concurrency,
+     * and holdability.
+     * <P>
+     * This method is the same as the <code>prepareStatement</code> method
+     * above, but it allows the default result set
+     * type, concurrency, and holdability to be overridden.
+     *
+     * @param sql a <code>String</code> object that is the SQL statement to
+     *            be sent to the database; may contain one or more ? IN
+     *            parameters
+     * @param resultSetType one of the following <code>ResultSet</code> 
+     *        constants:
+     *         <code>ResultSet.TYPE_FORWARD_ONLY</code>, 
+     *         <code>ResultSet.TYPE_SCROLL_INSENSITIVE</code>, or
+     *         <code>ResultSet.TYPE_SCROLL_SENSITIVE</code>
+     * @param resultSetConcurrency one of the following <code>ResultSet</code> 
+     *        constants:
+     *         <code>ResultSet.CONCUR_READ_ONLY</code> or
+     *         <code>ResultSet.CONCUR_UPDATABLE</code>
+     * @param resultSetHoldability one of the following <code>ResultSet</code> 
+     *        constants:
+     *         <code>ResultSet.HOLD_CURSORS_OVER_COMMIT</code> or
+     *         <code>ResultSet.CLOSE_CURSORS_AT_COMMIT</code>
+     * @return a new <code>PreparedStatement</code> object, containing the
+     *         pre-compiled SQL statement, that will generate
+     *         <code>ResultSet</code> objects with the given type,
+     *         concurrency, and holdability
+     * @exception SQLException if a database access error occurs
+     *            or the given parameters are not <code>ResultSet</code> 
+     *            constants indicating type, concurrency, and holdability
+     * @see ResultSet
+     * @since 1.4
+     */
+    public PreparedStatement prepareStatement(String sql, int resultSetType, 
+				       int resultSetConcurrency, int resultSetHoldability)
+	throws SQLException {
+      throw org.postgresql.Driver.notImplemented();
+    }
+ 
+
+    /**
+     * Creates a <code>CallableStatement</code> object that will generate
+     * <code>ResultSet</code> objects with the given type and concurrency.
+     * This method is the same as the <code>prepareCall</code> method
+     * above, but it allows the default result set
+     * type, result set concurrency type and holdability to be overridden.
+     *
+     * @param sql a <code>String</code> object that is the SQL statement to
+     *            be sent to the database; may contain on or more ? parameters
+     * @param resultSetType one of the following <code>ResultSet</code> 
+     *        constants:
+     *         <code>ResultSet.TYPE_FORWARD_ONLY</code>, 
+     *         <code>ResultSet.TYPE_SCROLL_INSENSITIVE</code>, or
+     *         <code>ResultSet.TYPE_SCROLL_SENSITIVE</code>
+     * @param resultSetConcurrency one of the following <code>ResultSet</code> 
+     *        constants:
+     *         <code>ResultSet.CONCUR_READ_ONLY</code> or
+     *         <code>ResultSet.CONCUR_UPDATABLE</code>
+     * @param resultSetHoldability one of the following <code>ResultSet</code> 
+     *        constants:
+     *         <code>ResultSet.HOLD_CURSORS_OVER_COMMIT</code> or
+     *         <code>ResultSet.CLOSE_CURSORS_AT_COMMIT</code>
+     * @return a new <code>CallableStatement</code> object, containing the
+     *         pre-compiled SQL statement, that will generate
+     *         <code>ResultSet</code> objects with the given type,
+     *         concurrency, and holdability
+     * @exception SQLException if a database access error occurs
+     *            or the given parameters are not <code>ResultSet</code> 
+     *            constants indicating type, concurrency, and holdability
+     * @see ResultSet
+     * @since 1.4
+     */
+    public CallableStatement prepareCall(String sql, int resultSetType, 
+				  int resultSetConcurrency, 
+				  int resultSetHoldability) throws SQLException {
+      throw org.postgresql.Driver.notImplemented();
+    }
+ 
+
+
+    /**
+     * Creates a default <code>PreparedStatement</code> object that has
+     * the capability to retrieve auto-generated keys. The given constant
+     * tells the driver whether it should make auto-generated keys
+     * available for retrieval.  This parameter is ignored if the SQL 
+     * statement is not an <code>INSERT</code> statement.
+     * <P>
+     * <B>Note:</B> This method is optimized for handling
+     * parametric SQL statements that benefit from precompilation. If
+     * the driver supports precompilation,
+     * the method <code>prepareStatement</code> will send
+     * the statement to the database for precompilation. Some drivers
+     * may not support precompilation. In this case, the statement may
+     * not be sent to the database until the <code>PreparedStatement</code> 
+     * object is executed.  This has no direct effect on users; however, it does
+     * affect which methods throw certain SQLExceptions.
+     * <P>
+     * Result sets created using the returned <code>PreparedStatement</code>
+     * object will by default be type <code>TYPE_FORWARD_ONLY</code>
+     * and have a concurrency level of <code>CONCUR_READ_ONLY</code>.
+     *
+     * @param sql an SQL statement that may contain one or more '?' IN
+     *        parameter placeholders
+     * @param autoGeneratedKeys a flag indicating whether auto-generated keys 
+     *        should be returned; one of the following <code>Statement</code>
+     *        constants:
+     * @param autoGeneratedKeys a flag indicating that auto-generated keys should be returned, one of
+     *        <code>Statement.RETURN_GENERATED_KEYS</code> or
+     *	      <code>Statement.NO_GENERATED_KEYS</code>.  
+     * @return a new <code>PreparedStatement</code> object, containing the
+     *         pre-compiled SQL statement, that will have the capability of
+     *         returning auto-generated keys
+     * @exception SQLException if a database access error occurs
+     *         or the given parameter is not a <code>Statement</code>
+     *         constant indicating whether auto-generated keys should be
+     *         returned
+     * @since 1.4
+     */
+    public PreparedStatement prepareStatement(String sql, int autoGeneratedKeys)
+	throws SQLException {
+      throw org.postgresql.Driver.notImplemented();
+    }
+ 
+
+    /**
+     * Creates a default <code>PreparedStatement</code> object capable
+     * of returning the auto-generated keys designated by the given array.
+     * This array contains the indexes of the columns in the target
+     * table that contain the auto-generated keys that should be made
+     * available. This array is ignored if the SQL 
+     * statement is not an <code>INSERT</code> statement.
+     * <P>
+     * An SQL statement with or without IN parameters can be
+     * pre-compiled and stored in a <code>PreparedStatement</code> object. This
+     * object can then be used to efficiently execute this statement
+     * multiple times.
+     * <P>
+     * <B>Note:</B> This method is optimized for handling
+     * parametric SQL statements that benefit from precompilation. If
+     * the driver supports precompilation,
+     * the method <code>prepareStatement</code> will send
+     * the statement to the database for precompilation. Some drivers
+     * may not support precompilation. In this case, the statement may
+     * not be sent to the database until the <code>PreparedStatement</code> 
+     * object is executed.  This has no direct effect on users; however, it does
+     * affect which methods throw certain SQLExceptions.
+     * <P>
+     * Result sets created using the returned <code>PreparedStatement</code>
+     * object will by default be type <code>TYPE_FORWARD_ONLY</code>
+     * and have a concurrency level of <code>CONCUR_READ_ONLY</code>.
+     *
+     * @param sql an SQL statement that may contain one or more '?' IN
+     *        parameter placeholders
+     * @param columnIndexes an array of column indexes indicating the columns
+     *        that should be returned from the inserted row or rows 
+     * @return a new <code>PreparedStatement</code> object, containing the
+     *         pre-compiled statement, that is capable of returning the
+     *         auto-generated keys designated by the given array of column
+     *         indexes
+     * @exception SQLException if a database access error occurs
+     *
+     * @since 1.4
+     */
+    public PreparedStatement prepareStatement(String sql, int columnIndexes[])
+	throws SQLException {
+      throw org.postgresql.Driver.notImplemented();
+    }
+ 
+
+    /**
+     * Creates a default <code>PreparedStatement</code> object capable
+     * of returning the auto-generated keys designated by the given array.
+     * This array contains the names of the columns in the target
+     * table that contain the auto-generated keys that should be returned.
+     * This array is ignored if the SQL 
+     * statement is not an <code>INSERT</code> statement.
+     * <P>
+     * An SQL statement with or without IN parameters can be
+     * pre-compiled and stored in a <code>PreparedStatement</code> object. This
+     * object can then be used to efficiently execute this statement
+     * multiple times.
+     * <P>
+     * <B>Note:</B> This method is optimized for handling
+     * parametric SQL statements that benefit from precompilation. If
+     * the driver supports precompilation,
+     * the method <code>prepareStatement</code> will send
+     * the statement to the database for precompilation. Some drivers
+     * may not support precompilation. In this case, the statement may
+     * not be sent to the database until the <code>PreparedStatement</code> 
+     * object is executed.  This has no direct effect on users; however, it does
+     * affect which methods throw certain SQLExceptions.
+     * <P>
+     * Result sets created using the returned <code>PreparedStatement</code>
+     * object will by default be type <code>TYPE_FORWARD_ONLY</code>
+     * and have a concurrency level of <code>CONCUR_READ_ONLY</code>.
+     *
+     * @param sql an SQL statement that may contain one or more '?' IN
+     *        parameter placeholders
+     * @param columnNames an array of column names indicating the columns
+     *        that should be returned from the inserted row or rows 
+     * @return a new <code>PreparedStatement</code> object, containing the
+     *         pre-compiled statement, that is capable of returning the
+     *         auto-generated keys designated by the given array of column
+     *         names
+     * @exception SQLException if a database access error occurs
+     *
+     * @since 1.4
+     */
+    public PreparedStatement prepareStatement(String sql, String columnNames[])
+	throws SQLException {
+      throw org.postgresql.Driver.notImplemented();
+    }
+ 
+
+}
+
+
diff --git a/src/interfaces/jdbc/org/postgresql/jdbc3/AbstractJdbc3DatabaseMetaData.java b/src/interfaces/jdbc/org/postgresql/jdbc3/AbstractJdbc3DatabaseMetaData.java
new file mode 100644
index 0000000000000000000000000000000000000000..0c2e61d3a266f933b3a5fc47056cb0f3470ba4bf
--- /dev/null
+++ b/src/interfaces/jdbc/org/postgresql/jdbc3/AbstractJdbc3DatabaseMetaData.java
@@ -0,0 +1,339 @@
+package org.postgresql.jdbc3;
+
+
+import java.sql.*;
+
+public abstract class AbstractJdbc3DatabaseMetaData extends org.postgresql.jdbc2.AbstractJdbc2DatabaseMetaData
+{
+
+	public AbstractJdbc3DatabaseMetaData(AbstractJdbc3Connection conn)
+	{
+	    super(conn);
+	}
+
+
+    /**
+     * Retrieves whether this database supports savepoints.
+     *
+     * @return <code>true</code> if savepoints are supported; 
+     *         <code>false</code> otherwise
+     * @exception SQLException if a database access error occurs
+     * @since 1.4
+     */
+    public boolean supportsSavepoints() throws SQLException {
+      throw org.postgresql.Driver.notImplemented();
+    } 
+
+    /**
+     * Retrieves whether this database supports named parameters to callable 
+     * statements.
+     *
+     * @return <code>true</code> if named parameters are supported; 
+     *         <code>false</code> otherwise
+     * @exception SQLException if a database access error occurs
+     * @since 1.4
+     */
+    public boolean supportsNamedParameters() throws SQLException {
+      throw org.postgresql.Driver.notImplemented();
+    }
+
+    /**
+     * 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
+     * @exception SQLException if a datanase access error occurs
+     * @since 1.4
+     */
+    public boolean supportsMultipleOpenResults() throws SQLException {
+      throw org.postgresql.Driver.notImplemented();
+    }
+
+    /**
+     * 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
+     * @exception SQLException if a database access error occurs
+     * @since 1.4
+     */
+    public boolean supportsGetGeneratedKeys() throws SQLException {
+      throw org.postgresql.Driver.notImplemented();
+    }
+
+    /**
+     * 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. 
+     * <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:
+     *  <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_NAME</B> String => the direct super type's name
+     *  </OL>
+     *
+     * <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
+     * @return a <code>ResultSet</code> object in which a row gives information
+     *         about the designated UDT
+     * @throws SQLException if a database access error occurs
+     * @since 1.4
+     */
+    public ResultSet getSuperTypes(String catalog, String schemaPattern, 
+				   String typeNamePattern) throws SQLException {
+      throw org.postgresql.Driver.notImplemented();
+    }
+    
+    /**
+     * Retrieves a description of the table hierarchies defined in a particular 
+     * schema in this database.
+     *
+     * <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>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>)
+     *  <LI><B>TABLE_NAME</B> String => type name
+     *  <LI><B>SUPERTABLE_NAME</B> String => the direct super type's name
+     *  </OL>
+     *
+     * <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
+     * @throws SQLException if a database access error occurs
+     * @since 1.4
+     */
+    public ResultSet getSuperTables(String catalog, String schemaPattern,
+				    String tableNamePattern) throws SQLException {
+      throw org.postgresql.Driver.notImplemented();
+    }
+
+    /**
+     * 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.
+     * <P>
+     * 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> short => 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>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
+     *      </UL>
+     *	<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)
+     *  </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
+     * @exception SQLException if a database access error occurs
+     * @since 1.4
+     */
+    public ResultSet getAttributes(String catalog, String schemaPattern,
+			    String typeNamePattern, String attributeNamePattern) 
+	throws SQLException {
+      throw org.postgresql.Driver.notImplemented();
+    }
+
+    /**
+     * 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 
+     * @exception SQLException if a database access error occurs
+     * @see Connection
+     * @since 1.4
+     */
+    public boolean supportsResultSetHoldability(int holdability) throws SQLException {
+      throw org.postgresql.Driver.notImplemented();
+    }
+
+    /**
+     * 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>
+     * @exception SQLException if a database access error occurs
+     * @since 1.4
+     */
+    public int getResultSetHoldability() throws SQLException {
+      throw org.postgresql.Driver.notImplemented();
+    }
+
+    /**
+     * Retrieves the major version number of the underlying database.
+     *
+     * @return the underlying database's major version
+     * @exception SQLException if a database access error occurs
+     * @since 1.4
+     */
+    public int getDatabaseMajorVersion() throws SQLException {
+      throw org.postgresql.Driver.notImplemented();
+    }
+
+    /**
+     * Retrieves the minor version number of the underlying database.
+     *
+     * @return underlying database's minor version
+     * @exception SQLException if a database access error occurs
+     * @since 1.4
+     */
+    public int getDatabaseMinorVersion() throws SQLException {
+      throw org.postgresql.Driver.notImplemented();
+    }
+
+    /**
+     * Retrieves the major JDBC version number for this
+     * driver.
+     * 
+     * @return JDBC version major number
+     * @exception SQLException if a database access error occurs
+     * @since 1.4
+     */
+    public int getJDBCMajorVersion() throws SQLException {
+      throw org.postgresql.Driver.notImplemented();
+    }
+
+    /**
+     * Retrieves the minor JDBC version number for this
+     * driver.
+     * 
+     * @return JDBC version minor number
+     * @exception SQLException if a database access error occurs
+     * @since 1.4
+     */
+    public int getJDBCMinorVersion() throws SQLException {
+      throw org.postgresql.Driver.notImplemented();
+    }
+
+    /**
+     * Indicates whether the SQLSTATEs returned by <code>SQLException.getSQLState</code>
+     * is X/Open (now known as Open Group) SQL CLI or SQL99.
+     * @return the type of SQLSTATEs, one of:
+     *        sqlStateXOpen or
+     *        sqlStateSQL99
+     * @throws SQLException if a database access error occurs
+     * @since 1.4
+     */
+    public int getSQLStateType() throws SQLException {
+      throw org.postgresql.Driver.notImplemented();
+    }
+
+    /**
+     * 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
+     * @throws SQLException if a database access error occurs
+     * @since 1.4
+     */
+    public boolean locatorsUpdateCopy() throws SQLException {
+      throw org.postgresql.Driver.notImplemented();
+    }
+
+    /**
+     * Retrieves weather this database supports statement pooling.
+     *
+     * @return <code>true</code> is so;
+	       <code>false</code> otherwise
+     * @throws SQLExcpetion if a database access error occurs
+     * @since 1.4
+     */
+    public boolean supportsStatementPooling() throws SQLException {
+      throw org.postgresql.Driver.notImplemented();
+    }
+
+}
diff --git a/src/interfaces/jdbc/org/postgresql/jdbc3/AbstractJdbc3ResultSet.java b/src/interfaces/jdbc/org/postgresql/jdbc3/AbstractJdbc3ResultSet.java
new file mode 100644
index 0000000000000000000000000000000000000000..cc1609d6462b5a18ac9be27165d1b2d738f92bd2
--- /dev/null
+++ b/src/interfaces/jdbc/org/postgresql/jdbc3/AbstractJdbc3ResultSet.java
@@ -0,0 +1,181 @@
+package org.postgresql.jdbc3;
+
+
+import java.sql.*;
+import java.util.Vector;
+
+/* $Header: /cvsroot/pgsql/src/interfaces/jdbc/org/postgresql/jdbc3/Attic/AbstractJdbc3ResultSet.java,v 1.1 2002/08/14 20:35:39 barry Exp $
+ * This class defines methods of the jdbc3 specification.  This class extends
+ * org.postgresql.jdbc2.AbstractJdbc2ResultSet which provides the jdbc2
+ * methods.  The real Statement class (for jdbc3) is org.postgresql.jdbc3.Jdbc3ResultSet
+ */
+public abstract class AbstractJdbc3ResultSet extends org.postgresql.jdbc2.AbstractJdbc2ResultSet {
+
+  public AbstractJdbc3ResultSet(org.postgresql.PGConnection conn, Statement statement, org.postgresql.Field[] fields, Vector tuples, String status, int updateCount, long insertOID, boolean binaryCursor) {
+    super (conn, statement, fields, tuples, status, updateCount, insertOID, binaryCursor);
+  }
+
+    /**
+     * 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
+     * @exception SQLException if a database access error occurs,
+     *            or if a URL is malformed
+     * @since 1.4
+     */
+    public java.net.URL getURL(int columnIndex) throws SQLException {
+      throw org.postgresql.Driver.notImplemented();
+    }
+
+    /**
+     * 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
+     * @exception SQLException if a database access error occurs
+     *            or if a URL is malformed
+     * @since 1.4
+     */
+    public java.net.URL getURL(String columnName) throws SQLException {
+      throw org.postgresql.Driver.notImplemented();
+    }
+
+    /**
+     * 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
+     * @exception SQLException if a database access error occurs
+     * @since 1.4
+     */
+    public void updateRef(int columnIndex, java.sql.Ref x) throws SQLException {
+      throw org.postgresql.Driver.notImplemented();
+    }
+    
+    /** 
+     * 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
+     * @exception SQLException if a database access error occurs
+     * @since 1.4
+     */
+    public void updateRef(String columnName, java.sql.Ref x) throws SQLException {
+      throw org.postgresql.Driver.notImplemented();
+    }
+
+    /**
+     * 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
+     * @exception SQLException if a database access error occurs
+     * @since 1.4
+     */
+    public void updateBlob(int columnIndex, java.sql.Blob x) throws SQLException {
+      throw org.postgresql.Driver.notImplemented();
+    }
+
+    /** 
+     * 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
+     * @exception SQLException if a database access error occurs
+     * @since 1.4
+     */
+    public void updateBlob(String columnName, java.sql.Blob x) throws SQLException {
+      throw org.postgresql.Driver.notImplemented();
+    }
+
+    /**
+     * 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
+     * @exception SQLException if a database access error occurs
+     * @since 1.4
+     */
+    public void updateClob(int columnIndex, java.sql.Clob x) throws SQLException {
+      throw org.postgresql.Driver.notImplemented();
+    }
+
+    /** 
+     * 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
+     * @exception SQLException if a database access error occurs
+     * @since 1.4
+     */
+    public void updateClob(String columnName, java.sql.Clob x) throws SQLException {
+      throw org.postgresql.Driver.notImplemented();
+    }
+
+    /**
+     * 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
+     * @exception SQLException if a database access error occurs
+     * @since 1.4
+     */
+    public void updateArray(int columnIndex, java.sql.Array x) throws SQLException {
+      throw org.postgresql.Driver.notImplemented();
+    }
+
+    /** 
+     * 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
+     * @exception SQLException if a database access error occurs
+     * @since 1.4
+     */
+    public void updateArray(String columnName, java.sql.Array x) throws SQLException {
+      throw org.postgresql.Driver.notImplemented();
+    }
+
+}
+
diff --git a/src/interfaces/jdbc/org/postgresql/jdbc3/AbstractJdbc3Statement.java b/src/interfaces/jdbc/org/postgresql/jdbc3/AbstractJdbc3Statement.java
new file mode 100644
index 0000000000000000000000000000000000000000..8b18e6153d9617290097ecdf11f02e0497eeb163
--- /dev/null
+++ b/src/interfaces/jdbc/org/postgresql/jdbc3/AbstractJdbc3Statement.java
@@ -0,0 +1,1300 @@
+package org.postgresql.jdbc3;
+
+
+import java.math.BigDecimal;
+import java.sql.*;
+import java.util.Calendar;
+
+/* $Header: /cvsroot/pgsql/src/interfaces/jdbc/org/postgresql/jdbc3/Attic/AbstractJdbc3Statement.java,v 1.1 2002/08/14 20:35:39 barry Exp $
+ * This class defines methods of the jdbc3 specification.  This class extends
+ * org.postgresql.jdbc2.AbstractJdbc2Statement which provides the jdbc2
+ * methods.  The real Statement class (for jdbc2) is org.postgresql.jdbc3.Jdbc3Statement
+ */
+public abstract class AbstractJdbc3Statement extends org.postgresql.jdbc2.AbstractJdbc2Statement
+{
+
+	public AbstractJdbc3Statement (AbstractJdbc3Connection c)
+	{
+		super(c);
+	}
+
+	public AbstractJdbc3Statement(AbstractJdbc3Connection connection, String sql) throws SQLException
+	{
+		super(connection, sql);
+	}
+
+    /**
+     * 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>There are no more results when the following is true:
+     * <PRE>
+     *      <code>(!getMoreResults() && (getUpdateCount() == -1)</code>
+     * </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>CLOSE_CURRENT_RESULT</code>, 
+     *        <code>KEEP_CURRENT_RESULT</code>, or
+     *        <code>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
+     * @exception SQLException if a database access error occurs
+     * @since 1.4
+     * @see #execute
+     */
+    public boolean getMoreResults(int current) throws SQLException {
+      throw org.postgresql.Driver.notImplemented();
+    }
+
+    /**
+     * 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.
+     *
+     * @return a <code>ResultSet</code> object containing the auto-generated key(s) 
+     *         generated by the execution of this <code>Statement</code> object
+     * @exception SQLException if a database access error occurs
+     * @since 1.4
+     */
+    public ResultSet getGeneratedKeys() throws SQLException {
+      throw org.postgresql.Driver.notImplemented();
+    }
+
+    /**
+     * 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
+     * @exception 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
+     * @since 1.4
+     */
+    public int executeUpdate(String sql, int autoGeneratedKeys) throws SQLException {
+      throw org.postgresql.Driver.notImplemented();
+    }
+
+    /**
+     * 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.
+     *
+     * @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
+     * @exception SQLException if a database access error occurs or the SQL
+     *            statement returns a <code>ResultSet</code> object
+     * @since 1.4
+     */
+    public int executeUpdate(String sql, int columnIndexes[]) throws SQLException {
+      throw org.postgresql.Driver.notImplemented();
+    }
+
+    /**
+     * 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.
+     *
+     * @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
+     * @exception SQLException if a database access error occurs
+     *
+     * @since 1.4
+     */
+    public int executeUpdate(String sql, String columnNames[]) throws SQLException {
+      throw org.postgresql.Driver.notImplemented();
+    }
+
+    /**
+     * 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.  
+     * <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).
+     *
+     * @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
+     * @exception SQLException if a database access error occurs
+     * @see #getResultSet
+     * @see #getUpdateCount
+     * @see #getMoreResults
+     * @see #getGeneratedKeys
+     *
+     * @since 1.4 
+     */
+    public boolean execute(String sql, int autoGeneratedKeys) throws SQLException {
+      throw org.postgresql.Driver.notImplemented();
+    }
+
+    /**
+     * 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.  
+     * <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).
+     *
+     * @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
+     * @exception SQLException if a database access error occurs
+     * @see #getResultSet
+     * @see #getUpdateCount
+     * @see #getMoreResults
+     *
+     * @since 1.4
+     */
+    public boolean execute(String sql, int columnIndexes[]) throws SQLException {
+      throw org.postgresql.Driver.notImplemented();
+    }
+
+    /**
+     * 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.  
+     * <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).
+     *
+     * @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
+     * @exception SQLException if a database access error occurs
+     * @see #getResultSet
+     * @see #getUpdateCount
+     * @see #getMoreResults
+     * @see #getGeneratedKeys
+     *
+     * @since 1.4 
+     */
+    public boolean execute(String sql, String columnNames[]) throws SQLException {
+      throw org.postgresql.Driver.notImplemented();
+    }
+
+   /**
+     * Retrieves the result set holdability for <code>ResultSet</code> objects
+     * generated by this <code>Statement</code> object.
+     *
+     * @return either <code>ResultSet.HOLD_CURSORS_OVER_COMMIT</code> or
+     *         <code>ResultSet.CLOSE_CURSORS_AT_COMMIT</code>
+     * @exception SQLException if a database access error occurs
+     *
+     * @since 1.4
+     */
+    public int getResultSetHoldability() throws SQLException {
+      throw org.postgresql.Driver.notImplemented();
+    }
+
+    /**
+     * 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.
+     *
+     * @param parameterIndex the first parameter is 1, the second is 2, ...
+     * @param x the <code>java.net.URL</code> object to be set
+     * @exception SQLException if a database access error occurs
+     * @since 1.4
+     */ 
+    public void setURL(int parameterIndex, java.net.URL x) throws SQLException {
+      throw org.postgresql.Driver.notImplemented();
+    }
+
+    /**
+     * Retrieves the number, types and properties of this 
+     * <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
+     * @exception SQLException if a database access error occurs
+     * @see ParameterMetaData
+     * @since 1.4
+     */
+    public ParameterMetaData getParameterMetaData() throws SQLException {
+      throw org.postgresql.Driver.notImplemented();
+    }
+
+    /**
+     * 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.
+     * <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.
+     * @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.
+     * @exception SQLException if a database access error occurs
+     * @since 1.4
+     * @see Types 
+     */
+    public void registerOutParameter(String parameterName, int sqlType)
+	throws SQLException {
+      throw org.postgresql.Driver.notImplemented();
+    }
+
+    /**
+     * 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.
+     * <p>
+     * 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.
+     * @exception SQLException if a database access error occurs
+     * @since 1.4
+     * @see Types 
+     */
+    public void registerOutParameter(String parameterName, int sqlType, int scale)
+	throws SQLException {
+      throw org.postgresql.Driver.notImplemented();
+    }
+
+    /**
+     * 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.
+     *
+     * 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.
+     *
+     * 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><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
+     * @exception SQLException if a database access error occurs
+     * @see Types
+     * @since 1.4
+     */
+    public void registerOutParameter (String parameterName, int sqlType, String typeName)
+	throws SQLException {
+      throw org.postgresql.Driver.notImplemented();
+    }
+
+    /**
+     * 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
+     * @exception 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
+     */
+    public java.net.URL getURL(int parameterIndex) throws SQLException {
+      throw org.postgresql.Driver.notImplemented();
+    }
+
+    /**
+     * 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.
+     *
+     * @param parameterName the name of the parameter
+     * @param val the parameter value
+     * @exception SQLException if a database access error occurs,
+     *            or if a URL is malformed
+     * @see #getURL
+     * @since 1.4
+     */
+    public void setURL(String parameterName, java.net.URL val) throws SQLException {
+      throw org.postgresql.Driver.notImplemented();
+    }
+
+    /**
+     * Sets the designated parameter to SQL <code>NULL</code>.
+     *
+     * <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>
+     * @exception SQLException if a database access error occurs
+     * @since 1.4
+     */
+    public void setNull(String parameterName, int sqlType) throws SQLException {
+      throw org.postgresql.Driver.notImplemented();
+    }
+
+    /**
+     * 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.
+     *
+     * @param parameterName the name of the parameter
+     * @param x the parameter value
+     * @exception SQLException if a database access error occurs
+     * @see #getBoolean
+     * @since 1.4
+     */
+    public void setBoolean(String parameterName, boolean x) throws SQLException {
+      throw org.postgresql.Driver.notImplemented();
+    }
+
+    /**
+     * 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
+     * @exception SQLException if a database access error occurs
+     * @see #getByte
+     * @since 1.4
+     */
+    public void setByte(String parameterName, byte x) throws SQLException {
+      throw org.postgresql.Driver.notImplemented();
+    }
+
+    /**
+     * 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
+     * @exception SQLException if a database access error occurs
+     * @see #getShort
+     * @since 1.4
+     */
+    public void setShort(String parameterName, short x) throws SQLException {
+      throw org.postgresql.Driver.notImplemented();
+    }
+
+    /**
+     * 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
+     * @exception SQLException if a database access error occurs
+     * @see #getInt
+     * @since 1.4
+     */
+    public void setInt(String parameterName, int x) throws SQLException {
+      throw org.postgresql.Driver.notImplemented();
+    }
+
+    /**
+     * 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
+     * @exception SQLException if a database access error occurs
+     * @see #getLong
+     * @since 1.4
+     */
+    public void setLong(String parameterName, long x) throws SQLException {
+      throw org.postgresql.Driver.notImplemented();
+    }
+
+    /**
+     * 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
+     * @exception SQLException if a database access error occurs
+     * @see #getFloat
+     * @since 1.4
+     */
+    public void setFloat(String parameterName, float x) throws SQLException {
+      throw org.postgresql.Driver.notImplemented();
+    }
+
+    /**
+     * 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.
+     *
+     * @param parameterName the name of the parameter
+     * @param x the parameter value
+     * @exception SQLException if a database access error occurs
+     * @see #getDouble
+     * @since 1.4
+     */
+    public void setDouble(String parameterName, double x) throws SQLException {
+      throw org.postgresql.Driver.notImplemented();
+    }
+
+    /**
+     * 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
+     * @exception SQLException if a database access error occurs
+     * @see #getBigDecimal
+     * @since 1.4
+     */
+    public void setBigDecimal(String parameterName, BigDecimal x) throws SQLException {
+      throw org.postgresql.Driver.notImplemented();
+    }
+
+    /**
+     * 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.
+     *
+     * @param parameterName the name of the parameter
+     * @param x the parameter value
+     * @exception SQLException if a database access error occurs
+     * @see #getString
+     * @since 1.4
+     */
+    public void setString(String parameterName, String x) throws SQLException {
+      throw org.postgresql.Driver.notImplemented();
+    }
+
+    /**
+     * 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 
+     * @exception SQLException if a database access error occurs
+     * @see #getBytes
+     * @since 1.4
+     */
+    public void setBytes(String parameterName, byte x[]) throws SQLException {
+      throw org.postgresql.Driver.notImplemented();
+    }
+
+    /**
+     * 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.
+     *
+     * @param parameterName the name of the parameter
+     * @param x the parameter value
+     * @exception SQLException if a database access error occurs
+     * @see #getDate
+     * @since 1.4
+     */
+    public void setDate(String parameterName, java.sql.Date x)
+	throws SQLException {
+      throw org.postgresql.Driver.notImplemented();
+    }
+
+    /**
+     * 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.
+     *
+     * @param parameterName the name of the parameter
+     * @param x the parameter value
+     * @exception SQLException if a database access error occurs
+     * @see #getTime
+     * @since 1.4
+     */
+    public void setTime(String parameterName, java.sql.Time x) 
+	throws SQLException {
+      throw org.postgresql.Driver.notImplemented();
+    }
+
+    /**
+     * 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 
+     * @exception SQLException if a database access error occurs
+     * @see #getTimestamp
+     * @since 1.4
+     */
+    public void setTimestamp(String parameterName, java.sql.Timestamp x)
+	throws SQLException {
+      throw org.postgresql.Driver.notImplemented();
+    }
+
+    /**
+     * 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><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 
+     * @exception SQLException if a database access error occurs
+     * @since 1.4
+     */
+    public void setAsciiStream(String parameterName, java.io.InputStream x, int length)
+	throws SQLException {
+      throw org.postgresql.Driver.notImplemented();
+    }
+
+    /**
+     * 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><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 
+     * @exception SQLException if a database access error occurs
+     * @since 1.4
+     */
+    public void setBinaryStream(String parameterName, java.io.InputStream x, 
+				int length) throws SQLException {
+      throw org.postgresql.Driver.notImplemented();
+    }
+
+    /**
+     * 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>The given Java object will be converted to the given targetSqlType
+     * before being sent to the database.
+     *
+     * 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. 
+     *
+     * @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.
+     * @exception SQLException if a database access error occurs
+     * @see Types
+     * @see #getObject
+     * @since 1.4 
+     */
+    public void setObject(String parameterName, Object x, int targetSqlType, int scale)
+	throws SQLException {
+      throw org.postgresql.Driver.notImplemented();
+    }
+
+    /**
+     * 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
+     * @exception SQLException if a database access error occurs
+     * @see #getObject
+     * @since 1.4
+     */
+    public void setObject(String parameterName, Object x, int targetSqlType) 
+	throws SQLException {
+      throw org.postgresql.Driver.notImplemented();
+    }
+
+    /**
+     * 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>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>Note that this method may be used to pass datatabase-
+     * specific abstract data types, by using a driver-specific Java
+     * type.
+     *
+     * 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.
+     * <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.
+     *
+     * @param parameterName the name of the parameter
+     * @param x the object containing the input parameter value 
+     * @exception SQLException if a database access error occurs or if the given
+     *            <code>Object</code> parameter is ambiguous
+     * @see #getObject
+     * @since 1.4
+     */
+    public void setObject(String parameterName, Object x) throws SQLException {
+      throw org.postgresql.Driver.notImplemented();
+    }
+   
+
+    /**
+     * 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><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 
+     * @exception SQLException if a database access error occurs
+     * @since 1.4
+     */
+    public void setCharacterStream(String parameterName,
+			    java.io.Reader reader,
+				   int length) throws SQLException {
+      throw org.postgresql.Driver.notImplemented();
+    }
+
+    /**
+     * 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.
+     *
+     * @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
+     * @exception SQLException if a database access error occurs
+     * @see #getDate
+     * @since 1.4
+     */
+    public void setDate(String parameterName, java.sql.Date x, Calendar cal)
+	throws SQLException {
+      throw org.postgresql.Driver.notImplemented();
+    }
+
+    /**
+     * 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.
+     *
+     * @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
+     * @exception SQLException if a database access error occurs
+     * @see #getTime
+     * @since 1.4
+     */
+    public void setTime(String parameterName, java.sql.Time x, Calendar cal) 
+	throws SQLException {
+      throw org.postgresql.Driver.notImplemented();
+    }
+
+    /**
+     * 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
+     * @exception SQLException if a database access error occurs
+     * @see #getTimestamp
+     * @since 1.4
+     */
+    public void setTimestamp(String parameterName, java.sql.Timestamp x, Calendar cal)
+	throws SQLException {
+      throw org.postgresql.Driver.notImplemented();
+    }
+
+    /**
+     * 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><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.     
+     *
+     * 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 paramName 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
+     * @exception SQLException if a database access error occurs
+     * @since 1.4
+     */
+    public void setNull (String parameterName, int sqlType, String typeName) 
+	throws SQLException {
+      throw org.postgresql.Driver.notImplemented();
+    }
+
+    /**
+     * 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.
+     * @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>.
+     * @exception SQLException if a database access error occurs
+     * @see #setString
+     * @since 1.4
+     */
+    public String getString(String parameterName) throws SQLException {
+      throw org.postgresql.Driver.notImplemented();
+    }
+
+    /**
+     * Retrieves the value of a JDBC <code>BIT</code> parameter as a
+     * <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>.
+     * @exception SQLException if a database access error occurs
+     * @see #setBoolean
+     * @since 1.4
+     */
+    public boolean getBoolean(String parameterName) throws SQLException {
+      throw org.postgresql.Driver.notImplemented();
+    }
+
+    /**
+     * 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>.
+     * @exception SQLException if a database access error occurs
+     * @see #setByte
+     * @since 1.4
+     */
+    public byte getByte(String parameterName) throws SQLException {
+      throw org.postgresql.Driver.notImplemented();
+    }
+
+    /**
+     * 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>.
+     * @exception SQLException if a database access error occurs
+     * @see #setShort
+     * @since 1.4
+     */
+    public short getShort(String parameterName) throws SQLException {
+      throw org.postgresql.Driver.notImplemented();
+    }
+
+    /**
+     * 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>.
+     * @exception SQLException if a database access error occurs
+     * @see #setInt
+     * @since 1.4
+     */
+    public int getInt(String parameterName) throws SQLException {
+      throw org.postgresql.Driver.notImplemented();
+    }
+
+    /**
+     * 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>.
+     * @exception SQLException if a database access error occurs
+     * @see #setLong
+     * @since 1.4
+     */
+    public long getLong(String parameterName) throws SQLException {
+      throw org.postgresql.Driver.notImplemented();
+    }
+
+    /**
+     * 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>.
+     * @exception SQLException if a database access error occurs
+     * @see #setFloat
+     * @since 1.4
+     */
+    public float getFloat(String parameterName) throws SQLException {
+      throw org.postgresql.Driver.notImplemented();
+    }
+
+    /**
+     * 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>.
+     * @exception SQLException if a database access error occurs
+     * @see #setDouble
+     * @since 1.4
+     */
+    public double getDouble(String parameterName) throws SQLException {
+      throw org.postgresql.Driver.notImplemented();
+    }
+
+    /**
+     * 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.
+     * @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>.
+     * @exception SQLException if a database access error occurs
+     * @see #setBytes
+     * @since 1.4
+     */
+    public byte[] getBytes(String parameterName) throws SQLException {
+      throw org.postgresql.Driver.notImplemented();
+    }
+
+    /**
+     * Retrieves the value of a JDBC <code>DATE</code> parameter as a 
+     * <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>.
+     * @exception SQLException if a database access error occurs
+     * @see #setDate
+     * @since 1.4
+     */
+    public java.sql.Date getDate(String parameterName) throws SQLException {
+      throw org.postgresql.Driver.notImplemented();
+    }
+
+    /**
+     * Retrieves the value of a JDBC <code>TIME</code> parameter as a 
+     * <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>.
+     * @exception SQLException if a database access error occurs
+     * @see #setTime
+     * @since 1.4
+     */
+    public java.sql.Time getTime(String parameterName) throws SQLException {
+      throw org.postgresql.Driver.notImplemented();
+    }
+
+    /**
+     * Retrieves the value of a JDBC <code>TIMESTAMP</code> parameter as a 
+     * <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>.
+     * @exception SQLException if a database access error occurs
+     * @see #setTimestamp
+     * @since 1.4
+     */
+    public java.sql.Timestamp getTimestamp(String parameterName) throws SQLException {
+      throw org.postgresql.Driver.notImplemented();
+    }
+
+    /**
+     * 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>.
+     * <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.
+     * @param parameterName the name of the parameter
+     * @return A <code>java.lang.Object</code> holding the OUT parameter value.
+     * @exception SQLException if a database access error occurs
+     * @see Types
+     * @see #setObject
+     * @since 1.4
+     */
+    public Object getObject(String parameterName) throws SQLException {
+      throw org.postgresql.Driver.notImplemented();
+    }
+
+    /**
+     * 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.
+     * @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>. 
+     * @exception SQLException if a database access error occurs
+     * @see #setBigDecimal
+     * @since 1.4
+     */
+    public BigDecimal getBigDecimal(String parameterName) throws SQLException {
+      throw org.postgresql.Driver.notImplemented();
+    }
+
+    /**
+     * 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.  
+     * @param parameterName the name of the parameter
+     * @param map the mapping from SQL type names to Java classes
+     * @return a <code>java.lang.Object</code> holding the OUT parameter value
+     * @exception SQLException if a database access error occurs
+     * @see #setObject
+     * @since 1.4
+     */
+    public Object  getObject (String parameterName, java.util.Map map) throws SQLException {
+      throw org.postgresql.Driver.notImplemented();
+    }
+
+    /**
+     * Retrieves the value of a JDBC <code>REF(&lt;structured-type&gt;)</code>
+     * parameter as a {@link 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.
+     * @exception SQLException if a database access error occurs
+     * @since 1.4
+     */
+    public Ref getRef (String parameterName) throws SQLException {
+      throw org.postgresql.Driver.notImplemented();
+    }
+
+    /**
+     * Retrieves the value of a JDBC <code>BLOB</code> parameter as a
+     * {@link 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.
+     * @exception SQLException if a database access error occurs
+     * @since 1.4
+     */
+    public Blob getBlob (String parameterName) throws SQLException {
+      throw org.postgresql.Driver.notImplemented();
+    }
+
+    /**
+     * Retrieves the value of a JDBC <code>CLOB</code> parameter as a
+     * <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.
+     * @exception SQLException if a database access error occurs
+     * @since 1.4
+     */
+    public Clob getClob (String parameterName) throws SQLException {
+      throw org.postgresql.Driver.notImplemented();
+    }
+
+    /**
+     * Retrieves the value of a JDBC <code>ARRAY</code> parameter as an
+     * {@link 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.
+     * @exception SQLException if a database access error occurs
+     * @since 1.4
+     */
+    public Array getArray (String parameterName) throws SQLException {
+      throw org.postgresql.Driver.notImplemented();
+    }
+
+    /**
+     * 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.
+     *
+     * @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>.
+     * @exception SQLException if a database access error occurs
+     * @see #setDate
+     * @since 1.4
+     */
+    public java.sql.Date getDate(String parameterName, Calendar cal) 
+	throws SQLException {
+      throw org.postgresql.Driver.notImplemented();
+    }
+
+    /**
+     * 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.
+     *
+     * @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>.
+     * @exception SQLException if a database access error occurs
+     * @see #setTime
+     * @since 1.4
+     */
+    public java.sql.Time getTime(String parameterName, Calendar cal) 
+	throws SQLException {
+      throw org.postgresql.Driver.notImplemented();
+    }
+
+    /**
+     * 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.
+     *
+     *
+     * @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>.
+     * @exception SQLException if a database access error occurs
+     * @see #setTimestamp
+     * @since 1.4
+     */
+    public java.sql.Timestamp getTimestamp(String parameterName, Calendar cal) 
+	throws SQLException {
+      throw org.postgresql.Driver.notImplemented();
+    }
+
+    /**
+     * Retrieves the value of a JDBC <code>DATALINK</code> parameter as a
+     * <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.
+     * @exception SQLException if a database access error occurs,
+     *            or if there is a problem with the URL
+     * @see #setURL
+     * @since 1.4
+     */
+    public java.net.URL getURL(String parameterName) throws SQLException {
+      throw org.postgresql.Driver.notImplemented();
+    }
+
+}
diff --git a/src/interfaces/jdbc/org/postgresql/jdbc3/Jdbc3Blob.java b/src/interfaces/jdbc/org/postgresql/jdbc3/Jdbc3Blob.java
new file mode 100644
index 0000000000000000000000000000000000000000..9d0839898bd55cc95268a628785f9b115f719b31
--- /dev/null
+++ b/src/interfaces/jdbc/org/postgresql/jdbc3/Jdbc3Blob.java
@@ -0,0 +1,14 @@
+package org.postgresql.jdbc3;
+
+
+import java.sql.*;
+
+public class Jdbc3Blob extends org.postgresql.jdbc3.AbstractJdbc3Blob implements java.sql.Blob
+{
+
+	public Jdbc3Blob(org.postgresql.PGConnection conn, int oid) throws SQLException
+	{
+		super(conn, oid);
+	}
+
+}
diff --git a/src/interfaces/jdbc/org/postgresql/jdbc3/Jdbc3CallableStatement.java b/src/interfaces/jdbc/org/postgresql/jdbc3/Jdbc3CallableStatement.java
new file mode 100644
index 0000000000000000000000000000000000000000..eef5bd4fbc679e583b5799960cdc4fcfb0361ca6
--- /dev/null
+++ b/src/interfaces/jdbc/org/postgresql/jdbc3/Jdbc3CallableStatement.java
@@ -0,0 +1,15 @@
+package org.postgresql.jdbc3;
+
+
+import java.sql.*;
+
+public class Jdbc3CallableStatement extends org.postgresql.jdbc3.AbstractJdbc3Statement implements java.sql.CallableStatement
+{
+    
+	public Jdbc3CallableStatement(Jdbc3Connection connection, String sql) throws SQLException
+	{
+		super(connection, sql);
+	}
+    
+}
+
diff --git a/src/interfaces/jdbc/org/postgresql/jdbc3/Jdbc3Clob.java b/src/interfaces/jdbc/org/postgresql/jdbc3/Jdbc3Clob.java
new file mode 100644
index 0000000000000000000000000000000000000000..b65ffc7082c52317a13c67c2e1f47e63248ba40e
--- /dev/null
+++ b/src/interfaces/jdbc/org/postgresql/jdbc3/Jdbc3Clob.java
@@ -0,0 +1,12 @@
+package org.postgresql.jdbc3;
+
+
+public class Jdbc3Clob extends org.postgresql.jdbc3.AbstractJdbc3Clob implements java.sql.Clob
+{
+
+	public Jdbc3Clob(org.postgresql.PGConnection conn, int oid) throws java.sql.SQLException
+	{
+		super(conn, oid);
+	}
+
+}
diff --git a/src/interfaces/jdbc/org/postgresql/jdbc3/Jdbc3Connection.java b/src/interfaces/jdbc/org/postgresql/jdbc3/Jdbc3Connection.java
new file mode 100644
index 0000000000000000000000000000000000000000..b6f279d7e23acb1144293c73a6a543ddcf518dfd
--- /dev/null
+++ b/src/interfaces/jdbc/org/postgresql/jdbc3/Jdbc3Connection.java
@@ -0,0 +1,61 @@
+package org.postgresql.jdbc3;
+
+
+import java.sql.*;
+import java.util.Vector;
+import java.util.Hashtable;
+import org.postgresql.Field;
+
+/* $Header: /cvsroot/pgsql/src/interfaces/jdbc/org/postgresql/jdbc3/Attic/Jdbc3Connection.java,v 1.1 2002/08/14 20:35:40 barry Exp $
+ * This class implements the java.sql.Connection interface for JDBC3.
+ * However most of the implementation is really done in 
+ * org.postgresql.jdbc3.AbstractJdbc3Connection or one of it's parents
+ */
+public class Jdbc3Connection extends org.postgresql.jdbc3.AbstractJdbc3Connection implements java.sql.Connection
+{
+   
+        public java.sql.Statement createStatement(int resultSetType, int resultSetConcurrency) throws SQLException
+        {
+                Jdbc3Statement s = new Jdbc3Statement(this);
+                s.setResultSetType(resultSetType);
+                s.setResultSetConcurrency(resultSetConcurrency);
+                return s;
+        }
+
+
+        public java.sql.PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency) throws SQLException
+        {
+                Jdbc3PreparedStatement s = new Jdbc3PreparedStatement(this, sql);
+                s.setResultSetType(resultSetType);
+                s.setResultSetConcurrency(resultSetConcurrency);
+                return s;
+        }
+
+        public java.sql.CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency) throws SQLException
+        {
+		Jdbc3CallableStatement s = new Jdbc3CallableStatement(this,sql);
+		s.setResultSetType(resultSetType);
+	      	s.setResultSetConcurrency(resultSetConcurrency);
+	       	return s;
+        }
+
+        public java.sql.DatabaseMetaData getMetaData() throws SQLException
+        {
+                if (metadata == null)
+                  metadata = new Jdbc3DatabaseMetaData(this);
+                return metadata;
+        }
+
+        public java.sql.ResultSet getResultSet(Statement statement, Field[] fields, Vector tuples, String status, int updateCount, long insertOID, boolean binaryCursor) throws SQLException
+        {
+                return new Jdbc3ResultSet(this, statement, fields, tuples, status, updateCount, insertOID, binaryCursor);
+        }
+
+        public java.sql.ResultSet getResultSet(Statement statement, Field[] fields, Vector tuples, String status, int updateCount) throws SQLException
+        {
+                return new Jdbc3ResultSet(this, statement, fields, tuples, status, updateCount, 0, false);
+        }
+    
+}
+
+
diff --git a/src/interfaces/jdbc/org/postgresql/jdbc3/Jdbc3DatabaseMetaData.java b/src/interfaces/jdbc/org/postgresql/jdbc3/Jdbc3DatabaseMetaData.java
new file mode 100644
index 0000000000000000000000000000000000000000..c242c6322837d135b6d34715c2a10079d0b85229
--- /dev/null
+++ b/src/interfaces/jdbc/org/postgresql/jdbc3/Jdbc3DatabaseMetaData.java
@@ -0,0 +1,12 @@
+package org.postgresql.jdbc3;
+
+
+public class Jdbc3DatabaseMetaData extends org.postgresql.jdbc3.AbstractJdbc3DatabaseMetaData implements java.sql.DatabaseMetaData
+{
+    
+	public Jdbc3DatabaseMetaData(Jdbc3Connection conn)
+	{
+		super(conn);
+	}
+    
+}
diff --git a/src/interfaces/jdbc/org/postgresql/jdbc3/Jdbc3PreparedStatement.java b/src/interfaces/jdbc/org/postgresql/jdbc3/Jdbc3PreparedStatement.java
new file mode 100644
index 0000000000000000000000000000000000000000..bc570129ebdddc72aa6acf1640d39f410849f2f5
--- /dev/null
+++ b/src/interfaces/jdbc/org/postgresql/jdbc3/Jdbc3PreparedStatement.java
@@ -0,0 +1,15 @@
+package org.postgresql.jdbc3;
+
+
+import java.sql.*;
+
+public class Jdbc3PreparedStatement extends org.postgresql.jdbc3.AbstractJdbc3Statement implements java.sql.PreparedStatement
+{
+   
+	public Jdbc3PreparedStatement(Jdbc3Connection connection, String sql) throws SQLException
+	{
+		super(connection, sql);
+	}
+   
+}
+
diff --git a/src/interfaces/jdbc/org/postgresql/jdbc3/Jdbc3ResultSet.java b/src/interfaces/jdbc/org/postgresql/jdbc3/Jdbc3ResultSet.java
new file mode 100644
index 0000000000000000000000000000000000000000..f2652ee1f5a2982a6e2a9a4291971672e5cf281d
--- /dev/null
+++ b/src/interfaces/jdbc/org/postgresql/jdbc3/Jdbc3ResultSet.java
@@ -0,0 +1,35 @@
+package org.postgresql.jdbc3;
+
+
+import java.sql.*;
+import java.util.Vector;
+import org.postgresql.Field;
+
+/* $Header: /cvsroot/pgsql/src/interfaces/jdbc/org/postgresql/jdbc3/Attic/Jdbc3ResultSet.java,v 1.1 2002/08/14 20:35:40 barry Exp $
+ * This class implements the java.sql.ResultSet interface for JDBC3.
+ * However most of the implementation is really done in 
+ * org.postgresql.jdbc3.AbstractJdbc3ResultSet or one of it's parents
+ */
+public class Jdbc3ResultSet extends org.postgresql.jdbc3.AbstractJdbc3ResultSet implements java.sql.ResultSet
+{
+    
+	public Jdbc3ResultSet(Jdbc3Connection conn, Statement statement, Field[] fields, Vector tuples, String status, int updateCount, long insertOID, boolean binaryCursor)
+	{
+		super(conn, statement, fields, tuples, status, updateCount, insertOID, binaryCursor);
+	}
+    
+	public java.sql.ResultSetMetaData getMetaData() throws SQLException
+	{
+		return new Jdbc3ResultSetMetaData(rows, fields);
+	}
+    
+        public java.sql.Clob getClob(int i) throws SQLException {
+          return new Jdbc3Clob(connection, getInt(i));
+        }
+
+        public java.sql.Blob getBlob(int i) throws SQLException {
+          return new Jdbc3Blob(connection, getInt(i));
+        }
+
+}
+
diff --git a/src/interfaces/jdbc/org/postgresql/jdbc3/Jdbc3ResultSetMetaData.java b/src/interfaces/jdbc/org/postgresql/jdbc3/Jdbc3ResultSetMetaData.java
new file mode 100644
index 0000000000000000000000000000000000000000..5dd48a9846334a30cc5442b3b6d8fdfe24ca98fb
--- /dev/null
+++ b/src/interfaces/jdbc/org/postgresql/jdbc3/Jdbc3ResultSetMetaData.java
@@ -0,0 +1,12 @@
+package org.postgresql.jdbc3;
+
+public class Jdbc3ResultSetMetaData extends org.postgresql.jdbc2.AbstractJdbc2ResultSetMetaData implements java.sql.ResultSetMetaData
+{
+    
+	public Jdbc3ResultSetMetaData(java.util.Vector rows, org.postgresql.Field[] fields)
+	{
+	    super(rows, fields);
+	}
+   
+}
+
diff --git a/src/interfaces/jdbc/org/postgresql/jdbc3/Jdbc3Statement.java b/src/interfaces/jdbc/org/postgresql/jdbc3/Jdbc3Statement.java
new file mode 100644
index 0000000000000000000000000000000000000000..bf6a0d5155ac43a4f964ea350f479c81c4e57f71
--- /dev/null
+++ b/src/interfaces/jdbc/org/postgresql/jdbc3/Jdbc3Statement.java
@@ -0,0 +1,19 @@
+package org.postgresql.jdbc3;
+
+
+import java.sql.*;
+
+/* $Header: /cvsroot/pgsql/src/interfaces/jdbc/org/postgresql/jdbc3/Attic/Jdbc3Statement.java,v 1.1 2002/08/14 20:35:40 barry Exp $
+ * This class implements the java.sql.Statement interface for JDBC3.
+ * However most of the implementation is really done in 
+ * org.postgresql.jdbc3.AbstractJdbc3Statement or one of it's parents
+ */
+public class Jdbc3Statement extends org.postgresql.jdbc3.AbstractJdbc3Statement implements java.sql.Statement
+{
+   
+	public Jdbc3Statement (Jdbc3Connection c)
+	{
+		super(c);
+	}
+    
+}
diff --git a/src/interfaces/jdbc/org/postgresql/test/JDBC2Tests.java b/src/interfaces/jdbc/org/postgresql/test/TestUtil.java
similarity index 59%
rename from src/interfaces/jdbc/org/postgresql/test/JDBC2Tests.java
rename to src/interfaces/jdbc/org/postgresql/test/TestUtil.java
index 33070c0d9b897cbcb8e1a0a979ecd03110053c2e..a9f9dfdf3f41423ceb03475489b2e9c0dfe14af6 100644
--- a/src/interfaces/jdbc/org/postgresql/test/JDBC2Tests.java
+++ b/src/interfaces/jdbc/org/postgresql/test/TestUtil.java
@@ -1,17 +1,12 @@
 package org.postgresql.test;
 
-import junit.framework.TestSuite;
-import junit.framework.TestCase;
-import junit.framework.Test;
-
-import org.postgresql.test.jdbc2.*;
 import java.sql.*;
-import java.lang.reflect.Method;
+import junit.framework.TestCase;
 
 /*
- * Executes all known tests for JDBC2 and includes some utility methods.
+ * Utility class for JDBC tests
  */
-public class JDBC2Tests extends TestSuite
+public class TestUtil
 {
 	/*
 	 * Returns the Test database JDBC URL
@@ -45,7 +40,7 @@ public class JDBC2Tests extends TestSuite
 		try
 		{
 			Class.forName("org.postgresql.Driver");
-			return java.sql.DriverManager.getConnection(JDBC2Tests.getURL(), JDBC2Tests.getUser(), JDBC2Tests.getPassword());
+			return java.sql.DriverManager.getConnection(getURL(), getUser(), getPassword());
 		}
 		catch (ClassNotFoundException ex)
 		{
@@ -180,68 +175,4 @@ public class JDBC2Tests extends TestSuite
 		String s = "0000000000".substring(0, l) + Integer.toString(v);
 		return s.substring(s.length() - l);
 	}
-
-	/*
-	 * The main entry point for JUnit
-	 */
-	public static TestSuite suite()
-	{
-		TestSuite suite = new TestSuite();
-
-		//
-		// Add one line per class in our test cases. These should be in order of
-		// complexity.
-
-		// ANTTest should be first as it ensures that test parameters are
-		// being sent to the suite. It also initialises the database (if required)
-		// with some simple global tables (will make each testcase use its own later).
-		//
-		suite.addTestSuite(ANTTest.class);
-
-		// Basic Driver internals
-		suite.addTestSuite(DriverTest.class);
-		suite.addTestSuite(ConnectionTest.class);
-		suite.addTestSuite(DatabaseMetaDataTest.class);
-		suite.addTestSuite(EncodingTest.class);
-
-		// Connectivity/Protocols
-
-		// ResultSet
-		suite.addTestSuite(ResultSetTest.class);
-
-		// Time, Date, Timestamp
-		suite.addTestSuite(DateTest.class);
-		suite.addTestSuite(TimeTest.class);
-		suite.addTestSuite(TimestampTest.class);
-
-		// PreparedStatement
-
-		// BatchExecute
-		suite.addTestSuite(BatchExecuteTest.class);
-
-		// MetaData
-
-		// Other misc tests, based on previous problems users have had or specific
-		// features some applications require.
-		suite.addTestSuite(JBuilderTest.class);
-		suite.addTestSuite(MiscTest.class);
-
-		// Fastpath/LargeObject
-		suite.addTestSuite(BlobTest.class);
-		suite.addTestSuite( UpdateableResultTest.class );
-
-		suite.addTestSuite( CallableStmtTest.class );
-		
-		// try to load the optional test classes
-		try {
-		    Class cls = Class.forName("org.postgresql.test.jdbc2.optional.OptionalTestSuite");
-		    Method meth = cls.getMethod("suite", new Class[0]);
-		    suite.addTest((Test)meth.invoke(null, new Object[0]));
-		} catch (Exception e) {
-		    System.err.println("Excluding JDBC 2 Optional Package (DataSource) tests");
-		}
-
-		// That's all folks
-		return suite;
-	}
 }
diff --git a/src/interfaces/jdbc/org/postgresql/test/jdbc2/BatchExecuteTest.java b/src/interfaces/jdbc/org/postgresql/test/jdbc2/BatchExecuteTest.java
index 26229b885608273fc2d26e33a9b57fa9abf343ee..1c2569296bee1a9856a37089e9e48e864ad30386 100644
--- a/src/interfaces/jdbc/org/postgresql/test/jdbc2/BatchExecuteTest.java
+++ b/src/interfaces/jdbc/org/postgresql/test/jdbc2/BatchExecuteTest.java
@@ -1,6 +1,6 @@
 package org.postgresql.test.jdbc2;
 
-import org.postgresql.test.JDBC2Tests;
+import org.postgresql.test.TestUtil;
 import junit.framework.TestCase;
 import java.sql.*;
 
@@ -26,12 +26,12 @@ public class BatchExecuteTest extends TestCase
 	// a table for this test.
 	protected void setUp() throws Exception
 	{
-		con = JDBC2Tests.openDB();
+		con = TestUtil.openDB();
 		Statement stmt = con.createStatement();
 
 		// Drop the test table if it already exists for some reason. It is
 		// not an error if it doesn't exist.
-		JDBC2Tests.createTable(con, "testbatch", "pk INTEGER, col1 INTEGER");
+		TestUtil.createTable(con, "testbatch", "pk INTEGER, col1 INTEGER");
 
 		stmt.executeUpdate("INSERT INTO testbatch VALUES (1, 0)");
 
@@ -45,8 +45,8 @@ public class BatchExecuteTest extends TestCase
 	{
 		con.setAutoCommit(true);
 
-		JDBC2Tests.dropTable(con, "testbatch");
-		JDBC2Tests.closeDB(con);
+		TestUtil.dropTable(con, "testbatch");
+		TestUtil.closeDB(con);
 	}
 
 	public void testSupportsBatchUpdates() throws Exception
diff --git a/src/interfaces/jdbc/org/postgresql/test/jdbc2/BlobTest.java b/src/interfaces/jdbc/org/postgresql/test/jdbc2/BlobTest.java
index 45bab13b0e0798d0fe7b8b1aa4d63dd1937d1b05..7a33ae53922dabc2e172e3d03d2afa598ee8d291 100644
--- a/src/interfaces/jdbc/org/postgresql/test/jdbc2/BlobTest.java
+++ b/src/interfaces/jdbc/org/postgresql/test/jdbc2/BlobTest.java
@@ -1,6 +1,6 @@
 package org.postgresql.test.jdbc2;
 
-import org.postgresql.test.JDBC2Tests;
+import org.postgresql.test.TestUtil;
 import junit.framework.TestCase;
 import java.io.*;
 import java.sql.*;
@@ -8,7 +8,7 @@ import java.sql.*;
 import org.postgresql.largeobject.*;
 
 /*
- * $Id: BlobTest.java,v 1.6 2002/07/23 03:59:55 barry Exp $
+ * $Id: BlobTest.java,v 1.7 2002/08/14 20:35:40 barry Exp $
  *
  * Some simple tests based on problems reported by users. Hopefully these will
  * help prevent previous problems from re-occuring ;-)
@@ -30,14 +30,14 @@ public class BlobTest extends TestCase
 
 	protected void setUp() throws Exception
 	{
-		con = JDBC2Tests.openDB();
-		JDBC2Tests.createTable(con, "testblob", "id name,lo oid");
+		con = TestUtil.openDB();
+		TestUtil.createTable(con, "testblob", "id name,lo oid");
 	}
 
 	protected void tearDown() throws Exception
 	{
-		JDBC2Tests.dropTable(con, "testblob");
-		JDBC2Tests.closeDB(con);
+		TestUtil.dropTable(con, "testblob");
+		TestUtil.closeDB(con);
 	}
 
 	/*
@@ -131,7 +131,7 @@ public class BlobTest extends TestCase
 
 			case JDBC_STREAM:
 				File f = new File(file);
-				PreparedStatement ps = con.prepareStatement(JDBC2Tests.insertSQL("testblob", "?"));
+				PreparedStatement ps = con.prepareStatement(TestUtil.insertSQL("testblob", "?"));
 				ps.setBinaryStream(1, fis, (int) f.length());
 				ps.execute();
 				break;
@@ -145,7 +145,7 @@ public class BlobTest extends TestCase
 
 		// Insert into the table
 		Statement st = con.createStatement();
-		st.executeUpdate(JDBC2Tests.insertSQL("testblob", "id,lo", "'" + file + "'," + oid));
+		st.executeUpdate(TestUtil.insertSQL("testblob", "id,lo", "'" + file + "'," + oid));
 		con.commit();
 		st.close();
 
@@ -163,7 +163,7 @@ public class BlobTest extends TestCase
 		LargeObjectManager lom = ((org.postgresql.PGConnection)con).getLargeObjectAPI();
 
 		Statement st = con.createStatement();
-		ResultSet rs = st.executeQuery(JDBC2Tests.selectSQL("testblob", "id,lo"));
+		ResultSet rs = st.executeQuery(TestUtil.selectSQL("testblob", "id,lo"));
 		assertNotNull(rs);
 
 		while (rs.next())
diff --git a/src/interfaces/jdbc/org/postgresql/test/jdbc2/CallableStmtTest.java b/src/interfaces/jdbc/org/postgresql/test/jdbc2/CallableStmtTest.java
index 5c83d8cdf2abe2a8d93cbf9bc7b0d7132a785df4..23cc28697f7cd2b4c3bd08d1205c77b764496ab6 100644
--- a/src/interfaces/jdbc/org/postgresql/test/jdbc2/CallableStmtTest.java
+++ b/src/interfaces/jdbc/org/postgresql/test/jdbc2/CallableStmtTest.java
@@ -1,6 +1,6 @@
 package org.postgresql.test.jdbc2;
 
-import org.postgresql.test.JDBC2Tests;
+import org.postgresql.test.TestUtil;
 import junit.framework.TestCase;
 import java.io.*;
 import java.sql.*;
@@ -20,7 +20,7 @@ public class CallableStmtTest extends TestCase
 
 	protected void setUp() throws Exception
 	{
-		con = JDBC2Tests.openDB();
+		con = TestUtil.openDB();
 		Statement stmt = con.createStatement ();
 		stmt.execute ("CREATE OR REPLACE FUNCTION testspg__getString (varchar) " + 
 					  "RETURNS varchar AS ' DECLARE inString alias for $1; begin "+
@@ -44,7 +44,7 @@ public class CallableStmtTest extends TestCase
 		stmt.execute ("drop FUNCTION testspg__getDouble (float);");
 		stmt.execute ("drop FUNCTION testspg__getInt (int);");
 		stmt.execute ("drop FUNCTION testspg__getNumeric (numeric);");
-		JDBC2Tests.closeDB(con);
+		TestUtil.closeDB(con);
 	}
 
 
diff --git a/src/interfaces/jdbc/org/postgresql/test/jdbc2/ConnectionTest.java b/src/interfaces/jdbc/org/postgresql/test/jdbc2/ConnectionTest.java
index 682118b6c1733cdd415fe759af5277c0498a4b67..e2f70f1b642e7cf07dfc3fc5844777a8993e2e6b 100644
--- a/src/interfaces/jdbc/org/postgresql/test/jdbc2/ConnectionTest.java
+++ b/src/interfaces/jdbc/org/postgresql/test/jdbc2/ConnectionTest.java
@@ -1,6 +1,6 @@
 package org.postgresql.test.jdbc2;
 
-import org.postgresql.test.JDBC2Tests;
+import org.postgresql.test.TestUtil;
 import junit.framework.TestCase;
 import java.sql.*;
 
@@ -10,7 +10,7 @@ import java.sql.*;
  *
  * PS: Do you know how difficult it is to type on a train? ;-)
  *
- * $Id: ConnectionTest.java,v 1.8 2002/07/23 03:59:55 barry Exp $
+ * $Id: ConnectionTest.java,v 1.9 2002/08/14 20:35:40 barry Exp $
  */
 
 public class ConnectionTest extends TestCase
@@ -27,23 +27,23 @@ public class ConnectionTest extends TestCase
 	// Set up the fixture for this testcase: the tables for this test.
 	protected void setUp() throws Exception
 	{
-		Connection con = JDBC2Tests.openDB();
+		Connection con = TestUtil.openDB();
 
-		JDBC2Tests.createTable(con, "test_a", "imagename name,image oid,id int4");
-		JDBC2Tests.createTable(con, "test_c", "source text,cost money,imageid int4");
+		TestUtil.createTable(con, "test_a", "imagename name,image oid,id int4");
+		TestUtil.createTable(con, "test_c", "source text,cost money,imageid int4");
 
-		JDBC2Tests.closeDB(con);
+		TestUtil.closeDB(con);
 	}
 
 	// Tear down the fixture for this test case.
 	protected void tearDown() throws Exception
 	{
-		Connection con = JDBC2Tests.openDB();
+		Connection con = TestUtil.openDB();
 
-		JDBC2Tests.dropTable(con, "test_a");
-		JDBC2Tests.dropTable(con, "test_c");
+		TestUtil.dropTable(con, "test_a");
+		TestUtil.dropTable(con, "test_c");
 
-		JDBC2Tests.closeDB(con);
+		TestUtil.closeDB(con);
 	}
 
 	/*
@@ -53,7 +53,7 @@ public class ConnectionTest extends TestCase
 	{
 		try
 		{
-			java.sql.Connection conn = JDBC2Tests.openDB();
+			java.sql.Connection conn = TestUtil.openDB();
 
 			// A standard Statement
 			java.sql.Statement stat = conn.createStatement();
@@ -79,7 +79,7 @@ public class ConnectionTest extends TestCase
 	{
 		try
 		{
-			java.sql.Connection conn = JDBC2Tests.openDB();
+			java.sql.Connection conn = TestUtil.openDB();
 
 			String sql = "select source,cost,imageid from test_c";
 
@@ -121,7 +121,7 @@ public class ConnectionTest extends TestCase
 	{
 		try
 		{
-			java.sql.Connection con = JDBC2Tests.openDB();
+			java.sql.Connection con = TestUtil.openDB();
 			java.sql.Statement st;
 			java.sql.ResultSet rs;
 
@@ -155,7 +155,7 @@ public class ConnectionTest extends TestCase
 			assertEquals(9876, rs.getInt(1)); // Should not change!
 			rs.close();
 
-			JDBC2Tests.closeDB(con);
+			TestUtil.closeDB(con);
 		}
 		catch (SQLException ex)
 		{
@@ -170,12 +170,12 @@ public class ConnectionTest extends TestCase
 	{
 		try
 		{
-			Connection con = JDBC2Tests.openDB();
+			Connection con = TestUtil.openDB();
 
 			// Should not say closed
 			assertTrue(!con.isClosed());
 
-			JDBC2Tests.closeDB(con);
+			TestUtil.closeDB(con);
 
 			// Should now say closed
 			assertTrue(con.isClosed());
@@ -194,7 +194,7 @@ public class ConnectionTest extends TestCase
 	{
 		try
 		{
-			Connection con = JDBC2Tests.openDB();
+			Connection con = TestUtil.openDB();
 
 			String testStr = "This Is OuR TeSt message";
 
@@ -216,7 +216,7 @@ public class ConnectionTest extends TestCase
 			con.clearWarnings();
 			assertTrue(con.getWarnings() == null);
 
-			JDBC2Tests.closeDB(con);
+			TestUtil.closeDB(con);
 		}
 		catch (SQLException ex)
 		{
@@ -231,7 +231,7 @@ public class ConnectionTest extends TestCase
 	{
 		try
 		{
-			Connection con = JDBC2Tests.openDB();
+			Connection con = TestUtil.openDB();
 
 			// PostgreSQL defaults to READ COMMITTED
 			assertEquals(Connection.TRANSACTION_READ_COMMITTED,
@@ -301,7 +301,7 @@ public class ConnectionTest extends TestCase
 			assertEquals(Connection.TRANSACTION_READ_COMMITTED,
 						 con.getTransactionIsolation());
 
-			JDBC2Tests.closeDB(con);
+			TestUtil.closeDB(con);
 		}
 		catch ( SQLException ex )
 		{
@@ -316,7 +316,7 @@ public class ConnectionTest extends TestCase
 	{
 		try
 		{
-			Connection con = JDBC2Tests.openDB();
+			Connection con = TestUtil.openDB();
 
 			// preserve the current map
 			java.util.Map oldmap = con.getTypeMap();
@@ -330,7 +330,7 @@ public class ConnectionTest extends TestCase
 			con.setTypeMap(oldmap);
 			assertEquals(oldmap, con.getTypeMap());
 
-			JDBC2Tests.closeDB(con);
+			TestUtil.closeDB(con);
 		}
 		catch (SQLException ex)
 		{
diff --git a/src/interfaces/jdbc/org/postgresql/test/jdbc2/DatabaseMetaDataTest.java b/src/interfaces/jdbc/org/postgresql/test/jdbc2/DatabaseMetaDataTest.java
index 772743c347f46c207ace5eed6571706f80cae8fc..85a6afe60bb60fc0752aa3d37295ae6bc911a30e 100644
--- a/src/interfaces/jdbc/org/postgresql/test/jdbc2/DatabaseMetaDataTest.java
+++ b/src/interfaces/jdbc/org/postgresql/test/jdbc2/DatabaseMetaDataTest.java
@@ -1,6 +1,6 @@
 package org.postgresql.test.jdbc2;
 
-import org.postgresql.test.JDBC2Tests;
+import org.postgresql.test.TestUtil;
 import junit.framework.TestCase;
 import java.sql.*;
 
@@ -9,7 +9,7 @@ import java.sql.*;
  *
  * PS: Do you know how difficult it is to type on a train? ;-)
  *
- * $Id: DatabaseMetaDataTest.java,v 1.10 2002/07/30 13:22:38 davec Exp $
+ * $Id: DatabaseMetaDataTest.java,v 1.11 2002/08/14 20:35:40 barry Exp $
  */
 
 public class DatabaseMetaDataTest extends TestCase
@@ -26,14 +26,14 @@ public class DatabaseMetaDataTest extends TestCase
 
 	protected void setUp() throws Exception
 	{
-		con = JDBC2Tests.openDB();
-		JDBC2Tests.createTable( con, "testmetadata", "id int4, name text, updated timestamp" );
+		con = TestUtil.openDB();
+		TestUtil.createTable( con, "testmetadata", "id int4, name text, updated timestamp" );
 	}
 	protected void tearDown() throws Exception
 	{
-		JDBC2Tests.dropTable( con, "testmetadata" );
+		TestUtil.dropTable( con, "testmetadata" );
 
-		JDBC2Tests.closeDB( con );
+		TestUtil.closeDB( con );
 	}
 	/*
 	 * The spec says this may return null, but we always do!
@@ -233,11 +233,11 @@ public class DatabaseMetaDataTest extends TestCase
   {
 		try
 		{
-		  Connection con1 = JDBC2Tests.openDB();
+		  Connection con1 = TestUtil.openDB();
 
-		  JDBC2Tests.createTable( con1, "vv", "a int not null, b int not null, primary key ( a, b )" );
+		  TestUtil.createTable( con1, "vv", "a int not null, b int not null, primary key ( a, b )" );
 
-		  JDBC2Tests.createTable( con1, "ww", "m int not null, n int not null, primary key ( m, n ), foreign key ( m, n ) references vv ( a, b )" );
+		  TestUtil.createTable( con1, "ww", "m int not null, n int not null, primary key ( m, n ), foreign key ( m, n ) references vv ( a, b )" );
 
 
 			DatabaseMetaData dbmd = con.getMetaData();
@@ -271,8 +271,8 @@ public class DatabaseMetaDataTest extends TestCase
       }
 
 
-      JDBC2Tests.dropTable( con1, "vv" );
-      JDBC2Tests.dropTable( con1, "ww" );
+      TestUtil.dropTable( con1, "vv" );
+      TestUtil.dropTable( con1, "ww" );
 
 		}
 		catch (SQLException ex)
@@ -284,11 +284,11 @@ public class DatabaseMetaDataTest extends TestCase
   {
 		try
 		{
-		  Connection con1 = JDBC2Tests.openDB();
-		  JDBC2Tests.createTable( con1, "people", "id int4 primary key, name text" );
-		  JDBC2Tests.createTable( con1, "policy", "id int4 primary key, name text" );
+		  Connection con1 = TestUtil.openDB();
+		  TestUtil.createTable( con1, "people", "id int4 primary key, name text" );
+		  TestUtil.createTable( con1, "policy", "id int4 primary key, name text" );
 
-		  JDBC2Tests.createTable( con1, "users", "id int4 primary key, people_id int4, policy_id int4,"+
+		  TestUtil.createTable( con1, "users", "id int4 primary key, people_id int4, policy_id int4,"+
                                     "CONSTRAINT people FOREIGN KEY (people_id) references people(id),"+
                                     "constraint policy FOREIGN KEY (policy_id) references policy(id)" );
 
@@ -337,9 +337,9 @@ public class DatabaseMetaDataTest extends TestCase
       assertTrue( rs.getString( "FK_NAME" ).equals( "people" ) );
 
 
-      JDBC2Tests.dropTable( con1, "users" );
-      JDBC2Tests.dropTable( con1, "people" );
-      JDBC2Tests.dropTable( con1, "policy" );
+      TestUtil.dropTable( con1, "users" );
+      TestUtil.dropTable( con1, "people" );
+      TestUtil.dropTable( con1, "policy" );
 
 		}
 		catch (SQLException ex)
@@ -405,8 +405,8 @@ public class DatabaseMetaDataTest extends TestCase
 			DatabaseMetaData dbmd = con.getMetaData();
 			assertNotNull(dbmd);
 
-			assertTrue(dbmd.getURL().equals(JDBC2Tests.getURL()));
-			assertTrue(dbmd.getUserName().equals(JDBC2Tests.getUser()));
+			assertTrue(dbmd.getURL().equals(TestUtil.getURL()));
+			assertTrue(dbmd.getUserName().equals(TestUtil.getUser()));
 
 		}
 		catch (SQLException ex)
diff --git a/src/interfaces/jdbc/org/postgresql/test/jdbc2/DateTest.java b/src/interfaces/jdbc/org/postgresql/test/jdbc2/DateTest.java
index 300d1549bbd4f8179fdf57fc33af0260cdc5fa3e..7c1f01a950731a45ec6ef9eb64f0d6e22e593272 100644
--- a/src/interfaces/jdbc/org/postgresql/test/jdbc2/DateTest.java
+++ b/src/interfaces/jdbc/org/postgresql/test/jdbc2/DateTest.java
@@ -1,11 +1,11 @@
 package org.postgresql.test.jdbc2;
 
-import org.postgresql.test.JDBC2Tests;
+import org.postgresql.test.TestUtil;
 import junit.framework.TestCase;
 import java.sql.*;
 
 /*
- * $Id: DateTest.java,v 1.4 2001/11/19 22:33:39 momjian Exp $
+ * $Id: DateTest.java,v 1.5 2002/08/14 20:35:40 barry Exp $
  *
  * Some simple tests based on problems reported by users. Hopefully these will
  * help prevent previous problems from re-occuring ;-)
@@ -23,14 +23,14 @@ public class DateTest extends TestCase
 
 	protected void setUp() throws Exception
 	{
-		con = JDBC2Tests.openDB();
-		JDBC2Tests.createTable(con, "testdate", "dt date");
+		con = TestUtil.openDB();
+		TestUtil.createTable(con, "testdate", "dt date");
 	}
 
 	protected void tearDown() throws Exception
 	{
-		JDBC2Tests.dropTable(con, "testdate");
-		JDBC2Tests.closeDB(con);
+		TestUtil.dropTable(con, "testdate");
+		TestUtil.closeDB(con);
 	}
 
 	/*
@@ -42,10 +42,10 @@ public class DateTest extends TestCase
 		{
 			Statement stmt = con.createStatement();
 
-			assertEquals(1, stmt.executeUpdate(JDBC2Tests.insertSQL("testdate", "'1950-02-07'")));
-			assertEquals(1, stmt.executeUpdate(JDBC2Tests.insertSQL("testdate", "'1970-06-02'")));
-			assertEquals(1, stmt.executeUpdate(JDBC2Tests.insertSQL("testdate", "'1999-08-11'")));
-			assertEquals(1, stmt.executeUpdate(JDBC2Tests.insertSQL("testdate", "'2001-02-13'")));
+			assertEquals(1, stmt.executeUpdate(TestUtil.insertSQL("testdate", "'1950-02-07'")));
+			assertEquals(1, stmt.executeUpdate(TestUtil.insertSQL("testdate", "'1970-06-02'")));
+			assertEquals(1, stmt.executeUpdate(TestUtil.insertSQL("testdate", "'1999-08-11'")));
+			assertEquals(1, stmt.executeUpdate(TestUtil.insertSQL("testdate", "'2001-02-13'")));
 
 			/* dateTest() contains all of the tests */
 			dateTest();
@@ -67,7 +67,7 @@ public class DateTest extends TestCase
 		try
 		{
 			Statement stmt = con.createStatement();
-			PreparedStatement ps = con.prepareStatement(JDBC2Tests.insertSQL("testdate", "?"));
+			PreparedStatement ps = con.prepareStatement(TestUtil.insertSQL("testdate", "?"));
 
 			ps.setDate(1, makeDate(1950, 2, 7));
 			assertEquals(1, ps.executeUpdate());
@@ -104,7 +104,7 @@ public class DateTest extends TestCase
 		ResultSet rs;
 		java.sql.Date d;
 
-		rs = st.executeQuery(JDBC2Tests.selectSQL("testdate", "dt"));
+		rs = st.executeQuery(TestUtil.selectSQL("testdate", "dt"));
 		assertNotNull(rs);
 
 		assertTrue(rs.next());
@@ -135,8 +135,8 @@ public class DateTest extends TestCase
 
 	private java.sql.Date makeDate(int y, int m, int d)
 	{
-		return java.sql.Date.valueOf(JDBC2Tests.fix(y, 4) + "-" +
-									 JDBC2Tests.fix(m, 2) + "-" +
-									 JDBC2Tests.fix(d, 2));
+		return java.sql.Date.valueOf(TestUtil.fix(y, 4) + "-" +
+									 TestUtil.fix(m, 2) + "-" +
+									 TestUtil.fix(d, 2));
 	}
 }
diff --git a/src/interfaces/jdbc/org/postgresql/test/jdbc2/DriverTest.java b/src/interfaces/jdbc/org/postgresql/test/jdbc2/DriverTest.java
index f2ec356c5ae3fdee37b8ce6a43e21d0ff313214c..d8e0ca56ef464cd4501918748c9044842bfa919f 100644
--- a/src/interfaces/jdbc/org/postgresql/test/jdbc2/DriverTest.java
+++ b/src/interfaces/jdbc/org/postgresql/test/jdbc2/DriverTest.java
@@ -1,11 +1,11 @@
 package org.postgresql.test.jdbc2;
 
-import org.postgresql.test.JDBC2Tests;
+import org.postgresql.test.TestUtil;
 import junit.framework.TestCase;
 import java.sql.*;
 
 /*
- * $Id: DriverTest.java,v 1.4 2001/11/19 22:33:39 momjian Exp $
+ * $Id: DriverTest.java,v 1.5 2002/08/14 20:35:40 barry Exp $
  *
  * Tests the dynamically created class org.postgresql.Driver
  *
@@ -63,12 +63,12 @@ public class DriverTest extends TestCase
 			Class.forName("org.postgresql.Driver");
 
 			// Test with the url, username & password
-			con = DriverManager.getConnection(JDBC2Tests.getURL(), JDBC2Tests.getUser(), JDBC2Tests.getPassword());
+			con = DriverManager.getConnection(TestUtil.getURL(), TestUtil.getUser(), TestUtil.getPassword());
 			assertNotNull(con);
 			con.close();
 
 			// Test with the username in the url
-			con = DriverManager.getConnection(JDBC2Tests.getURL() + "?user=" + JDBC2Tests.getUser() + "&password=" + JDBC2Tests.getPassword());
+			con = DriverManager.getConnection(TestUtil.getURL() + "?user=" + TestUtil.getUser() + "&password=" + TestUtil.getPassword());
 			assertNotNull(con);
 			con.close();
 		}
diff --git a/src/interfaces/jdbc/org/postgresql/test/jdbc2/JBuilderTest.java b/src/interfaces/jdbc/org/postgresql/test/jdbc2/JBuilderTest.java
index 456a514613e59f7208408775fca0f4db874e4a3a..ee4a0ebd5af2b22dc0868b21982c0f1d474103ab 100644
--- a/src/interfaces/jdbc/org/postgresql/test/jdbc2/JBuilderTest.java
+++ b/src/interfaces/jdbc/org/postgresql/test/jdbc2/JBuilderTest.java
@@ -1,12 +1,12 @@
 package org.postgresql.test.jdbc2;
 
-import org.postgresql.test.JDBC2Tests;
+import org.postgresql.test.TestUtil;
 import junit.framework.TestCase;
 import java.sql.*;
 import java.math.BigDecimal;
 
 /*
- * $Id: JBuilderTest.java,v 1.5 2001/11/19 22:33:39 momjian Exp $
+ * $Id: JBuilderTest.java,v 1.6 2002/08/14 20:35:40 barry Exp $
  *
  * Some simple tests to check that the required components needed for JBuilder
  * stay working
@@ -23,20 +23,20 @@ public class JBuilderTest extends TestCase
 	// Set up the fixture for this testcase: the tables for this test.
 	protected void setUp() throws Exception
 	{
-		Connection con = JDBC2Tests.openDB();
+		Connection con = TestUtil.openDB();
 
-		JDBC2Tests.createTable( con, "test_c",
+		TestUtil.createTable( con, "test_c",
 								"source text,cost money,imageid int4" );
 
-		JDBC2Tests.closeDB(con);
+		TestUtil.closeDB(con);
 	}
 
 	// Tear down the fixture for this test case.
 	protected void tearDown() throws Exception
 	{
-		Connection con = JDBC2Tests.openDB();
-		JDBC2Tests.dropTable(con, "test_c");
-		JDBC2Tests.closeDB(con);
+		Connection con = TestUtil.openDB();
+		TestUtil.dropTable(con, "test_c");
+		TestUtil.closeDB(con);
 	}
 
 	/*
@@ -46,7 +46,7 @@ public class JBuilderTest extends TestCase
 	{
 		try
 		{
-			Connection con = JDBC2Tests.openDB();
+			Connection con = TestUtil.openDB();
 
 			Statement st = con.createStatement();
 			ResultSet rs = st.executeQuery("select cost from test_c");
@@ -60,7 +60,7 @@ public class JBuilderTest extends TestCase
 			rs.close();
 			st.close();
 
-			JDBC2Tests.closeDB(con);
+			TestUtil.closeDB(con);
 		}
 		catch (Exception ex)
 		{
diff --git a/src/interfaces/jdbc/org/postgresql/test/jdbc2/Jdbc2TestSuite.java b/src/interfaces/jdbc/org/postgresql/test/jdbc2/Jdbc2TestSuite.java
new file mode 100644
index 0000000000000000000000000000000000000000..64dd44848a84f223bb0fc635b8aab1a2f7c7bb10
--- /dev/null
+++ b/src/interfaces/jdbc/org/postgresql/test/jdbc2/Jdbc2TestSuite.java
@@ -0,0 +1,70 @@
+package org.postgresql.test.jdbc2;
+
+import junit.framework.TestSuite;
+import junit.framework.TestCase;
+import junit.framework.Test;
+
+import java.sql.*;
+import java.lang.reflect.Method;
+
+/*
+ * Executes all known tests for JDBC2 and includes some utility methods.
+ */
+public class Jdbc2TestSuite extends TestSuite
+{
+
+	/*
+	 * The main entry point for JUnit
+	 */
+	public static TestSuite suite()
+	{
+		TestSuite suite = new TestSuite();
+
+		//
+		// Add one line per class in our test cases. These should be in order of
+		// complexity.
+
+		// ANTTest should be first as it ensures that test parameters are
+		// being sent to the suite. It also initialises the database (if required)
+		// with some simple global tables (will make each testcase use its own later).
+		//
+		suite.addTestSuite(ANTTest.class);
+
+		// Basic Driver internals
+		suite.addTestSuite(DriverTest.class);
+		suite.addTestSuite(ConnectionTest.class);
+		suite.addTestSuite(DatabaseMetaDataTest.class);
+		suite.addTestSuite(EncodingTest.class);
+
+		// Connectivity/Protocols
+
+		// ResultSet
+		suite.addTestSuite(ResultSetTest.class);
+
+		// Time, Date, Timestamp
+		suite.addTestSuite(DateTest.class);
+		suite.addTestSuite(TimeTest.class);
+		suite.addTestSuite(TimestampTest.class);
+
+		// PreparedStatement
+
+		// BatchExecute
+		suite.addTestSuite(BatchExecuteTest.class);
+
+		// MetaData
+
+		// Other misc tests, based on previous problems users have had or specific
+		// features some applications require.
+		suite.addTestSuite(JBuilderTest.class);
+		suite.addTestSuite(MiscTest.class);
+
+		// Fastpath/LargeObject
+		suite.addTestSuite(BlobTest.class);
+		suite.addTestSuite( UpdateableResultTest.class );
+
+		suite.addTestSuite( CallableStmtTest.class );
+		
+		// That's all folks
+		return suite;
+	}
+}
diff --git a/src/interfaces/jdbc/org/postgresql/test/jdbc2/MiscTest.java b/src/interfaces/jdbc/org/postgresql/test/jdbc2/MiscTest.java
index 753d33a3e6a314ea8245d1a3ca3192cea1135320..7164327f04158ed988ed4cc6ff3fda61ba5e6b5e 100644
--- a/src/interfaces/jdbc/org/postgresql/test/jdbc2/MiscTest.java
+++ b/src/interfaces/jdbc/org/postgresql/test/jdbc2/MiscTest.java
@@ -1,11 +1,11 @@
 package org.postgresql.test.jdbc2;
 
-import org.postgresql.test.JDBC2Tests;
+import org.postgresql.test.TestUtil;
 import junit.framework.TestCase;
 import java.sql.*;
 
 /*
- * $Id: MiscTest.java,v 1.6 2002/06/14 10:56:13 davec Exp $
+ * $Id: MiscTest.java,v 1.7 2002/08/14 20:35:40 barry Exp $
  *
  * Some simple tests based on problems reported by users. Hopefully these will
  * help prevent previous problems from re-occuring ;-)
@@ -30,7 +30,7 @@ public class MiscTest extends TestCase
 	{
 		try
 		{
-			Connection con = JDBC2Tests.openDB();
+			Connection con = TestUtil.openDB();
 
 			Statement st = con.createStatement();
 			ResultSet rs = st.executeQuery("select datname from pg_database");
@@ -44,7 +44,7 @@ public class MiscTest extends TestCase
 			rs.close();
 			st.close();
 
-			JDBC2Tests.closeDB(con);
+			TestUtil.closeDB(con);
 		}
 		catch (Exception ex)
 		{
@@ -54,7 +54,7 @@ public class MiscTest extends TestCase
 
   public void testError()
   {
-    Connection con = JDBC2Tests.openDB();
+    Connection con = TestUtil.openDB();
 		try
 		{
 
@@ -81,17 +81,17 @@ public class MiscTest extends TestCase
 		System.out.println("testing lock");
 		try
 		{
-			Connection con = JDBC2Tests.openDB();
-			Connection con2 = JDBC2Tests.openDB();
+			Connection con = TestUtil.openDB();
+			Connection con2 = TestUtil.openDB();
 
-			JDBC2Tests.createTable(con, "test_lock", "name text");
+			TestUtil.createTable(con, "test_lock", "name text");
 			Statement st = con.createStatement();
 			Statement st2 = con2.createStatement();
 			con.setAutoCommit(false);
 			st.execute("lock table test_lock");
 			st2.executeUpdate( "insert into test_lock ( name ) values ('hello')" );
  			con.commit();
-			JDBC2Tests.dropTable(con, "test_lock");
+			TestUtil.dropTable(con, "test_lock");
 			con.close();
 		}
 		catch ( Exception ex )
diff --git a/src/interfaces/jdbc/org/postgresql/test/jdbc2/ResultSetTest.java b/src/interfaces/jdbc/org/postgresql/test/jdbc2/ResultSetTest.java
index 49af9e5ce9f7cbdc7c08eac4e19b85ca68f5d3b3..0a818c529bdef48f1ef4e63f5a27c71afceef63f 100644
--- a/src/interfaces/jdbc/org/postgresql/test/jdbc2/ResultSetTest.java
+++ b/src/interfaces/jdbc/org/postgresql/test/jdbc2/ResultSetTest.java
@@ -1,6 +1,6 @@
 package org.postgresql.test.jdbc2;
 
-import org.postgresql.test.JDBC2Tests;
+import org.postgresql.test.TestUtil;
 import junit.framework.TestCase;
 import java.io.*;
 import java.sql.*;
@@ -19,10 +19,10 @@ public class ResultSetTest extends TestCase
 
 	protected void setUp() throws Exception
 	{
-		con = JDBC2Tests.openDB();
+		con = TestUtil.openDB();
 		Statement stmt = con.createStatement();
 
-		JDBC2Tests.createTable(con, "testrs", "id integer");
+		TestUtil.createTable(con, "testrs", "id integer");
 
 		stmt.executeUpdate("INSERT INTO testrs VALUES (1)");
 		stmt.executeUpdate("INSERT INTO testrs VALUES (2)");
@@ -36,8 +36,8 @@ public class ResultSetTest extends TestCase
 
 	protected void tearDown() throws Exception
 	{
-		JDBC2Tests.dropTable(con, "testrs");
-		JDBC2Tests.closeDB(con);
+		TestUtil.dropTable(con, "testrs");
+		TestUtil.closeDB(con);
 	}
 
 	public void testAbsolute() throws Exception
diff --git a/src/interfaces/jdbc/org/postgresql/test/jdbc2/TimeTest.java b/src/interfaces/jdbc/org/postgresql/test/jdbc2/TimeTest.java
index 88ba63f76aae98e6529cf2888f6a6e67b5da4f78..9f2dc1600fad2dff13be3f75086fafa016e073b3 100644
--- a/src/interfaces/jdbc/org/postgresql/test/jdbc2/TimeTest.java
+++ b/src/interfaces/jdbc/org/postgresql/test/jdbc2/TimeTest.java
@@ -1,11 +1,11 @@
 package org.postgresql.test.jdbc2;
 
-import org.postgresql.test.JDBC2Tests;
+import org.postgresql.test.TestUtil;
 import junit.framework.TestCase;
 import java.sql.*;
 
 /*
- * $Id: TimeTest.java,v 1.4 2001/11/19 22:33:39 momjian Exp $
+ * $Id: TimeTest.java,v 1.5 2002/08/14 20:35:40 barry Exp $
  *
  * Some simple tests based on problems reported by users. Hopefully these will
  * help prevent previous problems from re-occuring ;-)
@@ -23,14 +23,14 @@ public class TimeTest extends TestCase
 
 	protected void setUp() throws Exception
 	{
-		con = JDBC2Tests.openDB();
-		JDBC2Tests.createTable(con, "testtime", "tm time");
+		con = TestUtil.openDB();
+		TestUtil.createTable(con, "testtime", "tm time");
 	}
 
 	protected void tearDown() throws Exception
 	{
-		JDBC2Tests.dropTable(con, "testtime");
-		JDBC2Tests.closeDB(con);
+		TestUtil.dropTable(con, "testtime");
+		TestUtil.closeDB(con);
 	}
 
 	/*
@@ -42,8 +42,8 @@ public class TimeTest extends TestCase
 		{
 			Statement stmt = con.createStatement();
 
-			assertEquals(1, stmt.executeUpdate(JDBC2Tests.insertSQL("testtime", "'01:02:03'")));
-			assertEquals(1, stmt.executeUpdate(JDBC2Tests.insertSQL("testtime", "'23:59:59'")));
+			assertEquals(1, stmt.executeUpdate(TestUtil.insertSQL("testtime", "'01:02:03'")));
+			assertEquals(1, stmt.executeUpdate(TestUtil.insertSQL("testtime", "'23:59:59'")));
 
 			// Fall through helper
 			timeTest();
@@ -64,7 +64,7 @@ public class TimeTest extends TestCase
 	{
 		try
 		{
-			PreparedStatement ps = con.prepareStatement(JDBC2Tests.insertSQL("testtime", "?"));
+			PreparedStatement ps = con.prepareStatement(TestUtil.insertSQL("testtime", "?"));
 			Statement stmt = con.createStatement();
 
 			ps.setTime(1, makeTime(1, 2, 3));
@@ -95,7 +95,7 @@ public class TimeTest extends TestCase
 		ResultSet rs;
 		java.sql.Time t;
 
-		rs = st.executeQuery(JDBC2Tests.selectSQL("testtime", "tm"));
+		rs = st.executeQuery(TestUtil.selectSQL("testtime", "tm"));
 		assertNotNull(rs);
 
 		assertTrue(rs.next());
@@ -115,8 +115,8 @@ public class TimeTest extends TestCase
 
 	private java.sql.Time makeTime(int h, int m, int s)
 	{
-		return java.sql.Time.valueOf(JDBC2Tests.fix(h, 2) + ":" +
-									 JDBC2Tests.fix(m, 2) + ":" +
-									 JDBC2Tests.fix(s, 2));
+		return java.sql.Time.valueOf(TestUtil.fix(h, 2) + ":" +
+									 TestUtil.fix(m, 2) + ":" +
+									 TestUtil.fix(s, 2));
 	}
 }
diff --git a/src/interfaces/jdbc/org/postgresql/test/jdbc2/TimestampTest.java b/src/interfaces/jdbc/org/postgresql/test/jdbc2/TimestampTest.java
index 37eff6c5b7591546c299474f2e03690ed05664ba..444427f13fcde93652b8834cbae4ebdd152b4276 100644
--- a/src/interfaces/jdbc/org/postgresql/test/jdbc2/TimestampTest.java
+++ b/src/interfaces/jdbc/org/postgresql/test/jdbc2/TimestampTest.java
@@ -1,11 +1,11 @@
 package org.postgresql.test.jdbc2;
 
-import org.postgresql.test.JDBC2Tests;
+import org.postgresql.test.TestUtil;
 import junit.framework.TestCase;
 import java.sql.*;
 
 /*
- * $Id: TimestampTest.java,v 1.7 2002/07/23 03:59:55 barry Exp $
+ * $Id: TimestampTest.java,v 1.8 2002/08/14 20:35:40 barry Exp $
  *
  * Test get/setTimestamp for both timestamp with time zone and 
  * timestamp without time zone datatypes
@@ -23,18 +23,18 @@ public class TimestampTest extends TestCase
 
 	protected void setUp() throws Exception
 	{
-		con = JDBC2Tests.openDB();
+		con = TestUtil.openDB();
 		Statement stmt = con.createStatement();
 
-		JDBC2Tests.createTable(con, TSWTZ_TABLE, "ts timestamp with time zone");
-		JDBC2Tests.createTable(con, TSWOTZ_TABLE, "ts timestamp without time zone");
+		TestUtil.createTable(con, TSWTZ_TABLE, "ts timestamp with time zone");
+		TestUtil.createTable(con, TSWOTZ_TABLE, "ts timestamp without time zone");
 	}
 
 	protected void tearDown() throws Exception
 	{
-		JDBC2Tests.dropTable(con, TSWTZ_TABLE);
-		JDBC2Tests.dropTable(con, TSWOTZ_TABLE);
-		JDBC2Tests.closeDB(con);
+		TestUtil.dropTable(con, TSWTZ_TABLE);
+		TestUtil.dropTable(con, TSWOTZ_TABLE);
+		TestUtil.closeDB(con);
 	}
 
 	/*
@@ -49,9 +49,9 @@ public class TimestampTest extends TestCase
 			Statement stmt = con.createStatement();
 
                         //Insert the three timestamp values in raw pg format
-			assertEquals(1, stmt.executeUpdate(JDBC2Tests.insertSQL(TSWTZ_TABLE,"'" + TS1WTZ_PGFORMAT + "'")));
-			assertEquals(1, stmt.executeUpdate(JDBC2Tests.insertSQL(TSWTZ_TABLE,"'" + TS2WTZ_PGFORMAT + "'")));
-			assertEquals(1, stmt.executeUpdate(JDBC2Tests.insertSQL(TSWTZ_TABLE,"'" + TS3WTZ_PGFORMAT + "'")));
+			assertEquals(1, stmt.executeUpdate(TestUtil.insertSQL(TSWTZ_TABLE,"'" + TS1WTZ_PGFORMAT + "'")));
+			assertEquals(1, stmt.executeUpdate(TestUtil.insertSQL(TSWTZ_TABLE,"'" + TS2WTZ_PGFORMAT + "'")));
+			assertEquals(1, stmt.executeUpdate(TestUtil.insertSQL(TSWTZ_TABLE,"'" + TS3WTZ_PGFORMAT + "'")));
 
 			// Fall through helper
                         timestampTestWTZ();
@@ -77,7 +77,7 @@ public class TimestampTest extends TestCase
 		try
 		{
 			Statement stmt = con.createStatement();
-			PreparedStatement pstmt = con.prepareStatement(JDBC2Tests.insertSQL(TSWTZ_TABLE, "?"));
+			PreparedStatement pstmt = con.prepareStatement(TestUtil.insertSQL(TSWTZ_TABLE, "?"));
 
 			pstmt.setTimestamp(1, TS1WTZ);
                         assertEquals(1, pstmt.executeUpdate());
@@ -114,9 +114,9 @@ public class TimestampTest extends TestCase
 			Statement stmt = con.createStatement();
 
                         //Insert the three timestamp values in raw pg format
-			assertEquals(1, stmt.executeUpdate(JDBC2Tests.insertSQL(TSWOTZ_TABLE,"'" + TS1WOTZ_PGFORMAT + "'")));
-			assertEquals(1, stmt.executeUpdate(JDBC2Tests.insertSQL(TSWOTZ_TABLE,"'" + TS2WOTZ_PGFORMAT + "'")));
-			assertEquals(1, stmt.executeUpdate(JDBC2Tests.insertSQL(TSWOTZ_TABLE,"'" + TS3WOTZ_PGFORMAT + "'")));
+			assertEquals(1, stmt.executeUpdate(TestUtil.insertSQL(TSWOTZ_TABLE,"'" + TS1WOTZ_PGFORMAT + "'")));
+			assertEquals(1, stmt.executeUpdate(TestUtil.insertSQL(TSWOTZ_TABLE,"'" + TS2WOTZ_PGFORMAT + "'")));
+			assertEquals(1, stmt.executeUpdate(TestUtil.insertSQL(TSWOTZ_TABLE,"'" + TS3WOTZ_PGFORMAT + "'")));
 
 			// Fall through helper
 			timestampTestWOTZ();
@@ -143,7 +143,7 @@ public class TimestampTest extends TestCase
 		try
 		{
 			Statement stmt = con.createStatement();
-			PreparedStatement pstmt = con.prepareStatement(JDBC2Tests.insertSQL(TSWOTZ_TABLE, "?"));
+			PreparedStatement pstmt = con.prepareStatement(TestUtil.insertSQL(TSWOTZ_TABLE, "?"));
 
 			pstmt.setTimestamp(1, TS1WOTZ);
                         assertEquals(1, pstmt.executeUpdate());
@@ -240,12 +240,12 @@ public class TimestampTest extends TestCase
             java.text.DateFormat l_df;
 	    try {
    	        String l_ts;
-                l_ts = JDBC2Tests.fix(y, 4) + "-" +
-		   JDBC2Tests.fix(m, 2) + "-" +
-		   JDBC2Tests.fix(d, 2) + " " +
-		   JDBC2Tests.fix(h, 2) + ":" +
-		   JDBC2Tests.fix(mn, 2) + ":" +
-		   JDBC2Tests.fix(se, 2) + " ";
+                l_ts = TestUtil.fix(y, 4) + "-" +
+		   TestUtil.fix(m, 2) + "-" +
+		   TestUtil.fix(d, 2) + " " +
+		   TestUtil.fix(h, 2) + ":" +
+		   TestUtil.fix(mn, 2) + ":" +
+		   TestUtil.fix(se, 2) + " ";
 
                 if (tz == null) {
                     l_df = new java.text.SimpleDateFormat("y-M-d H:m:s");
diff --git a/src/interfaces/jdbc/org/postgresql/test/jdbc2/UpdateableResultTest.java b/src/interfaces/jdbc/org/postgresql/test/jdbc2/UpdateableResultTest.java
index 056e68eba0524ea5bca755dcf805765045c75984..8fd45c29f04e6a838159367e2a8ccec49a030d17 100644
--- a/src/interfaces/jdbc/org/postgresql/test/jdbc2/UpdateableResultTest.java
+++ b/src/interfaces/jdbc/org/postgresql/test/jdbc2/UpdateableResultTest.java
@@ -3,7 +3,7 @@ package org.postgresql.test.jdbc2;
 import java.sql.*;
 import junit.framework.TestCase;
 
-import org.postgresql.test.JDBC2Tests;
+import org.postgresql.test.TestUtil;
 /**
  * <p>Title: </p>
  * <p>Description: </p>
@@ -25,12 +25,12 @@ public class UpdateableResultTest extends TestCase
   {
 		try
 		{
-			Connection con = JDBC2Tests.openDB();
-      JDBC2Tests.createTable(con, "updateable","id int primary key, name text, notselected text");
-      JDBC2Tests.createTable(con, "second","id1 int primary key, name1 text");
+			Connection con = TestUtil.openDB();
+      TestUtil.createTable(con, "updateable","id int primary key, name text, notselected text");
+      TestUtil.createTable(con, "second","id1 int primary key, name1 text");
       Statement st1 = con.createStatement();
       boolean retVal = st1.execute( "insert into updateable ( id, name, notselected ) values (1, 'jake', 'avalue')" );
-      assert( retVal== false );
+      assertTrue(!retVal);
 
       retVal = st1.execute( "insert into second (id1, name1) values (1, 'jake')" );
       assertTrue( !retVal );
@@ -121,8 +121,8 @@ public class UpdateableResultTest extends TestCase
 
 			st.close();
 
-      JDBC2Tests.dropTable( con,"updateable" );
-			JDBC2Tests.closeDB( con );
+      TestUtil.dropTable( con,"updateable" );
+			TestUtil.closeDB( con );
 		}
 		catch (Exception ex)
 		{
diff --git a/src/interfaces/jdbc/org/postgresql/test/jdbc3/Jdbc3TestSuite.java b/src/interfaces/jdbc/org/postgresql/test/jdbc3/Jdbc3TestSuite.java
new file mode 100644
index 0000000000000000000000000000000000000000..5e01e4ffe87fc4b989fa69f5d67a69704be548f0
--- /dev/null
+++ b/src/interfaces/jdbc/org/postgresql/test/jdbc3/Jdbc3TestSuite.java
@@ -0,0 +1,23 @@
+package org.postgresql.test.jdbc3;
+
+import junit.framework.TestSuite;
+import junit.framework.TestCase;
+import junit.framework.Test;
+
+import java.sql.*;
+
+/*
+ * Executes all known tests for JDBC3 
+ */
+public class Jdbc3TestSuite extends TestSuite
+{
+
+	/*
+	 * The main entry point for JUnit
+	 */
+	public static TestSuite suite()
+	{
+	    //Currently there are no specific jdbc3 tests so just run the jdbc2 tests
+            return org.postgresql.test.jdbc2.Jdbc2TestSuite.suite();
+	}
+}
diff --git a/src/interfaces/jdbc/org/postgresql/xa/ClientConnection.java b/src/interfaces/jdbc/org/postgresql/xa/ClientConnection.java
deleted file mode 100644
index dc46c873e8cd803c104a996822fe4435b4f38890..0000000000000000000000000000000000000000
--- a/src/interfaces/jdbc/org/postgresql/xa/ClientConnection.java
+++ /dev/null
@@ -1,567 +0,0 @@
-/*
-* Redistribution and use of this software and associated documentation
-* ("Software"), with or without modification, are permitted provided
-* that the following conditions are met:
-*
-* 1. Redistributions of source code must retain copyright
-*	 statements and notices.  Redistributions must also contain a
-*	 copy of this document.
-*
-* 2. Redistributions in binary form must reproduce the
-*	 above copyright notice, this list of conditions and the
-*	 following disclaimer in the documentation and/or other
-*	 materials provided with the distribution.
-*
-* 3. The name "Exolab" must not be used to endorse or promote
-*	 products derived from this Software without prior written
-*	 permission of Exoffice Technologies.  For written permission,
-*	 please contact info@exolab.org.
-*
-* 4. Products derived from this Software may not be called "Exolab"
-*	 nor may "Exolab" appear in their names without prior written
-*	 permission of Exoffice Technologies. Exolab is a registered
-*	 trademark of Exoffice Technologies.
-*
-* 5. Due credit should be given to the Exolab Project
-*	 (http://www.exolab.org/).
-*
-* THIS SOFTWARE IS PROVIDED BY EXOFFICE TECHNOLOGIES AND CONTRIBUTORS
-* ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT
-* NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
-* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.	IN NO EVENT SHALL
-* EXOFFICE TECHNOLOGIES OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
-* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
-* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
-* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
-* OF THE POSSIBILITY OF SUCH DAMAGE.
-*
-* Copyright 1999 (C) Exoffice Technologies Inc. All Rights Reserved.
-*
-* $Id: ClientConnection.java,v 1.4 2001/11/19 23:19:21 momjian Exp $
-*/
-
-
-package org.postgresql.xa;
-
-
-import java.util.*;
-import java.sql.*;
-
-
-/*
- * Encapsulates an application's view of an XA/pooled connection.
- * The XA connection is managed by the application server through it's
- * {@link javax.sql.XAConnection} interface. The underlying JDBC
- * connection is a standard JDBC connection. The application's
- * JDBC connection gives access to the underlying JDBC connection but
- * is managed by the application server. The application is given an
- * instance of this class and not the underlying connection directly.
- *
- *
- * @author <a href="arkin@exoffice.com">Assaf Arkin</a>
- * @version 1.0
- * @see XAConnectionImpl
- * @see XADataSourceImpl
- * @see Connection
- */
-final class ClientConnection
-			implements Connection
-{
-
-
-	/*
-	 * The pooled XA connection that created this client connection
-	 * and should be used to report closure and fatal errors.
-	 */
-	private XAConnectionImpl _xaConn;
-
-
-	/*
-	 * This identifier was handed on to use when we were created by
-	 * {@link XAConnection}. If since then the XA connection was asked
-	 * to create another connection or was closed, our identifier will
-	 * no longer be valid and any call to {@link
-	 * XAConnection#getUnderlying} will throw an exception. Previously,
-	 * the XA connection would hold a reference to use and tell us to
-	 * terminate, but that prevented ClientConnection from being
-	 * finalized.
-	 */
-	private int _clientId;
-
-
-
-
-	/*
-	 * Construct a new client connection to provide access to the
-	 * underlying JDBC connection (<tt>underlying</tt>) on behalf of
-	 * an XA/pooled connection (<tt>xaConn<tt/>). The pooled connection
-	 * is required to notify of connection closure and fatal errors.
-	 *
-	 * @param xaConn The XA/pooled connection that created this
-	 *	 client connection
-	 * @param clientId A unique identifier handed to us by
-	 *	 {@link XAConnection}
-	 * @param underlying The underlying JDBC connection
-	 */
-	ClientConnection( XAConnectionImpl xaConn, int clientId )
-	{
-		_xaConn = xaConn;
-		_clientId = clientId;
-	}
-
-
-	public Statement createStatement()
-	throws SQLException
-	{
-		try
-		{
-			return getUnderlying().createStatement();
-		}
-		catch ( SQLException except )
-		{
-			notifyError( except );
-			throw except;
-		}
-	}
-
-
-	public Statement createStatement( int resultSetType, int resultSetConcurrency )
-	throws SQLException
-	{
-		try
-		{
-			return getUnderlying().createStatement( resultSetType, resultSetConcurrency );
-		}
-		catch ( SQLException except )
-		{
-			notifyError( except );
-			throw except;
-		}
-	}
-
-
-	public PreparedStatement prepareStatement( String sql )
-	throws SQLException
-	{
-		try
-		{
-			return getUnderlying().prepareStatement( sql );
-		}
-		catch ( SQLException except )
-		{
-			notifyError( except );
-			throw except;
-		}
-	}
-
-
-	public PreparedStatement prepareStatement( String sql, int resultSetType, int resultSetConcurrency )
-	throws SQLException
-	{
-		try
-		{
-			return getUnderlying().prepareStatement( sql, resultSetType, resultSetConcurrency );
-		}
-		catch ( SQLException except )
-		{
-			notifyError( except );
-			throw except;
-		}
-	}
-
-
-	public CallableStatement prepareCall( String sql )
-	throws SQLException
-	{
-		try
-		{
-			return getUnderlying().prepareCall( sql );
-		}
-		catch ( SQLException except )
-		{
-			notifyError( except );
-			throw except;
-		}
-	}
-
-
-	public CallableStatement prepareCall( String sql, int resultSetType, int resultSetConcurrency )
-	throws SQLException
-	{
-		try
-		{
-			return getUnderlying().prepareCall( sql, resultSetType, resultSetConcurrency );
-		}
-		catch ( SQLException except )
-		{
-			notifyError( except );
-			throw except;
-		}
-	}
-
-
-	public String nativeSQL( String sql )
-	throws SQLException
-	{
-		try
-		{
-			return getUnderlying().nativeSQL( sql );
-		}
-		catch ( SQLException except )
-		{
-			notifyError( except );
-			throw except;
-		}
-	}
-
-
-	public DatabaseMetaData getMetaData()
-	throws SQLException
-	{
-		try
-		{
-			return getUnderlying().getMetaData();
-		}
-		catch ( SQLException except )
-		{
-			notifyError( except );
-			throw except;
-		}
-	}
-
-
-	public void setCatalog( String catalog )
-	throws SQLException
-	{
-		try
-		{
-			getUnderlying().setCatalog( catalog );
-		}
-		catch ( SQLException except )
-		{
-			notifyError( except );
-			throw except;
-		}
-	}
-
-
-	public String getCatalog()
-	throws SQLException
-	{
-		try
-		{
-			return getUnderlying().getCatalog();
-		}
-		catch ( SQLException except )
-		{
-			notifyError( except );
-			throw except;
-		}
-	}
-
-
-	public SQLWarning getWarnings()
-	throws SQLException
-	{
-		try
-		{
-			return getUnderlying().getWarnings();
-		}
-		catch ( SQLException except )
-		{
-			notifyError( except );
-			throw except;
-		}
-	}
-
-
-	public void clearWarnings()
-	throws SQLException
-	{
-		try
-		{
-			getUnderlying().clearWarnings();
-		}
-		catch ( SQLException except )
-		{
-			notifyError( except );
-			throw except;
-		}
-	}
-
-
-	public Map getTypeMap()
-	throws SQLException
-	{
-		try
-		{
-			return getUnderlying().getTypeMap();
-		}
-		catch ( SQLException except )
-		{
-			notifyError( except );
-			throw except;
-		}
-	}
-
-
-	public void setTypeMap( Map map )
-	throws SQLException
-	{
-		try
-		{
-			getUnderlying().setTypeMap( map );
-		}
-		catch ( SQLException except )
-		{
-			notifyError( except );
-			throw except;
-		}
-	}
-
-
-	public void setAutoCommit( boolean autoCommit )
-	throws SQLException
-	{
-		// Cannot set auto-commit inside a transaction.
-		if ( _xaConn.insideGlobalTx() )
-			throw new SQLException( "Cannot commit/rollback a connection managed by the transaction manager" );
-		try
-		{
-			getUnderlying().setAutoCommit( autoCommit );
-		}
-		catch ( SQLException except )
-		{
-			notifyError( except );
-			throw except;
-		}
-	}
-
-
-	public boolean getAutoCommit()
-	throws SQLException
-	{
-		try
-		{
-			return getUnderlying().getAutoCommit();
-		}
-		catch ( SQLException except )
-		{
-			notifyError( except );
-			throw except;
-		}
-	}
-
-
-	public void commit()
-	throws SQLException
-	{
-		// Cannot commit directly if we're inside a global transaction.
-		if ( _xaConn.insideGlobalTx() )
-			throw new SQLException( "Cannot commit/rollback a connection managed by the transaction manager" );
-		// Cannot commit a read-only transaction.
-		if ( isReadOnly() )
-			throw new SQLException( "Cannot commit/rollback a read-only transaction" );
-
-		// This only occurs if not inside a local transaction.
-		try
-		{
-			getUnderlying().commit();
-		}
-		catch ( SQLException except )
-		{
-			notifyError( except );
-			throw except;
-		}
-	}
-
-
-
-	public void rollback()
-	throws SQLException
-	{
-		// Cannot commit directly if we're inside a global transaction.
-		if ( _xaConn.insideGlobalTx() )
-			throw new SQLException( "Cannot commit/rollback a connection managed by the transaction manager" );
-
-		// This only occurs if not inside a local transaction.
-		try
-		{
-			getUnderlying().rollback();
-		}
-		catch ( SQLException except )
-		{
-			notifyError( except );
-			throw except;
-		}
-	}
-
-
-	public void setReadOnly( boolean readOnly )
-	throws SQLException
-	{
-		try
-		{
-			getUnderlying().setReadOnly( readOnly );
-		}
-		catch ( SQLException except )
-		{
-			notifyError( except );
-			throw except;
-		}
-	}
-
-
-	public boolean isReadOnly()
-	throws SQLException
-	{
-		try
-		{
-			return getUnderlying().isReadOnly();
-		}
-		catch ( SQLException except )
-		{
-			notifyError( except );
-			throw except;
-		}
-	}
-
-
-	public void setTransactionIsolation( int level )
-	throws SQLException
-	{
-		try
-		{
-			getUnderlying().setTransactionIsolation( level );
-		}
-		catch ( SQLException except )
-		{
-			notifyError( except );
-			throw except;
-		}
-	}
-
-
-	public int getTransactionIsolation()
-	throws SQLException
-	{
-		try
-		{
-			return getUnderlying().getTransactionIsolation();
-		}
-		catch ( SQLException except )
-		{
-			notifyError( except );
-			throw except;
-		}
-	}
-
-
-	public synchronized void close()
-	throws SQLException
-	{
-		if ( _xaConn == null )
-			return;
-
-		// Notify the XA connection that we are no longer going
-		// to be used. Whether the underlying connection is released,
-		// held until the transaction terminates, etc is not
-		// a concern of us.
-		_xaConn.notifyClose( _clientId );
-		_xaConn = null;
-	}
-
-
-	public synchronized boolean isClosed()
-	{
-		// Simple way of determining if this connection is closed.
-		// The actual connection is never closed, it is pooled.
-		return ( _xaConn == null );
-	}
-
-
-	/*
-	 * Called by {@link XAConnectionImpl} to terminate this connection
-	 * by dissociating it from the underlying JDBC connection.
-	 * The application would call {@link #close} but {@link
-	 * XAConnectionImpl} cannot, since pooled connection requirements
-	 * will cause an inifinite loop. This method should not attempt
-	 * to notify either a closure or fatal error, but rather throw an
-	 * exception if it fails.
-	 */
-	/* Deprecated: see XAConnection._clientId
-	void terminate()
-{
-	_xaConn = null;
-}
-	*/
-
-
-	protected void finalize()
-	throws Throwable
-	{
-		close();
-	}
-
-
-	public String toString()
-	{
-		try
-		{
-			return getUnderlying().toString();
-		}
-		catch ( SQLException except )
-		{
-			return "XAConnection: Connection closed";
-		}
-	}
-
-
-	/*
-	 * Called when an exception is thrown by the underlying connection
-	 * to determine whether the exception is critical or not. If the
-	 * exception is critical, notifies the XA connection to forget
-	 * about this connection.
-	 *
-	 * @param except The exception thrown by the underlying
-	 *	 connection
-	 */
-	void notifyError( SQLException except )
-	{
-		if ( _xaConn != null )
-			_xaConn.notifyError( _clientId, except );
-	}
-
-
-	/*
-	 * Called to retrieve the underlying JDBC connection. Actual JDBC
-	 * operations are performed against it. Throws an SQLException if
-	 * this connection has been closed.
-	 */
-	Connection getUnderlying()
-	throws SQLException
-	{
-		if ( _xaConn == null )
-			throw new SQLException( "This connection has been closed" );
-		// Must pass the client identifier so XAConnection can determine
-		// whether we are still valid. If it tells us we're no longer
-		// valid, we have little to do.
-		try
-		{
-			return _xaConn.getUnderlying( _clientId );
-		}
-		catch ( SQLException except )
-		{
-			_xaConn = null;
-			throw except;
-		}
-	}
-
-
-}
-
-
-
diff --git a/src/interfaces/jdbc/org/postgresql/xa/TwoPhaseConnection.java b/src/interfaces/jdbc/org/postgresql/xa/TwoPhaseConnection.java
deleted file mode 100644
index 7b0ce88f498bc1dfd96c9f7d11d69726b8f8a8c0..0000000000000000000000000000000000000000
--- a/src/interfaces/jdbc/org/postgresql/xa/TwoPhaseConnection.java
+++ /dev/null
@@ -1,116 +0,0 @@
-/*
-* Redistribution and use of this software and associated documentation
-* ("Software"), with or without modification, are permitted provided
-* that the following conditions are met:
-*
-* 1. Redistributions of source code must retain copyright
-*	 statements and notices.  Redistributions must also contain a
-*	 copy of this document.
-*
-* 2. Redistributions in binary form must reproduce the
-*	 above copyright notice, this list of conditions and the
-*	 following disclaimer in the documentation and/or other
-*	 materials provided with the distribution.
-*
-* 3. The name "Exolab" must not be used to endorse or promote
-*	 products derived from this Software without prior written
-*	 permission of Exoffice Technologies.  For written permission,
-*	 please contact info@exolab.org.
-*
-* 4. Products derived from this Software may not be called "Exolab"
-*	 nor may "Exolab" appear in their names without prior written
-*	 permission of Exoffice Technologies. Exolab is a registered
-*	 trademark of Exoffice Technologies.
-*
-* 5. Due credit should be given to the Exolab Project
-*	 (http://www.exolab.org/).
-*
-* THIS SOFTWARE IS PROVIDED BY EXOFFICE TECHNOLOGIES AND CONTRIBUTORS
-* ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT
-* NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
-* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.	IN NO EVENT SHALL
-* EXOFFICE TECHNOLOGIES OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
-* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
-* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
-* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
-* OF THE POSSIBILITY OF SUCH DAMAGE.
-*
-* Copyright 1999 (C) Exoffice Technologies Inc. All Rights Reserved.
-*
-* $Id: TwoPhaseConnection.java,v 1.3 2001/11/19 22:33:39 momjian Exp $
-*/
-
-
-package org.postgresql.xa;
-
-
-import java.sql.SQLException;
-
-
-/*
- * Defines two-phase commit support for a JDBC connection used by
- * {@link XAConnection}. A JDBC connection that can implement any of
- * these features should extend this interface and attempt to
- * implement as much as it can.
- * <p>
- * {@link #prepare} is used as part of the two phase commit protocol
- * to determine whether the transaction can commit or must rollback.
- * Failure to implement this method will cause all connections to vote
- * for commit, whether or not they can actually commit, leading to
- * mixed heuristics.
- * <p>
- * {@link #enableSQLTransactions} allows the SQL begin/commit/rollback
- * commands to be disabled for the duration of a transaction managed
- * through an {@link javax.transaction.xaXAResource}, preventing the
- * application from demarcating transactions directly.
- * <p>
- * {@link #isCriticalError} is used to tell if an exception thrown by
- * the connection is fatal and the connection should not be returned
- * to the pool.
- *
- *
- * @author <a href="arkin@exoffice.com">Assaf Arkin</a>
- * @version 1.0
- */
-public interface TwoPhaseConnection
-{
-
-
-	/*
-	 * Enables or disables transaction demarcation through SQL commit
-	 * and rollback. When the connection falls under control of
-	 * {@link XAConnection}, SQL commit/rollback commands will be
-	 * disabled to prevent direct transaction demarcation.
-	 *
-	 * @param flag True to enable SQL transactions (the default)
-	 */
-	public void enableSQLTransactions( boolean flag );
-
-
-	/*
-	 * Called to prepare the transaction for commit. Returns true if
-	 * the transaction is prepared, false if the transaction is
-	 * read-only. If the transaction has been marked for rollback,
-	 * throws a {@link RollbackException}.
-	 *
-	 * @return True if can commit, false if read-only
-	 * @throws SQLException If transaction has been marked for
-	 *	 rollback or cannot commit for any other reason
-	 */
-	public boolean prepare()
-	throws SQLException;
-
-
-	/*
-	 * Returns true if the error issued by this connection is a
-	 * critical error and the connection should be terminated.
-	 *
-	 * @param except The exception thrown by this connection
-	 */
-	public boolean isCriticalError( SQLException except );
-
-
-}
diff --git a/src/interfaces/jdbc/org/postgresql/xa/TxConnection.java b/src/interfaces/jdbc/org/postgresql/xa/TxConnection.java
deleted file mode 100644
index ef2179285f0e42d0b06dfaad72218f2cfa040343..0000000000000000000000000000000000000000
--- a/src/interfaces/jdbc/org/postgresql/xa/TxConnection.java
+++ /dev/null
@@ -1,129 +0,0 @@
-/*
-* Redistribution and use of this software and associated documentation
-* ("Software"), with or without modification, are permitted provided
-* that the following conditions are met:
-*
-* 1. Redistributions of source code must retain copyright
-*	 statements and notices.  Redistributions must also contain a
-*	 copy of this document.
-*
-* 2. Redistributions in binary form must reproduce the
-*	 above copyright notice, this list of conditions and the
-*	 following disclaimer in the documentation and/or other
-*	 materials provided with the distribution.
-*
-* 3. The name "Exolab" must not be used to endorse or promote
-*	 products derived from this Software without prior written
-*	 permission of Exoffice Technologies.  For written permission,
-*	 please contact info@exolab.org.
-*
-* 4. Products derived from this Software may not be called "Exolab"
-*	 nor may "Exolab" appear in their names without prior written
-*	 permission of Exoffice Technologies. Exolab is a registered
-*	 trademark of Exoffice Technologies.
-*
-* 5. Due credit should be given to the Exolab Project
-*	 (http://www.exolab.org/).
-*
-* THIS SOFTWARE IS PROVIDED BY EXOFFICE TECHNOLOGIES AND CONTRIBUTORS
-* ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT
-* NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
-* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.	IN NO EVENT SHALL
-* EXOFFICE TECHNOLOGIES OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
-* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
-* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
-* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
-* OF THE POSSIBILITY OF SUCH DAMAGE.
-*
-* Copyright 1999 (C) Exoffice Technologies Inc. All Rights Reserved.
-*
-* $Id: TxConnection.java,v 1.3 2001/11/19 22:33:39 momjian Exp $
-*/
-
-
-package org.postgresql.xa;
-
-
-import java.sql.Connection;
-import javax.transaction.xa.Xid;
-
-
-/*
- * Describes an open connection associated with a transaction. When a
- * transaction is opened for a connection, this record is created for
- * the connection. It indicates the underlying JDBC connection and
- * transaction Xid. Multiple XA connection that fall under the same
- * transaction Xid will share the same TxConnection object.
- *
- *
- * @author <a href="arkin@exoffice.com">Assaf Arkin</a>
- * @version 1.0
- * @see Xid
- * @see XAConnectionImpl
- */
-final class TxConnection
-{
-
-
-	/*
-	 * The Xid of the transactions. Connections that are not
-	 * associated with a transaction are not represented here.
-	 */
-	Xid xid;
-
-
-	/*
-	 * Holds the underlying JDBC connection for as long as this
-	 * connection is useable. If the connection has been rolled back,
-	 * timed out or had any other error, this variable will null
-	 * and the connection is considered failed.
-	 */
-	Connection conn;
-
-
-
-	/*
-	 * Indicates the clock time (in ms) when the transaction should
-	 * time out. The transaction times out when
-	 * <tt>System.currentTimeMillis() > timeout</tt>.
-	 */
-	long timeout;
-
-
-	/*
-	 * Indicates the clock time (in ms) when the transaction started.
-	 */
-	long started;
-
-
-	/*
-	 * Reference counter indicates how many XA connections share this
-	 * underlying connection and transaction. Always one or more.
-	 */
-	int count;
-
-
-	/*
-	 * True if the transaction has failed due to time out.
-	 */
-	boolean timedOut;
-
-
-	/*
-	 * True if the transaction has already been prepared.
-	 */
-	boolean prepared;
-
-
-	/*
-	 * True if the transaction has been prepared and found out to be
-	 * read-only. Read-only transactions do not require commit/rollback.
-	 */
-	boolean readOnly;
-
-
-}
-
diff --git a/src/interfaces/jdbc/org/postgresql/xa/XAConnectionImpl.java b/src/interfaces/jdbc/org/postgresql/xa/XAConnectionImpl.java
deleted file mode 100644
index 776badfd6d4046a955ea2cc2126f7a07dab4a6c6..0000000000000000000000000000000000000000
--- a/src/interfaces/jdbc/org/postgresql/xa/XAConnectionImpl.java
+++ /dev/null
@@ -1,956 +0,0 @@
-/*
-* Redistribution and use of this software and associated documentation
-* ("Software"), with or without modification, are permitted provided
-* that the following conditions are met:
-*
-* 1. Redistributions of source code must retain copyright
-*	 statements and notices.  Redistributions must also contain a
-*	 copy of this document.
-*
-* 2. Redistributions in binary form must reproduce the
-*	 above copyright notice, this list of conditions and the
-*	 following disclaimer in the documentation and/or other
-*	 materials provided with the distribution.
-*
-* 3. The name "Exolab" must not be used to endorse or promote
-*	 products derived from this Software without prior written
-*	 permission of Exoffice Technologies.  For written permission,
-*	 please contact info@exolab.org.
-*
-* 4. Products derived from this Software may not be called "Exolab"
-*	 nor may "Exolab" appear in their names without prior written
-*	 permission of Exoffice Technologies. Exolab is a registered
-*	 trademark of Exoffice Technologies.
-*
-* 5. Due credit should be given to the Exolab Project
-*	 (http://www.exolab.org/).
-*
-* THIS SOFTWARE IS PROVIDED BY EXOFFICE TECHNOLOGIES AND CONTRIBUTORS
-* ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT
-* NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
-* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.	IN NO EVENT SHALL
-* EXOFFICE TECHNOLOGIES OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
-* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
-* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
-* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
-* OF THE POSSIBILITY OF SUCH DAMAGE.
-*
-* Copyright 1999 (C) Exoffice Technologies Inc. All Rights Reserved.
-*
-* $Id: XAConnectionImpl.java,v 1.4 2001/11/19 23:19:21 momjian Exp $
-*/
-
-
-package org.postgresql.xa;
-
-
-import java.sql.Connection;
-import java.sql.SQLException;
-import java.util.Vector;
-import javax.sql.XAConnection;
-import javax.sql.PooledConnection;
-import javax.sql.ConnectionEvent;
-import javax.sql.ConnectionEventListener;
-import javax.transaction.RollbackException;
-import javax.transaction.xa.XAResource;
-import javax.transaction.xa.Xid;
-import javax.transaction.xa.XAException;
-
-
-/*
- * Implements an X/A connection that can be pooled and managed from
- * inside a transaction monitor. This is the XA connection returned
- * to the application server from the {@link XADataSourceImpl} and
- * will be used to obtain {@link ClientConnection} for the
- * application.
- * <p>
- * If the transaction is managed through the JDBC interface, this
- * connection will reference the underlying JDBC connection directly.
- * If this resource is enlisted with a global transaction through
- * the {@link XAResource} interface, it will reference a transactional
- * connection, or {@link TxConnection}. Such a connection may be
- * shared by two or more XA connections enlisted with the same
- * transaction.
- *
- *
- * @author <a href="arkin@exoffice.com">Assaf Arkin</a>
- * @version 1.0
- * @see ClientConnection
- * @see ConnectionEventListener
- * @see TxConnection
- */
-public final class XAConnectionImpl
-			implements XAConnection, XAResource
-{
-
-
-	/*
-	 * This is the underlying JDBC connection represented
-	 * by this pooled connection. This variable may initially be null,
-	 * in which case {@link #getUnderlying} will return a new
-	 * connection and set this variable. This variable is mutually
-	 * exclusive with {@link #_txConn} and is always null for
-	 * connections inside a transaction.
-	 */
-	Connection _underlying;
-
-
-	/*
-	 * If this connection is part of a global transaction, this
-	 * object identifies the transaction. The transaction's
-	 * underlying JDBC connection is exposed through this object and
-	 * {@link #_underlying} is null. If this connection is closed,
-	 * then the connection has been timedout. Commit/rollback will
-	 * always set this variable to null.
-	 */
-	private TxConnection _txConn;
-
-
-	/*
-	 * The client connection last handed to the application. If the
-	 * application calls {@link #getConnection} again, we should hand
-	 * out a new client connection and render the previous one closed.
-	 */
-	// No longer in use, see _clientId
-	//private ClientConnection			  _clientConn;
-
-
-	/*
-	 * An event listener can be registered and notified when the
-	 * client connection has been closed by the application or a
-	 * fatal error rendered it unuseable.
-	 */
-	private ConnectionEventListener _listener;
-
-
-	/*
-	 * The resource manager is used to share connections within the
-	 * same transaction.
-	 */
-	private XADataSourceImpl _resManager;
-
-
-	/*
-	 * This is an identifier we hand to the client connection when we
-	 * create it. When the client connection asks for the underlying
-	 * connection, we compare the identifiers. If since that point we
-	 * created a new client connection, we regard an old client
-	 * connection as discarded and do not hand it the underlying
-	 * connection.
-	 * <p>
-	 * Previously, when a new client connection was created, we used
-	 * a reference to the old one to terminate it. This proved to
-	 * not work well, since the client connection could never be
-	 * finalized.
-	 */
-	private int _clientId = 1;
-
-
-	/*
-	 * Construct a new XA/pooled connection with the underlying JDBC
-	 * connection suitable for this driver only. This is a one to one
-	 * mapping between this connection and the underlying connection.
-	 * The underlying connection is only provided for pooled
-	 * connections. XA connections are suspect of being enlisted with
-	 * a global transaction which might already bear an underlying
-	 * connection. If not, one will be created later on.
-	 */
-	XAConnectionImpl( XADataSourceImpl resManager,
-					  Connection underlying )
-	{
-		_underlying = underlying;
-		_resManager = resManager;
-	}
-
-
-	public synchronized void close()
-	throws SQLException
-	{
-		// This is our indication that this connection has been
-		// closed programmatically.
-		if ( _resManager == null )
-			throw new SQLException( "This connection has been closed" );
-
-		// The client connection is no longer useable.
-		/* Deprecated: see _clientId
-		if ( _clientConn != null )
-			_clientConn.terminate();
-		*/
-		_clientId = -1;
-
-		// The underlying connection is closed and this connection
-		// is no longer useable. This method can be called any number
-		// of times (e.g. we use it in finalizer).	We do not handle
-		// transactions, we just kill the connection.
-		try
-		{
-			if ( _underlying != null )
-			{
-				_underlying.commit();
-				_underlying.close();
-			}
-			else if ( _txConn != null )
-			{
-				try
-				{
-					end( _txConn.xid, TMSUCCESS );
-				}
-				catch ( XAException except )
-				{ }
-			}
-		}
-		finally
-		{
-			_resManager = null;
-			_underlying = null;
-			_txConn = null;
-			_listener = null;
-		}
-	}
-
-
-	public XAResource getXAResource()
-	{
-		// The connection acts as it's own resource manager
-		return this;
-	}
-
-
-	public synchronized void addConnectionEventListener( ConnectionEventListener listener )
-	{
-		if ( listener == null )
-			throw new NullPointerException( "XAConnection: Argument 'listener' is null" );
-		if ( _listener != null )
-			throw new IllegalStateException( "XAConnection: Only one listener supported per connection" );
-		_listener = listener;
-	}
-
-
-	public synchronized void removeConnectionEventListener( ConnectionEventListener listener )
-	{
-		if ( listener == null )
-			throw new NullPointerException( "XAConnection: Argument 'listener' is null" );
-		if ( _listener == null || _listener != listener )
-			throw new IllegalStateException( "XAConnection: Listener never registered with this pooled connection" );
-		_listener = null;
-	}
-
-
-	public synchronized java.sql.Connection getConnection()
-	throws SQLException
-	{
-		// If this pooled connection has been closed, throw an exception.
-		if ( _resManager == null )
-			throw new SQLException( "This connection has been closed" );
-
-		// If getConnection() was called before and the underlying
-		// connection was not closed, we take it away from the previous
-		// recieved as per the PooledConnection design.
-		/* Deprecated: see _clientId
-		if ( _clientConn != null )
-			_clientConn.terminate();
-		*/
-
-		// If we are handling an underlying connection, we commit the
-		// old transaction and are ready to work for a new one.
-		// If we are part of a global transaction we hope that end/
-		// start were called properly, but we're not longer in that
-		// transaction.
-		if ( _underlying != null )
-		{
-			try
-			{
-				_underlying.commit();
-			}
-			catch ( SQLException except )
-			{
-				ConnectionEvent event;
-
-				if ( _listener != null )
-				{
-					event = new ConnectionEvent( this, except );
-					_listener.connectionErrorOccurred( event );
-				}
-			}
-		}
-
-		// Create a new ClientConnection which will be returned to the
-		// application. The ClientConnection cannot be closed directly
-		// and cannot manage it's own transactions.
-		/* Deprecated: see _clientId
-		_clientConn = new ClientConnection( this );
-		return _clientConn;
-		*/
-		return new ClientConnection( this, ++_clientId );
-	}
-
-
-	/*
-	 * Called by {@link ClientConnection} to notify that the application
-	 * has attempted to close the connection. After this call, the client
-	 * connection is no longer useable and this pooled connection can be
-	 * reused. The event listener is notified immediately.
-	 *
-	 * @param clientId The {@link ClientConnection} identifier
-	 */
-	synchronized void notifyClose( int clientId )
-	{
-		ConnectionEvent event;
-
-		// ClientConnection has been closed, we dissociated it from
-		// the underlying connection and notify any listener that this
-		// pooled connection can be reused.
-		/* Deprecated: see clientId
-		_clientConn.terminate();
-		_clientConn = null;
-		*/
-		// We have to expect being called by a ClientConnection that we
-		// no longer regard as valid. That's acceptable, we just ignore.
-		if ( clientId != _clientId )
-			return;
-
-		// If we are handling an underlying connection, we commit the
-		// old transaction and are ready to work for a new one.
-		// If we are part of a global transaction we hope that end/
-		// start were called properly.
-		if ( _underlying != null )
-		{
-			try
-			{
-				_underlying.commit();
-			}
-			catch ( SQLException except )
-			{
-				if ( _listener != null )
-				{
-					event = new ConnectionEvent( this, except );
-					_listener.connectionErrorOccurred( event );
-				}
-				return;
-			}
-		}
-		// Notify the listener.
-		if ( _listener != null )
-		{
-			event = new ConnectionEvent( this );
-			_listener.connectionClosed( event );
-		}
-	}
-
-
-	/*
-	 * Called by {@link ClientConnection} to notify that an error
-	 * occured with the underlying connection. If the error is
-	 * critical, the underlying connection is closed and the listener
-	 * is notified.
-	 *
-	 * @param clientId The {@link ClientConnection} identifier
-	 * @param except The exception raised by the underlying connection
-	 */
-	synchronized void notifyError( int clientId, SQLException except )
-	{
-		ConnectionEvent event;
-
-		if ( clientId != _clientId )
-			return;
-
-		// If the connection is not two-phase commit we cannot determine
-		// whether the error is critical, we just return. If the connection
-		// is two phase commit, but the error is not critical, we return.
-		if ( _underlying != null )
-		{
-			if ( ! ( _underlying instanceof TwoPhaseConnection ) ||
-					! ( (TwoPhaseConnection) _underlying ).isCriticalError( except ) )
-				return;
-			if ( _txConn.conn == null ||
-					! ( _txConn.conn instanceof TwoPhaseConnection ) ||
-					! ( (TwoPhaseConnection) _txConn.conn ).isCriticalError( except ) )
-				return;
-		}
-
-		// The client connection is no longer useable, the underlying
-		// connection (if used) is closed, the TxConnection (if used)
-		// is rolledback and this connection dies (but close() may
-		// still be called).
-		++_clientId;
-		if ( _underlying != null )
-		{
-			try
-			{
-				_underlying.close();
-			}
-			catch ( SQLException e2 )
-			{
-				// Ignore that, we know there's an error.
-			}
-			_underlying = null;
-		}
-		else if ( _txConn != null )
-		{
-			try
-			{
-				end( _txConn.xid, TMFAIL );
-			}
-			catch ( XAException e2 )
-			{
-				// Ignore that, we know there's an error.
-			}
-			_txConn = null;
-		}
-
-		// Notify the listener.
-		if ( _listener != null )
-		{
-			event = new ConnectionEvent( this, except );
-			_listener.connectionErrorOccurred( event );
-		}
-	}
-
-
-	protected void finalize()
-	throws Throwable
-	{
-		// We are no longer referenced by anyone (including the
-		// connection pool). Time to close down.
-		close();
-	}
-
-
-	public String toString()
-	{
-		if ( _underlying != null )
-			return "XAConnection: " + _underlying;
-		else
-			return "XAConnection: unused";
-	}
-
-
-	public synchronized void start( Xid xid, int flags )
-	throws XAException
-	{
-		// General checks.
-		if ( xid == null )
-			throw new XAException( XAException.XAER_INVAL );
-		if ( _txConn != null )
-			throw new XAException( XAException.XAER_OUTSIDE );
-
-		synchronized ( _resManager )
-		{
-			if ( flags == TMNOFLAGS )
-			{
-				// Starting a new transaction. First, make sure it is
-				// not shared with any other connection (need to join
-				// for that).
-				if ( _resManager.getTxConnection( xid ) != null )
-					throw new XAException( XAException.XAER_DUPID );
-
-				// Create a new TxConnection to describe this
-				// connection in the context of a transaction and
-				// register it with the resource manager so it can
-				// be shared.
-				try
-				{
-					_txConn = new TxConnection();
-					if ( _underlying != null )
-					{
-						_txConn.conn = _underlying;
-						_underlying = null;
-					}
-					else
-						_txConn.conn = _resManager.newConnection();
-					_txConn.xid = xid;
-					_txConn.count = 1;
-					_txConn.started = System.currentTimeMillis();
-					_txConn.timeout = _txConn.started + ( _resManager.getTransactionTimeout() * 1000 );
-					_resManager.setTxConnection( xid, _txConn );
-				}
-				catch ( SQLException except )
-				{
-					// If error occured at this point, we can only
-					// report it as resource manager error.
-					if ( _resManager.getLogWriter() != null )
-						_resManager.getLogWriter().println( "XAConnection: failed to begin a transaction: " + except );
-					throw new XAException( XAException.XAER_RMERR );
-				}
-
-				try
-				{
-					_txConn.conn.setAutoCommit( false );
-					try
-					{
-						if ( _resManager.isolationLevel() != Connection.TRANSACTION_NONE )
-							_txConn.conn.setTransactionIsolation( _resManager.isolationLevel() );
-					}
-					catch ( SQLException e )
-					{
-						// The underlying driver might not support this
-						// isolation level that we use by default.
-					}
-					if ( _txConn.conn instanceof TwoPhaseConnection )
-						( (TwoPhaseConnection) _txConn.conn ).enableSQLTransactions( false );
-				}
-				catch ( SQLException except )
-				{
-					// If error occured at this point, we can only
-					// report it as resource manager error.
-					if ( _resManager.getLogWriter() != null )
-						_resManager.getLogWriter().println( "XAConnection: failed to begin a transaction: " + except );
-					throw new XAException( XAException.XAER_RMERR );
-				}
-			}
-			else if ( flags == TMJOIN || flags == TMRESUME )
-			{
-				// We are joining another transaction with an
-				// existing TxConnection.
-				_txConn = _resManager.getTxConnection( xid );
-				if ( _txConn == null )
-					throw new XAException( XAException.XAER_INVAL );
-
-				// Update the number of XAConnections sharing this
-				// transaction connection.
-				if ( flags == TMJOIN && _txConn.count == 0 )
-					throw new XAException( XAException.XAER_PROTO );
-				++_txConn.count;
-
-				// If we already have an underlying connection (as we can
-				// expect to), we should release that underlying connection
-				// and make it available to the resource manager.
-				if ( _underlying != null )
-				{
-					_resManager.releaseConnection( _underlying );
-					_underlying = null;
-				}
-			}
-			else
-				// No other flags supported in start().
-				throw new XAException( XAException.XAER_INVAL );
-		}
-	}
-
-
-	public synchronized void end( Xid xid, int flags )
-	throws XAException
-	{
-		// General checks.
-		if ( xid == null )
-			throw new XAException( XAException.XAER_INVAL );
-		// Note: we could get end with success or failure even it
-		// we were previously excluded from the transaction.
-		if ( _txConn == null && flags == TMSUSPEND )
-			throw new XAException( XAException.XAER_NOTA );
-
-		synchronized ( _resManager )
-		{
-			if ( flags == TMSUCCESS || flags == TMFAIL)
-			{
-				// We are now leaving a transaction we started or
-				// joined before. We can expect any of prepare/
-				// commit/rollback to be called next, so TxConnection
-				// is still valid.
-
-				// If we were suspended from the transaction, we'll
-				// join it for the duration of this operation.
-				// Make sure the reference count reaches zero by the
-				// time we get to prepare.
-				if ( _txConn == null )
-				{
-					_txConn = _resManager.getTxConnection( xid );
-					if ( _txConn == null )
-						throw new XAException( XAException.XAER_NOTA );
-				}
-				else
-				{
-					if ( _txConn.xid != null && ! _txConn.xid.equals( xid ) )
-						throw new XAException( XAException.XAER_NOTA );
-					--_txConn.count;
-				}
-
-				// If transaction failed, we can rollback the
-				// transaction and release the underlying connection.
-				// We can expect all other resources to recieved the
-				// same end notification. We don't expect forget to happen.
-				if ( flags == TMFAIL && _txConn.conn != null )
-				{
-					try
-					{
-						if ( _txConn.conn instanceof TwoPhaseConnection )
-							( (TwoPhaseConnection) _txConn.conn ).enableSQLTransactions( true );
-						_txConn.conn.rollback();
-						_resManager.releaseConnection( _txConn.conn );
-					}
-					catch ( SQLException except )
-					{
-						// There is a problem with the underlying
-						// connection, but it was not added to the poll.
-					}
-					_resManager.setTxConnection( _txConn.xid, null );
-					_txConn.conn = null;
-					_txConn.xid = null;
-				}
-
-				if ( flags == TMSUCCESS)
-				{
-					// We should be looking for a new transaction.
-					// Next thing we might be participating in a new
-					// transaction while the current one is being
-					// rolled back.
-					_txConn = null;
-				}
-			}
-			else if ( flags == TMSUSPEND )
-			{
-				// We no longer take part in this transaction.
-				// Possibly we'll be asked to resume later on, but
-				// right now we have to forget about the transaction
-				// and the underlying connection.
-				--_txConn.count;
-				_txConn = null;
-			}
-			else
-				// No other flags supported in end().
-				throw new XAException( XAException.XAER_INVAL );
-		}
-	}
-
-
-	public synchronized void forget( Xid xid )
-	throws XAException
-	{
-		TxConnection txConn;
-
-		// General checks.
-		if ( xid == null )
-			throw new XAException( XAException.XAER_INVAL );
-		synchronized ( _resManager )
-		{
-			// We have to forget about the transaction, meaning the
-			// transaction no longer exists for this or any other
-			// connection. We might be called multiple times.
-			txConn = _resManager.setTxConnection( xid, null );
-			if ( _txConn == txConn )
-				_txConn = null;
-			if ( txConn != null )
-			{
-				if ( txConn.conn != null )
-				{
-					_resManager.releaseConnection( txConn.conn );
-					txConn.conn = null;
-				}
-				txConn.xid = null;
-			}
-		}
-	}
-
-
-	public synchronized int prepare( Xid xid )
-	throws XAException
-	{
-		TxConnection txConn;
-
-		// General checks.
-		if ( xid == null )
-			throw new XAException( XAException.XAER_INVAL );
-
-		synchronized ( _resManager )
-		{
-			// Technically, prepare may be called for any connection,
-			// not just this one.
-			txConn = _resManager.getTxConnection( xid );
-			if ( txConn == null )
-				throw new XAException( XAException.XAER_NOTA );
-
-			// This is an error and should never happen. All other
-			// parties in the transaction should have left it before.
-			if ( txConn.count > 0 )
-				throw new XAException( XAException.XAER_PROTO );
-
-			// If the transaction failed, we have to force a rollback.
-			// We track the case of failure due to a timeout.
-			if ( txConn.timedOut )
-				throw new XAException( XAException.XA_RBTIMEOUT );
-			if ( txConn.conn == null )
-				throw new XAException( XAException.XA_RBROLLBACK );
-
-			// Since there is no preparation mechanism in a generic
-			// JDBC driver, we only test for read-only transaction
-			// but do not commit at this point.
-			try
-			{
-				txConn.prepared = true;
-				if ( txConn.conn instanceof TwoPhaseConnection )
-				{
-					// For 2pc connection we ask it to prepare and determine
-					// whether it's commiting or read-only. If a rollback
-					// exception happens, we report it.
-					try
-					{
-						if ( ( (TwoPhaseConnection) txConn.conn ).prepare() )
-							return XA_OK;
-						else
-						{
-							txConn.readOnly = true;
-							return XA_RDONLY;
-						}
-					}
-					catch ( SQLException except )
-					{
-						throw new XAException( XAException.XA_RBROLLBACK );
-					}
-				}
-				else
-				{
-					// For standard connection we cannot prepare, we can
-					// only guess if it's read only.
-					if ( txConn.conn.isReadOnly() )
-					{
-						txConn.readOnly = true;
-						return XA_RDONLY;
-					}
-					return XA_OK;
-				}
-			}
-			catch ( SQLException except )
-			{
-				try
-				{
-					// Fatal error in the connection, kill it.
-					txConn.conn.close();
-				}
-				catch ( SQLException e )
-				{ }
-				txConn.conn = null;
-				if ( _resManager.getLogWriter() != null )
-					_resManager.getLogWriter().println( "XAConnection: failed to commit a transaction: " + except );
-				// If we cannot commit the transaction, force a rollback.
-				throw new XAException( XAException.XA_RBROLLBACK );
-			}
-		}
-	}
-
-
-	public Xid[] recover( int flags )
-	throws XAException
-	{
-		synchronized ( _resManager )
-		{
-			return _resManager.getTxRecover();
-		}
-	}
-
-
-	public synchronized void commit( Xid xid, boolean onePhase )
-	throws XAException
-	{
-		TxConnection txConn;
-
-		// General checks.
-		if ( xid == null )
-			throw new XAException( XAException.XAER_INVAL );
-
-		synchronized ( _resManager )
-		{
-			// Technically, commit may be called for any connection,
-			// not just this one.
-			txConn = _resManager.getTxConnection( xid );
-			if ( txConn == null )
-				throw new XAException( XAException.XAER_NOTA );
-
-			// If the transaction failed, we have to force
-			// a rollback.
-			if ( txConn.conn == null )
-				throw new XAException( XAException.XA_RBROLLBACK );
-
-			// If connection has been prepared and is read-only,
-			// nothing to do at this stage.
-			if ( txConn.readOnly )
-				return;
-
-			// This must be a one-phase commite, or the connection
-			// should have been prepared before.
-			if ( onePhase || txConn.prepared )
-			{
-				try
-				{
-					// Prevent multiple commit attempts.
-					txConn.readOnly = true;
-					if ( txConn.conn instanceof TwoPhaseConnection )
-						( (TwoPhaseConnection) txConn.conn ).enableSQLTransactions( true );
-					txConn.conn.commit();
-				}
-				catch ( SQLException except )
-				{
-					try
-					{
-						// Unknown error in the connection, better kill it.
-						txConn.conn.close();
-					}
-					catch ( SQLException e )
-					{ }
-					txConn.conn = null;
-					if ( _resManager.getLogWriter() != null )
-						_resManager.getLogWriter().println( "XAConnection: failed to commit a transaction: " + except );
-					// If we cannot commit the transaction, a heuristic tollback.
-					throw new XAException( XAException.XA_HEURRB );
-				}
-			}
-			else
-			{
-				// 2pc we should have prepared before.
-				if ( ! txConn.prepared )
-					throw new XAException( XAException.XAER_PROTO );
-			}
-		}
-	}
-
-
-	public synchronized void rollback( Xid xid )
-	throws XAException
-	{
-		TxConnection txConn;
-
-
-		// General checks.
-		if ( xid == null )
-			throw new XAException( XAException.XAER_INVAL );
-
-		synchronized ( _resManager )
-		{
-			// Technically, rollback may be called for any connection,
-			// not just this one.
-			txConn = _resManager.getTxConnection( xid );
-			if ( txConn == null )
-				throw new XAException( XAException.XAER_NOTA );
-
-			// If connection has been prepared and is read-only,
-			// nothing to do at this stage. If connection has
-			// been terminated any other way, nothing to do
-			// either.
-			if ( txConn.readOnly || txConn.conn == null )
-				return;
-
-			try
-			{
-				txConn.prepared = false;
-				if ( txConn.conn instanceof TwoPhaseConnection )
-					( (TwoPhaseConnection) txConn.conn ).enableSQLTransactions( true );
-				txConn.conn.rollback();
-			}
-			catch ( SQLException except )
-			{
-				try
-				{
-					// Unknown error in the connection, better kill it.
-					txConn.conn.close();
-				}
-				catch ( SQLException e )
-				{ }
-				txConn.conn = null;
-				if ( _resManager.getLogWriter() != null )
-					_resManager.getLogWriter().println( "XAConnection: failed to rollback a transaction: " + except );
-				// If we cannot commit the transaction, a heuristic tollback.
-				throw new XAException( XAException.XA_RBROLLBACK );
-			}
-			finally
-			{
-				forget( xid );
-			}
-		}
-	}
-
-
-	public synchronized boolean isSameRM( XAResource xaRes )
-	throws XAException
-	{
-		// Two resource managers are equal if they produce equivalent
-		// connection (i.e. same database, same user). If the two are
-		// equivalent they would share a transaction by joining.
-		if ( xaRes == null || ! ( xaRes instanceof XAConnectionImpl ) )
-			return false;
-		if ( _resManager.equals( ( (XAConnectionImpl) xaRes )._resManager ) )
-			return true;
-		return false;
-	}
-
-
-	public synchronized boolean setTransactionTimeout( int seconds )
-	throws XAException
-	{
-		if ( seconds < 0 )
-			throw new XAException( XAException.XAER_INVAL );
-		// Zero resets to the default for all transactions.
-		if ( seconds == 0 )
-			seconds = _resManager.getTransactionTimeout();
-		// If a transaction has started, change it's timeout to the new value.
-		if ( _txConn != null )
-		{
-			_txConn.timeout = _txConn.started + ( seconds * 1000 );
-			return true;
-		}
-		return false;
-	}
-
-
-	public int getTransactionTimeout()
-	{
-		long timeout;
-
-		if ( _txConn == null )
-			return 0;
-		return (int) ( _txConn.timeout - _txConn.started ) / 1000;
-	}
-
-
-	/*
-	 * Returns true if this connection is inside a global transaction.
-	 * If the connection is inside a global transaction it will not
-	 * allow commit/rollback directly from the {@link
-	 * java.sql.Connection} interface.
-	 */
-	boolean insideGlobalTx()
-	{
-		return ( _txConn != null );
-	}
-
-	/*
-	 * Called to obtain the underlying connections. If this connection
-	 * is part of a transaction, the transction's underlying connection
-	 * is returned, or an exception is thrown if the connection was
-	 * terminated due to timeout. If this connection is not part of a
-	 * transaction, a non-transactional connection is returned.
-	 *
-	 * @param clientId The {@link ClientConnection} identifier
-	 */
-	Connection getUnderlying( int clientId )
-	throws SQLException
-	{
-		// If we were notified of the client closing, or have been
-		// requested to have a new client connection since then,
-		// the client id will not match to that of the caller.
-		// We use that to decide that the caller has been closed.
-		if ( clientId != _clientId )
-			throw new SQLException( "This application connection has been closed" );
-
-		if ( _txConn != null )
-		{
-			if ( _txConn.timedOut )
-				throw new SQLException( "The transaction has timed out and has been rolledback and closed" );
-			if ( _txConn.conn == null )
-				throw new SQLException( "The transaction has been terminated and this connection has been closed" );
-			return _txConn.conn;
-		}
-		if ( _underlying == null )
-		{
-			_underlying = _resManager.newConnection();
-			_underlying.setAutoCommit( true );
-		}
-		return _underlying;
-	}
-
-
-}
-
-
-
diff --git a/src/interfaces/jdbc/org/postgresql/xa/XADataSourceImpl.java b/src/interfaces/jdbc/org/postgresql/xa/XADataSourceImpl.java
deleted file mode 100644
index ae34143cb234ad3cc469f735c172bbb275d72685..0000000000000000000000000000000000000000
--- a/src/interfaces/jdbc/org/postgresql/xa/XADataSourceImpl.java
+++ /dev/null
@@ -1,489 +0,0 @@
-/*
-* Redistribution and use of this software and associated documentation
-* ("Software"), with or without modification, are permitted provided
-* that the following conditions are met:
-*
-* 1. Redistributions of source code must retain copyright
-*	 statements and notices.  Redistributions must also contain a
-*	 copy of this document.
-*
-* 2. Redistributions in binary form must reproduce the
-*	 above copyright notice, this list of conditions and the
-*	 following disclaimer in the documentation and/or other
-*	 materials provided with the distribution.
-*
-* 3. The name "Exolab" must not be used to endorse or promote
-*	 products derived from this Software without prior written
-*	 permission of Exoffice Technologies.  For written permission,
-*	 please contact info@exolab.org.
-*
-* 4. Products derived from this Software may not be called "Exolab"
-*	 nor may "Exolab" appear in their names without prior written
-*	 permission of Exoffice Technologies. Exolab is a registered
-*	 trademark of Exoffice Technologies.
-*
-* 5. Due credit should be given to the Exolab Project
-*	 (http://www.exolab.org/).
-*
-* THIS SOFTWARE IS PROVIDED BY EXOFFICE TECHNOLOGIES AND CONTRIBUTORS
-* ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT
-* NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
-* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.	IN NO EVENT SHALL
-* EXOFFICE TECHNOLOGIES OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
-* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
-* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
-* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
-* OF THE POSSIBILITY OF SUCH DAMAGE.
-*
-* Copyright 1999 (C) Exoffice Technologies Inc. All Rights Reserved.
-*
-* $Id: XADataSourceImpl.java,v 1.4 2001/11/19 23:16:46 momjian Exp $
-*/
-
-
-package org.postgresql.xa;
-
-
-import java.io.Serializable;
-import java.io.PrintWriter;
-import java.util.Hashtable;
-import java.util.Vector;
-import java.util.Stack;
-import java.util.Enumeration;
-import java.sql.Connection;
-import java.sql.SQLException;
-
-import javax.sql.DataSource;
-import javax.sql.PooledConnection;
-import javax.sql.ConnectionPoolDataSource;
-import javax.sql.XAConnection;
-import javax.sql.XADataSource;
-import javax.transaction.xa.Xid;
-
-
-
-/*
- * Implements a JDBC 2.0 {@link XADataSource} for any JDBC driver
- * with JNDI persistance support. The base implementation is actually
- * provided by a different {@link DataSource} class; although this is
- * the super class, it only provides the pooling and XA specific
- * implementation.
- *
- *
- * @author <a href="arkin@exoffice.com">Assaf Arkin</a>
- * @version 1.0
- */
-public abstract class XADataSourceImpl
-			implements DataSource, ConnectionPoolDataSource,
-			XADataSource, Serializable, Runnable
-{
-
-
-	/*
-	 * Maps underlying JDBC connections into global transaction Xids.
-	 */
-	private transient Hashtable _txConnections = new Hashtable();
-
-
-	/*
-	 * This is a pool of free underlying JDBC connections. If two
-	 * XA connections are used in the same transaction, the second
-	 * one will make its underlying JDBC connection available to
-	 * the pool. This is not a real connection pool, only a marginal
-	 * efficiency solution for dealing with shared transactions.
-	 */
-	private transient Stack _pool = new Stack();
-
-
-	/*
-	 * A background deamon thread terminating connections that have
-	 * timed out.
-	 */
-	private transient Thread _background;
-
-
-	/*
-	 * The default timeout for all new transactions.
-	 */
-	private int _txTimeout = DEFAULT_TX_TIMEOUT;
-
-
-	/*
-	 * The default timeout for all new transactions is 10 seconds.
-	 */
-	public final static int DEFAULT_TX_TIMEOUT = 10;
-
-
-
-
-	/*
-	 * Implementation details:
-	 *	 If two XAConnections are associated with the same transaction
-	 *	 (one with a start the other with a join) they must use the
-	 *	 same underlying JDBC connection. They lookup the underlying
-	 *	 JDBC connection based on the transaction's Xid in the
-	 *	 originating XADataSource.
-	 *
-	 *	 Currently the XADataSource must be the exact same object,
-	 *	 this should be changed so all XADataSources that are equal
-	 *	 share a table of all enlisted connections
-	 *
-	 *	 To test is two connections should fall under the same
-	 *	 transaction we match the resource managers by comparing the
-	 *	 database/user they fall under using a comparison of the
-	 *	 XADataSource properties.
-	 */
-
-
-	public XADataSourceImpl()
-	{
-		super();
-
-		// Create a background thread that will track transactions
-		// that timeout, abort them and release the underlying
-		// connections to the pool.
-		_background = new Thread( this, "XADataSource Timeout Daemon" );
-		_background.setPriority( Thread.MIN_PRIORITY );
-		_background.setDaemon( true );
-		_background.start();
-	}
-
-
-	public XAConnection getXAConnection()
-	throws SQLException
-	{
-		// Construct a new XAConnection with no underlying connection.
-		// When a JDBC method requires an underlying connection, one
-		// will be created. We don't create the underlying connection
-		// beforehand, as it might be coming from an existing
-		// transaction.
-		return new XAConnectionImpl( this, null );
-	}
-
-
-	public XAConnection getXAConnection( String user, String password )
-	throws SQLException
-	{
-		// Since we create the connection on-demand with newConnection
-		// or obtain it from a transaction, we cannot support XA
-		// connections with a caller specified user name.
-		throw new SQLException( "XAConnection does not support connections with caller specified user name" );
-	}
-
-
-	public PooledConnection getPooledConnection()
-	throws SQLException
-	{
-		// Construct a new pooled connection and an underlying JDBC
-		// connection to go along with it.
-		return new XAConnectionImpl( this, getConnection() );
-	}
-
-
-	public PooledConnection getPooledConnection( String user, String password )
-	throws SQLException
-	{
-		// Construct a new pooled connection and an underlying JDBC
-		// connection to go along with it.
-		return new XAConnectionImpl( this, getConnection( user, password ) );
-	}
-
-
-	/*
-	 * Returns the default timeout for all transactions.
-	 */
-	public int getTransactionTimeout()
-	{
-		return _txTimeout;
-	}
-
-
-	/*
-	 * This method is defined in the interface and implemented in the
-	 * derived class, we re-define it just to make sure it does not
-	 * throw an {@link SQLException} and that we do not need to
-	 * catch one.
-	 */
-	public abstract java.io.PrintWriter getLogWriter();
-
-
-	/*
-	 * Sets the default timeout for all transactions. The timeout is
-	 * specified in seconds. Use zero for the default timeout. Calling
-	 * this method does not affect transactions in progress.
-	 *
-	 * @param seconds The timeout in seconds
-	 */
-	public void setTransactionTimeout( int seconds )
-	{
-		if ( seconds <= 0 )
-			_txTimeout = DEFAULT_TX_TIMEOUT;
-		else
-			_txTimeout = seconds;
-		_background.interrupt();
-	}
-
-
-	/*
-	 * Returns an underlying connection for the global transaction,
-	 * if one has been associated before.
-	 *
-	 * @param xid The transaction Xid
-	 * @return A connection associated with that transaction, or null
-	 */
-	TxConnection getTxConnection( Xid xid )
-	{
-		return (TxConnection) _txConnections.get( xid );
-	}
-
-
-	/*
-	 * Associates the global transaction with an underlying connection,
-	 * or dissociate it when null is passed.
-	 *
-	 * @param xid The transaction Xid
-	 * @param conn The connection to associate, null to dissociate
-	 */
-	TxConnection setTxConnection( Xid xid, TxConnection txConn )
-	{
-		if ( txConn == null )
-			return (TxConnection) _txConnections.remove( xid );
-		else
-			return (TxConnection) _txConnections.put( xid, txConn );
-	}
-
-
-	/*
-	 * Release an unused connection back to the pool. If an XA
-	 * connection has been asked to join an existing transaction,
-	 * it will no longer use it's own connection and make it available
-	 * to newly created connections.
-	 *
-	 * @param conn An open connection that is no longer in use
-	 */
-	void releaseConnection( Connection conn )
-	{
-		_pool.push( conn );
-	}
-
-
-	/*
-	 * Creates a new underlying connection. Used by XA connection
-	 * that lost it's underlying connection when joining a
-	 * transaction and is now asked to produce a new connection.
-	 *
-	 * @return An open connection ready for use
-	 * @throws SQLException An error occured trying to open
-	 *	 a connection
-	 */
-	Connection newConnection()
-	throws SQLException
-	{
-		Connection conn;
-
-		// Check in the pool first.
-		if ( ! _pool.empty() )
-		{
-			conn = (Connection) _pool.pop();
-			return conn;
-		}
-		return getConnection();
-	}
-
-
-	/*
-	 * XXX Not fully implemented yet and no code to really
-	 *	   test it.
-	 */
-	Xid[] getTxRecover()
-	{
-		Vector list;
-		Enumeration enum;
-		TxConnection txConn;
-
-		list = new Vector();
-		enum = _txConnections.elements();
-		while ( enum.hasMoreElements() )
-		{
-			txConn = (TxConnection) enum.nextElement();
-			if ( txConn.conn != null && txConn.prepared )
-				list.add( txConn.xid );
-		}
-		return (Xid[]) list.toArray();
-	}
-
-
-	/*
-	 * Returns the transaction isolation level to use with all newly
-	 * created transactions, or {@link Connection#TRANSACTION_NONE}
-	 * if using the driver's default isolation level.
-	 */
-	public int isolationLevel()
-	{
-		return Connection.TRANSACTION_NONE;
-	}
-
-
-	public void run()
-	{
-		Enumeration enum;
-		int reduce;
-		long timeout;
-		TxConnection txConn;
-
-		while ( true )
-		{
-			// Go to sleep for the duration of a transaction
-			// timeout. This mean transactions will timeout on average
-			// at _txTimeout * 1.5.
-			try
-			{
-				Thread.sleep( _txTimeout * 1000 );
-			}
-			catch ( InterruptedException except )
-			{}
-
-			try
-			{
-				// Check to see if there are any pooled connections
-				// we can release. We release 10% of the pooled
-				// connections each time, so in a heavy loaded
-				// environment we don't get to release that many, but
-				// as load goes down we do. These are not actually
-				// pooled connections, but connections that happen to
-				// get in and out of a transaction, not that many.
-				reduce = _pool.size() - ( _pool.size() / 10 ) - 1;
-				if ( reduce >= 0 && _pool.size() > reduce )
-				{
-					if ( getLogWriter() != null )
-						getLogWriter().println( "DataSource " + toString() +
-												": Reducing internal connection pool size from " +
-												_pool.size() + " to " + reduce );
-					while ( _pool.size() > reduce )
-					{
-						try
-						{
-							( (Connection) _pool.pop() ).close();
-						}
-						catch ( SQLException except )
-						{ }
-					}
-				}
-			}
-			catch ( Exception except )
-			{ }
-
-			// Look for all connections inside a transaction that
-			// should have timed out by now.
-
-
-			timeout = System.currentTimeMillis();
-			enum = _txConnections.elements();
-			while ( enum.hasMoreElements() )
-			{
-				txConn = (TxConnection) enum.nextElement();
-				// If the transaction timed out, we roll it back and
-				// invalidate it, but do not remove it from the transaction
-				// list yet. We wait for the next iteration, minimizing the
-				// chance of a NOTA exception.
-				if ( txConn.conn == null )
-				{
-					_txConnections.remove( txConn.xid );
-					// Chose not to use an iterator so we must
-					// re-enumerate the list after removing
-					// an element from it.
-					enum = _txConnections.elements();
-				}
-				else if ( txConn.timeout < timeout )
-				{
-
-					try
-					{
-						Connection underlying;
-
-						synchronized ( txConn )
-						{
-							if ( txConn.conn == null )
-								continue;
-							if ( getLogWriter() != null )
-								getLogWriter().println( "DataSource " + toString() +
-														": Transaction timed out and being aborted: " +
-														txConn.xid );
-							// Remove the connection from the transaction
-							// association. XAConnection will now have
-							// no underlying connection and attempt to
-							// create a new one.
-							underlying = txConn.conn;
-							txConn.conn = null;
-							txConn.timedOut = true;
-
-							// Rollback the underlying connection to
-							// abort the transaction and release the
-							// underlying connection to the pool.
-							try
-							{
-								underlying.rollback();
-								releaseConnection( underlying );
-							}
-							catch ( SQLException except )
-							{
-								if ( getLogWriter() != null )
-									getLogWriter().println( "DataSource " + toString() +
-															": Error aborting timed out transaction: " + except );
-								try
-								{
-									underlying.close();
-								}
-								catch ( SQLException e2 )
-								{ }
-							}
-						}
-					}
-					catch ( Exception except )
-					{ }
-
-				}
-			}
-		}
-	}
-
-
-
-	public void debug( PrintWriter writer )
-	{
-		Enumeration enum;
-		TxConnection txConn;
-		StringBuffer buffer;
-
-		writer.println( "Debug info for XADataSource:" );
-		enum = _txConnections.elements();
-		if ( ! enum.hasMoreElements() )
-			writer.println( "Empty" );
-		while ( enum.hasMoreElements() )
-		{
-			buffer = new StringBuffer();
-			txConn = (TxConnection) enum.nextElement();
-			buffer.append( "TxConnection " );
-			if ( txConn.xid != null )
-				buffer.append( txConn.xid );
-			if ( txConn.conn != null )
-				buffer.append( ' ' ).append( txConn.conn );
-			buffer.append( " count: " ).append( txConn.count );
-			if ( txConn.prepared )
-				buffer.append( " prepared" );
-			if ( txConn.timedOut )
-				buffer.append( " timed-out" );
-			if ( txConn.readOnly )
-				buffer.append( " read-only" );
-			writer.println( buffer.toString() );
-		}
-		enum = _pool.elements();
-		while ( enum.hasMoreElements() )
-			writer.println( "Pooled underlying: " + enum.nextElement().toString() );
-	}
-
-
-}