/*
 *
 * Derby - Class org.apache.derbyTesting.junit.TestConfiguration
 *
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, 
 * software distributed under the License is distributed on an 
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 
 * either express or implied. See the License for the specific 
 * language governing permissions and limitations under the License.
 */
package org.apache.derbyTesting.junit;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintWriter;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.security.PrivilegedActionException;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Properties;
import junit.extensions.TestSetup;
import junit.framework.Assert;
import junit.framework.Test;
import junit.framework.TestCase;

import org.apache.derbyTesting.functionTests.util.PrivilegedFileOpsForTests;

/**
 * Class which holds information about the configuration of a Test.
 * 
 * A configuration manages the pool of databases in use
 * in <code>usedDbNames</code> property. One of those databases
 * is supposed to be the default database. A new default database
 * is added to the pool by <code>singleUseDatabaseDecorator</code> function.
 * <br>
 * Additional databases may be added by <code>additionalDatabaseDecorator</code>
 * function. Each of the additional databases has its logical and physical name.
 * Physical database name is automatically generated as 'singleUse/oneuseXX'
 * where 'XX' is unique number. The logical database name is used to establish
 * a connection to the database using
 * a <code>TestConfiguration::openConnection(String logicalDatabaseName)</code>
 * function.
 * <br>
 * The database files are supposed to be local and they will be
 * removed by <code>DropDatabaseSetup</code>.
 *
 */
public final class TestConfiguration {
    /**
     * Default values for configurations
     */
    private final static String DEFAULT_DBNAME = "wombat";
    private final static String DEFAULT_DBNAME_SQL = "dbsqlauth";
    
    private final static String DEFAULT_USER_NAME = "APP";
    private final static String DEFAULT_USER_PASSWORD = "APP";
    private final static int    DEFAULT_PORT = 1527;
    private final static String DEFAULT_FRAMEWORK = "embedded";
    private final static String DEFAULT_HOSTNAME = "localhost";

    private static final int LOCKFILETIMEOUT = 300000; // 5 mins

    /**
     * Maximum number of ports used by Suites.All 
     * If this changes, this constant and the Wiki
     * page at  http://wiki.apache.org/db-derby/DerbyJUnitTesting
     * need to be updated. 
     */
    private final static int MAX_PORTS_USED = 22;
    
    /** This is the base port. This does NOT change EVER during the run of a suite.
     *	It is set using the property derby.tests.basePort and it is set to default when
     *	a property isn't used. */
    private final static int basePort;
    private static int lastAssignedPort;
    private static final int bogusPort;
    static {
    	String port = BaseTestCase.getSystemProperty("derby.tests.basePort");
        if (port == null) {
        	lastAssignedPort = DEFAULT_PORT;
        } else {
        	lastAssignedPort = Integer.parseInt(port);
        }
        basePort = lastAssignedPort;
        bogusPort = ++lastAssignedPort;
    }
    private static int assignedPortCount = 2;

    private FileOutputStream serverOutput;
		
    /** Sleep for 1000 ms before pinging the network server (again) */
    private static final int SLEEP_TIME = 1000;
            
    /**
     * Keys to use to look up values in properties files.
     */
    private final static String KEY_DBNAME = "databaseName";
    private final static String KEY_FRAMEWORK = "framework";
    private final static String KEY_USER_PASSWORD = "password";
    private final static String KEY_USER_NAME = "user";
    private final static String KEY_HOSTNAME = "hostName";
    private final static String KEY_PORT = "port";
    private final static String KEY_VERBOSE = "derby.tests.debug";    
    private final static String KEY_LOGIN_TIMEOUT = "derby.tests.login.timeout";    
    private final static String KEY_TRACE = "derby.tests.trace";
    public  final static String KEY_OMIT_LUCENE = "derby.tests.omitLucene";
    public  final static String KEY_OMIT_JSON = "derby.tests.omitJson";

    /**
     * derby.tests.stopAfterFirstFail - debugging property to exit after 
     * first failure. Can be useful for debugging cascading failures or errors
     * that lead to hang scenario.
     */
    private final static String KEY_STOP_AFTER_FIRST_FAIL = "derby.tests.stopAfterFirstFail";
    private final static String KEY_SSL = "ssl";
    private final static String KEY_JMX_PORT = "jmxPort";
    
    /**
     * Simple count to provide a unique number for database
     * names.
     */
    private static int uniqueDB;

    /** Repository of old/previous Derby releases available on the local system. */
    private static ReleaseRepository releaseRepository;

    /**
     * Default configuration for standalone JUnit tests,
     * an embedded configuration.
     */
    private static final TestConfiguration JUNIT_CONFIG
        = new TestConfiguration();
    
    /**
     * The default configuration.
     */
    private static final TestConfiguration DEFAULT_CONFIG;
        
    static {
        DEFAULT_CONFIG = JUNIT_CONFIG;
        
        final   File dsh = new File("system");

        String absolutePath = PrivilegedFileOpsForTests.getAbsolutePath(dsh);

        BaseTestCase.setSystemProperty(
                "derby.system.home", absolutePath);
     }
    
    /**
     * Current configuration is stored in a ThreadLocal to
     * allow the potential for multiple tests to be running
     * concurrently with different configurations.
     */
    private static final ThreadLocal<TestConfiguration>
            CURRENT_CONFIG = new ThreadLocal<TestConfiguration>() {
        protected TestConfiguration initialValue() {
            return DEFAULT_CONFIG;
        }
    };
   
    /**
     * Get this Thread's current configuraiton for running
     * the tests.
     * Note this call must only be used while a test is
     * running, they make no sense when setting up a suite.
     * A suite itself sets up which test configurations
     * the fixtures will run in.

     * @return TestConfiguration to use.
     */
    public static TestConfiguration getCurrent() {
        return (TestConfiguration) CURRENT_CONFIG.get();
    }

    /**
     * Returns the release repository containing old Derby releases available
     * on the local system.
     * <p>
     * <strong>NOTE</strong>: It is your responsibility to keep the repository
     * up to date. This usually involves syncing the local Subversion repository
     * of previous Derby releases with the master repository at Apache.
     *
     * @see ReleaseRepository
     */
    public static synchronized ReleaseRepository getReleaseRepository() {
        if (releaseRepository == null) {
            try {
                releaseRepository = ReleaseRepository.getInstance();
            } catch (IOException ioe) {
                BaseTestCase.printStackTrace(ioe);
                Assert.fail("failed to initialize the release repository: " +
                        ioe.getMessage());
            }
        }
        return releaseRepository;
    }

    /**
     * WORK IN PROGRESS
     * Set this Thread's current configuration for running tests.
     * @param config Configuration to set it to.
     */
    static void setCurrent(TestConfiguration config)
    {
        CURRENT_CONFIG.set(config);
    }
    
    
    /**
     * Return a Test suite that contains all the test fixtures
     * for the passed in class running in embedded and the
     * default client server configuration.
     * <BR>
     * Each set of embedded and set of client server tests
     * is decorated with a CleanDatabaseTestSetup.
     * <BR>
     * The client server configuration is setup using clientServerSuite
     */
    public static Test defaultSuite(Class testClass)
    {
        return defaultSuite(testClass, true);
    }

    /**
     * Does the work of "defaultSuite" as defined above.  Takes
     * a boolean argument to determine whether or not to "clean"
     * the test database before each suite.  If the resultant
     * suite is going to be wrapped inside a TestSetup that creates
     * database objects to be used throughout the tests, then the
     * cleanDB parameter should be "false" to prevent cleanup of the
     * database objects that TestSetup created.  For example, see
     * XMLBindingTest.suite().
     */
    public static Test defaultSuite(Class testClass, boolean cleanDB)
    {
         final BaseTestSuite suite = new BaseTestSuite(suiteName(testClass));
         
        if (cleanDB)
        {
            suite.addTest(new CleanDatabaseTestSetup(embeddedSuite(testClass)));
            suite.addTest(new CleanDatabaseTestSetup(clientServerSuite(testClass)));
        }
        else
        {
            suite.addTest(embeddedSuite(testClass));
            suite.addTest(clientServerSuite(testClass));
        }

        return (suite);
    }
    /**
     * Equivalent to "defaultSuite" as defined above, but assumes a server
     * has already been started. 
     * <BR>
     * Does NOT decorate for running in embedded mode, only for running on
     * the already started server.
     * <BR>
     * Return a Test suite that contains all the test fixtures
     * for the passed in class running in client server configuration
     * on an already started server.
     * <BR>
     * The set of client server tests
     * is decorated with a CleanDatabaseTestSetup.
     * <BR>
     * The client server configuration is setup using clientExistingServerSuite
     */
    public static Test defaultExistingServerSuite(Class testClass)
    {
        return defaultExistingServerSuite(testClass, true);
    }
    
    /**
     * Does the work of "defaultExistingServerSuite" as defined above.  Takes
     * a boolean argument to determine whether or not to "clean"
     * the test database before each suite.  If the resultant
     * suite is going to be wrapped inside a TestSetup that creates
     * database objects to be used throughout the tests, then the
     * cleanDB parameter should be "false" to prevent cleanup of the
     * database objects that TestSetup created.
     * <BR>
     * Does NOT decorate for running in embedded mode, only for running on
     * an already started server.
     */
    public static Test defaultExistingServerSuite(Class testClass, boolean cleanDB)
    {
         final BaseTestSuite suite = new BaseTestSuite(suiteName(testClass));
         
        if (cleanDB)
        {
            suite.addTest(new CleanDatabaseTestSetup(clientExistingServerSuite(testClass)));
        }
        else
        {
            suite.addTest(clientExistingServerSuite(testClass));
        }

        return (suite);
    }

    /**
     * Return a Test suite that contains all the test fixtures
     * for the passed in class running in client server configuration
     * on an already started server on a given host and port number.
     * <BR>
     * Takes a boolean argument to determine whether or not to "clean"
     * the test database before each suite.  If the resultant
     * suite is going to be wrapped inside a TestSetup that creates
     * database objects to be used throughout the tests, then the
     * cleanDB parameter should be "false" to prevent cleanup of the
     * database objects that TestSetup created.
     * <BR>
     * Takes a String argument to specify which host the server runs on, and
     * takes an int argument to specify the port number to use.
     * <BR>
     * Does NOT decorate for running in embedded mode, only for running on
     * an already started server.
     * <BR>
     * The set of client server tests
     * is decorated with a CleanDatabaseTestSetup.
     * <BR>
     * The client server configuration is setup using clientExistingServerSuite
     */
    public static Test existingServerSuite(Class testClass, 
            boolean cleanDB,
            String hostName,
            int portNumber)
    {
         final BaseTestSuite suite = new BaseTestSuite(suiteName(testClass));
         
        if (cleanDB)
        {
            suite.addTest(new CleanDatabaseTestSetup(
                    clientExistingServerSuite(testClass, hostName, portNumber)));
        }
        else
        {
            suite.addTest(clientExistingServerSuite(testClass, hostName, portNumber));
        }

        return (suite);
    }
    public static Test existingServerSuite(Class testClass, 
            boolean cleanDB,
            String hostName,
            int portNumber,
            String dbPath)
    {
         final BaseTestSuite suite = new BaseTestSuite(suiteName(testClass));
         
        if (cleanDB)
        {
            suite.addTest(new CleanDatabaseTestSetup(
                    clientExistingServerSuite(testClass, hostName, portNumber, dbPath)));
        }
        else
        {
            suite.addTest(clientExistingServerSuite(testClass, hostName, portNumber, dbPath));
        }

        return (suite);
    }

    /**
     * Return a Test suite that contains all the test fixtures
     * for the passed in class running in embedded and client-
     * server *JDBC3* configurations.
     * <BR>
     * Each set of embedded and set of client server tests is
     * decorated with a CleanDatabaseTestSetup.
     * <BR>
     */
    public static Test forceJDBC3Suite(Class testClass)
    {
        final BaseTestSuite suite = new BaseTestSuite(suiteName(testClass));

        suite.addTest(
            new CleanDatabaseTestSetup(
                forceJDBC3Embedded(embeddedSuite(testClass))));

        suite.addTest(
            new CleanDatabaseTestSetup(
                forceJDBC3NetClient(clientServerSuite(testClass))));

        return (suite);
    }

    /**
     * Generate a suite name from a class name, taking
     * only the last element of the fully qualified class name.
     */
    static String suiteName(Class testClass)
    {
        int lastDot = testClass.getName().lastIndexOf('.');
        String suiteName = testClass.getName();
        if (lastDot != -1)
            suiteName = suiteName.substring(lastDot + 1, suiteName.length());
        
        return suiteName;
    }

    /**
     * Create a suite for the passed test class that includes
     * all the default fixtures from the class.
      */
    public static Test embeddedSuite(Class testClass)
    {
        return new BaseTestSuite(testClass,
                suiteName(testClass)+":embedded");
    }
    
    /**
     * Create a suite for the passed test class that includes
     * all the default fixtures from the class, wrapped in
     * a derbyClientServerDecorator.
     * 
     */
    public static Test clientServerSuite(Class testClass)
    {
        return clientServerDecorator(bareClientServerSuite(testClass));
    }
    /**
     * Create a suite for the passed test class that includes
     * all the default fixtures from the class, wrapped in
     * a derbyClientServerDecorator with alternative port.
     * 
     */

    public static Test clientServerSuiteWithAlternativePort(Class testClass) {
        return clientServerDecoratorWithAlternativePort(
                bareClientServerSuite(testClass));
    }

    /**
     * Equivalent to 'clientServerSuite' above, but assumes server is
     * already running.
     *
     */
    public static Test clientExistingServerSuite(Class testClass)
    {
        // Will not start server and does not stop it when done.
        return defaultExistingServerDecorator(bareClientServerSuite(testClass));
    }
    
    /**
     * Create a suite for the passed test class that includes
     * all the default fixtures from the class, wrapped in
     * a existingServerDecorator.
     * <BR>
     * Equivalent to 'clientServerSuite' above, but assumes server is
     * already running. Will also NOT shut down the server.
     *
     */
    public static Test clientExistingServerSuite(Class testClass, String hostName, int portNumber)
    {
               // Will not start server and does not stop it when done!.
        return existingServerDecorator(bareClientServerSuite(testClass),
                hostName, portNumber);
    }
    public static Test clientExistingServerSuite(Class testClass, 
            String hostName, int portNumber, String dbPath)
    {
               // Will not start server and does not stop it when done!.
        return existingServerDecorator(bareClientServerSuite(testClass),
                hostName, portNumber, dbPath);
    }

    /**
     * Return a decorator for the passed in tests that sets the
     * configuration for the client to be Derby's JDBC client
     * and to start the network server at setUp.
     * <BR>
     * The database configuration (name etc.) is based upon
     * the previous configuration.
     * <BR>
     * The previous TestConfiguration is restored at tearDown and
     * the network server is shutdown.
     * @param suite the suite to decorate
     */
    public static Test clientServerDecorator(Test suite)
    {
        Test test = new NetworkServerTestSetup(suite, false);
            
        return defaultServerDecorator(test);
    }

    /**
     * Return a decorator for the passed in tests that sets the
     * configuration for the client to be Derby's JDBC client
     * and to start the network server at setUp.
     * <BR>
     * The database configuration (name etc.) is based upon
     * the previous configuration.
     * <BR>
     * The previous TestConfiguration is restored at tearDown and
     * the network server is shutdown.
     * @param suite the suite to decorate
     */
    public static Test clientServerDecoratorWithPort(Test suite, int port)
    {
        Test test = new NetworkServerTestSetup(suite, false);

        return existingServerDecorator(test,"localhost",port);
    }

    /**
     * Wrapper to use the alternative port number.
     */
    public static Test clientServerDecoratorWithAlternativePort(Test suite) {
        Test test = new NetworkServerTestSetup(suite, false);

        return defaultServerDecoratorWithAlternativePort(test);
    }
    /**
     * Decorate a test to use suite's default host and port, 
     * but assuming the server is already running.
     */
    public static Test defaultExistingServerDecorator(Test test)
    {
        // As defaultServerDecorator but assuming 
        // server is already started.
        // Need to have client 
        // and not running in J2ME (JSR169).
        if (!(Derby.hasClient())
                || JDBC.vmSupportsJSR169())
        {
            return new BaseTestSuite(
                "empty: no network server support in JSR169 " +
                "(or derbyclient.jar missing).");
        }
        
        Test r =
                new ServerSetup(test, DEFAULT_HOSTNAME, TestConfiguration.getCurrent().getPort());
        ((ServerSetup)r).setJDBCClient(JDBCClient.DERBYNETCLIENT); 
        
        return r;
    }
   
    /**
     * Decorate a test to use suite's default host and port.
     */
    public static Test defaultServerDecorator(Test test)
    {
        // Need to have network server and client and not
        // running in J2ME (JSR169).
        if (!supportsClientServer()) {
            return new BaseTestSuite("empty: no network server support");
        }

        //
        // This looks bogus to me. Shouldn't this get the hostname and port
        // which are specific to this test run (perhaps overridden on the
        // command line)?
        //
        return new ServerSetup(test, DEFAULT_HOSTNAME, TestConfiguration.getCurrent().getPort());
    }
   /**
    * A variant of defaultServerDecorator allowing 
    * non-default hostname and portnumber.
    */
    public static Test existingServerDecorator(Test test, 
            String hostName, int PortNumber)
    {
    	// Need to have network server and client and not
        // running in J2ME (JSR169).
        if (!supportsClientServer()) {
            return new BaseTestSuite("empty: no network server support");
        }

        Test r =
                new ServerSetup(test, hostName, PortNumber);
        ((ServerSetup)r).setJDBCClient(JDBCClient.DERBYNETCLIENT);
        return r;
    }
    /**
    * A variant of defaultServerDecorator allowing 
    * non-default hostname, portnumber and database name.
    */
    public static Test existingServerDecorator(Test test, 
            String hostName, int PortNumber, String dbPath)
    {
    	// Need to have network server and client and not
        // running in J2ME (JSR169).
        if (!supportsClientServer()) {
            return new BaseTestSuite("empty: no network server support");
        }

        Test r =
                new ServerSetup(test, hostName, PortNumber);
        ((ServerSetup)r).setJDBCClient(JDBCClient.DERBYNETCLIENT);
        ((ServerSetup)r).setDbPath(dbPath);
        return r;
    }
   
    /**
     * Decorate a test to use suite's default host and Alternative port.
     */
    public static Test defaultServerDecoratorWithAlternativePort(Test test) {
        // Need to have network server and client and not
        // running in J2ME (JSR169).
        if (!supportsClientServer()) {
            return new BaseTestSuite("empty: no network server support");
        }

        int port = getCurrent().getNextAvailablePort();

        //
        // This looks bogus to me. Shouldn't this get the hostname and port
        // which are specific to this test run (perhaps overridden on the
        // command line)?
        //
        return new ServerSetup(test, DEFAULT_HOSTNAME, port);
    }

    /**
     * Check if client and server testing is supported in the test environment.
     */
    private static boolean supportsClientServer() {
        return JDBC.vmSupportsJDBC3() && Derby.hasClient() && Derby.hasServer();
    }

    /**
     * Create a suite of test cases to run in a client/server environment. The
     * returned test suite is not decorated with a ServerSetup.
     *
     * @param testClass the class from which to extract the test cases
     * @return a test suite with all the test cases in {@code testClass}, or
     * an empty test suite if client/server is not supported in the test
     * environment
     */
    private static Test bareClientServerSuite(Class testClass) {
        BaseTestSuite suite =
            new BaseTestSuite(suiteName(testClass) + ":client");

        if (supportsClientServer()) {
            suite.addTestSuite(testClass);
        }
        return suite;
    }

    /**
     * Generate the unique database name for single use.
     */
    public static synchronized String generateUniqueDatabaseName()
    {
        // Forward slash is ok, Derby treats database names
        // as URLs and translates forward slash to the local
        // separator.
        String dbName = "singleUse/oneuse";
        dbName = dbName.concat(Integer.toHexString(uniqueDB++));
        return dbName;
    }

 
    /**
     * Decorate a test to use a new database that is created upon the
     * first connection request to the database and shutdown and deleted at
     * tearDown. The configuration differs only from the current configuration
     * by the list of used databases. The new database name
     * is generated automatically as 'singleUse/oneuseXX' where 'XX' is
     * the unique number. The generated database name is added at the end
     * of <code>usedDbNames</code> and assigned as a default database name.
     * This decorator expects the database file to be local so it
     * can be removed.
     * @param test Test to be decorated
     * @return decorated test.
     */
    public static TestSetup singleUseDatabaseDecorator(Test test)
    {
        String dbName = generateUniqueDatabaseName();

        return new DatabaseChangeSetup(new DropDatabaseSetup(test, dbName), dbName, dbName, true);
    }


    /**
     * Decorate a test to use a new database that is created upon the first
     * connection request to the database and shutdown and deleted at
     * tearDown. The configuration differs only from the current configuration
     * by the list of used databases. The generated database name is added at
     * the end of <code>usedDbNames</code> and assigned as a default database
     * name.  This decorator expects the database file to be local so it can be
     * removed.
     * @param test Test to be decorated
     * @param dbName We sometimes need to know outside to be able to pass it on
     *               to other VMs/processes.
     * @return decorated test.
     */
    public static TestSetup singleUseDatabaseDecorator(Test test, String dbName)
    {
        return new DatabaseChangeSetup(
            new DropDatabaseSetup(test, dbName), dbName, dbName, true);
    }

    /**
     * Decorate a test to use a new database that is created upon the
     * first connection request to the database and deleted at
     * tearDown. In contrast to plain singleUseDatabaseDecorator, the
     * database is expected to be shutdown by the test.  The
     * configuration differs only from the current configuration by
     * the list of used databases. The new database name is generated
     * automatically as 'singleUse/oneuseXX' where 'XX' is the unique
     * number. The generated database name is added at the end of
     * <code>usedDbNames</code> and assigned as a default database
     * name.  This decorator expects the database file to be local so
     * it can be removed.
     * @param test Test to be decorated
     * @return decorated test.
     */
    public static TestSetup singleUseDatabaseDecoratorNoShutdown(Test test)
    {
        String dbName = generateUniqueDatabaseName();

        return new DatabaseChangeSetup(
            new DropDatabaseSetup(test, dbName, false),
            dbName, dbName, true);
    }

    /**
     * Decorate a test to use a new database that is created upon the
     * first connection request to the database and shutdown and deleted at
     * tearDown. The configuration differs only from the current configuration
     * by the list of used databases. 
     * The passed database name is mapped to the generated database
     * name 'singleUse/oneuseXX' where 'XX' is the unique number.
     * (by generateUniqueDatabaseName). The generated database name is added
     * at the end of <code>usedDbNames</code>.
     * This decorator expects the database file to be local so it
     * can be removed.
     * @param test Test to be decorated
     * @param logicalDbName The logical database name. This name is used to identify
     * the database in openConnection(String logicalDatabaseName) method calls.
     * @return decorated test.
     */
    public static DatabaseChangeSetup additionalDatabaseDecorator(Test test, String logicalDbName)
    {
        return new DatabaseChangeSetup(new DropDatabaseSetup(test, logicalDbName),
                                       logicalDbName,
                                       generateUniqueDatabaseName(),
                                       false);
    }
    
    /**
     * Similar to additionalDatabaseDecorator except the database will
     * not be shutdown, only deleted. It is the responsibility of the
     * test to shut it down.
     *
     * @param test Test to be decorated
     * @param logicalDbName The logical database name. This name is
     *                      used to identify the database in
     *                      openConnection(String logicalDatabaseName)
     *                      method calls.
     * @return decorated test.
     */
    public static DatabaseChangeSetup additionalDatabaseDecoratorNoShutdown(
        Test test,
        String logicalDbName)
    {
        return additionalDatabaseDecoratorNoShutdown( test, logicalDbName, false );
    }

    /**
     * Similar to additionalDatabaseDecorator except the database will
     * not be shutdown, only deleted. It is the responsibility of the
     * test to shut it down.
     *
     * @param test Test to be decorated
     * @param logicalDbName The logical database name. This name is
     *                      used to identify the database in
     *                      openConnection(String logicalDatabaseName)
     *                      method calls.
     * @param defaultDB True if the database should store its own name in its TestConfiguration.
     * @return decorated test.
     */
    public static DatabaseChangeSetup additionalDatabaseDecoratorNoShutdown
        (
         Test test,
         String logicalDbName,
         boolean defaultDB
        )
    {
        return new DatabaseChangeSetup(
            new DropDatabaseSetup(test, logicalDbName, false),
            logicalDbName,
            generateUniqueDatabaseName(),
            defaultDB);
    }

    /**
     * Similar to additionalDatabaseDecorator except the database will
     * not be shutdown, only deleted. It is the responsibility of the
     * test to shut it down.
     *
     * @param test Test to be decorated
     * @param logicalDbName The logical database name. This name is
     *                      used to identify the database in
     *                      openConnection(String logicalDatabaseName)
     *                      method calls.
     * @param physicalDbName - Real database name on disk.
     * @return decorated test.
     */
    public static DatabaseChangeSetup additionalDatabaseDecoratorNoShutdown(
        Test test,
        String logicalDbName, String physicalDbName )
    {
        return new DatabaseChangeSetup(
            new DropDatabaseSetup(test, logicalDbName, false),
            logicalDbName,
            physicalDbName,
            false);
    }

    /**
     * Decorate a test changing the default user name and password.
     * Typically used along with DatabasePropertyTestSetup.builtinAuthentication.
     * The tearDown method resets the default user and password value to
     * their previous settings.
     * 
     * @param test Test to decorate
     * @param user New default user
     * @param password New password
     * @return decorated test
     * 
     * @see DatabasePropertyTestSetup#builtinAuthentication(Test, String[], String)
     */
    public static Test changeUserDecorator(Test test, String user, String password)
    {
        return new ChangeUserSetup(test, user, password);
    }   
    
    /**
     * Decorate a test to use the default database that has
     * was created in SQL authorization mode.
     * The tearDown reverts the configuration to the previous
     * configuration.
     * 
     * The database owner of this default SQL authorization mode
     * database is TEST_DBO. This decorator sets the default user
     * to be TEST_DBO.
     * 
     * Tests can use this in conjunction with
     * DatabasePropertyTestSetup.builtinAuthentication
     * to set up BUILTIN authentication and changeUserDecorator
     * to switch users. The database owner TEST_DBO must be included
     * in the list of users provided to builtinAuthentication.
     * This decorator must be the outer one in this mode.
     * <code>
     * test = DatabasePropertyTestSetup.builtinAuthentication(test,
                new String[] {TEST_DBO,"U1","U2",},
                "nh32ew");
       test = TestConfiguration.sqlAuthorizationDecorator(test);
     * </code>
     * A utility version of sqlAuthorizationDecorator is provided
     * that combines the two setups.
     * 
     * @param test Test to be decorated
     * @return decorated test.
     * 
     * @see DatabasePropertyTestSetup#builtinAuthentication(Test, String[], String)
     */
    public static Test sqlAuthorizationDecorator(Test test)
    {       
        // Set the SQL authorization mode as a database property
        // with a modified DatabasePropertyTestSetup that does not
        // reset it.
        final Properties sqlAuth = new Properties();
        sqlAuth.setProperty("derby.database.sqlAuthorization", "true");
        Test setSQLAuthMode = DatabasePropertyTestSetup.getNoTeardownInstance(
                test, sqlAuth, true);
        
        return changeUserDecorator(
            new DatabaseChangeSetup(setSQLAuthMode, DEFAULT_DBNAME_SQL, DEFAULT_DBNAME_SQL, true),
            DerbyConstants.TEST_DBO, "dummy"); // DRDA doesn't like empty pw
    }


    /**
     * Same as sqlAuthorizationDecorator, except that the database is dropped
     * at teardown and the test is responsible for shutting down the database.
     *
     * @param test Test to be decorated
     * @return decorated test.
     *
     * @see TestConfiguration#sqlAuthorizationDecorator(Test test)
     */
    public static Test sqlAuthorizationDecoratorSingleUse(Test test)
    {
        return sqlAuthorizationDecoratorSingleUse(
                test, DEFAULT_DBNAME_SQL, false);
    }
    
    /**
     * Same as sqlAuthorizationDecoratorSingleUse, except that you can name
     * the database yourself, and you can choose whether or not the decorator
     * should shut down the database before it attempts to drop it.
     *
     * @param test Test to be decorated
     * @param dbName The name of the database to use in the test
     * @param shutdownDatabase Whether or not to shut down the database
     *   before it is dropped
     * @return decorated test.
     *
     * @see TestConfiguration#sqlAuthorizationDecorator(Test test)
     */
    public static Test sqlAuthorizationDecoratorSingleUse(
            Test test, String dbName, boolean shutdownDatabase)
    {
        // Set the SQL authorization mode as a database property
        // with a modified DatabasePropertyTestSetup that does not
        // reset it.
        final Properties sqlAuth = new Properties();
        sqlAuth.setProperty("derby.database.sqlAuthorization", "true");
        Test setSQLAuthMode = DatabasePropertyTestSetup.getNoTeardownInstance(
                test, sqlAuth, true);

        setSQLAuthMode = new DropDatabaseSetup(
                setSQLAuthMode, dbName, shutdownDatabase);
        
        setSQLAuthMode = new DatabaseChangeSetup
            ( setSQLAuthMode, dbName, dbName, true );

        return changeUserDecorator(setSQLAuthMode,
                                   DerbyConstants.TEST_DBO,
                                   "dummy"); // DRDA doesn't like empty pw
    }
    

    /**
     * Utility version of sqlAuthorizationDecorator that also sets
     * up authentication. A combination of
     * DatabasePropertyTestSetup.builtinAuthentication wrapped in
     * sqlAuthorizationDecorator.
     * <BR>
     * The database owner of this default SQL authorization mode
     * database is TEST_DBO. This decorator sets the default user
     * to be TEST_DBO.
     * <BR>
     * Assumption is that no authentication is enabled on the default
     * SQL authorization database on entry.
     * 
     * @param users Set of users excluding the database owner, that will
     * be added by this decorator.
     */
    public static Test sqlAuthorizationDecorator(Test test,
            String[] users, String passwordToken)
    {
        String[] usersWithDBO = new String[users.length + 1];
        usersWithDBO[0] = DerbyConstants.TEST_DBO;
        System.arraycopy(users, 0, usersWithDBO, 1, users.length);
        return sqlAuthorizationDecorator(
            DatabasePropertyTestSetup.builtinAuthentication(test, 
                    usersWithDBO, passwordToken));
    }
    
    /**
     * Return a decorator that changes the configuration to obtain
     * connections from a ConnectionPoolDataSource using
     * <code>getPooledConnection().getConnection()</code>
     * <p>
     * Note that statement pooling is enabled in the data source and in all the
     * connections created from it.
     * <p>
     * The tearDown reverts the configuration to the previous
     * configuration.
     * 
     * @param test the test/suite to decorate
     * @return A test setup with the requested decorator.
     */
    public static Test connectionCPDecorator(Test test)
    {
        if (JDBC.vmSupportsJDBC3()) {
            return new ConnectorSetup(test,
             "org.apache.derbyTesting.junit.ConnectionPoolDataSourceConnector");
        } else {
            return new BaseTestSuite("ConnectionPoolDataSource not supported");
        }

    }

    /**
     * Return a decorator that changes the configuration to obtain
     * connections from an XADataSource using
     * <code>
     * getXAConnection().getConnection()
     * </code>
     * The connection is not connected to any global transaction,
     * thus it is in local connection mode.
     * The tearDown reverts the configuration to the previous
     * configuration.
     */
    public static Test connectionXADecorator(Test test)
    {
        if (JDBC.vmSupportsJDBC3()) {
            return new ConnectorSetup(test,
                "org.apache.derbyTesting.junit.XADataSourceConnector");
        } else {
            return new BaseTestSuite("XADataSource not supported");
        }
    }
    /**
     * Return a decorator that changes the configuration to obtain
     * connections from a standard DataSource using
     * <code>
     * getConnection()
     * </code>
     * The tearDown reverts the configuration to the previous
     * configuration.
     */
    public static TestSetup connectionDSDecorator(Test test)
    {
        return new ConnectorSetup(test,
            "org.apache.derbyTesting.junit.DataSourceConnector");
    }
    
    /**
     * Returns a decorator that forces the JDBC 3 embedded client  in
     * a Java SE 6/JDBC 4 environment. The only difference is that
     * the DataSource class names will be the "old" JDBC 3 versions
     * and not the JDBC 4 specific ones.
     * that
     * @param test
     */
    public static Test forceJDBC3Embedded(Test test)
    {
        if (JDBC.vmSupportsJDBC4()) {
            test = new JDBCClientSetup(test, JDBCClient.EMBEDDED_30);
        }
        return test;
    }
    
    /**
     * Returns a decorator that forces the JDBC 3 network client in
     * a Java SE 6/JDBC 4 environment. The only difference is that
     * the DataSource class names will be the "old" JDBC 3 versions
     * and not the JDBC 4 specific ones.
     *
     * Assumption is that the received Test is an instance of ServerSetup,
     * which is the decorator for client server tests.  If that is not
     * the case then this method is a no-op.
     *
     * @param test Test around which to wrap the JDBC 3 network client
     *  configuration.
     */
    public static Test forceJDBC3NetClient(Test test)
    {
        if (JDBC.vmSupportsJDBC4() && (test instanceof ServerSetup))
            ((ServerSetup)test).setJDBCClient(JDBCClient.DERBYNETCLIENT_30);
        return test;
    }
    
    /**
     * Decorate a test changing the default ssl mode.
     * The tearDown method resets the default user and password value to
     * their previous settings.
     * 
     * @param test Test to decorate
     * @param ssl New ssl mode
     * @return decorated test
     */
    public static Test changeSSLDecorator(Test test, String ssl)
    {
        return new ChangeSSLSetup(test, ssl);
    }   
    
    /**
     * Default embedded configuration
     *
     */
    private TestConfiguration() {
        // Check for possibly passed in DatabaseName
        // this is used in OCRecoveryTest
        String propDefDbName = getSystemProperties().getProperty(
                "derby.tests.defaultDatabaseName");
        if (propDefDbName != null)
            this.defaultDbName = propDefDbName;
        else
            this.defaultDbName=DEFAULT_DBNAME;
        usedDbNames.add(DEFAULT_DBNAME);
        logicalDbMapping.put(DEFAULT_DBNAME, DEFAULT_DBNAME);
        this.userName = DEFAULT_USER_NAME;
        this.userPassword = DEFAULT_USER_PASSWORD;
        this.connectionAttributes = new Properties();
        this.hostName = DEFAULT_HOSTNAME;
        this.port = basePort;
        this.isVerbose = Boolean.valueOf(
            getSystemProperties().getProperty(KEY_VERBOSE)).
            booleanValue();
        this.doTrace = Boolean.valueOf(
            getSystemProperties().getProperty(KEY_TRACE)).
            booleanValue();
        this.stopAfterFirstFail = Boolean.valueOf(
                getSystemProperties().getProperty(KEY_STOP_AFTER_FIRST_FAIL)).
                booleanValue();
        this.jdbcClient = JDBCClient.getDefaultEmbedded();
        this.ssl = null;
        this.jmxPort = getNextAvailablePort();
        println("basePort=" + basePort + ", bogusPort=" + bogusPort +
                ", jmxPort=" + jmxPort);
        url = createJDBCUrlWithDatabaseName(defaultDbName);
        initConnector(null);
 
    }

    /**
     * Obtain a new configuration identical to the passed one.
     */
    TestConfiguration(TestConfiguration copy)
    {
        this.defaultDbName = copy.defaultDbName;
        this.usedDbNames.addAll(copy.usedDbNames);
        logicalDbMapping.putAll(copy.logicalDbMapping);
        this.userName = copy.userName;
        this.userPassword = copy.userPassword;
        this.connectionAttributes = new Properties(copy.connectionAttributes);

        this.isVerbose = copy.isVerbose;
        this.doTrace = copy.doTrace;
        this.port = copy.port;
        this.jmxPort = copy.jmxPort;
        
        this.jdbcClient = copy.jdbcClient;
        this.hostName = copy.hostName;
        
        this.ssl = copy.ssl;

        this.url = copy.url;
        initConnector(copy.connector);
    }

    TestConfiguration(TestConfiguration copy, JDBCClient client,
            String hostName, int port)
    {
        this.defaultDbName = copy.defaultDbName;
        this.usedDbNames.addAll(copy.usedDbNames);        
        logicalDbMapping.putAll(copy.logicalDbMapping);
        this.userName = copy.userName;
        this.userPassword = copy.userPassword;
        this.connectionAttributes = new Properties(copy.connectionAttributes);

        this.isVerbose = copy.isVerbose;
        this.doTrace = copy.doTrace;
        this.port = port;
        this.jmxPort = copy.jmxPort;
        if (bogusPort == port) {
            throw new IllegalStateException(
                    "port cannot equal bogusPort: " + bogusPort);
        }
        
        this.jdbcClient = client;
        this.hostName = hostName;

        this.ssl = copy.ssl;
        
        this.url = createJDBCUrlWithDatabaseName(defaultDbName);
        initConnector(copy.connector);
    }

    TestConfiguration(TestConfiguration copy, JDBCClient client,
            String hostName, int port, String dataBasePath)
    {
        this.defaultDbName = dataBasePath;
        this.usedDbNames.addAll(copy.usedDbNames);        
        logicalDbMapping.putAll(copy.logicalDbMapping);
        this.userName = copy.userName;
        this.userPassword = copy.userPassword;
        this.connectionAttributes = new Properties(copy.connectionAttributes);

        this.isVerbose = copy.isVerbose;
        this.doTrace = copy.doTrace;
        this.port = port;
        this.jmxPort = copy.jmxPort;
        if (bogusPort == port) {
            throw new IllegalStateException(
                    "port cannot equal bogusPort: " + bogusPort);
        }
        
        this.jdbcClient = client;
        this.hostName = hostName;

        this.ssl = copy.ssl;
        
        this.url = createJDBCUrlWithDatabaseName(defaultDbName);
        initConnector(copy.connector);
    }

    /**
     * Obtain a new configuration identical to the passed in
     * one except for the default user and password.
     * @param copy Configuration to copy.
     * @param user New default user
     * @param password New default password.
     */
    TestConfiguration(TestConfiguration copy, String user,
            String password, String passwordToken)
    {
        this.defaultDbName = copy.defaultDbName;
        this.usedDbNames.addAll(copy.usedDbNames);
        logicalDbMapping.putAll(copy.logicalDbMapping);
        this.userName = user;
        this.userPassword = password;
        this.passwordToken = passwordToken == null ?
                copy.passwordToken : passwordToken;
        this.connectionAttributes = new Properties(copy.connectionAttributes);

        this.isVerbose = copy.isVerbose;
        this.doTrace = copy.doTrace;
        this.port = copy.port;
        this.jmxPort = copy.jmxPort;
        
        this.jdbcClient = copy.jdbcClient;
        this.hostName = copy.hostName;

        this.ssl = copy.ssl;
        
        this.url = copy.url;
        initConnector(copy.connector);
    }

    /**
     * Obtains a new configuration identical to the passed in one, except for
     * the default SSL mode.
     * <p>
     * The modes supported at the moment are <tt>basic</tt> and <tt>off</tt>.
     * The mode <tt>peerAuthentication</tt> is not yet supported.
     *
     * @param copy configuration to copy
     * @param ssl default SSL mode
     */
    TestConfiguration(TestConfiguration copy, String ssl)
    {
        this(copy);
        this.ssl = ssl;
    }

    /**
     * Obtain a new configuration identical to the passed in
     * one except for the database name. The passed database name
     * is added at the end of the list of used databases.
     * If the <code>defaulDb</code> parameter is <code>true</code>
     * the new database name is used as a default database.
     * @param copy Configuration to copy.
     * @param dbName New database name
     * @param defaultDb Indicates that the passed <code>dbName</code> is supposed
     * to be used as the default database name.
     */
    TestConfiguration(TestConfiguration copy, String logicalDbName,
                      String dbName, boolean defaultDb)
    {
        this.usedDbNames.addAll(copy.usedDbNames);
        this.usedDbNames.add(dbName);
        logicalDbMapping.putAll(copy.logicalDbMapping);

        // Can not use the same logical name for different database.
        // If this assert will make failures it might be safely removed
        // since having more physical databases accessible throught the same
        // logical database name will access only the last physical database
        Assert.assertNull(logicalDbMapping.put(logicalDbName, dbName));

        if (defaultDb) {
            this.defaultDbName = dbName;
        } else {
            this.defaultDbName = copy.defaultDbName;
        }
        
        this.userName = copy.userName;
        this.userPassword = copy.userPassword;
        this.connectionAttributes = new Properties(copy.connectionAttributes);

        this.isVerbose = copy.isVerbose;
        this.doTrace = copy.doTrace;
        this.port = copy.port;
        this.jmxPort = copy.jmxPort;
        
        this.jdbcClient = copy.jdbcClient;
        this.hostName = copy.hostName;

        this.ssl = copy.ssl;
        
        this.url = createJDBCUrlWithDatabaseName(this.defaultDbName);
        initConnector(copy.connector);
    }
  
    /**
     * This constructor creates a TestConfiguration from a Properties object.
     *
     * @throws NumberFormatException if the port specification is not an integer.
     */
    private TestConfiguration(Properties props) 
        throws NumberFormatException {

        defaultDbName = props.getProperty(KEY_DBNAME, DEFAULT_DBNAME);
        usedDbNames.add(defaultDbName);
        logicalDbMapping.put(defaultDbName, defaultDbName);
        userName = props.getProperty(KEY_USER_NAME, DEFAULT_USER_NAME);
        userPassword = props.getProperty(KEY_USER_PASSWORD, 
                                         DEFAULT_USER_PASSWORD);
        connectionAttributes = new Properties();
        hostName = props.getProperty(KEY_HOSTNAME, DEFAULT_HOSTNAME);
        isVerbose = Boolean.valueOf(props.getProperty(KEY_VERBOSE)).booleanValue();
        doTrace =  Boolean.valueOf(props.getProperty(KEY_TRACE)).booleanValue();
        port = basePort;
        jmxPort = getNextAvailablePort();
        println("basePort=" + basePort + ", bogusPort=" + bogusPort +
                ", jmxPort=" + jmxPort);

        ssl = props.getProperty(KEY_SSL);
        
        String framework = props.getProperty(KEY_FRAMEWORK, DEFAULT_FRAMEWORK);
        
        if ("DerbyNetClient".equals(framework)) {
            jdbcClient = JDBCClient.DERBYNETCLIENT;
        } else if ("DerbyNet".equals(framework)) {
            jdbcClient = JDBCClient.DB2CLIENT;
        } else {
            jdbcClient = JDBCClient.getDefaultEmbedded();
        }
        url = createJDBCUrlWithDatabaseName(defaultDbName);
        initConnector(null);
    }

    /**
     * Create a copy of this configuration with some additional connection
     * attributes.
     *
     * @param attrs the extra connection attributes
     * @return a copy of the configuration with extra attributes
     */
    TestConfiguration addConnectionAttributes(Properties attrs) {
        TestConfiguration copy = new TestConfiguration(this);
        Enumeration e = attrs.propertyNames();
        while (e.hasMoreElements()) {
            String key = (String) e.nextElement();
            String val = attrs.getProperty(key);
            copy.connectionAttributes.setProperty(key, val);
        }
        copy.initConnector(connector);
        return copy;
    }

    /**
     * Get the system properties in a privileged block.
     *
     * @return the system properties.
     */
    public  static final Properties getSystemProperties() {
        // Fetch system properties in a privileged block.
        return AccessController.doPrivileged(
                new PrivilegedAction<Properties>() {
            public Properties run() {
                return System.getProperties();
            }
        });
    }

    /**
     * Create JDBC connection url, including the name of the database.
     *
     * @return JDBC connection url, without attributes.
     */
    private String createJDBCUrlWithDatabaseName(String name) {
        if (JDBC.vmSupportsJDBC3())
        {
            String url;
           if (jdbcClient.isEmbedded()) {
               url = jdbcClient.getUrlBase();
           } else {
               url = jdbcClient.getUrlBase() + hostName + ":" + port + "/";
           }
           return url.concat(name);
        }
        // No DriverManager support so no URL support.
        return null;
    }
    
    /**
     * Initialize the connection factory.
     * Defaults to the DriverManager implementation
     * if running JDBC 2.0 or higher, otherwise a
     * DataSource implementation for JSR 169.
     *
     */
    private void initConnector(Connector oldConnector)
    {
        if (oldConnector != null)
        {
            // Use the same type of connector as the
            // configuration we are copying from.
            
            try {
                Class<?> clazz = Class.forName(oldConnector.getClass().getName());
                connector = (Connector) clazz.getConstructor().newInstance();
            } catch (Exception e) {
                Assert.fail(e.getMessage());
            }            
        }
        else if (JDBC.vmSupportsJDBC3())
        {
            try {
                Class<?> clazz = Class.forName("org.apache.derbyTesting.junit.DriverManagerConnector");
                connector = (Connector) clazz.getConstructor().newInstance();
            } catch (Exception e) {
                Assert.fail(e.getMessage());
            }
            
        } else {
            connector = new DataSourceConnector();
        }
        connector.setConfiguration(this);

        try {
            String  loginTimeoutString = BaseTestCase.getSystemProperty( KEY_LOGIN_TIMEOUT );
            
            if ( loginTimeoutString != null )
            {
                int loginTimeout = Integer.parseInt( loginTimeoutString );

                connector.setLoginTimeout( loginTimeout );
            }
        }
        catch (Exception e) { Assert.fail(e.getMessage()); }
    }

    /**
     * Get configured JDBCClient object.
     *
     * @return JDBCClient
     */
    public JDBCClient getJDBCClient() {
        return jdbcClient;
    }

    /**
     * <p>
     * Return the jdbc url for connecting to the default database.
     * </p>
     *
     * <p>
     * The returned URL does not include the connection attributes. These must
     * either be appended to the URL when connecting, or they must be passed
     * as a {@code Properties} object to {@code DriverManager.getConnection()}.
     * </p>
     *
     * @return JDBC url.
     */
    public String getJDBCUrl() {
        return url;
    }

    /**
     * Return the jdbc url for a connecting to the database.
     * 
     * @param databaseName name of database.
     * @return JDBC connection url, including database name.
     */
    public String getJDBCUrl(String databaseName) {
        return createJDBCUrlWithDatabaseName(databaseName);
    }
    
    /**
     * Return the default database name.
     * 
     * @return default database name.
     */
    public String getDefaultDatabaseName() {
        return defaultDbName;
    }
    
    /**
     * Return the physical name for a database
     * given its logical name.
     * 
     * @return Physical name of the database.
     */
    public String getPhysicalDatabaseName(String logicalName) {
        return (String) logicalDbMapping.get(logicalName);
    }

    /**
     * Return the user name.
     * 
     * @return user name.
     */
    public String getUserName() {
        return userName;
    }
    
    /**
     * Return the user password.
     * 
     * @return user password.
     */
    public String getUserPassword() {
        return userPassword;
    }

    /**
     * Return the connection attributes to use in this configuration. The
     * attributes won't contain user name or password. Use
     * {@link #getUserName()} or {@link #getUserPassword()} instead to
     * retrieve those attributes.
     *
     * @return connection attributes (never {@code null})
     */
    public Properties getConnectionAttributes() {
        return connectionAttributes;
    }

    /**
     * Get a flat string representation of the connection attributes. To
     * be used in the connectionAttributes property of a data source.
     *
     * @return all connection attributes concatenated ({@code null} if there
     * are no attributes)
     */
    String getConnectionAttributesString() {
        StringBuffer sb = new StringBuffer();
        Enumeration e = connectionAttributes.propertyNames();
        boolean first = true;
        while (e.hasMoreElements()) {
            if (!first) {
                sb.append(';');
            }
            String key = (String) e.nextElement();
            sb.append(key);
            sb.append('=');
            sb.append(connectionAttributes.getProperty(key));
            first = false;
        }

        if (first) {
            // No connection attributes.
            return null;
        }

        return sb.toString();
    }

    /**
     * Return the host name for the network server.
     *
     * @return host name.
     */
    public String getHostName() {
        return hostName;
    }

    /**
     * Return if the base port is default or not.
     *
     * @return true if base port is default.
     */
    public static boolean isDefaultBasePort() {
        return (basePort == DEFAULT_PORT);
    }

    public static int getBasePort() {
        return basePort;
    }

    /**
     * Get port number for network server.
     * 
     * @return port number.
     */
    public int getPort() {
        return port;
    }
    
    /**
     * Get the next available port. This method is multi-purposed.
     * It can be used for alternative servers and also for JMX and replication.
     * 
     * @return port number.
     */
    public int getNextAvailablePort() {
    	/* We want to crash. If you are reading this, you have to increment
    	 * the MAX_PORTS_USED constant and to edit the wiki page relative to
    	 * concurrent test running */
    	if (assignedPortCount+1 > MAX_PORTS_USED) {
    		Assert.fail("Port "+(lastAssignedPort+1)+" exceeeds expected maximum. " +
    					"You may need to update TestConfiguration.MAX_PORTS_USED and "+
    					"the Wiki page at http://wiki.apache.org/db-derby/DerbyJUnitTesting "+
    					"if test runs now require more available ports");
    	}
    	
    	int possiblePort = lastAssignedPort + 1;
		
		assignedPortCount++;
		
		lastAssignedPort = possiblePort;
		return possiblePort;
    }
    
    /**
     * Gets the value of the port number that may be used for "remote"
     * JMX monitoring and management.
     * @return the port number on which the JMX MBean server is listening for 
     *         connections
     */
    public int getJmxPort() {
        return jmxPort;
    }

    /**
     * Returns a port number where no Derby network servers are supposed to
     * be running.
     *
     * @return A port number where no Derby network servers are started.
     */
    public int getBogusPort() {
        return bogusPort;
    }

    /**
     * Get ssl mode for network server
     * 
     * @return ssl mode
     */
    public String getSsl() {
        return ssl;
    }

    
    /**
     * Open connection to the default database.
     * If the database does not exist, it will be created.
     * A default username and password will be used for the connection.
     *
     * @return connection to default database.
     */
    public Connection openDefaultConnection()
        throws SQLException {
        return connector.openConnection();
    }
    
    /**
     * Open connection to the default database.
     * If the database does not exist, it will be created.
     *
     * @return connection to default database.
     */
    Connection openDefaultConnection(String user, String password)
        throws SQLException {
        return connector.openConnection(user, password);
    }

    /**
     * Open connection to the specified database.
     * If the database does not exist, it will be created.
     * A default username and password will be used for the connection.
     * Requires that the test has been decorated with
     * additionalDatabaseDecorator with the matching name.
     * The physical database name may differ.
     * @param logicalDatabaseName A logical database name as passed
     * to <code>additionalDatabaseDecorator</code> function.
     * @return connection to specified database.
     */
    Connection openConnection(String logicalDatabaseName)
        throws SQLException
    {
        return connector.openConnection( getAndVetPhysicalDatabaseName( logicalDatabaseName ) );
    }
    private String  getAndVetPhysicalDatabaseName( String logicalDatabaseName )
        throws SQLException
    {
        String databaseName = getPhysicalDatabaseName( logicalDatabaseName );
        
        if ( usedDbNames.contains(databaseName) ) { return databaseName; }
        else
        {
            throw new SQLException("Database name \"" + logicalDatabaseName
                      + "\" is not in a list of used databases."
                      + "Use method TestConfiguration.additionalDatabaseDecorator first.");
        }
    }

    /**
     * Open connection to the specified database using the supplied username and password.
     * If the database does not exist, it will be created.
     * Requires that the test has been decorated with
     * additionalDatabaseDecorator with the matching name.
     * The physical database name may differ.
     * @param logicalDatabaseName A logical database name as passed
     * to <code>additionalDatabaseDecorator</code> function.
     * @return connection to specified database.
     */
    public  Connection openConnection( String logicalDatabaseName, String user, String password )
        throws SQLException
    {
        return connector.openConnection
            (
             getAndVetPhysicalDatabaseName( logicalDatabaseName ),
             user,
             password
             );
    }

    /**
     * Open connection to the specified database using the supplied username and password.
     * Treat the database name as a physical database name rather than as a logical name
     * which needs to be mapped.
     * If the database does not exist, it will be created.
     * Requires that the test has been decorated with
     * additionalDatabaseDecorator with the matching name.
     * @param physicalDatabaseName The real database name to use.
     * @param user name of user
     * @param password password of user
     * @param props extra properties to pass to the connection
     * @return connection to specified database.
     */
    public  Connection openPhysicalConnection( String physicalDatabaseName, String user, String password, Properties props )
        throws SQLException
    {
        return connector.openConnection
            (
             physicalDatabaseName,
             user,
             password,
             props
             );
    }

    /**
     * Shutdown the database for this configuration
     * assuming it is booted.
     *
     */
    public void shutdownDatabase()
    {
        try {
            connector.shutDatabase();
            Assert.fail("Database failed to shut down");
        } catch (SQLException e) {
             BaseJDBCTestCase.assertSQLState("Database shutdown", "08006", e);
        }
    }
    
    /**
     * Shutdown the engine for this configuration
     * assuming it is booted.
     * This method can only be called when the engine
     * is running embedded in this JVM.
     *
     */
    public void shutdownEngine()
    {
        try {
            connector.shutEngine(true);
            Assert.fail("Engine failed to shut down");
        } catch (SQLException e) {
             BaseJDBCTestCase.assertSQLState("Engine shutdown", "XJ015", e);
        }
    }

    /**
     * Shutdown the engine for this configuration
     * assuming it is booted.
     * This method can only be called when the engine
     * is running embedded in this JVM.
     *
     * @param deregisterDeriver if true, deregister the driver
     */
    public void shutdownEngine(boolean deregisterDeriver)
    {
        try {
            connector.shutEngine(deregisterDeriver);
            Assert.fail("Engine failed to shut down");
        } catch (SQLException e) {
             BaseJDBCTestCase.assertSQLState("Engine shutdown", "XJ015", e);
        }
    }

    /** Get the login timeout from the connector */
    public  int getLoginTimeout() throws SQLException
    {
        return connector.getLoginTimeout();
    }

    /**
     * Set the login timeout for the connector.
     * @param seconds the login timeout in seconds
     * @throws SQLException if the timeout cannot be set
     */
    public void setLoginTimeout(int seconds) throws SQLException {
        connector.setLoginTimeout(seconds);
    }

    public void waitForShutdownComplete(String physicalDatabaseName) {
        String path = getDatabasePath(physicalDatabaseName);
        boolean lockfilepresent = true;
        int timeout = LOCKFILETIMEOUT; // 5 mins
        int totalsleep = 0;
        File lockfile = new File (path + File.separatorChar + "db.lck");
        File exlockfile = new File (path + File.separatorChar + "dbex.lck");
        while (lockfilepresent) {
            if (totalsleep >= timeout)
            {
                System.out.println("TestConfigruation.waitForShutdownComplete: " +
                        "been looping waiting for lock files to be deleted for at least 5 minutes, giving up");
                break;
            }
            if (lockfile.exists() || exlockfile.exists())
            {
                // TODO: is it interesting to know whether db.lck or dbex.lck or both is still present?
                try {
                    System.out.println("TestConfiguration.waitForShutdownComplete: " +
                            "db*.lck files not deleted after " + totalsleep + " ms.");
                    Thread.sleep(1000);
                    totalsleep=totalsleep+1000;
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            else
                lockfilepresent=false;
        }
    }
    
   /**
     * stops the Network server for this configuration.
     *
     */
    public void stopNetworkServer() {
        try {
            NetworkServerControlWrapper networkServer =
                    new NetworkServerControlWrapper();

            networkServer.shutdown();
            if (serverOutput != null) {
                serverOutput.close();
            }
        } catch(Exception e) {
            SQLException se = new SQLException("Error shutting down server");
            se.initCause(e);
        }
    }

   /**
     * starts the Networs server for this configuration.
     *
     */
    public void startNetworkServer() throws SQLException
    {
        Exception failException = null;
        try {
            
            NetworkServerControlWrapper networkServer =
                    new NetworkServerControlWrapper();

 	    serverOutput = AccessController.doPrivileged(
                            new PrivilegedAction<FileOutputStream>() {
                public FileOutputStream run() {
                    File logs = new File("logs");
                    logs.mkdir();
                    File console = new File(logs, "serverConsoleOutput.log");
                    FileOutputStream fos = null;
                    try {
                        fos = new FileOutputStream(console.getPath(), true);
                    } catch (FileNotFoundException ex) {
                        ex.printStackTrace();
                    }
                    return fos;
                }
            });

            networkServer.start(new PrintWriter(serverOutput));

            // Wait for the network server to start
            boolean started = false;
            int retries = 10;         // Max retries = max seconds to wait

            while (!started && retries > 0) {
                try {
                    // Sleep 1 second and then ping the network server
                    Thread.sleep(SLEEP_TIME);
                    networkServer.ping();

                    // If ping does not throw an exception the server has started
                    started = true;
                } catch(Exception e) {		   
                    retries--;
                    failException = e;
                 }
                
             }

            // Check if we got a reply on ping
            if (!started) {
                 throw failException;
            }
        } catch (Exception e) {
            SQLException se = new SQLException("Error starting network  server");
            se.initCause(failException);
            throw se;
      }
    }
    /**
     * Set the verbosity, i.e., whether debug statements print.
     */
    public void	setVerbosity( boolean isChatty )	{ isVerbose = isChatty; }
    /**
     * Set JUnit test method tracing.
     */
    public void setTrace( boolean isChatty )    { doTrace = isChatty; }
    
    /**
     * Return verbose flag.
     *
     * @return verbose flag.
     */
    public boolean isVerbose() {
        return isVerbose;
    }

    /**
     * Private method printing debug information to standard out if debugging
     * is enabled.
     * <p>
     * <em>Note:</em> This method may direct output to a different location
     * than the println method in <tt>BaseJDBCTestCase</tt>.
     */
    private void println(CharSequence msg) {
        if (isVerbose) {
            System.out.println("DEBUG: {TC@" + hashCode() + "} " + msg);
        }
    }

    /**
     * Return JUnit test method trace flag.
     *
     * @return JUnit test method trace flag.
     */
    public boolean doTrace() {
        return doTrace;
    }

    public boolean stopAfterFirstFail() {
        return stopAfterFirstFail;
    }
	/**
	 * <p>
	 * Return true if we classes are being loaded from jar files. For the time
	 * being, this simply tests that the JVMInfo class (common to the client and
	 * the server) comes out of a jar file.
	 * </p>
	 */
	public static boolean loadingFromJars()
	{
        return SecurityManagerSetup.isJars;
	}
    
    /**
     * Returns true if this JUnit test being run by the old harness.
     * Temp method to ease the switch over by allowing
     * suites to alter their behaviour based upon the
     * need to still run under the old harness.
     */
    //public static boolean runningInDerbyHarness()
    //{
    //    return runningInDerbyHarness;
    //}
    
    /**
     * Get a folder already created where a test can
     * write its failure information. The name of the folder,
     * relative to ${user.dir} is:
     * <BR>
     * <code>
     * fail/client/testclass/testname
     * <code>
     * <UL>
     * <LI> client - value of JDBCClient.getName() for the test's configuration
     * <LI> testclass - last element of the class name
     * <LI> testname - value of test.getName()
     *  </UL>
     */
    File getFailureFolder(TestCase test){
        
        StringBuffer sb = new StringBuffer();
      
        sb.append("fail");
        sb.append(File.separatorChar);
        sb.append(getJDBCClient().getName());
        sb.append(File.separatorChar);
        
        String className = test.getClass().getName();
        int lastDot = className.lastIndexOf('.');
        if (lastDot != -1)
            className = className.substring(lastDot+1, className.length());
        
        sb.append(className);
        sb.append(File.separatorChar);
        // DERBY-5620: Ensure valid file name.
        char[] tmpName = test.getName().toCharArray();
        for (int i=0; i < tmpName.length; i++) {
            switch (tmpName[i]) {
                case '-':
                case '_':
                    continue;
                default:
                    if (!Character.isLetterOrDigit(tmpName[i])) {
                        tmpName[i] = '_';
                    }
            }
        }
        sb.append(tmpName);
        
        String base = sb.toString().intern();
        final File folder = new File(base);
        
        // Create the folder
        // TODO: Dump this configuration in some human readable format
        synchronized (base) {
            AccessController.doPrivileged(new PrivilegedAction<Boolean>() {
                public Boolean run() {
                    if (folder.exists()) {
                        // do something
                    }
                    return folder.mkdirs();
                }
            });
        }

        return folder;
        
    }
    
    /*
     * Immutable data members in test configuration
     */
    
    /** The default database name for tests. */
    private final String defaultDbName;
    /** Holds the names of all other databases used in a test to perform a proper cleanup.
     * The <code>defaultDbName</code> is also contained here.  */
    private final ArrayList<String> usedDbNames = new ArrayList<String>();
    /** Contains the mapping of logical database names to physical database names. */
    private final HashMap<String, String> logicalDbMapping = new HashMap<String, String>();
    private final String url;
    private final String userName; 
    private final String userPassword; 
    private final int port;
    private final String hostName;
    private final JDBCClient jdbcClient;
    private final int jmxPort;
    private boolean isVerbose;
    private boolean doTrace;
    private boolean stopAfterFirstFail;
    private String ssl;

    /**
     * Extra connection attributes. Not for user name and password, use the
     * fields {@link #userName} and {@link #userPassword} for those attributes.
     */
    private Properties connectionAttributes;

    /**
     * Password token used by the builtin authentication decorators.
     * Default simple scheme is the password is a function
     * of the user and a password token. password token
     * is set by DatabasePropertyTestSetup.builtinAuthentication
     */
    private String passwordToken = "";
    
    /**
     * Indirection for obtaining connections based upon
     * this configuration.
     */
    Connector connector;
    
    /*
     * SecurityManager related configuration.
     */
    
    /**
     * Install the default security manager setup,
     * for the current configuration.
     * @throws PrivilegedActionException 
     */
    boolean defaultSecurityManagerSetup() {
    	
    	// Testing with the DB2 client has not been performed
    	// under the security manager since it's not part
    	// of Derby so no real interest in tracking down issues.
    	if (jdbcClient.isDB2Client()) {
    		SecurityManagerSetup.noSecurityManager();
    		return false;
    	} else {
            if (SecurityManagerSetup.NO_POLICY.equals(
                    BaseTestCase.getSystemProperty("java.security.policy")))
            {
                // Explict setting of no security manager
                return false;
            }
    		SecurityManagerSetup.installSecurityManager();
    		return true;
    	}
    }
    
    
    /*
    ** BUILTIN password handling.
    */
    
    /**
     * Get the password that is a function of the user
     * name and the passed in token.
     */
    static final String getPassword(String user, String token)
    {
        return user.concat(token);
    }
    
    /**
     * Get the password that is a function of the user
     * name and the token for the current configuration.
     */
    public final String getPassword(String user)
    {
        return getPassword(user, passwordToken);
    }
    
    public final String getDatabasePath(String physicalDatabaseName) 
    {
        String dbName = physicalDatabaseName.replace('/', File.separatorChar);
        String dsh = BaseTestCase.getSystemProperty("derby.system.home");
        if (dsh == null) {
            Assert.fail("not implemented");
        } else {
            dbName = dsh + File.separator + dbName;
        }
        return dbName;
    }
}
