Subversion Repositories DevTools

Rev

Rev 4285 | Blame | Compare with Previous | Last modification | View Log | RSS feed

package com.erggroup.buildtool.ripple;

import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.sql.Types;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.Iterator;
import java.util.ListIterator;
import java.util.Vector;
import java.util.concurrent.locks.ReentrantLock;

import org.apache.log4j.Logger;

/**Release Manager schema abstraction
 */
public class ReleaseManager
{
  /**Unit test hook.
   * Prevents Oracle interaction when false.
   * @attribute
   */
  public static boolean mUseDatabase = true;

  /**Debug Support.
   * Set to false if EnvVar GBE_BUILDTOOL_DEBUG exists
   * Value of GBE_BUILDTOOL_DEBUG is expected to be an email if greater than
   * one character.
   *
   * When set to false will:
   *    Prevents use of Oracle Mutex and potential lockout during debug sessions.
   *    Prevent the initiation of an indefinite pause.
   * @attribute
   */
  public static boolean mUseMutex = true;

  /**Unit test hook
   * Container of persisted run levels for unit test usage
   * Must be managed by the unit test code
   * @attribute
   */
  public static Vector<Integer> mPersistedRunLevelCollection = new Vector<Integer>();

  /**database represented enumerated value
   * @attribute
   */
  public static final int DB_CANNOT_CONTINUE = 1;

  /**database represented enumerated value
   * @attribute
   */
  public static final int DB_PAUSED = 2;

  /**database represented enumerated value
   * @attribute
   */
  public static final int DB_ACTIVE = 3;

  /**database represented enumerated value
   * @attribute
   */
  public static final int DB_IDLE = 4;

  /**database represented enumerated value
   * @attribute
   */
  public static final int DB_WAITING = 5;

  /**database represented enumerated value
   * @attribute
   */
  public static final int DB_PUBLISHING = 6;

  /**package object of no consequence
   * @attribute
   */
  public static final Package NULL_PACKAGE = new Package();

  /**registered status
   * @attribute
   */
  static boolean mRegistered = false;

  /**Logger
   * @attribute
   */
  private static final Logger mLogger = Logger.getLogger(ReleaseManager.class);

  /**database session handle
   * @attribute
   */
  private static Connection mNonPlanningConnection = null;

  /**database session handle
   * @attribute
   */
  private static Connection mPlanningConnection = null;
  
  /**database session handle
   * note this handle is only ever set to mNonPlanningConnection or mPlanningConnection
   * @attribute
   */
  private Connection mConnection = null;

  /**thread synchronization governing non planning database connection usage
   * this lock is used by all build threads
   * @attribute
   */
  private static final ReentrantLock mSession = new ReentrantLock();

  /**thread synchronization governing database connection usage
   * this lock is used by master threads with a high priority planning requirement
   * and at most one thread with a low priority planning requirement
   * @attribute
   */
  private static final ReentrantLock mPlanningSession = new ReentrantLock();

  /**thread synchronization governing database connection request queueing
   * this lock is used by master threads with a low priority planning requirement
   * use the fairness parameter to grant access to the longest waiting thread
   * @attribute
   */
  private static final ReentrantLock mLowPriorityQueue = new ReentrantLock(true);

   /**collection of ReleaseConfig objects
   * @attribute
   */
  public Vector<ReleaseConfig> mReleaseConfigCollection = new Vector<ReleaseConfig>();

  /**database connection string
   * @attribute
   */
  private static String mConnectionString = new String();

  /**database username
   * @attribute
   */
  private static String mUsername = new String();

  /**database password
   * @attribute
   */
  private static String mPassword = new String();

  /**collection of RunLevel objects
   * @attribute
   */
  public Vector<RunLevelData> mRunLevelCollection = new Vector<RunLevelData>();
  
  /**set in claimVersion, cleared in discardVersion
   * @attribute
   */
  private String mPlannedPkgId = null;
  
  /**prevents inadvertently attempting a commit which releases record locks in between claimMutex and releaseMutex
   * @attribute
   */
  private boolean mDoNotCommit = false;
  
  /**set in claimVersion, cleared in discardVersion
   * @attribute
   */

  private String mPlannedPkgVersion = null;

  /** Set in autoMakeRelease
   * @attribute
   */
   public String mAutoMakeReleaseCause = null;

  /**in daemon mode
   *   select gm.gbe_value from release_manager.release_config rc, release_manager.gbe_machtype gm
   *   where rc.rtag_id=<baseline> and gm.gbe_id=rc.gbe_id;
   * in escrow mode
   *   select gm.gbe_value from deployment_manager.boms b, release_manager.release_config rc,
   *   release_manager.gbe_machtype gm
   *   where b.bom_id=<baseline> and rc.rtag_id=b.rtag_id_fk and gm.gbe_id=rc.gbe_id;
   * populates the machtypeCollection with the resultset
   */
  void queryMachtypes(Vector<String> machtypeCollection, boolean daemonMode, int baseline) throws SQLException, Exception
  {
    mLogger.debug("queryMachtypes " + daemonMode);
    if ( !mUseDatabase )
    {
      mLogger.info("queryMachtypes !mUseDatabase");
      // a highly unlikely set of machtypes
      String machtype = new String("linux_i386");
      machtypeCollection.add(machtype);
      machtype = new String("sparc");
      machtypeCollection.add(machtype);
      machtype = new String("solaris10_x86");
      machtypeCollection.add(machtype);
    }
    else
    {
      String sql = new String("");
      
      if ( daemonMode )
      {
        sql = "select gm.gbe_value" +
              " from release_manager.release_config rc, release_manager.gbe_machtype gm" +
              " where rc.rtag_id=" + baseline + " and gm.gbe_id=rc.gbe_id";
      }
      else
      {
        sql = "select gm.gbe_value" +
              " from deployment_manager.boms b, release_manager.release_config rc, release_manager.gbe_machtype gm" +
              " where b.bom_id=" + baseline +  " and gm.gbe_id=rc.gbe_id" +
              " and rc.rtag_id=b.rtag_id_fk ";
      }

      try
      {
        CallableStatement stmt = mConnection.prepareCall(sql);
        ResultSet rset = stmt.executeQuery();
        
        while( rset.next() )
        {
          String machtype = rset.getString("gbe_value");
          
          if ( machtype != null )
          {
            machtypeCollection.add(machtype);
          }
        }
        
        rset.close();
        stmt.close();
      }
      catch ( SQLException e )
      {
        if ( mConnection == null || ( mConnection != null && !mConnection.isValid(10) ) )
        {
          mLogger.error("queryMachtypes database access error only");
          throw new SQLException();
        }
        else
        {
          mLogger.fatal("queryMachtypes show stopper:" + e.toString());
          throw new Exception("queryMachtypes show stopper");
        }
      }
    }
  }

  /**in daemon mode
   *   select p.proj_name, rt.rtag_name from release_manager.projects p, release_manager.release_tags rt
   *   where rt.rtag_id=<baseline> and p.proj_id=rt.proj_id;
   * returns a concatenation of the proj_name and rtag_name
   * in escrow mode
   *     dp.proj_name, br.branch_name, b.bom_version, b.bom_lifecycle
   *   from deployment_manager.dm_projects dp, deployment_manager.branches br, deployment_manager.boms b
   *   where b.bom_id=<baseline> and br.branch_id=b.branch_id and dp.proj_id=br.proj_id;
   * returns a concatenation of the proj_name, branch_name, bom_version and bom_lifecycle
   */
  String queryBaselineName(boolean daemonMode, int baseline) throws SQLException, Exception
  {
    mLogger.debug("queryBaselineName " + daemonMode);
    String retVal = new String();

    if ( !mUseDatabase )
    {
      mLogger.info("queryBaselineName !mUseDatabase");
      // a highly unlikely baseline name
      if (daemonMode)
      {
        retVal = "TIMBUKTU (TIM) > R7";
      }
      else
      {
        retVal = "TIMBUKTU (TIM) > R7 7.9";
      }
    }
    else
    {
      String sql = new String("");
      
      if ( daemonMode )
      {
        sql = "select p.proj_name, rt.rtag_name from release_manager.projects p, release_manager.release_tags rt where rt.rtag_id=" + baseline + " and p.proj_id=rt.proj_id";
      }
      else
      {
        sql = 
        "select dp.proj_name, br.branch_name, b.bom_version, b.bom_lifecycle from deployment_manager.dm_projects dp, deployment_manager.branches br, deployment_manager.boms b where b.bom_id=" + 
        baseline + " and br.branch_id=b.branch_id and dp.proj_id=br.proj_id";
      }
      
      try
      {
        CallableStatement stmt = mConnection.prepareCall(sql);
        ResultSet rset = stmt.executeQuery();
        
        while( rset.next() )
        {
          String proj_name = rset.getString("proj_name");
          
          if ( proj_name != null )
          {
            retVal += proj_name;
          }
          
          if ( daemonMode )
          {
            String rtag_name = rset.getString("rtag_name");
            
            if ( rtag_name != null )
            {
              retVal += " > " + rtag_name;
            }
          }
          else
          {
            String branch_name = rset.getString("branch_name");
            
            if ( branch_name != null )
            {
              retVal += " > " + branch_name;
            }
            
            String bom_version = rset.getString("bom_version");
            
            if ( bom_version != null )
            {
              retVal += " " + bom_version;
            }
            
            String bom_lifecycle = rset.getString("bom_lifecycle");
            
            if ( bom_lifecycle != null )
            {
              retVal += "." + bom_lifecycle;
            }
          }
        }
        
        rset.close();
        stmt.close();
      }
      catch ( SQLException e )
      {
        if ( mConnection == null || ( mConnection != null && !mConnection.isValid(10) ) )
        {
          mLogger.error("queryBaselineName database access error only");
          throw new SQLException();
        }
        else
        {
          mLogger.fatal("queryBaselineName show stopper");
          throw new Exception("queryBaselineName show stopper");
        }
      }
    }
    mLogger.info("queryBaselineName returned " + retVal);
    return retVal;
  }

  /**in daemon mode
   *  1 get planned package info
   *     select pl.pv_id, p.pkg_id, p.pkg_name, pv.v_ext, pv.pkg_vcs_tag, pv.change_type
   *     from release_manager.planned pl, release_manager.package_versions pv, release_manager.packages p
   *     where pl.rtag_id=<mBaseline> and pv.build_type='A' and pv.dlocked='A'
   *     and pv.pv_id=pl.pv_id and p.pkg_id=pv.pkg_id
   *     order by pl.pv_id;
   *  2 get planned package dependency info
   *     select pl.pv_id, p.pkg_name, dpv.v_ext
   *     from release_manager.planned pl, release_manager.package_versions pv, release_manager.package_dependencies pd, release_manager.package_versions dpv, release_manager.packages p
   *     where pl.rtag_id=<mBaseline> and pv.build_type='A' and pv.dlocked='A'
   *     and pv.pv_id = pl.pv_id and pd.pv_id=pl.pv_id and dpv.pv_id=pd.dpv_id and p.pkg_id=dpv.pkg_id
   *     order by pl.pv_id;
   *  3 get planned package build info
   *     select pl.pv_id, bm.bm_name, bsa.bsa_name
   *     from release_manager.planned pl, release_manager.package_versions pv, release_manager.package_build_info pbi, release_manager.build_machines bm, release_manager.build_standards_addendum bsa
   *     where pl.rtag_id=<mBaseline> and pv.build_type='A' and pv.dlocked='A'
   *     and pv.pv_id = pl.pv_id and pbi.pv_id=pv.pv_id and bm.bm_id=pbi.bm_id and bsa.bsa_id=pbi.bsa_id
   *     order by pl.pv_id;
   *  4 get planned package unit test info
   *     select pl.pv_id, tt.test_type_name
   *     from release_manager.planned pl, release_manager.package_versions pv, release_manager.unit_tests ut, release_manager.test_types tt
   *     where pl.rtag_id=<mBaseline> and pv.build_type='A' and pv.dlocked='A'
   *     and pv.pv_id = pl.pv_id and ut.pv_id=pv.pv_id and tt.test_type_id=ut.test_types_fk
   *     order by pl.pv_id;
   *  5 get planned package build failure info
   *     select pl.pv_id, u.user_email
   *     from release_manager.planned pl, release_manager.release_tags rt, release_manager.package_versions pv, release_manager.autobuild_failure af, release_manager.members_group mg, release_manager.users u
   *     where pl.rtag_id=<mBaseline> and rt.rtag_id=pl.rtag_id and pv.build_type='A' and pv.dlocked='A'
   *     and pv.pv_id = pl.pv_id and af.view_id=pl.view_id and mg.group_email_id=af.group_email_id and u.user_id=mg.user_id and af.proj_id=rt.proj_id
   *     order by pl.pv_id;
   *  6 get planned package do not ripple info
   *     select pl.pv_id
   *     from release_manager.planned pl, release_manager.package_versions pv, release_manager.do_not_ripple dnr
   *     where pl.rtag_id=<mBaseline> and pv.build_type='A' and pv.dlocked='A'
   *     and pv.pv_id = pl.pv_id and dnr.rtag_id=pl.rtag_id and dnr.pv_id=pl.pv_id
   *     order by pl.pv_id;
   *  7 get planned package advisory ripple info
   *     select pl.pv_id
   *     from release_manager.planned pl, release_manager.package_versions pv, release_manager.advisory_ripple ar
   *     where pl.rtag_id=<mBaseline> and pv.build_type='A' and pv.dlocked='A'
   *     and pv.pv_id = pl.pv_id and ar.rtag_id=pl.rtag_id and ar.pv_id=pl.pv_id
   *     order by pl.pv_id;
   *  8 get released package info
   *     select rc.pv_id, p.pkg_id, p.pkg_name, pv.pkg_version, pv.v_ext, pv.pkg_vcs_tag, pv.ripple_field
   *     pv.major_limit, pv.minor_limit, pv.patch_limit, pv.build_number_limit
   *     from release_manager.release_content rc, release_manager.package_versions pv, release_manager.packages p
   *     where rc.rtag_id=<mBaseline>
   *     and pv.pv_id = rc.pv_id and p.pkg_id = pv.pkg_id
   *     order by rc.pv_id;
   *  9 get released package dependency info
   *     select rc.pv_id, dpv.pv_id, p.pkg_name, dpv.v_ext
   *     from release_manager.release_content rc, release_manager.package_versions pv, release_manager.package_dependencies pd, release_manager.package_versions dpv, release_manager.packages p
   *     where rc.rtag_id=<mBaseline>
   *     and pv.pv_id = rc.pv_id and pd.pv_id=pv.pv_id and dpv.pv_id=pd.dpv_id and p.pkg_id=dpv.pkg_id
   *     order by rc.pv_id;
   * 10 get released package build info
   *     select rc.pv_id, bm.bm_name, bsa.bsa_name
   *     from release_manager.release_content rc, release_manager.package_versions pv, release_manager.package_build_info pbi, release_manager.build_machines bm, release_manager.build_standards_addendum bsa
   *     where rc.rtag_id=<mBaseline>
   *     and pv.pv_id = rc.pv_id and pbi.pv_id=pv.pv_id and bm.bm_id=pbi.bm_id and bsa.bsa_id=pbi.bsa_id
   *     order by rc.pv_id;
   * 11 get released package unit test info
   *     select rc.pv_id, tt.test_type_name
   *     from release_manager.release_content rc, release_manager.package_versions pv, release_manager.unit_tests ut, release_manager.test_types tt
   *     where rc.rtag_id=<mBaseline>
   *     and pv.pv_id = rc.pv_id and ut.pv_id=pv.pv_id and tt.test_type_id=ut.test_types_fk
   *     order by rc.pv_id;
   * 12 get released package build failure email info
   *     select rc.pv_id, u.user_email
   *     from release_manager.release_content rc, release_manager.release_tags rt, release_manager.package_versions pv, release_manager.autobuild_failure af, release_manager.members_group mg, release_manager.users u
   *     where rc.rtag_id=<mBaseline> and rt.rtag_id=rc.rtag_id
   *     and pv.pv_id = rc.pv_id and af.view_id=rc.base_view_id and mg.group_email_id=af.group_email_id and u.user_id=mg.user_id and af.proj_id=rt.proj_id
   *     order by rc.pv_id;
   * 13 get released package do not ripple info
   *     select rc.pv_id
   *     from release_manager.release_content rc, release_manager.package_versions pv, release_manager.do_not_ripple dnr
   *     where rc.rtag_id=<mBaseline>
   *     and pv.pv_id = rc.pv_id and dnr.rtag_id=rc.rtag_id and dnr.pv_id=rc.pv_id
   *     order by rc.pv_id;
   * 14 get released advisory ripple info
   *     select rc.pv_id
   *     from release_manager.release_content rc, release_manager.package_versions pv, release_manager.advisory_ripple ar
   *     where rc.rtag_id=<mBaseline>
   *     and pv.pv_id = rc.pv_id and ar.rtag_id=rc.rtag_id and ar.pv_id=rc.pv_id
   *     order by rc.pv_id;
   * in escrow mode
   *  1 get released product info
   *     select oc.prod_id, p.pkg_name, pv.pkg_version, pv.v_ext, pv.pkg_vcs_tag
   *     from deployment_manager.bom_contents bc, deployment_manager.operating_systems os, deployment_manager.os_contents oc, release_manager.package_versions pv, release_manager.packages p
   *     where bc.bom_id=<mBaseline> and os.node_id=bc.node_id and oc.os_id=os.os_id and pv.pv_id=oc.prod_id and p.pkg_id=pv.pkg_id
   *     order by oc.prod_id;
   *    this will generate a list of pv_ids associtaed with products
   *    many in the list will reference cots products outside the scope of a escrow build
   *  2 for each <pv_id>, call traverseDependencies( packageCollection, pv_id, false ) to traverse its set of dependencies
   *  3 for each Package, call queryBuildInfo to get released package build info
   *  
   * Supports
   *    test_type_name="Autobuild UTF"
   *    bm_name="Generic"|"Linux"|"Solaris"|"Win32"
   *    bsa_name="Debug"|"Production"|"Production and Debug"|"Java 1.4"|"Java 1.5"|"Java 1.6"
   */
  void queryPackageVersions(RippleEngine rippleEngine, 
                            Vector<Package> packageCollection, boolean daemonMode, int baseline) throws SQLException, Exception
  {
    mLogger.debug("queryPackageVersions " + daemonMode);
  
    if ( !mUseDatabase )
    {
      mLogger.info("queryPackageVersions !mUseDatabase");
      
      if (daemonMode)
      {
        /* a highly unlikely set of packages
         * planned info
         * pv_id pkg_id pkg_name                     v_ext pkg_vcs_tag                            change_type
         * 0     76     UncommonDependency           .tim  0.TIM.WIP \vob\UncommonDependency           P
         * 1     1011   DependencyMissingFromRelease .tim  1.TIM.WIP \vob\DependencyMissingFromRelease M
         * 2     34     CommonDependency             .tim  2.TIM.WIP \vob\CommonDependency             M
         * 3     908    SolarisCentricProduct        .tim  3.TIM.WIP \vob\SolarisCentricProduct        N
         * 4     6      GenericProduct               .tim  4.TIM.WIP \vob\GenericProduct               P
         * 5     11     Product                      .tim  5.TIM.WIP \vob\Product                      M
         * 6     113    UnfinishedProduct            .tim  6.TIM.WIP \vob\UnfinishedProduct            M
         * 25    45     Banana                       .tim  B.TIM.WIP \vob\Banana                       M
         */
         if ( mConnectionString.compareTo("iteration1") == 0 )
         {
           Package p = new Package(0, "UncommonDependency", ".tim", "UncommonDependency.tim", "CC::/vob/UncommonDependency::0.TIM.WIP", 'P', 'b', "1.0.0000");
           p.mPid = 76;
           p.mDirectlyPlanned = true;
           packageCollection.add(p);
         }
         
         Package p = new Package(1, "DependencyMissingFromRelease", ".tim", "DependencyMissingFromRelease.tim", "CC::/vob/DependencyMissingFromRelease::1.TIM.WIP", 'M', 'b', "1.0.0000");
         p.mPid = 1011;
         p.mDirectlyPlanned = true;
         packageCollection.add(p);
         
         if ( mConnectionString.compareTo("iteration1") == 0 || mConnectionString.compareTo("iteration2") == 0 )
         {
           p = new Package(2, "CommonDependency", ".tim", "CommonDependency.tim", "CC::/vob/CommonDependency::2.TIM.WIP", 'M', 'b', "1.0.0000");
           p.mPid = 34;
           p.mDirectlyPlanned = true;
           packageCollection.add(p);
         }
         
         if ( mConnectionString.compareTo("iteration1") == 0 
           || mConnectionString.compareTo("iteration2") == 0
           || mConnectionString.compareTo("iteration3") == 0 )
         {
           p = new Package(3, "SolarisCentricProduct", ".tim", "SolarisCentricProduct.tim", "CC::/vob/SolarisCentricProduct::3.TIM.WIP", 'N', 'b', "1.0.0000");
           p.mPid = 908;
           p.mDirectlyPlanned = true;
           packageCollection.add(p);
         }
         
         if ( mConnectionString.compareTo("iteration1") == 0 
           || mConnectionString.compareTo("iteration2") == 0
           || mConnectionString.compareTo("iteration3") == 0
           || mConnectionString.compareTo("iteration4") == 0 )
         {
           p = new Package(4, "GenericProduct", ".tim", "GenericProduct.tim", "CC::/vob/GenericProduct::4.TIM.WIP", 'P', 'b', "1.0.0000");
           p.mPid = 6;
           p.mDirectlyPlanned = true;
           packageCollection.add(p);
         }
         
         if ( mConnectionString.compareTo("iteration1") == 0 
           || mConnectionString.compareTo("iteration2") == 0
           || mConnectionString.compareTo("iteration3") == 0
           || mConnectionString.compareTo("iteration4") == 0
           || mConnectionString.compareTo("iteration5") == 0 )
         {
           p = new Package(5, "Product", ".tim", "Product.tim", "CC::/vob/Product::5.TIM.WIP", 'M', 'b', "1.0.0000");
           p.mPid = 11;
           p.mDirectlyPlanned = true;
           packageCollection.add(p);
         }
        
         p = new Package(6, "UnfinishedProduct", ".tim", "UnfinishedProduct.tim", "CC::/vob/UnfinishedProduct::6.TIM.WIP", 'M', 'b', "1.0.0000");
         p.mPid = 113;
         p.mDirectlyPlanned = true;
         packageCollection.add(p);
         
         if ( mConnectionString.compareTo("iteration1") == 0 )
         {
           p = new Package(25, "Banana", ".tim", "Banana.tim", "CC::B.TIM.WIP/vob/Banana", 'M', 'b', "1.0.0000");
           p.mPid = 45;
           p.mDirectlyPlanned = true;
           packageCollection.add(p);
         }
         
        /* planned dependencies
         * pv_id pkg_name                     v_ext
         * 1     NotInTheRelease              .cots
         * 2     CotsWithFunnyVersion         .cots
         * 2     UncommonDependency           .tim
         * 3     CommonDependency             .tim
         * 4     CommonDependency             .tim
         * 5     UncommonDependency           .tim
         * 25    Car                          .tim
         */
         p = findPackage(1, packageCollection);
         p.mDependencyCollection.add("NotInTheRelease.cots");
         p.mDependencyIDCollection.add(-1);
         
         if ( mConnectionString.compareTo("iteration1") == 0 || mConnectionString.compareTo("iteration2") == 0 )
         {
           p = findPackage(2, packageCollection);
           p.mDependencyCollection.add("CotsWithFunnyVersion.cots");
           p.mDependencyIDCollection.add(-1);
           p.mDependencyCollection.add("UncommonDependency.tim");
           p.mDependencyIDCollection.add(-1);
         }
         
         if ( mConnectionString.compareTo("iteration1") == 0 
           || mConnectionString.compareTo("iteration2") == 0
           || mConnectionString.compareTo("iteration3") == 0 )
         {
           p = findPackage(3, packageCollection);
           p.mDependencyCollection.add("CommonDependency.tim");
           p.mDependencyIDCollection.add(-1);
         }
         
         if ( mConnectionString.compareTo("iteration1") == 0 
           || mConnectionString.compareTo("iteration2") == 0
           || mConnectionString.compareTo("iteration3") == 0
           || mConnectionString.compareTo("iteration4") == 0 )
         {
           p = findPackage(4, packageCollection);
           p.mDependencyCollection.add("CommonDependency.tim");
           p.mDependencyIDCollection.add(-1);
         }
         
         if ( mConnectionString.compareTo("iteration1") == 0 
           || mConnectionString.compareTo("iteration2") == 0
           || mConnectionString.compareTo("iteration3") == 0
           || mConnectionString.compareTo("iteration4") == 0
           || mConnectionString.compareTo("iteration5") == 0 )
         {
           p = findPackage(5, packageCollection);
           p.mDependencyCollection.add("UncommonDependency.tim");
           p.mDependencyIDCollection.add(-1);
         }
         
         if ( mConnectionString.compareTo("iteration1") == 0 )
         {
           p = findPackage(25, packageCollection);
           p.mDependencyCollection.add("Car.tim");
           p.mDependencyIDCollection.add(-1);
         }
         
        /* planned build info
         * pv_id bm_name bsa_name
         * 0     Linux   Java 1.6
         * 1     Linux   Debug
         * 2     Linux   Debug
         * 2     Solaris Production
         * 2     Win32   Production and Debug
         * 3     Solaris Java 1.4
         * 4     Generic Java 1.5
         * 5     Linux   Java 1.6
         * 5     Win32   Java 1.6
         * 25    Linux   Java 1.6
         */
         if ( mConnectionString.compareTo("iteration1") == 0 )
         {
           p = findPackage(0, packageCollection);
           BuildStandard bs = new BuildStandard(rippleEngine);
           bs.setLinux();
           bs.set1_6();
           p.mBuildStandardCollection.add(bs);
         }
         
         p = findPackage(1, packageCollection);
         BuildStandard bs = new BuildStandard(rippleEngine);
         bs.setLinux();
         bs.setDebug();
         p.mBuildStandardCollection.add(bs);
         
         if ( mConnectionString.compareTo("iteration1") == 0 || mConnectionString.compareTo("iteration2") == 0 )
         {
           p = findPackage(2, packageCollection);
           bs = new BuildStandard(rippleEngine);
           bs.setLinux();
           bs.setDebug();
           p.mBuildStandardCollection.add(bs);
           bs = new BuildStandard(rippleEngine);
           bs.setSolaris();
           bs.setProduction();
           p.mBuildStandardCollection.add(bs);
           bs = new BuildStandard(rippleEngine);
           bs.setWin32();
           bs.setAll();
           p.mBuildStandardCollection.add(bs);
         }
         
         if ( mConnectionString.compareTo("iteration1") == 0 
           || mConnectionString.compareTo("iteration2") == 0
           || mConnectionString.compareTo("iteration3") == 0 )
         {
           p = findPackage(3, packageCollection);
           bs = new BuildStandard(rippleEngine);
           bs.setSolaris();
           bs.set1_4();
           p.mBuildStandardCollection.add(bs);
         }
         
         if ( mConnectionString.compareTo("iteration1") == 0 
           || mConnectionString.compareTo("iteration2") == 0
           || mConnectionString.compareTo("iteration3") == 0
           || mConnectionString.compareTo("iteration4") == 0 )
         {
           p = findPackage(4, packageCollection);
           bs = new BuildStandard(rippleEngine);
           bs.setGeneric();
           bs.set1_5();
           p.mBuildStandardCollection.add(bs);
         }
         
         if ( mConnectionString.compareTo("iteration1") == 0 
           || mConnectionString.compareTo("iteration2") == 0
           || mConnectionString.compareTo("iteration3") == 0
           || mConnectionString.compareTo("iteration4") == 0
           || mConnectionString.compareTo("iteration5") == 0 )
         {
           p = findPackage(5, packageCollection);
           bs = new BuildStandard(rippleEngine);
           bs.setLinux();
           bs.set1_6();
           p.mBuildStandardCollection.add(bs);
           bs = new BuildStandard(rippleEngine);
           bs.setWin32();
           bs.set1_6();
           p.mBuildStandardCollection.add(bs);
         }
         
         if ( mConnectionString.compareTo("iteration1") == 0 )
         {
           p = findPackage(25, packageCollection);
           bs = new BuildStandard(rippleEngine);
           bs.setLinux();
           bs.set1_6();
           p.mBuildStandardCollection.add(bs);
         }

         /* planned unit test info
         * pv_id test_type_name
         * 2     Manual Test
         * 2     Interactive Test
         * 2     Integration Test
         * 5     Autobuild UTF
         */
         if ( mConnectionString.compareTo("iteration1") == 0 
           || mConnectionString.compareTo("iteration2") == 0
           || mConnectionString.compareTo("iteration3") == 0
           || mConnectionString.compareTo("iteration4") == 0
           || mConnectionString.compareTo("iteration5") == 0 )
         {
           p = findPackage(5, packageCollection);
           p.mHasAutomatedUnitTests = true;
         }
         
        /* planned build failure info
         * pv_id user_email
         * 3     jimmyfishcake@erggroup.com
         * 3     rayhaddock@erggroup.com
         * 5     timbutdim@erggroup.com
         */
         if ( mConnectionString.compareTo("iteration1") == 0 
           || mConnectionString.compareTo("iteration2") == 0
           || mConnectionString.compareTo("iteration3") == 0 )
         {
           p = findPackage(3, packageCollection);
           p.addEmail("jimmyfishcake@erggroup.com");
           p.addEmail("rayhaddock@erggroup.com");
         }
         
         if ( mConnectionString.compareTo("iteration1") == 0 
           || mConnectionString.compareTo("iteration2") == 0
           || mConnectionString.compareTo("iteration3") == 0
           || mConnectionString.compareTo("iteration4") == 0
           || mConnectionString.compareTo("iteration5") == 0 )
         {
           p = findPackage(5, packageCollection);
           p.addEmail("timbutdim@erggroup.com");
         }
         
        /* planned advisory ripple info
         * pv_id
         * 0
         */
         if ( mConnectionString.compareTo("iteration1") == 0 )
         {
           p = findPackage(0, packageCollection);
           p.mAdvisoryRipple = true;
         }
         
        /* released info
         * pv_id pkg_id pkg_name                     pkg_version      v_ext pkg_vcs_tag                                                    ripple_field
         * 7     8      CotsWithFunnyVersion         hoopla2_x.cots   .cots CotsWithFunnyVersion_hoopla2_x.cots \vob\CotsWithFunnyVersion
         * 8     17     NotInAnyWayReproducible      1.0.0.tim        .tim  NA                                  NA
         * 9     34     CommonDependency             1.0.0000.tim     .tim  CommonDependency_1.0.0000.tim       \vob\CommonDependency
         * 10    908    SolarisCentricProduct        1.0.0000.tim     .tim  SolarisCentricProduct_1.0.0000.tim  \vob\SolarisCentricProduct m
         * 11    16     LinuxCentricProduct          1.0.0000.tim     .tim  LinuxCentricProduct_1.0.0000.tim    \vob\LinuxCentricProduct
         * 12    312    Win32CentricProduct          1.0.0000.tim     .tim  Win32CentricProduct_1.0.0000.tim    \vob\Win32CentricProduct
         * 13    6      GenericProduct               1.0.0000.tim     .tim  GenericProduct_1.0.0000.tim         \vob\ToBeMovedFromHere     M
         * 14    81     AdvisoryDependency           1.0.0000.tim     .tim  AdvisoryDependency_1.0.0000.tim     \vob\AdvisoryDependency
         * 15    1      MergedProduct                1.0.0000.tim     .tim  MergedProduct_1.0.0000.tim          \vob\MergedProduct         m
         * 22    45     Banana                       1.1.0000.tim     .tim  Banana_1.1.0000.tim                 \vob\Banana
         * 23    18     Aardvark                     1.1.1000.tim     .tim  Aardvark_1.1.1000.tim               \vob\Aardvark
         * 24    227    Car                          1.0.10000.tim    .tim  Car_1.0.10000.tim                   \vob\Car
         */
         if ( mConnectionString.compareTo("iteration1") != 0 )
         {
           p = new Package(0, "UncommonDependency", "0.0.1000.tim", ".tim", "UncommonDependency.tim", "CC::/vob/UncommonDependency::UncommonDependency_0.0.1000.tim", 'x');
           p.mPid = 76;
           Integer pv_id = new Integer(0);
           rippleEngine.mReleasedPvIDCollection.add(pv_id);
           Package plannedPackage = findPackage(p.mAlias, packageCollection);
           
           if ( plannedPackage == NULL_PACKAGE )
           {
             packageCollection.add(p);
           }
           else
           {
             plannedPackage.mVersion = "0.0.1000";
           }
         }
         
         if ( mConnectionString.compareTo("iteration1") != 0 && mConnectionString.compareTo("iteration2") != 0 )
         {
           p = new Package(2, "CommonDependency", "2.0.0000.tim", ".tim", "CommonDependency.tim", "CC::/vob/CommonDependency::CommonDependency_2.0.0000.tim", 'x');
           p.mPid = 34;
           Integer pv_id = new Integer(2);
           rippleEngine.mReleasedPvIDCollection.add(pv_id);
           Package plannedPackage = findPackage(p.mAlias, packageCollection);
           
           if ( plannedPackage == NULL_PACKAGE )
           {
             packageCollection.add(p);
           }
           else
           {
             plannedPackage.mVersion = "2.0.0000";
           }
         }

         if ( mConnectionString.compareTo("iteration1") != 0 
           && mConnectionString.compareTo("iteration2") != 0
           && mConnectionString.compareTo("iteration3") != 0 )
         {
           p = new Package(3, "SolarisCentricProduct", "1.1.0000.tim", ".tim", "SolarisCentricProduct.tim", "CC::/vob/SolarisCentricProduct::SolarisCentricProduct_1.1.0000.tim", 'm');
           p.mPid = 908;
           Integer pv_id = new Integer(3);
           rippleEngine.mReleasedPvIDCollection.add(pv_id);
           Package plannedPackage = findPackage(p.mAlias, packageCollection);
           
           if ( plannedPackage == NULL_PACKAGE )
           {
             packageCollection.add(p);
           }
           else
           {
             plannedPackage.mVersion = "1.1.0000";
           }
         }
        
         if ( mConnectionString.compareTo("iteration1") != 0 
           && mConnectionString.compareTo("iteration2") != 0
           && mConnectionString.compareTo("iteration3") != 0
           && mConnectionString.compareTo("iteration4") != 0 )
         {
           p = new Package(4, "GenericProduct", "1.0.1000.tim", ".tim", "GenericProduct.tim", "CC::/vob/GenericProduct::GenericProduct_1.0.1000.tim", 'M');
           p.mPid = 6;
           Integer pv_id = new Integer(4);
           rippleEngine.mReleasedPvIDCollection.add(pv_id);
           Package plannedPackage = findPackage(p.mAlias, packageCollection);
           
           if ( plannedPackage == NULL_PACKAGE )
           {
             packageCollection.add(p);
           }
           else
           {
             plannedPackage.mVersion = "1.0.1000";
           }
         }
         
         if ( mConnectionString.compareTo("iteration1") != 0 
           && mConnectionString.compareTo("iteration2") != 0
           && mConnectionString.compareTo("iteration3") != 0
           && mConnectionString.compareTo("iteration4") != 0
           && mConnectionString.compareTo("iteration5") != 0 )
         {
           p = new Package(5, "Product", "1.0.0000.tim", ".tim", "Product.tim", "CC::/vob/Product::Product_1.0.0000.tim", 'M');
           p.mPid = 11;
           Integer pv_id = new Integer(5);
           rippleEngine.mReleasedPvIDCollection.add(pv_id);
           Package plannedPackage = findPackage(p.mAlias, packageCollection);
           
           if ( plannedPackage == NULL_PACKAGE )
           {
             packageCollection.add(p);
           }
           else
           {
             plannedPackage.mVersion = "1.0.0000";
           }
         }
        
         p = new Package(7, "CotsWithFunnyVersion", "hoopla2_x.cots", ".cots", "CotsWithFunnyVersion.cots", "CC::/vob/CotsWithFunnyVersion::CotsWithFunnyVersion_hoopla2_x", 'x');
         p.mPid = 8;
         Integer pv_id = new Integer(7);
         rippleEngine.mReleasedPvIDCollection.add(pv_id);
         Package plannedPackage = findPackage(p.mAlias, packageCollection);
         
         if ( plannedPackage == NULL_PACKAGE )
         {
           packageCollection.add(p);
         }
         else
         {
           plannedPackage.mVersion = "hoopla2_x";
         }
         
         p = new Package(8, "NotInAnyWayReproducible", "1.0.0.tim", ".tim", "NotInAnyWayReproducible.tim", "CC::NA::NA", 'x');
         p.mPid = 17;
         pv_id = new Integer(8);
         rippleEngine.mReleasedPvIDCollection.add(pv_id);
         plannedPackage = findPackage(p.mAlias, packageCollection);
        
         if ( plannedPackage == NULL_PACKAGE )
         {
           packageCollection.add(p);
         }
         else
         {
           plannedPackage.mVersion = "1.0.0";
         }

         if ( mConnectionString.compareTo("iteration1") == 0 || mConnectionString.compareTo("iteration2") == 0 )
         {
           p = new Package(9, "CommonDependency", "1.0.0000.tim", ".tim", "CommonDependency.tim", "CC::/vob/CommonDependency::CommonDependency_1.0.0000.tim", 'x');
           p.mPid = 34;
           pv_id = new Integer(9);
           rippleEngine.mReleasedPvIDCollection.add(pv_id);
           plannedPackage = findPackage(p.mAlias, packageCollection);
          
           if ( plannedPackage == NULL_PACKAGE )
           {
             packageCollection.add(p);
           }
           else
           {
             plannedPackage.mVersion = "1.0.0000";
           }
         }
        
         if ( mConnectionString.compareTo("iteration1") == 0 
           || mConnectionString.compareTo("iteration2") == 0
           || mConnectionString.compareTo("iteration3") == 0 )
         {
           p = new Package(10, "SolarisCentricProduct", "1.0.0000.tim", ".tim", "SolarisCentricProduct.tim", "CC::/vob/SolarisCentricProduct::SolarisCentricProduct_1.0.0000.tim", 'm');
           p.mPid = 908;
           pv_id = new Integer(10);
           rippleEngine.mReleasedPvIDCollection.add(pv_id);
           plannedPackage = findPackage(p.mAlias, packageCollection);
          
           if ( plannedPackage == NULL_PACKAGE )
           {
             packageCollection.add(p);
           }
           else
           {
             plannedPackage.mVersion = "1.0.0000";
           }
         }
        
         p = new Package(11, "LinuxCentricProduct", "1.0.0000.tim", ".tim", "LinuxCentricProduct.tim", "CC::/vob/LinuxCentricProduct::LinuxCentricProduct_1.0.0000.tim", 'x');
         p.mPid = 16;
         pv_id = new Integer(11);
         rippleEngine.mReleasedPvIDCollection.add(pv_id);
         plannedPackage = findPackage(p.mAlias, packageCollection);
        
         if ( plannedPackage == NULL_PACKAGE )
         {
           packageCollection.add(p);
         }
         else
         {
           plannedPackage.mVersion = "1.0.0000";
         }
        
         p = new Package(12, "Win32CentricProduct", "1.0.0000.tim", ".tim", "Win32CentricProduct.tim", "CC::/vob/Win32CentricProduct::Win32CentricProduct_1.0.0000.tim", 'x');
         p.mPid = 312;
         pv_id = new Integer(12);
         rippleEngine.mReleasedPvIDCollection.add(pv_id);
         plannedPackage = findPackage(p.mAlias, packageCollection);
        
         if ( plannedPackage == NULL_PACKAGE )
         {
           packageCollection.add(p);
         }
         else
         {
           plannedPackage.mVersion = "1.0.0000";
         }
        
         if ( mConnectionString.compareTo("iteration1") == 0 
           || mConnectionString.compareTo("iteration2") == 0
           || mConnectionString.compareTo("iteration3") == 0
           || mConnectionString.compareTo("iteration4") == 0 )
         {
           p = new Package(13, "GenericProduct", "1.0.0000.tim", ".tim", "GenericProduct.tim", "CC::/vob/ToBeMovedFromHere::GenericProduct_1.0.0000.tim", 'M');
           p.mPid = 6;
           pv_id = new Integer(13);
           rippleEngine.mReleasedPvIDCollection.add(pv_id);
           plannedPackage = findPackage(p.mAlias, packageCollection);
         }
        
         if ( plannedPackage == NULL_PACKAGE )
         {
           packageCollection.add(p);
         }
         else
         {
           plannedPackage.mVersion = "1.0.0000";
         }
        
         p = new Package(14, "AdvisoryDependency", "1.0.0000.tim", ".tim", "AdvisoryDependency.tim", "CC::/vob/AdvisoryDependency::AdvisoryDependency_1.0.0000.tim", 'x');
         p.mPid = 81;
         pv_id = new Integer(14);
         rippleEngine.mReleasedPvIDCollection.add(pv_id);
         plannedPackage = findPackage(p.mAlias, packageCollection);
        
         if ( plannedPackage == NULL_PACKAGE )
         {
           packageCollection.add(p);
         }
         else
         {
           plannedPackage.mVersion = "1.0.0000";
         }
         
         if ( mConnectionString.compareTo("iteration1") == 0 
           || mConnectionString.compareTo("iteration2") == 0
           || mConnectionString.compareTo("iteration3") == 0
           || mConnectionString.compareTo("iteration4") == 0
           || mConnectionString.compareTo("iteration5") == 0
           || mConnectionString.compareTo("iteration6") == 0 )
         {
           p = new Package(15, "MergedProduct", "1.0.0000.tim", ".tim", "MergedProduct.tim", "CC::/vob/MergedProduct::MergedProduct_1.0.0000.tim", 'm');
           p.mPid = 1;
           pv_id = new Integer(15);
           rippleEngine.mReleasedPvIDCollection.add(pv_id);
           plannedPackage = findPackage(p.mAlias, packageCollection);
         }
         else
         {
           p = new Package(16, "MergedProduct", "1.0.0000.tim", ".tim", "MergedProduct.tim", "CC::/vob/MergedProduct::MergedProduct_1.0.0000.tim", 'm');
           p.mPid = 1;
           pv_id = new Integer(16);
           rippleEngine.mReleasedPvIDCollection.add(pv_id);
           plannedPackage = findPackage(p.mAlias, packageCollection);
         }
        
         if ( plannedPackage == NULL_PACKAGE )
         {
           packageCollection.add(p);
         }
         else
         {
           plannedPackage.mVersion = "1.0.0000";
         }
         
         if ( mConnectionString.compareTo("iteration1") == 0 )
         {
           p = new Package(22, "Banana", "1.1.0000.tim", ".tim", "Banana.tim", "CC::/vob/Banana::Banana_1.1.0000.tim", 'x');
           p.mPid = 45;
           pv_id = new Integer(22);
           rippleEngine.mReleasedPvIDCollection.add(pv_id);
           plannedPackage = findPackage(p.mAlias, packageCollection);
          
           if ( plannedPackage == NULL_PACKAGE )
           {
             packageCollection.add(p);
           }
           else
           {
             plannedPackage.mVersion = "1.1.0000";
           }
  
           p = new Package(23, "Aardvark", "1.1.1000.tim", ".tim", "Aardvark.tim", "CC::/vob/Aardvark::Aardvark_1.1.1000.tim", 'x');
           p.mPid = 18;
           pv_id = new Integer(18);
           rippleEngine.mReleasedPvIDCollection.add(pv_id);
           plannedPackage = findPackage(p.mAlias, packageCollection);
          
           if ( plannedPackage == NULL_PACKAGE )
           {
             packageCollection.add(p);
           }
           else
           {
             plannedPackage.mVersion = "1.1.1000";
           }
           
           p = new Package(24, "Car", "1.0.10000.tim", ".tim", "Car.tim", "CC::/vob/Car::Car_1.0.10000.tim", 'x');
           p.mPid = 227;
           pv_id = new Integer(227);
           rippleEngine.mReleasedPvIDCollection.add(pv_id);
           plannedPackage = findPackage(p.mAlias, packageCollection);
          
           if ( plannedPackage == NULL_PACKAGE )
           {
             packageCollection.add(p);
           }
           else
           {
             plannedPackage.mVersion = "1.0.10000";
           }
         }
         
         /* released dependencies
         * pv_id dpv_id pkg_name                     v_ext
         * 8     9      CommonDependency             .tim
         * 9     7      CotsWithFunnyVersion         .cots
         * 10    9      CommonDependency             .tim
         * 11    44     AdvisoryDependency           .tim
         * 13    9      CommonDependency             .tim
         * 15    99     CommonDependency             .tim
         * 23    22     Banana                       .tim
         * 24    23     Aardvark                     .tim
         */
         if ( mConnectionString.compareTo("iteration1") != 0 && mConnectionString.compareTo("iteration2") != 0 )
         {
           p = findPackage(2, packageCollection);
           p.mDependencyCollection.add("CotsWithFunnyVersion.cots");
           p.mDependencyIDCollection.add(7);
           p.mDependencyCollection.add("UncommonDependency.tim");
           p.mDependencyIDCollection.add(0);
         }
         
         if ( mConnectionString.compareTo("iteration1") != 0 
           && mConnectionString.compareTo("iteration2") != 0
           && mConnectionString.compareTo("iteration3") != 0 )
         {
           p = findPackage(3, packageCollection);
           p.mDependencyCollection.add("CommonDependency.tim");
           p.mDependencyIDCollection.add(2);
         }

         if ( mConnectionString.compareTo("iteration1") != 0 
           && mConnectionString.compareTo("iteration2") != 0
           && mConnectionString.compareTo("iteration3") != 0
           && mConnectionString.compareTo("iteration4") != 0 )
         {
           p = findPackage(4, packageCollection);
           p.mDependencyCollection.add("CommonDependency.tim");
           p.mDependencyIDCollection.add(2);
         }
         
         if ( mConnectionString.compareTo("iteration1") != 0 
           && mConnectionString.compareTo("iteration2") != 0
           && mConnectionString.compareTo("iteration3") != 0
           && mConnectionString.compareTo("iteration4") != 0
           && mConnectionString.compareTo("iteration5") != 0 )
         {
           p = findPackage(5, packageCollection);
           p.mDependencyCollection.add("UncommonDependency.tim");
           p.mDependencyIDCollection.add(0);
         }

         p = findPackage(8, packageCollection);
         p.mDependencyCollection.add("CommonDependency.tim");
         p.mDependencyIDCollection.add(9);
         
         if ( mConnectionString.compareTo("iteration1") == 0 || mConnectionString.compareTo("iteration2") == 0 )
         {
           p = findPackage(9, packageCollection);
           p.mDependencyCollection.add("CotsWithFunnyVersion.cots");
           p.mDependencyIDCollection.add(7);
         }
         
         if ( mConnectionString.compareTo("iteration1") == 0 
           || mConnectionString.compareTo("iteration2") == 0
           || mConnectionString.compareTo("iteration3") == 0 )
         {
           p = findPackage(10, packageCollection);
           p.mDependencyCollection.add("CommonDependency.tim");
           p.mDependencyIDCollection.add(9);
         }
         
         p = findPackage(11, packageCollection);
         p.mDependencyCollection.add("AdvisoryDependency.tim");
         p.mDependencyIDCollection.add(44);
         
         if ( mConnectionString.compareTo("iteration1") == 0 
           || mConnectionString.compareTo("iteration2") == 0
           || mConnectionString.compareTo("iteration3") == 0
           || mConnectionString.compareTo("iteration4") == 0 )
         {
           p = findPackage(13, packageCollection);
           p.mDependencyCollection.add("CommonDependency.tim");
           p.mDependencyIDCollection.add(9);
         }
         
         if ( mConnectionString.compareTo("iteration1") == 0 
           || mConnectionString.compareTo("iteration2") == 0
           || mConnectionString.compareTo("iteration3") == 0
           || mConnectionString.compareTo("iteration4") == 0
           || mConnectionString.compareTo("iteration5") == 0
           || mConnectionString.compareTo("iteration6") == 0 )
         {
           p = findPackage(15, packageCollection);
           p.mDependencyCollection.add("CommonDependency.tim");
           p.mDependencyIDCollection.add(99);
         }
         else
         {
           p = findPackage(16, packageCollection);
           p.mDependencyCollection.add("CommonDependency.tim");
           p.mDependencyIDCollection.add(2);
         }
         
         if ( mConnectionString.compareTo("iteration1") == 0 )
         {
           p = findPackage(23, packageCollection);
           p.mDependencyCollection.add("Banana.tim");
           p.mDependencyIDCollection.add(22);
  
           p = findPackage(24, packageCollection);
           p.mDependencyCollection.add("Aardvark.tim");
           p.mDependencyIDCollection.add(23);
         }

        /* released build info
         * pv_id bm_name bsa_name
         * 7     Solaris Debug
         * 9     Linux   Debug
         * 9     Solaris Debug
         * 9     Win32   Production
         * 10    Solaris Java 1.4
         * 11    Linux   Production and Debug
         * 12    Win32   Java 1.6
         * 13    Generic Java 1.4
         * 14    Linux   Debug
         * 15    Linux   Debug
         * 22    Linux   Java 1.6
         * 23    Linux   Java 1.6
         * 24    Linux   Java 1.6
         */
         if ( mConnectionString.compareTo("iteration1") != 0 )
         {
           p = findPackage(0, packageCollection);
           bs = new BuildStandard(rippleEngine);
           bs.setLinux();
           bs.set1_6();
           p.mBuildStandardCollection.add(bs);
         }
         
         if ( mConnectionString.compareTo("iteration1") != 0 && mConnectionString.compareTo("iteration2") != 0 )
         {
           p = findPackage(2, packageCollection);
           bs = new BuildStandard(rippleEngine);
           bs.setLinux();
           bs.setDebug();
           p.mBuildStandardCollection.add(bs);
           bs = new BuildStandard(rippleEngine);
           bs.setSolaris();
           bs.setProduction();
           p.mBuildStandardCollection.add(bs);
           bs = new BuildStandard(rippleEngine);
           bs.setWin32();
           bs.setAll();
           p.mBuildStandardCollection.add(bs);
         }
         
         if ( mConnectionString.compareTo("iteration1") != 0 
           && mConnectionString.compareTo("iteration2") != 0
           && mConnectionString.compareTo("iteration3") != 0 )
         {
           p = findPackage(3, packageCollection);
           bs = new BuildStandard(rippleEngine);
           bs.setSolaris();
           bs.set1_4();
           p.mBuildStandardCollection.add(bs);
         }

         if ( mConnectionString.compareTo("iteration1") != 0 
           && mConnectionString.compareTo("iteration2") != 0
           && mConnectionString.compareTo("iteration3") != 0
           && mConnectionString.compareTo("iteration4") != 0 )
         {
           p = findPackage(4, packageCollection);
           bs = new BuildStandard(rippleEngine);
           bs.setGeneric();
           bs.set1_5();
           p.mBuildStandardCollection.add(bs);
         }
        
         if ( mConnectionString.compareTo("iteration1") != 0 
           && mConnectionString.compareTo("iteration2") != 0
           && mConnectionString.compareTo("iteration3") != 0
           && mConnectionString.compareTo("iteration4") != 0
           && mConnectionString.compareTo("iteration5") != 0 )
         {
           p = findPackage(5, packageCollection);
           bs = new BuildStandard(rippleEngine);
           bs.setLinux();
           bs.set1_6();
           p.mBuildStandardCollection.add(bs);
           bs = new BuildStandard(rippleEngine);
           bs.setWin32();
           bs.set1_6();
           p.mBuildStandardCollection.add(bs);
         }

         p = findPackage(7, packageCollection);
         bs = new BuildStandard(rippleEngine);
         bs.setSolaris();
         bs.setDebug();
         p.mBuildStandardCollection.add(bs);
         
         if ( mConnectionString.compareTo("iteration1") == 0 || mConnectionString.compareTo("iteration2") == 0 )
         {
           p = findPackage(9, packageCollection);
           bs = new BuildStandard(rippleEngine);
           bs.setLinux();
           bs.setDebug();
           p.mBuildStandardCollection.add(bs);
           bs = new BuildStandard(rippleEngine);
           bs.setSolaris();
           bs.setDebug();
           p.mBuildStandardCollection.add(bs);
           bs = new BuildStandard(rippleEngine);
           bs.setWin32();
           bs.setProduction();
           p.mBuildStandardCollection.add(bs);
         }
         
         if ( mConnectionString.compareTo("iteration1") == 0 
           || mConnectionString.compareTo("iteration2") == 0
           || mConnectionString.compareTo("iteration3") == 0 )
         {
           p = findPackage(10, packageCollection);
           bs = new BuildStandard(rippleEngine);
           bs.setSolaris();
           bs.set1_4();
           p.mBuildStandardCollection.add(bs);
         }
         
         p = findPackage(11, packageCollection);
         bs = new BuildStandard(rippleEngine);
         bs.setLinux();
         bs.setAll();
         p.mBuildStandardCollection.add(bs);

         p = findPackage(12, packageCollection);
         bs = new BuildStandard(rippleEngine);
         bs.setWin32();
         bs.set1_6();
         p.mBuildStandardCollection.add(bs);

         if ( mConnectionString.compareTo("iteration1") == 0 
           || mConnectionString.compareTo("iteration2") == 0
           || mConnectionString.compareTo("iteration3") == 0
           || mConnectionString.compareTo("iteration4") == 0 )
         {
           p = findPackage(13, packageCollection);
           bs = new BuildStandard(rippleEngine);
           bs.setGeneric();
           bs.set1_4();
           p.mBuildStandardCollection.add(bs);
         }

         p = findPackage(14, packageCollection);
         bs = new BuildStandard(rippleEngine);
         bs.setLinux();
         bs.setDebug();
         p.mBuildStandardCollection.add(bs);
         
         if ( mConnectionString.compareTo("iteration1") == 0 
           || mConnectionString.compareTo("iteration2") == 0
           || mConnectionString.compareTo("iteration3") == 0
           || mConnectionString.compareTo("iteration4") == 0
           || mConnectionString.compareTo("iteration5") == 0
           || mConnectionString.compareTo("iteration6") == 0 )
         {
           p = findPackage(15, packageCollection);
           bs = new BuildStandard(rippleEngine);
           bs.setLinux();
           bs.setDebug();
           p.mBuildStandardCollection.add(bs);
         }
         else
         {
           p = findPackage(16, packageCollection);
           bs = new BuildStandard(rippleEngine);
           bs.setLinux();
           bs.setDebug();
           p.mBuildStandardCollection.add(bs);
         }        
 
         if ( mConnectionString.compareTo("iteration1") == 0 )
         {
           p = findPackage(22, packageCollection);
           bs = new BuildStandard(rippleEngine);
           bs.setLinux();
           bs.set1_6();
           p.mBuildStandardCollection.add(bs);
  
           p = findPackage(23, packageCollection);
           bs = new BuildStandard(rippleEngine);
           bs.setLinux();
           bs.set1_6();
           p.mBuildStandardCollection.add(bs);
  
           p = findPackage(24, packageCollection);
           bs = new BuildStandard(rippleEngine);
           bs.setLinux();
           bs.set1_6();
           p.mBuildStandardCollection.add(bs);
         }

         /* released package unit test info
         * pv_id tt.test_type_name
         * 9     Manual Test
         * 9     Interactive Test
         * 9     Integration Test
         * 11    Autobuild UTF
         */
         if ( mConnectionString.compareTo("iteration1") != 0 
           && mConnectionString.compareTo("iteration2") != 0
           && mConnectionString.compareTo("iteration3") != 0
           && mConnectionString.compareTo("iteration4") != 0
           && mConnectionString.compareTo("iteration5") != 0 )
         {
           p = findPackage(5, packageCollection);
           p.mHasAutomatedUnitTests = true;
         }

         p = findPackage(11, packageCollection);
         p.mHasAutomatedUnitTests = true;
         
        /* released build failure email info
         * pv_id user_email
         * 10    jimmyfishcake@erggroup.com
         */
         if ( mConnectionString.compareTo("iteration1") != 0 
           && mConnectionString.compareTo("iteration2") != 0
           && mConnectionString.compareTo("iteration3") != 0 )
         {
           p = findPackage(3, packageCollection);
           p.addEmail("jimmyfishcake@erggroup.com");
           p.addEmail("rayhaddock@erggroup.com");
         }

         if ( mConnectionString.compareTo("iteration1") != 0 
           && mConnectionString.compareTo("iteration2") != 0
           && mConnectionString.compareTo("iteration3") != 0
           && mConnectionString.compareTo("iteration4") != 0
           && mConnectionString.compareTo("iteration5") != 0 )
         {
           p = findPackage(5, packageCollection);
           p.addEmail("timbutdim@erggroup.com");
         }

         if ( mConnectionString.compareTo("iteration1") == 0 
           || mConnectionString.compareTo("iteration2") == 0
           || mConnectionString.compareTo("iteration3") == 0 )
         {
           p = findPackage(10, packageCollection);
           p.addEmail("jimmyfishcake@erggroup.com");
         }
         
        /* released advisory ripple info
         * pv_id
         * 14
         */
         if ( mConnectionString.compareTo("iteration1") != 0 )
         {
           p = findPackage(0, packageCollection);
           p.mAdvisoryRipple = true;
         }

         p = findPackage(14, packageCollection);
         p.mAdvisoryRipple = true;
      }
      else
      {
        /* prod_id pkg_name                pkg_version  v_ext pkg_vcs_tag
         * 8       NotInAnyWayReproducible 1.0.0.tim    .tim  NA                                  NA
         * 10      SolarisCentricProduct   1.0.0000.tim .tim  SolarisCentricProduct_1.0.0000.tim  \vob\SolarisCentricProduct
         * 11      LinuxCentricProduct     1.0.0000.tim .tim  LinuxCentricProduct_1.0.0000.tim    \vob\LinuxCentricProduct
         * 12      Win32CentricProduct     1.0.0000.tim .tim  Win32CentricProduct_1.0.0000.tim    \vob\Win32CentricProduct
         * 13      GenericProduct          1.0.0000.tim .tim  GenericProduct_1.0.0000.tim         \vob\ToBeMovedFromHere
         */
         Package p = new Package(8, "NotInAnyWayReproducible", "1.0.0.tim", ".tim", "NotInAnyWayReproducible.1.0.0.tim", "CC::NA::NA", 'x');
         packageCollection.add(p);
         p = new Package(10, "SolarisCentricProduct", "1.0.0000.tim", ".tim", "SolarisCentricProduct.1.0.0000.tim", "CC::/vob/SolarisCentricProduct::SolarisCentricProduct_1.0.0000.tim", 'x');
         packageCollection.add(p);
         p = new Package(11, "LinuxCentricProduct", "1.0.0000.tim", ".tim", "LinuxCentricProduct.1.0.0000.tim", "CC::/vob/LinuxCentricProduct::LinuxCentricProduct_1.0.0000.tim", 'x');
         packageCollection.add(p);
         p = new Package(12, "Win32CentricProduct", "1.0.0000.tim", ".tim", "Win32CentricProduct.1.0.0000.tim", "CC::/vob/Win32CentricProduct::Win32CentricProduct_1.0.0000.tim", 'x');
         packageCollection.add(p);
         p = new Package(13, "GenericProduct", "1.0.0000.tim", ".tim", "GenericProduct.1.0.0000.tim", "CC::/vob/ToBeMovedFromHere::GenericProduct_1.0.0000.tim", 'x');
         packageCollection.add(p);

        /* the above products have the following dependencies which will be discovered in traverseDependencies
         * pv_id   pkg_name, dpv.pkg_version, dpv.v_ext, dpv.pkg_vcs_tag
         * 7     CotsWithFunnyVersion         hoopla2_x.cots   .cots CotsWithFunnyVersion_hoopla2_x.cots \vob\CotsWithFunnyVersion
         * 9     CommonDependency             1.0.0000.tim     .tim  CommonDependency_1.0.0000.tim       \vob\CommonDependency
         * 14    AdvisoryDependency           1.0.0000.tim     .tim  AdvisoryDependency_1.0.0000.tim     \vob\AdvisoryDependency
         * the above packages have the following build info
         * pv_id bm_name bsa_name
         * 7     Solaris Debug
         * 9     Linux   Debug
         * 9     Solaris Debug
         * 9     Win32   Production
         * 10    Solaris Java 1.4
         * 11    Linux   Production and Debug
         * 12    Win32   Java 1.6
         * 13    Generic Java 1.4
         * 14    Linux   Debug
         */
      }
    }
    else
    {
      try
      {
        if (daemonMode)
        {
          mLogger.warn("queryPackageVersions: stmt0");
          Vector<String> globalAndProjectWideBuildFailureEmailCollection = new Vector<String>();
          globalAndProjectWideBuildFailureEmailCollection.add(queryGlobalAddresses());

          CallableStatement stmt0 = mConnection.prepareCall(
          "select u.user_email " +
          "from release_manager.autobuild_failure af, " + 
                "release_manager.members_group mg, " + 
                "release_manager.users u, " + 
                "release_manager.views v, " + 
                "release_manager.release_tags rt " +
          "where rt.rtag_id=" + baseline + " " +
          "and v.view_name='PROJECT WIDE' " +
          "and af.proj_id=rt.proj_id " +
          "and af.view_id=v.view_id " +
          "and mg.group_email_id=af.group_email_id " +
          "and u.user_id=mg.user_id"
          );
          ResultSet rset0 = stmt0.executeQuery();
          
          while( rset0.next() )
          {
            String email = rset0.getString("user_email");
             
            if ( email != null )
            {
              globalAndProjectWideBuildFailureEmailCollection.add(email);
            }
          }
              
          rset0.close();
          stmt0.close();
          
          // get planned package info
          // devi 48629 support multiple wips on the same package and build in the order they were released
          // These are packages that are marked as pending build
          //
          mLogger.warn("queryPackageVersions: stmt1");
          CallableStatement stmt1 = mConnection.prepareCall(
                "select pl.pv_id, p.pkg_id, p.pkg_name, pv.pkg_version, " +
                       "pv.v_ext, pv.change_type, pv.ripple_field," +
                       "pv.major_limit, pv.minor_limit, pv.patch_limit, pv.build_number_limit," +
                       "pv.modified_stamp," +
                       "release_manager.PK_RMAPI.return_vcs_tag(pl.pv_id) AS vcsTag" +
                " from release_manager.planned pl," +
                     "release_manager.package_versions pv," +
                     "release_manager.packages p" +
                " where pl.rtag_id=" + baseline +
                   " and pv.build_type='A' and pv.dlocked='A'" +
                   " and pv.pv_id=pl.pv_id and p.pkg_id=pv.pkg_id" +
                " order by pv.modified_stamp"
          );
          ResultSet rset1 = stmt1.executeQuery();
           
          while( rset1.next() )
          {
            int pv_id = rset1.getInt("pv_id");
            
            if ( rset1.wasNull() )
            {
              mLogger.fatal("queryPackageVersions rset1 null pv_id");
              // show stopper
              throw new Exception("queryPackageVersions rset1 null pv_id");
            }
            
            int pkg_id = rset1.getInt("pkg_id");
            
            if ( rset1.wasNull() )
            {
              mLogger.fatal("queryPackageVersions rset1 null pkg_id " + pv_id);
              // show stopper
              throw new Exception("queryPackageVersions rset1 null pkg_id " + pv_id);
            }

            String pkg_name = rset1.getString("pkg_name");
             
            if ( pkg_name == null )
            {
              mLogger.fatal("queryPackageVersions rset1 null pkg_name " + pv_id);
              // show stopper
              throw new Exception("queryPackageVersions rset1 null pkg_name " + pv_id);
            }

            String pkg_version = rset1.getString("pkg_version");
            if (pkg_version == null) 
            {
                pkg_version = "1.0.0000";
                mLogger.fatal("queryPackageVersions rset1 null pkg_version " + pv_id);
                // show stopper
                throw new Exception("queryPackageVersions rset1 null pkg_version " + pv_id);
            }

            String v_ext = rset1.getString("v_ext");
             
            if ( v_ext == null )
            {
              v_ext = "";
            }

            String change_type = rset1.getString("change_type");
             
            if ( change_type == null )
            {
              change_type = "P";
            }

            char ct = 'x';
            
            if ( change_type.compareTo("M") == 0 )
            {
              ct = 'M';
            }
            else if ( change_type.compareTo("N") == 0 )
            {
              ct = 'N';
            }
            else if ( change_type.compareTo("P") == 0 )
            {
              ct = 'P';
            }
            else if ( change_type.compareTo("F") == 0 )
            {
              ct = 'F';
            }
            
            if ( ct != 'x' )
            {
              String ripple_field = rset1.getString("ripple_field");
              
              if ( ripple_field == null )
              {
                ripple_field = "b";
              }
              else if ( ripple_field.length() == 0 )
              {
                ripple_field = "b";
              }
              
              int major_limit = rset1.getInt("major_limit");
              
              if ( rset1.wasNull() )
              {
                major_limit = 0;
              }
              
              int minor_limit = rset1.getInt("minor_limit");
              
              if ( rset1.wasNull() )
              {
                minor_limit = 0;
              }

              int patch_limit = rset1.getInt("patch_limit");
              
              if ( rset1.wasNull() )
              {
                patch_limit = 0;
              }

              int build_number_limit = rset1.getInt("build_number_limit");
              
              if ( rset1.wasNull() )
              {
                build_number_limit = 0;
              }

              String vcs_tag = rset1.getString("vcsTag");
              if ( vcs_tag == null )
              {
                vcs_tag = "";
              }
              
              Package p = new Package(pv_id, pkg_name, v_ext, pkg_name + v_ext, vcs_tag, ct, ripple_field.charAt(0), pkg_version);
              p.mPid = pkg_id;
              p.mDirectlyPlanned = true;
              p.mMajorLimit = major_limit;
              p.mMinorLimit = minor_limit;
              p.mPatchLimit = patch_limit;
              p.mBuildLimit = build_number_limit;
              Package plannedPackage = findPackage(p.mAlias, packageCollection);
              
              if ( plannedPackage == NULL_PACKAGE )
              {
                mLogger.info("queryPackageVersions rset1 no previous planned package " + pv_id);
                packageCollection.add(p);
              }
            }
          }
          
          rset1.close();
          stmt1.close();

          // get planned package dependency info
          mLogger.warn("queryPackageVersions: stmt2");
          CallableStatement stmt2 = mConnection.prepareCall(
          "select pl.pv_id, p.pkg_name, dpv.v_ext, pv.modified_stamp " +
          "from release_manager.planned pl, release_manager.package_versions pv, release_manager.package_dependencies pd, release_manager.package_versions dpv, release_manager.packages p " +
          "where pl.rtag_id=" + baseline + " and pv.build_type='A' and pv.dlocked='A' " +
          "and pv.pv_id = pl.pv_id and pd.pv_id=pl.pv_id and dpv.pv_id=pd.dpv_id and p.pkg_id=dpv.pkg_id " +
          "order by pv.modified_stamp"
          );
          ResultSet rset2 = stmt2.executeQuery();
            
          while( rset2.next() )
          {
            boolean ignore = false;
            
            int pv_id = rset2.getInt("pv_id");
            
            if ( rset2.wasNull() )
            {
              mLogger.fatal("queryPackageVersions rset2 null pv_id");
              // show stopper
              throw new Exception("queryPackageVersions rset2 null pv_id");
            }
            
            Package p = findPackage(pv_id, packageCollection);
            
            if ( p == NULL_PACKAGE )
            {
              mLogger.info("queryPackageVersions rset2 package superceded by planned " + pv_id);
              ignore = true;
            }
            
            String pkg_name = rset2.getString("pkg_name");
            
            if ( pkg_name == null )
            {
              mLogger.fatal("queryPackageVersions rset2 null pkg_name " + pv_id);
              // show stopper
              throw new Exception("queryPackageVersions rset2 null pkg_name " + pv_id);
            }
            
            String v_ext = rset2.getString("v_ext");
            
            if ( v_ext == null )
            {
              v_ext = "";
            }

            if ( !ignore )
            {
              p.mDependencyCollection.add(pkg_name + v_ext);
              p.mDependencyIDCollection.add(-1);
            }
          }
          
          rset2.close();
          stmt2.close();
          
          // get planned package build info
          mLogger.warn("queryPackageVersions: stmt3");
          CallableStatement stmt3 = mConnection.prepareCall(
          "select pl.pv_id, bm.bm_name, bsa.bsa_name, pv.modified_stamp " +
          "from release_manager.planned pl," +
          "     release_manager.package_versions pv," +
          "     release_manager.package_build_info pbi," +
          "     release_manager.build_machines bm," +
          "     release_manager.build_standards_addendum bsa " +
          "where pl.rtag_id=" + baseline + 
          "     and pv.build_type='A' and pv.dlocked='A' " +
          "     and pv.pv_id = pl.pv_id" +
          "     and pbi.pv_id=pv.pv_id" +
          "     and bm.bm_id=pbi.bm_id" +
          "     and bsa.bsa_id=pbi.bsa_id " +
          "order by pv.modified_stamp"
          );
          ResultSet rset3 = stmt3.executeQuery();
             
          while( rset3.next() )
          {
            boolean ignore = false;
            int pv_id = rset3.getInt("pv_id");
            
            if ( rset3.wasNull() )
            {
              mLogger.fatal("queryPackageVersions rset3 null pv_id");
              // show stopper
              throw new Exception("queryPackageVersions rset3 null pv_id");
            }
             
            Package p = findPackage(pv_id, packageCollection);
             
            if ( p == NULL_PACKAGE )
            {
              mLogger.info("queryPackageVersions rset3 package superceded by planned " + pv_id);
              ignore = true;
            }
             
            String bm_name = rset3.getString("bm_name");
             
            if ( bm_name == null )
            {
              mLogger.fatal("queryPackageVersions rset3 null bm_name " + pv_id);
              // show stopper
              throw new Exception("queryPackageVersions rset3 null bm_name " + pv_id);
            }
             
            String bsa_name = rset3.getString("bsa_name");
             
            if ( bsa_name == null )
            {
              mLogger.fatal("queryPackageVersions rset3 null bsa_name " + pv_id);
              // show stopper
              throw new Exception("queryPackageVersions rset3 null bsa_name " + pv_id);
            }

            if ( !ignore )
            {
              BuildStandard bs = new BuildStandard(rippleEngine, bm_name, bsa_name);

              if ( bs.supportedBuildStandard() )
              {
                p.mBuildStandardCollection.add(bs);
              }
            }
          }
          
          rset3.close();
          stmt3.close();

          // get planned package unit test info
          mLogger.warn("queryPackageVersions: stmt4");
          CallableStatement stmt4 = mConnection.prepareCall(
          "select pl.pv_id, tt.test_type_name, pv.modified_stamp " +
          "from release_manager.planned pl, release_manager.package_versions pv, release_manager.unit_tests ut, release_manager.test_types tt " +
          "where pl.rtag_id=" + baseline + " and pv.build_type='A' and pv.dlocked='A' " +
          "and pv.pv_id = pl.pv_id and ut.pv_id=pv.pv_id and tt.test_type_id=ut.test_types_fk " +
          "order by pv.modified_stamp"
          );
          ResultSet rset4 = stmt4.executeQuery();
             
          while( rset4.next() )
          {
            boolean ignore = false;
             
            int pv_id = rset4.getInt("pv_id");
             
            if ( rset4.wasNull() )
            {
              mLogger.fatal("queryPackageVersions rset4 null pv_id");
              // show stopper
              throw new Exception("queryPackageVersions rset4 null pv_id");
            }
             
            Package p = findPackage(pv_id, packageCollection);
             
            if ( p == NULL_PACKAGE )
            {
              mLogger.info("queryPackageVersions rset4 package superceded by planned " + pv_id);
              ignore = true;
            }
             
            String test_type_name = rset4.getString("test_type_name");
             
            if ( test_type_name == null )
            {
              mLogger.fatal("queryPackageVersions rset4 null test_type_name " + pv_id);
              // show stopper
              throw new Exception("queryPackageVersions rset4 null test_type_name " + pv_id);
            }
             
            if ( !ignore )
            {
              if ( test_type_name.compareTo("Autobuild UTF") == 0 )
              {
                p.mHasAutomatedUnitTests = true;
              }
            }
          }
          
          rset4.close();
          stmt4.close();

          // get planned package build failure info...
          // global and project wide based
          mLogger.warn("queryPackageVersions: stmt50");
          CallableStatement stmt50 = mConnection.prepareCall(
          "select pl.pv_id, pv.modified_stamp " +
          "from release_manager.planned pl, release_manager.release_tags rt, release_manager.package_versions pv " +
          "where pl.rtag_id=" + baseline + " and rt.rtag_id=pl.rtag_id and pv.build_type='A' and pv.dlocked='A' " +
          "and pv.pv_id = pl.pv_id " +
          "order by pv.modified_stamp"
          );
          ResultSet rset50 = stmt50.executeQuery();
              
          while( rset50.next() )
          {
            int pv_id = rset50.getInt("pv_id");
             
            if ( rset50.wasNull() )
            {
              mLogger.fatal("queryPackageVersions rset50 null pv_id");
              // show stopper
              throw new Exception("queryPackageVersions rset50 null pv_id");
            }
              
            Package p = findPackage(pv_id, packageCollection);
              
            if ( p == NULL_PACKAGE )
            {
              mLogger.info("queryPackageVersions rset50 package superceded by planned " + pv_id);
            }
            else
            {
              for (Iterator<String> it = globalAndProjectWideBuildFailureEmailCollection.iterator(); it.hasNext(); )
              {
                p.addEmail(it.next());
              }
            }
          }
              
          rset50.close();
          stmt50.close();

          // view based
          mLogger.warn("queryPackageVersions: stmt5");
          CallableStatement stmt5 = mConnection.prepareCall(
          "select pl.pv_id, u.user_email, pv.modified_stamp " +
          " from release_manager.planned pl, " +
          "      release_manager.release_tags rt, " +
          "      release_manager.package_versions pv, " +
          "      release_manager.autobuild_failure af, " +
          "      release_manager.members_group mg, " +
          "      release_manager.users u " +
          " where pl.rtag_id=" + baseline + 
          "      and rt.rtag_id=pl.rtag_id" +
          "      and pv.build_type='A' and pv.dlocked='A' " +
          "      and pv.pv_id = pl.pv_id " +
          "      and af.view_id=pl.view_id " +
          "      and mg.group_email_id=af.group_email_id " +
          "      and u.user_id=mg.user_id " +
          "      and af.proj_id=rt.proj_id " +
          " order by pv.modified_stamp"
          );
          ResultSet rset5 = stmt5.executeQuery();
              
          while( rset5.next() )
          {
            int pv_id = rset5.getInt("pv_id");
             
            if ( rset5.wasNull() )
            {
              mLogger.fatal("queryPackageVersions rset5 null pv_id");
              // show stopper
              throw new Exception("queryPackageVersions rset5 null pv_id");
            }
              
            Package p = findPackage(pv_id, packageCollection);
              
            if ( p == NULL_PACKAGE )
            {
              mLogger.info("queryPackageVersions rset5 package superceded by planned " + pv_id);
            }
            else
            {
              String user_email = rset5.getString("user_email");
              
              if ( user_email != null )
              {
                p.addEmail(user_email);
              }
            }
          }
          
          rset5.close();
          stmt5.close();

          // package version
          mLogger.warn("queryPackageVersions: stmt51");
          CallableStatement stmt51 = mConnection.prepareCall(
          "select pl.pv_id, u1.user_email, u2.user_email, u3.user_email, pv.modified_stamp " +
          "from release_manager.planned pl, release_manager.release_tags rt, release_manager.package_versions pv, release_manager.users u1, release_manager.users u2, release_manager.users u3 " +
          "where pl.rtag_id=" + baseline + " and rt.rtag_id=pl.rtag_id and pv.build_type='A' and pv.dlocked='A' " +
          "and pv.pv_id = pl.pv_id and u1.user_id=pv.creator_id and u2.user_id=pv.owner_id and u3.user_id=pv.modifier_id " +
          "order by pv.modified_stamp"
          );
          ResultSet rset51 = stmt51.executeQuery();
              
          while( rset51.next() )
          {
            int pv_id = rset51.getInt("pv_id");
             
            if ( rset51.wasNull() )
            {
              mLogger.fatal("queryPackageVersions rset51 null pv_id");
              // show stopper
              throw new Exception("queryPackageVersions rset51 null pv_id");
            }
              
            Package p = findPackage(pv_id, packageCollection);
              
            if ( p == NULL_PACKAGE )
            {
              mLogger.info("queryPackageVersions rset51 package superceded by planned " + pv_id);
            }
            else
            {
              
              // walk the 3 columns of user_email in the resultset
              // columns 2, 3 and 4, all of the same name, repectively
              for(int column=2; column<5; column++ )
              {
                String user_email = rset51.getString(column);
                
                if ( user_email != null )
                {
                  p.addEmail(user_email);
                }
              }
            }
          }
          
          rset51.close();
          stmt51.close();

          // get planned package advisory ripple info
          mLogger.warn("queryPackageVersions: stmt7");
          CallableStatement stmt7 = mConnection.prepareCall(
          "select pl.pv_id, pv.modified_stamp " +
          "from release_manager.planned pl, release_manager.package_versions pv, release_manager.advisory_ripple ar " +
          "where pl.rtag_id=" + baseline + " and pv.build_type='A' and pv.dlocked='A' " +
          "and pv.pv_id = pl.pv_id and ar.rtag_id=pl.rtag_id and ar.pv_id=pl.pv_id " +
          "order by pv.modified_stamp"
          );
          ResultSet rset7 = stmt7.executeQuery();
               
          while( rset7.next() )
          {
            boolean ignore = false;
             
            int pv_id = rset7.getInt("pv_id");
              
            if ( rset7.wasNull() )
            {
              mLogger.fatal("queryPackageVersions rset7 null pv_id");
              // show stopper
              throw new Exception("queryPackageVersions rset7 null pv_id");
            }
               
            Package p = findPackage(pv_id, packageCollection);
               
            if ( p == NULL_PACKAGE )
            {
              mLogger.info("queryPackageVersions rset7 package superceded by planned " + pv_id);
              ignore = true;
            }
               
            if ( !ignore )
            {
              p.mAdvisoryRipple = true;
            }
          }
          
          rset7.close();
          stmt7.close();
          
          // get released package info
          //    Get package information on ALL released packages within the release of interest
          //
          mLogger.warn("queryPackageVersions: stmt8");
          CallableStatement stmt8 = mConnection.prepareCall(
            "select rc.pv_id, p.pkg_id, p.pkg_name, pv.pkg_version, pv.v_ext," +
                "pv.ripple_field,pv.major_limit, pv.minor_limit, pv.patch_limit," +
                "pv.build_number_limit," +
                "release_manager.PK_RMAPI.return_vcs_tag(rc.pv_id) AS vcsTag" +
            " from release_manager.release_content rc," +
                  "release_manager.package_versions pv, " +
                  "release_manager.packages p " +
            " where rc.rtag_id=" + baseline +
              " and pv.pv_id = rc.pv_id" +
              " and p.pkg_id = pv.pkg_id" +
            " order by rc.pv_id"
          );
mLogger.warn("queryPackageVersions: stmt8 Prepared");
          ResultSet rset8 = stmt8.executeQuery();
mLogger.warn("queryPackageVersions: stmt8 Query Done");
          
          while( rset8.next() )
          {
            int pv_id = rset8.getInt("pv_id");
            
            if ( rset8.wasNull() )
            {
              mLogger.fatal("queryPackageVersions rset8 null pv_id");
              // show stopper
              throw new Exception("queryPackageVersions rset8 null pv_id");
            }
            
            int pkg_id = rset8.getInt("pkg_id");
            
            if ( rset8.wasNull() )
            {
              mLogger.fatal("queryPackageVersions rset8 null pkg_id " + pv_id);
              // show stopper
              throw new Exception("queryPackageVersions rset8 null pkg_id " + pv_id);
            }
            
            String pkg_name = rset8.getString("pkg_name");
            
            if ( pkg_name == null )
            {
              mLogger.fatal("queryPackageVersions rset8 null pkg_name " + pv_id);
              // show stopper
              throw new Exception("queryPackageVersions rset8 null pkg_name " + pv_id);
            }
            
            String pkg_version = rset8.getString("pkg_version");
            
            if ( pkg_version == null )
            {
              mLogger.fatal("queryPackageVersions rset8 null pkg_version " + pv_id);
              // show stopper
              throw new Exception("queryPackageVersions rset8 null pkg_version " + pv_id);
            }
            
            String v_ext = rset8.getString("v_ext");
            
            if ( v_ext == null )
            {
              v_ext = "";
            }
            
            String ripple_field = rset8.getString("ripple_field");
            
            if ( ripple_field == null )
            {
              ripple_field = "b";
            }
            else if ( ripple_field.length() == 0 )
            {
              ripple_field = "b";
            }
            
            int major_limit = rset8.getInt("major_limit");
            
            if ( rset8.wasNull() )
            {
              major_limit = 0;
            }
            
            int minor_limit = rset8.getInt("minor_limit");
            
            if ( rset8.wasNull() )
            {
              minor_limit = 0;
            }

            int patch_limit = rset8.getInt("patch_limit");
            
            if ( rset8.wasNull() )
            {
              patch_limit = 0;
            }

            int build_number_limit = rset8.getInt("build_number_limit");
            
            if ( rset8.wasNull() )
            {
              build_number_limit = 0;
            }

            String vcs_tag = rset8.getString("vcsTag");
            if ( vcs_tag == null )
            {
              vcs_tag = "";
            }

            Package p = new Package(pv_id, pkg_name, pkg_version, v_ext, pkg_name + v_ext, vcs_tag, ripple_field.charAt(0));
            p.mMajorLimit = major_limit;
            p.mMinorLimit = minor_limit;
            p.mPatchLimit = patch_limit;
            p.mBuildLimit = build_number_limit;
            p.mPid = pkg_id;
            Integer ipv_id = new Integer(pv_id);
            rippleEngine.mReleasedPvIDCollection.add(ipv_id);
            Package plannedPackage = findPackage(p.mAlias, packageCollection);
            
            if ( plannedPackage == NULL_PACKAGE )
            {
              mLogger.info("queryPackageVersions rset8 no planned package " + pv_id);
              packageCollection.add(p);
            }
            else
            {
              int endindex = pkg_version.length() - v_ext.length();
              
              if ( endindex > 0 )
              {
                pkg_version = pkg_version.substring(0, endindex);
              }

              plannedPackage.mVersion = pkg_version;
            }
          }
          
mLogger.warn("queryPackageVersions: stmt8 processing complete");
          rset8.close();
          stmt8.close();

          // get released package dependency info
          // the not exists subquery was added to ignore dependencies for 'pegged' package versions in a release - DEVI 48876
          // this is the ONLY support for dealing with an inconsistent set of package versions
          mLogger.warn("queryPackageVersions: stmt9");
          CallableStatement stmt9 = mConnection.prepareCall(
          "select rc.pv_id, dpv.pv_id, p.pkg_name, dpv.v_ext " +
          "from release_manager.release_content rc, release_manager.package_versions pv, release_manager.package_dependencies pd, release_manager.package_versions dpv, release_manager.packages p " +
          "where rc.rtag_id=" + baseline +
          " and pv.pv_id = rc.pv_id and pd.pv_id=pv.pv_id and dpv.pv_id=pd.dpv_id and p.pkg_id=dpv.pkg_id " +
          " and not exists (select pv_id from pegged_versions where pv_id=pv.pv_id and rtag_id=rc.rtag_id) " +
          "order by rc.pv_id"
          );
mLogger.warn("queryPackageVersions: stmt9 prepared");
          ResultSet rset9 = stmt9.executeQuery();
mLogger.warn("queryPackageVersions: stmt9 query done");
             
          while( rset9.next() )
          {
            boolean ignore = false;
             
            int pv_id = rset9.getInt(1);
             
            if ( rset9.wasNull() )
            {
              mLogger.fatal("queryPackageVersions rset9 null pv_id");
              // show stopper
              throw new Exception("queryPackageVersions rset9 null pv_id");
            }
             
            int dpv_id = rset9.getInt(2);
             
            if ( rset9.wasNull() )
            {
              mLogger.fatal("queryPackageVersions rset9 null dpv_id " + pv_id);
              // show stopper
              throw new Exception("queryPackageVersions rset9 null dpv_id " + pv_id);
            }
             
            Package p = findPackage(pv_id, packageCollection);
             
            if ( p == NULL_PACKAGE )
            {
              mLogger.info("queryPackageVersions rset9 package superceded by planned " + pv_id);
              ignore = true;
            }
             
            String pkg_name = rset9.getString("pkg_name");
             
            if ( pkg_name == null )
            {
              mLogger.fatal("queryPackageVersions rset9 null pkg_name " + pv_id);
              // show stopper
              throw new Exception("queryPackageVersions rset9 null pkg_name " + pv_id);
            }
             
            String v_ext = rset9.getString("v_ext");
             
            if ( v_ext == null )
            {
              v_ext = "";
            }

            if ( !ignore )
            {
              p.mDependencyCollection.add(pkg_name + v_ext);
              p.mDependencyIDCollection.add(dpv_id);
            }
          }
mLogger.warn("queryPackageVersions: stmt9 processing complete");

          rset9.close();
          stmt9.close();
           
          // get released package build info
          mLogger.warn("queryPackageVersions: stmt10");
          CallableStatement stmt10 = mConnection.prepareCall(
          "select rc.pv_id, bm.bm_name, bsa.bsa_name " +
          "from release_manager.release_content rc," +
          "     release_manager.package_versions pv," +
          "     release_manager.package_build_info pbi," +
          "     release_manager.build_machines bm," +
          "     release_manager.build_standards_addendum bsa " +
          "where rc.rtag_id=" + baseline +
          "     and pv.pv_id = rc.pv_id" +
          "     and pbi.pv_id=pv.pv_id" +
          "     and bm.bm_id=pbi.bm_id" +
          "     and bsa.bsa_id=pbi.bsa_id " +
          "order by rc.pv_id"
          );
          ResultSet rset10 = stmt10.executeQuery();
              
          while( rset10.next() )
          {
            boolean ignore = false;
            int pv_id = rset10.getInt("pv_id");
             
            if ( rset10.wasNull() )
            {
              mLogger.fatal("queryPackageVersions rset10 null pv_id");
              // show stopper
              throw new Exception("queryPackageVersions rset10 null pv_id");
            }
              
            Package p = findPackage(pv_id, packageCollection);
              
            if ( p == NULL_PACKAGE )
            {
              mLogger.info("queryPackageVersions rset10 package superceded by planned " + pv_id);
              ignore = true;
            }
              
            String bm_name = rset10.getString("bm_name");
              
            if ( bm_name == null )
            {
              mLogger.fatal("queryPackageVersions rset10 null bm_name " + pv_id);
              // show stopper
              throw new Exception("queryPackageVersions rset10 null bm_name " + pv_id);
            }
              
            String bsa_name = rset10.getString("bsa_name");
              
            if ( bsa_name == null )
            {
              mLogger.fatal("queryPackageVersions rset10 null bsa_name " + pv_id);
              // show stopper
              throw new Exception("queryPackageVersions rset10 null bsa_name " + pv_id);
            }

            if ( !ignore )
            {
              BuildStandard bs = new BuildStandard(rippleEngine, bm_name, bsa_name);

              if ( bs.supportedBuildStandard() )
              {
                p.mBuildStandardCollection.add(bs);
              }
            }
          }
          
          rset10.close();
          stmt10.close();

          // get released package unit test info
          mLogger.warn("queryPackageVersions: stmt11");
          CallableStatement stmt11 = mConnection.prepareCall(
          "select rc.pv_id, tt.test_type_name " +
          "from release_manager.release_content rc, release_manager.package_versions pv, release_manager.unit_tests ut, release_manager.test_types tt " +
          "where rc.rtag_id=" + baseline +
          " and pv.pv_id = rc.pv_id and ut.pv_id=pv.pv_id and tt.test_type_id=ut.test_types_fk " +
          "order by rc.pv_id"
          );
          ResultSet rset11 = stmt11.executeQuery();
              
          while( rset11.next() )
          {
            boolean ignore = false;
              
            int pv_id = rset11.getInt("pv_id");
              
            if ( rset11.wasNull() )
            {
              mLogger.fatal("queryPackageVersions rset11 null pv_id");
              // show stopper
              throw new Exception("queryPackageVersions rset11 null pv_id");
            }
              
            Package p = findPackage(pv_id, packageCollection);
              
            if ( p == NULL_PACKAGE )
            {
              mLogger.info("queryPackageVersions rset11 package superceded by planned " + pv_id);
              ignore = true;
            }
              
            String test_type_name = rset11.getString("test_type_name");
              
            if ( test_type_name == null )
            {
              mLogger.fatal("queryPackageVersions rset11 null test_type_name " + pv_id);
              // show stopper
              throw new Exception("queryPackageVersions rset11 null test_type_name " + pv_id);
            }
              
            if ( !ignore )
            {
              if ( test_type_name.compareTo("Autobuild UTF") == 0 )
              {
                p.mHasAutomatedUnitTests = true;
              }
            }
          }
          
          rset11.close();
          stmt11.close();

          // get released package build failure info...
          // global and project wide based
          mLogger.warn("queryPackageVersions: stmt120");
          CallableStatement stmt120 = mConnection.prepareCall(
          "select rc.pv_id " +
          "from release_manager.release_content rc, release_manager.release_tags rt, release_manager.package_versions pv " +
          "where rc.rtag_id=" + baseline + " and rt.rtag_id=rc.rtag_id " +
          "and pv.pv_id = rc.pv_id " +
          "order by rc.pv_id"
          );
          ResultSet rset120 = stmt120.executeQuery();
              
          while( rset120.next() )
          {
            int pv_id = rset120.getInt("pv_id");
             
            if ( rset120.wasNull() )
            {
              mLogger.fatal("queryPackageVersions rset120 null pv_id");
              // show stopper
              throw new Exception("queryPackageVersions rset120 null pv_id");
            }
              
            Package p = findPackage(pv_id, packageCollection);
              
            if ( p == NULL_PACKAGE )
            {
              mLogger.info("queryPackageVersions rset120 package superceded by planned " + pv_id);
            }
            else
            {
              for (Iterator<String> it = globalAndProjectWideBuildFailureEmailCollection.iterator(); it.hasNext(); )
              {
                p.addEmail(it.next());
              }
            }
          }
              
          rset120.close();
          stmt120.close();
          
          // view based
          mLogger.warn("queryPackageVersions: stmt12");
          CallableStatement stmt12 = mConnection.prepareCall(
          "select rc.pv_id, u.user_email " +
          "from release_manager.release_content rc, release_manager.release_tags rt, release_manager.package_versions pv, release_manager.autobuild_failure af, release_manager.members_group mg, release_manager.users u " +
          "where rc.rtag_id=" + baseline + " and rt.rtag_id=rc.rtag_id " +
          "and pv.pv_id = rc.pv_id and af.view_id=rc.base_view_id and mg.group_email_id=af.group_email_id and u.user_id=mg.user_id and af.proj_id=rt.proj_id " +
          "order by rc.pv_id"
          );
          ResultSet rset12 = stmt12.executeQuery();
               
          while( rset12.next() )
          {
            int pv_id = rset12.getInt("pv_id");
              
            if ( rset12.wasNull() )
            {
              mLogger.fatal("queryPackageVersions rset12 null pv_id");
              // show stopper
              throw new Exception("queryPackageVersions rset12 null pv_id");
            }
               
            Package p = findPackage(pv_id, packageCollection);
               
            if ( p == NULL_PACKAGE )
            {
              mLogger.info("queryPackageVersions rset12 package superceded by planned " + pv_id);
            }
            else
            {
              String user_email = rset12.getString("user_email");
               
              if ( user_email != null )
              {
                p.addEmail(user_email);
              }
            }
          }
          
          rset12.close();
          stmt12.close();

          // get released advisory ripple info
          mLogger.warn("queryPackageVersions: stmt14");
          CallableStatement stmt14 = mConnection.prepareCall(
          "select rc.pv_id " +
          "from release_manager.release_content rc, release_manager.package_versions pv, release_manager.advisory_ripple ar " +
          "where rc.rtag_id=" + baseline +
          " and pv.pv_id = rc.pv_id and ar.rtag_id=rc.rtag_id and ar.pv_id=rc.pv_id " +
          "order by rc.pv_id"
          );
          ResultSet rset14 = stmt14.executeQuery();
                
          while( rset14.next() )
          {
            boolean ignore = false;
              
            int pv_id = rset14.getInt("pv_id");
               
            if ( rset14.wasNull() )
            {
              mLogger.fatal("queryPackageVersions rset14 null pv_id");
              // show stopper
              throw new Exception("queryPackageVersions rset14 null pv_id");
            }
                
            Package p = findPackage(pv_id, packageCollection);
                
            if ( p == NULL_PACKAGE )
            {
              mLogger.info("queryPackageVersions rset14 package superceded by planned " + pv_id);
              ignore = true;
            }
                
            if ( !ignore )
            {
              p.mAdvisoryRipple = true;
            }
          }
          
          rset14.close();
          stmt14.close();

          // force ripple info
          // an op code of 0 means force ripple
          MutableInt instruction = new MutableInt();
          instruction.value = 0;
          MutableInt pvid = new MutableInt();
          MutableInt userid = new MutableInt();
          
          while ( getDaemonInst( baseline, instruction, 0, pvid, userid ) )
          {
            Package p = findPackage(pvid.value, packageCollection);
            
            if ( p != NULL_PACKAGE )
            {
              mLogger.info("queryPackageVersions forced ripple data " + pvid.value);
              p.mForcedRippleInstruction = instruction.value;
            }
            else
            {
              // discard
              markDaemonInstCompleted( instruction.value );
            }
          }
          
          // test build info
          // bare minimal data collection - last thing needed is more data to collect
          // the approach...
          // query all test build instructions for this baseline
          // for each, query its build information
          // store them in "mTestBuild" Package attributes as follows:
          // - mTestBuildInstruction (default 0)
          // - mTestBuildEmail (default "null")
          // - mTestBuildVcsTag (default "null")
          // - mTestBuildStandardCollection
          // - mTestBuildDependencyCollection
          // additionally, trust nothing - these are wips that at any time may have:
          // - no build location
          // - no build label
          // - an empty build standard collection
          // proceed with defaults above if necessary (the build will subsequently fail)
          // in all cases, build a meaningful email body to inform the user
          // of the snapshot of build information that applied to the build and store in:
          // - mTestBuildEmailBody

          // an op code of 1 means test build
          mLogger.warn("queryPackageVersions: stmt141");
          instruction.value = 0;
          while ( getDaemonInst( baseline, instruction, 1, pvid, userid ) )
          {
            // can only do one test build at a time - others will be discarded until future cycle
            boolean discard = false;
            mLogger.info("queryPackageVersions test build data " + pvid.value);
            int testBuildPvId = pvid.value;
            int testBuildInstruction = instruction.value;
            String testBuildEmail = "";
            CallableStatement stmt141 = mConnection.prepareCall(
            "select user_email from release_manager.users where user_id=" + userid.value);
            ResultSet rset141 = stmt141.executeQuery();
            
            while( rset141.next() )
            {
              testBuildEmail = rset141.getString("user_email");
              
              if ( testBuildEmail == null )
              {
                // no one to inform - discard
                discard = true;
              }
            }
            
            rset141.close();
            stmt141.close();

            if ( discard )
            {
              mLogger.error("queryPackageVersions rset141 null user_email " + userid.value);
              markDaemonInstCompleted( instruction.value );
            }
            else
            {
              String pkg_name = "";
              String pkg_ext = "";
              String testBuildVcsTag = "null";

              // get wip package info
              mLogger.warn("queryPackageVersions: stmt15");
              CallableStatement stmt15 = mConnection.prepareCall(
              "select p.pkg_name, pv.v_ext, release_manager.PK_RMAPI.return_vcs_tag(pv.pv_id) AS vcsTag " +
              " from release_manager.work_in_progress wip," +
                    "release_manager.package_versions pv," +
                    "release_manager.packages p" +
              " where wip.rtag_id=" + baseline +
                " and pv.pv_id=" + testBuildPvId +
                " and wip.pv_id=" + testBuildPvId +
                " and p.pkg_id=pv.pkg_id "
              );
              ResultSet rset15 = stmt15.executeQuery();
              
              int rsetSize = 0;
               
              while( rset15.next() )
              {
                rsetSize++;
                pkg_name = rset15.getString("pkg_name");
                 
                if ( pkg_name == null )
                {
                  mLogger.fatal("queryPackageVersions rset15 null pkg_name " + testBuildPvId);
                  // show stopper
                  throw new Exception("queryPackageVersions rset15 null pkg_name " + testBuildPvId);
                }
    
                pkg_ext = rset15.getString("v_ext");
                 
                if ( pkg_ext == null )
                {
                  pkg_ext = "";
                }

                testBuildVcsTag = rset15.getString("vcsTag");
                if ( testBuildVcsTag == null )
                {
                    testBuildVcsTag = "null";
                }
              }
              
              rset15.close();
              stmt15.close();
              
              mLogger.warn("queryPackageVersions: stmt16");
              if ( rsetSize == 0 )
              {
                mLogger.error("queryPackageVersions rset15 no wip found " + instruction.value);
                markDaemonInstCompleted( instruction.value );
              }
              else
              {
                Package q = findPackage(pkg_name + pkg_ext, packageCollection);
                
                if ( q == NULL_PACKAGE )
                {
                  // wip package alias does not exist in this release (planned or released packages)
                  q = new Package( pkg_name, pkg_ext, pkg_name + pkg_ext, testBuildVcsTag, testBuildInstruction, testBuildEmail);
                  packageCollection.add(q);
                }
                else
                {
                  // avoid interaction with real versions
                  q.mVersion = "0.0.0000";
                  q.mTestBuildVcsTag = testBuildVcsTag;
                  q.mTestBuildInstruction = testBuildInstruction;
                  q.mTestBuildEmail = testBuildEmail;
                }
  
                // get wip package dependency info
                CallableStatement stmt16 = mConnection.prepareCall(
                "select p.pkg_name, dpv.v_ext " +
                "from release_manager.work_in_progress wip, release_manager.package_versions pv, " +
                "release_manager.package_dependencies pd, release_manager.package_versions dpv, release_manager.packages p " +
                "where wip.rtag_id=" + baseline +
                " and pv.pv_id=" + testBuildPvId +
                " and wip.pv_id=" + testBuildPvId +
                " and pd.pv_id=" + testBuildPvId +
                " and dpv.pv_id=pd.dpv_id and p.pkg_id=dpv.pkg_id "
                );
                ResultSet rset16 = stmt16.executeQuery();
                  
                while( rset16.next() )
                {
                  String dpkg_name = rset16.getString("pkg_name");
                  
                  if ( dpkg_name == null )
                  {
                    mLogger.fatal("queryPackageVersions rset16 null pkg_name " + testBuildPvId);
                    // show stopper
                    throw new Exception("queryPackageVersions rset16 null pkg_name " + testBuildPvId);
                  }
                  
                  String v_ext = rset16.getString("v_ext");
                  
                  if ( v_ext == null )
                  {
                    v_ext = "";
                  }
      
                  q.mTestBuildDependencyCollection.add(dpkg_name + v_ext);
                }
                
                rset16.close();
                stmt16.close();
  
                // get planned package build info
                mLogger.warn("queryPackageVersions: stmt17");
                CallableStatement stmt17 = mConnection.prepareCall(
                "select bm.bm_name, bsa.bsa_name " +
                "from release_manager.work_in_progress wip," +
                "     release_manager.package_versions pv," +
                "     release_manager.package_build_info pbi," +
                "     release_manager.build_machines bm," +
                "     release_manager.build_standards_addendum bsa " +
                "where wip.rtag_id=" + baseline +
                "   and wip.pv_id=" + testBuildPvId +
                "   and pv.pv_id=" + testBuildPvId +
                "   and pbi.pv_id=pv.pv_id" +
                "   and bm.bm_id=pbi.bm_id" +
                "   and bsa.bsa_id=pbi.bsa_id"
                );
                ResultSet rset17 = stmt17.executeQuery();
                   
                while( rset17.next() )
                {
                  String bm_name = rset17.getString("bm_name");
                   
                  if ( bm_name == null )
                  {
                    mLogger.fatal("queryPackageVersions rset17 null bm_name " + testBuildPvId);
                    // show stopper
                    throw new Exception("queryPackageVersions rset17 null bm_name " + testBuildPvId);
                  }
                   
                  String bsa_name = rset17.getString("bsa_name");
                   
                  if ( bsa_name == null )
                  {
                    mLogger.fatal("queryPackageVersions rset17 null bsa_name " + testBuildPvId);
                    // show stopper
                    throw new Exception("queryPackageVersions rset17 null bsa_name " + testBuildPvId);
                  }
      
                  BuildStandard bs = new BuildStandard(rippleEngine, bm_name, bsa_name);
  
                  if ( bs.supportedBuildStandard() )
                  {
                    q.mTestBuildStandardCollection.add(bs);
                  }
                }
                
                rset17.close();
                stmt17.close();
              }
            }
          }
        }
        else
        {
          // get released product info
          mLogger.warn("queryPackageVersions: stmt18");
          CallableStatement stmt = mConnection.prepareCall(
            "select oc.prod_id, p.pkg_name, pv.pkg_version, pv.v_ext," +
                   "release_manager.PK_RMAPI.return_vcs_tag(pv.pv_id) AS vcsTag" +
            " from deployment_manager.bom_contents bc," +
                "deployment_manager.operating_systems os," +
                "deployment_manager.os_contents oc," +
                "release_manager.package_versions pv," +
                "release_manager.packages p" +
            " where bc.bom_id=" + baseline +
                " and os.node_id=bc.node_id" +
                " and oc.os_id=os.os_id" +
                " and pv.pv_id=oc.prod_id" +
                " and p.pkg_id=pv.pkg_id" +
            " order by oc.prod_id"
          );
          ResultSet rset = stmt.executeQuery();
            
          while( rset.next() )
          {
            int pv_id = rset.getInt("prod_id");
              
            if ( rset.wasNull() )
            {
              mLogger.fatal("queryPackageVersions rset null prod_id");
              // show stopper
              throw new Exception("queryPackageVersions rset null prod_id");
            }
              
            String pkg_name = rset.getString("pkg_name");
              
            if ( pkg_name == null )
            {
              mLogger.fatal("queryPackageVersions rset null pkg_name " + pv_id);
              // show stopper
              throw new Exception("queryPackageVersions rset null pkg_name " + pv_id);
            }
              
            String pkg_version = rset.getString("pkg_version");
              
            if ( pkg_version == null )
            {
              mLogger.fatal("queryPackageVersions rset null pkg_version " + pv_id);
              // show stopper
              throw new Exception("queryPackageVersions rset null pkg_version " + pv_id);
            }
              
            String v_ext = rset.getString("v_ext");
             
            if ( v_ext == null )
            {
              v_ext = "";
            }

            String vcs_tag = rset.getString("vcsTag");
            if ( vcs_tag == null )
            {
              vcs_tag = "";
            }
              
            Package p = findPackage(pv_id, packageCollection);
            
            if ( p == NULL_PACKAGE )
            {
                    Package q = new Package(pv_id, pkg_name, pkg_version, v_ext, pkg_name + "." + pkg_version, vcs_tag, 'x');
                    packageCollection.add(q);
            }
          }
          
          rset.close();
          stmt.close();
        }
      }
      catch ( SQLException e )
      {
        if ( mConnection == null || ( mConnection != null && !mConnection.isValid(10) ) )
        {
          mLogger.error("queryPackageVersions database access error only");
          throw new SQLException();
        }
        else
        {
          mLogger.fatal("queryPackageVersions show stopper");
          throw new Exception("queryPackageVersions show stopper");
        }
      }
    }
    
    if (!daemonMode)
    {
      // use a ListIterator as it allows traverseDependencies to modify the packageCollection
      for (ListIterator<Package> it = packageCollection.listIterator(); it.hasNext(); )
      {
        Package p = it.next();
        traverseDependencies(packageCollection, p, false, it);
      }

      for (Iterator<Package> it = packageCollection.iterator(); it.hasNext(); )
      {
        Package p = it.next();
        queryBuildInfo(rippleEngine, p);
      }
    }

  }

  /**only used in daemon mode
   *   select config from release_manager.build_service_config where service='MAIL SERVER';
   * returns the configured service
   */
  String queryMailServer() throws SQLException, Exception
  {
    mLogger.debug("queryMailServer");
    String retVal = new String();
    
    if ( !mUseDatabase )
    {
      mLogger.info("queryMailServer !mUseDatabase");
      // a highly likely mail server
      retVal = "auperadom10.aupera.erggroup.com";
    }
    else
    {
      try
      {
        CallableStatement stmt = mConnection.prepareCall("select config from release_manager.build_service_config where service='MAIL SERVER'");
        ResultSet rset = stmt.executeQuery();
        
        while( rset.next() )
        {
          String config = rset.getString("config");
          
          if ( config != null )
          {
            retVal += config;
          }
        }
        
        rset.close();
        stmt.close();
      }
      catch ( SQLException e )
      {
        if ( mConnection == null || ( mConnection != null && !mConnection.isValid(10) ) )
        {
          mLogger.error("queryMailServer database access error only");
          throw new SQLException();
        }
        else
        {
          mLogger.fatal("queryMailServer show stopper");
          throw new Exception("queryMailServer show stopper");
        }
      }
    }
    
    mLogger.info("queryMailServer returned " + retVal);
    return retVal;
  }

  /**only used in daemon mode
   *   select config from release_manager.build_service_config where service='BUILD FAILURE MAIL SENDER';
   * returns the configured service
   */
  String queryMailSender() throws SQLException, Exception
  {
    mLogger.debug("queryMailSender");
    String retVal = new String();

    if ( !mUseDatabase )
    {
      mLogger.info("queryMailSender !mUseDatabase");
      // a highly likely mail sender
      retVal = "buildadm@erggroup.com";
    }
    else
    {
      try
      {
        CallableStatement stmt = mConnection.prepareCall("select config from release_manager.build_service_config where service='BUILD FAILURE MAIL SENDER'");
        ResultSet rset = stmt.executeQuery();
        
        while( rset.next() )
        {
          String config = rset.getString("config");
          
          if ( config != null )
          {
            retVal += config;
          }
        }
        
        rset.close();
        stmt.close();
      }
      catch ( SQLException e )
      {
        if ( mConnection == null || ( mConnection != null && !mConnection.isValid(10) ) )
        {
          mLogger.error("queryMailSender database access error only");
          throw new SQLException();
        }
        else
        {
          mLogger.fatal("queryMailSender show stopper");
          throw new Exception("queryMailSender show stopper");
        }
      }
    }

    mLogger.debug("queryMailSender returned " + retVal);
    return retVal;
  }

  /**only used in daemon mode
   * select u.user_email from release_manager.build_service_config bsc, release_manager.users u
   * where bsc.service='GLOBAL EMAIL ADDRESS LIST' and u.full_name=bsc.config
   * returns the configured global email addresses
   */
  String queryGlobalAddresses() throws SQLException, Exception
  {
    mLogger.debug("queryGlobalAddresses");
    String retVal = new String();

    if ( !mUseDatabase )
    {
      mLogger.info("queryGlobalAddresses !mUseDatabase");
      // a highly unlikely address
      retVal = "buildadm@erggroup.com";
    }
    else
    {
      try
      {
        CallableStatement stmt = mConnection.prepareCall(
        "select u.user_email from release_manager.build_service_config bsc, release_manager.users u " +
        "where bsc.service='GLOBAL EMAIL ADDRESS LIST' and u.full_name=bsc.config"
        );
        ResultSet rset = stmt.executeQuery();
        
        while( rset.next() )
        {
          String email = rset.getString("user_email");
           
          if ( email != null )
          {
            retVal += email;
          }
        }
            
        rset.close();
        stmt.close();
      }
      catch ( SQLException e )
      {
        if ( mConnection == null || ( mConnection != null && !mConnection.isValid(10) ) )
        {
          mLogger.error("queryGlobalAddresses database access error only");
          throw new SQLException();
        }
        else
        {
          mLogger.fatal("queryGlobalAddresses show stopper");
          throw new Exception("queryGlobalAddresses show stopper");
        }
      }
    }

    mLogger.debug("queryGlobalAddresses returned " + retVal);
    return retVal;
  }

  /**called only in escrow mode
   * if checkCollection is true, checks the pv_id is in the packageCollection
   * if checkCollection is false, or the pv_id is not in the collection
   * 1 traverses the pv_id package dependencies
   *   select dpv.pv_id, p.pkg_name, dpv.pkg_version, dpv.v_ext
   *   from release_manager.package_versions pv, release_manager.package_dependencies pd, release_manager.package_versions dpv, release_manager.packages p
   *   where pv.pv_id = <pv_id> and pd.pv_id=pv.pv_id and dpv.pv_id=pd.dpv_id and p.pkg_id=dpv.pkg_id
   *   order by pv.pv_id;
   * 2 for each dpv.pv_id in the resultset
   *     call traverseDependencies( packageCollection, dpv.pv_id, true )
   *     if the pv_id is not in the collection, add it
   *   
   */
  private void traverseDependencies(Vector<Package> packageCollection, Package pkg, 
                                     boolean checkCollection, 
                                     ListIterator<Package> listIterator) throws SQLException, Exception
  {
    mLogger.debug("traverseDependencies " + checkCollection);
    boolean pvIdInCollection = false;
    
    if ( checkCollection )
    {
      for (Iterator<Package> it = packageCollection.iterator(); it.hasNext(); )
      {
        Package p = it.next();
        
        if ( p.mId == pkg.mId )
        {
          pvIdInCollection = true;
          break;
        }
      }
    }
    
    if ( !pvIdInCollection )
    {
      Vector<Package> resultset = new Vector<Package>();

      if ( !mUseDatabase )
      {
        mLogger.info("traverseDependencies !mUseDatabase");
        
        if ( pkg.mId == 8 || pkg.mId == 10 || pkg.mId == 13 )
        {
          Package p = new Package(9, "CommonDependency", "1.0.0000.tim", ".tim", "CommonDependency.1.0.0000.tim", "CC::/vob/CommonDependency::CommonDependency_1.0.0000.tim", 'x');
          resultset.add(p);
          pkg.mDependencyCollection.add(p.mAlias);
        }
        else if ( pkg.mId == 9 )
        {
          Package p = new Package(7, "CotsWithFunnyVersion", "hoopla2_x.cots", ".cots", "CotsWithFunnyVersion.hoopla2_x.cots", "CC::/vob/CotsWithFunnyVersion::CotsWithFunnyVersion_hoopla2_x.cots", 'x');
          resultset.add(p);
          pkg.mDependencyCollection.add(p.mAlias);
        }
        else if ( pkg.mId == 11 )
        {
          Package p = new Package(14, "AdvisoryDependency", "1.0.0000.tim", ".tim", "AdvisoryDependency.1.0.0000.tim", "CC::/vob/AdvisoryDependency::AdvisoryDependency_1.0.0000.tim", 'x');
          resultset.add(p);
          pkg.mDependencyCollection.add(p.mAlias);
        }
      }
      else
      {
        try
        {
          CallableStatement stmt = mConnection.prepareCall(
            "select dpv.pv_id," +
                   "p.pkg_name," +
                   "dpv.pkg_version," +
                   "dpv.v_ext," +
                   "release_manager.PK_RMAPI.return_vcs_tag(dpv.pv_id) AS vcsTag" +
            " from release_manager.package_versions pv," +
                  "release_manager.package_dependencies pd," +
                  "release_manager.package_versions dpv," +
                  "release_manager.packages p" +
            " where pv.pv_id=" + pkg.mId +
              " and pd.pv_id=pv.pv_id" +
              " and dpv.pv_id=pd.dpv_id" +
              " and p.pkg_id=dpv.pkg_id" +
            " order by pv.pv_id"
          );
          ResultSet rset = stmt.executeQuery();
          
          while( rset.next() )
          {
            int pv_id = rset.getInt("pv_id");
            
            if ( rset.wasNull() )
            {
              mLogger.fatal("traverseDependencies null pv_id");
              // show stopper
              throw new Exception("traverseDependencies null pv_id");
            }
            
            String pkg_name = rset.getString("pkg_name");
            
            if ( pkg_name == null )
            {
              mLogger.fatal("traverseDependencies null pkg_name " + pv_id);
              // show stopper
              throw new Exception("traverseDependencies null pkg_name " + pv_id);
            }
            
            String pkg_version = rset.getString("pkg_version");
            
            if ( pkg_version == null )
            {
              mLogger.fatal("traverseDependencies null pkg_version " + pv_id);
              // show stopper
              throw new Exception("traverseDependencies null pkg_version " + pv_id);
            }
            
            String v_ext = rset.getString("v_ext");
            
            if ( v_ext == null )
            {
              v_ext = "";
            }

            String vcs_tag = rset.getString("vcsTag");
            if ( vcs_tag == null )
            {
              vcs_tag = "";
            }

            Package p = new Package(pv_id, pkg_name, pkg_version, v_ext, pkg_name + "." + pkg_version, vcs_tag, 'x');
            resultset.add(p);
            pkg.mDependencyCollection.add(p.mAlias);
          }
          
          rset.close();
          stmt.close();
        }
        catch ( SQLException e )
        {
          if ( mConnection == null || ( mConnection != null && !mConnection.isValid(10) ) )
          {
            mLogger.fatal("traverseDependencies database access error only");
            throw new SQLException();
          }
          else
          {
            mLogger.fatal("traverseDependencies show stopper");
            throw new Exception("traverseDependencies show stopper");
          }
        }
      }
      
      for (Iterator<Package> it = resultset.iterator(); it.hasNext(); )
      {
        Package r = it.next();
        traverseDependencies(packageCollection, r, true, listIterator);
        
        pvIdInCollection = false;
        
        for (Iterator<Package> it2 = packageCollection.iterator(); it2.hasNext(); )
        {
          Package p = it2.next();
          
          if ( p.mId == r.mId )
          {
            pvIdInCollection = true;
            break;
          }
        }
        
        if (!pvIdInCollection)
        {
          // insert the Package immediately before the next Package returned by next
          // this does not change the next Package (if any) to be returned by next
          listIterator.add(r);
        }
       
      }
    }
  }

  /**called only in escrow mode to add build info to the Package
   * select bm.bm_name, bsa.bsa_name
   * from release_manager.package_versions pv, release_manager.package_build_info pbi, release_manager.build_machines bm, release_manager.build_standards_addendum bsa
   * where pv.pv_id = <p.pv_id> and pbi.pv_id=pv.pv_id and bm.bm_id=pbi.bm_id and bsa.bsa_id=pbi.bsa_id
   * order by pv.pv_id;
   */
  private void queryBuildInfo(RippleEngine rippleEngine, Package p) throws SQLException, Exception
  {
    mLogger.debug("queryBuildInfo");
    if ( !mUseDatabase )
    {
      mLogger.info("queryBuildInfo !mUseDatabase");
      
      if (p.mId == 7)
      {
        BuildStandard bs = new BuildStandard(rippleEngine);
        bs.setSolaris();
        bs.setDebug();
        p.mBuildStandardCollection.add(bs);
      }
      else if (p.mId == 9)
      {
        BuildStandard bs = new BuildStandard(rippleEngine);
        bs.setLinux();
        bs.setDebug();
        p.mBuildStandardCollection.add(bs);
        bs = new BuildStandard(rippleEngine);
        bs.setSolaris();
        bs.setDebug();
        p.mBuildStandardCollection.add(bs);
        bs = new BuildStandard(rippleEngine);
        bs.setWin32();
        bs.setProduction();
        p.mBuildStandardCollection.add(bs);
      }
      else if (p.mId == 10)
      {
        BuildStandard bs = new BuildStandard(rippleEngine);
        bs.setSolaris();
        bs.set1_4();
        p.mBuildStandardCollection.add(bs);
      }
      else if (p.mId == 11)
      {
        BuildStandard bs = new BuildStandard(rippleEngine);
        bs.setLinux();
        bs.setAll();
        p.mBuildStandardCollection.add(bs);
      }
      else if (p.mId == 12)
      {
        BuildStandard bs = new BuildStandard(rippleEngine);
        bs.setWin32();
        bs.set1_6();
        p.mBuildStandardCollection.add(bs);
      }
      else if (p.mId == 13)
      {
        BuildStandard bs = new BuildStandard(rippleEngine);
        bs.setGeneric();
        bs.set1_4();
        p.mBuildStandardCollection.add(bs);
      }
      else if (p.mId == 14)
      {
        BuildStandard bs = new BuildStandard(rippleEngine);
        bs.setLinux();
        bs.setDebug();
        p.mBuildStandardCollection.add(bs);
      }
      
    }
    else
    {
      try
      {
        CallableStatement stmt = mConnection.prepareCall(
        "select bm.bm_name, bsa.bsa_name " +
        "from release_manager.package_versions pv," +
        "     release_manager.package_build_info pbi," +
        "     release_manager.build_machines bm," +
        "     release_manager.build_standards_addendum bsa " +
        "where pv.pv_id=" + p.mId + 
        "   and pbi.pv_id=pv.pv_id" +
        "   and bm.bm_id=pbi.bm_id" +
        "   and bsa.bsa_id=pbi.bsa_id " +
        "order by pv.pv_id"
        );
        ResultSet rset = stmt.executeQuery();
         
        while( rset.next() )
        {
          String bm_name = rset.getString("bm_name");
          
          if ( bm_name == null )
          {
            mLogger.fatal("queryBuildInfo null bm_name " + p.mId);
            // show stopper
            throw new Exception("queryBuildInfo null bm_name " + p.mId);
          }
          
          String bsa_name = rset.getString("bsa_name");
          
          if ( bsa_name == null )
          {
            mLogger.fatal("queryBuildInfo null bsa_name " + p.mId);
            // show stopper
            throw new Exception("queryBuildInfo null bsa_name " + p.mId);
          }

          BuildStandard bs = new BuildStandard(rippleEngine, bm_name, bsa_name);
           
          if ( bs.supportedBuildStandard() )
          {
            p.mBuildStandardCollection.add(bs);
          }
        }
        
        rset.close();
        stmt.close();
      }
      catch ( SQLException e )
      {
        if ( mConnection == null || ( mConnection != null && !mConnection.isValid(10) ) )
        {
          mLogger.error("queryBuildInfo database access error only");
          throw new SQLException();
        }
        else
        {
          mLogger.fatal("queryBuildInfo show stopper");
          throw new Exception("queryBuildInfo show stopper");
        }
      }
    }
  }

  /**returns the Package with the matching mID or NULL_PACKAGE if no package has the mID
   */
  private Package findPackage(int id, Vector<Package> packageCollection)
  {
    mLogger.debug("findPackage 1 id " + id);
    Package retVal = NULL_PACKAGE;

    for (Iterator<Package> it = packageCollection.iterator(); it.hasNext(); )
    {
      Package p = it.next();
      
      if ( p.mId == id )
      {
        retVal = p;
        break;
      }
    }
    
    mLogger.debug("findPackage 1 returned " + retVal.mName);
    return retVal;
  }

/**returns the Package with the matching mAlias or NULL_PACKAGE if no package has the mAlias
   */
  private Package findPackage(String alias, Vector<Package> packageCollection)
  {
    mLogger.debug("findPackage 2 alias " + alias);
    Package retVal = NULL_PACKAGE;

    for (Iterator<Package> it = packageCollection.iterator(); it.hasNext(); )
    {
      Package p = it.next();
      
      if ( p.mAlias.compareTo( alias ) == 0 )
      {
        retVal = p;
        break;
      }
    }

    mLogger.info("findPackage 2 returned " + retVal.mName);
    return retVal;
  }

  /**essentially locks the row in the BUILD_SERVICE_CONFIG table with a service of MUTEX
   * for the duration of the transaction
   * this prevents other MasterThreads from generating build files in parallel
   * and hence prevents planned version numbering contention
   * select CONFIG from release_manager.BUILD_SERVICE_CONFIG WHERE SERVICE='MUTEX' FOR UPDATE
   */
  public void claimMutex() throws SQLException, Exception
  {
    mLogger.debug("claimMutex");
    if ( mUseDatabase && mUseMutex )
    {
      try
      {
        CallableStatement stmt = mConnection.prepareCall("select CONFIG from release_manager.BUILD_SERVICE_CONFIG WHERE SERVICE='MUTEX' FOR UPDATE");
        mLogger.fatal("claimMutex calling stmt.executeUpdate");
        stmt.executeUpdate();
        mLogger.fatal("claimMutex called stmt.executeUpdate");
        stmt.close();
        mDoNotCommit = true;
      }
      catch ( SQLException e )
      {
        if ( mConnection == null || ( mConnection != null && !mConnection.isValid(10) ) )
        {
          mLogger.error("claimMutex database access error only");
          throw new SQLException();
        }
        else
        {
          mLogger.fatal("claimMutex show stopper");
          throw new Exception("claimMutex show stopper");
        }
      }
      // about to start the planning process again, discard previous
      discardVersions();
    }
  }

  /**essentially unlocks the row in the BUILD_SERVICE_CONFIG table with a service of MUTEX
   */
  public void releaseMutex() throws SQLException, Exception
  {
    mLogger.debug("releaseMutex");
    if ( mUseDatabase )
    {
      try
      {
        mDoNotCommit = false;
        mLogger.fatal("releaseMutex calling commit");
        commit();
        mLogger.fatal("releaseMutex called commit");
      }
      catch ( SQLException e )
      {
        if ( mConnection == null || ( mConnection != null && !mConnection.isValid(10) ) )
        {
          mLogger.error("releaseMutex database access error only");
          throw new SQLException();
        }
        else
        {
          mLogger.fatal("releaseMutex show stopper");
          throw new Exception("releaseMutex show stopper");
        }
      }
    }
  }

  /**central commit protection
   */
  private void commit() throws SQLException, Exception
  {
    mLogger.debug("commit");
    if ( mUseDatabase )
    {
      if ( mDoNotCommit )
      {
        mLogger.error("commit attempted commit with mDoNotCommit set, this is a programming error");
      }
      else
      {
        mConnection.commit();
      }
    }
  }

  /**sets CURRENT_BUILD_FILES to NULL for the rcon_id
   * update release_manager.run_level set current_build_files=null where rcon_id=<rcon_id>
   */
  public void clearBuildFile(int rcon_id) throws SQLException, Exception
  {
    mLogger.debug("clearBuildFile");

    try
    {
      connect();
      
      if ( isRconIdConfigured( rcon_id ))
      {
        CallableStatement stmt = mConnection.prepareCall("update release_manager.run_level set current_build_files=null where rcon_id=" + rcon_id);
        stmt.executeUpdate();
        stmt.close();
        commit();
      }
    }
    catch ( SQLException e )
    {
      if ( mConnection == null || ( mConnection != null && !mConnection.isValid(10) ) )
      {
        mLogger.error("clearBuildFile database access error only");
        throw new SQLException();
      }
      else
      {
        mLogger.fatal("clearBuildFile show stopper");
        throw new Exception("clearBuildFile show stopper");
      }
    }
    finally
    {
      // this block is executed regardless of what happens in the try block
      // even if an exception is thrown
      // ensure disconnect
      disconnect();
    }
  }

  /**updates the CURRENT_BUILD_FILES for the rtag_id
   * update (
   * select current_build_files from release_manager.release_manager.run_level rl, release_manager.release_manager.release_config rc
   * where rc.rtag_id=<rtag_id> and rl.rcon_id=rc.rcon_id
   * ) set current_build_files=<buildFile>
   */
  public void publishBuildFile(int rtag_id, String buildFile) throws SQLException, Exception
  {
    mLogger.debug("publishBuildFile publishing a build file of length " + buildFile.length());
    
    try
    {
      connect();

      if ( isRtagIdConfigured( rtag_id ) )
      {
        PreparedStatement stmt = mConnection.prepareStatement(
        "update (" +
        "select current_build_files from release_manager.run_level rl, release_manager.release_config rc " +
        "where rc.rtag_id=? and rl.rcon_id=rc.rcon_id" +
        ") set current_build_files=?");
        stmt.setInt(1, rtag_id);
        stmt.setString(2, buildFile);
        stmt.executeUpdate();
        stmt.close();
        commit();
      }
    }
    catch ( SQLException e )
    {
      if ( mConnection == null || ( mConnection != null && !mConnection.isValid(10) ) )
      {
        mLogger.error("publishBuildFile database access error only");
        throw new SQLException();
      }
      else
      {
        mLogger.fatal("publishBuildFile show stopper");
        throw new Exception("publishBuildFile show stopper");
      }
    }
    catch ( Exception e )
    {
      // this catch and rethrow is historical
      // problems were found using CallableStatement when updating a CLOB column with data > 4000 bytes
      mLogger.fatal("publishBuildFile caught Exception " + e.getMessage());
      throw new Exception("publishBuildFile caught Exception " + e.getMessage());
    }
    finally
    {
      // this block is executed regardless of what happens in the try block
      // even if an exception is thrown
      // ensure disconnect
      disconnect();
    }
  }

  /**ensures a run_level_schedule row with a non null indefinite_pause column exists
   * this is aimed at stopping all daemons dead
   * it is raised when handling an unsupported exception case in either the main or slave daemons
   * typically an SQLException other than a database connection related one
   */
  public void indefinitePause()
  {
    mLogger.debug("indefinitePause");
    if ( mUseDatabase && mUseMutex )
    {
      try
      {
        connect();
        CallableStatement stmt = mConnection.prepareCall( "begin PK_BUILDAPI.SET_INFINITE_PAUSE(); end;" );
        stmt.executeUpdate();
        stmt.close();
        commit();
      }
      catch( SQLException e )
      {
        // do not throw Exception
        // this is part of Exception handling
        mLogger.fatal( "indefinitePause caught SQLException " + e.getMessage() );
      }
      catch( Exception e )
      {
        mLogger.fatal( "indefinitePause caught Exception " + e.getMessage() );
      }
      finally
      {
        // this block is executed regardless of what happens in the try block
        // even if an exception is thrown
        // ensure disconnect
        try
        {
          disconnect();
        }
        catch( SQLException e )
        {
          // do not throw Exception
          // this is part of Exception handling
          mLogger.fatal( "indefinitePause2 caught SQLException " + e.getMessage() );
        }
        catch( Exception e )
        {
          mLogger.fatal( "indefinitePause2 caught Exception " + e.getMessage() );
        }
      }
    }
  }

  /**ensures a run_level_schedule row with a non null indefinite_pause column does not exist
   * this is aimed at resuming all daemons
   */
  private void resume() throws SQLException, Exception
  {
    mLogger.debug("resume");
    if ( mUseDatabase )
    {
      try
      {
        CallableStatement stmt = mConnection.prepareCall( "begin PK_BUILDAPI.SET_RESUME(); end;" );
        stmt.executeUpdate();
        stmt.close();
        commit();
      }
      catch ( SQLException e )
      {
        if ( mConnection == null || ( mConnection != null && !mConnection.isValid(10) ) )
        {
          mLogger.error("resume database access error only");
          throw new SQLException();
        }
        else
        {
          mLogger.fatal("resume show stopper");
          throw new Exception("resume show stopper");
        }
      }
    }
  }

  /**only used in daemon mode to determine version existence in the database
   *  1 select pkg_id from release_manager.package_versions where pkg_id=<pkg_id> and pkg_version=<pkg_version>;
   *  2 select pkg_id from release_manager.planned_versions where pkg_id=<pkg_id> and pkg_version=<pkg_version>;
   * returns true if either resultset contains one record to indicate it already exists
   */
  boolean queryPackageVersions(int pkg_id, String pkg_version) throws SQLException, Exception
  {
    mLogger.debug("queryPackageVersions");
    boolean retVal = false;
    
    if ( mUseDatabase )
    {
      try
      {
        mLogger.info("queryPackageVersions release_manager.package_versions");
        CallableStatement stmt1 = mConnection.prepareCall("select pkg_id from release_manager.package_versions where pkg_id=" + pkg_id + " and pkg_version='" + pkg_version + "'");
        ResultSet rset1 = stmt1.executeQuery();
        int rsetSize = 0;
        
        while( rset1.next() )
        {
          rsetSize++;
        }
        
        rset1.close();
        stmt1.close();

        if ( rsetSize > 1 )
        {
          mLogger.fatal("queryPackageVersions rsetSize > 1 " + pkg_id + " " + pkg_version);
          // show stopper
          throw new Exception("queryPackageVersions rsetSize > 1 " + pkg_id + " " + pkg_version);
        }
        
        if ( rsetSize == 1 )
        {
          retVal = true;
        }
        else
        {
          mLogger.info("queryPackageVersions release_manager.planned_versions");
          CallableStatement stmt2 = mConnection.prepareCall("select pkg_id from release_manager.planned_versions where pkg_id=" + pkg_id + " and pkg_version='" + pkg_version + "'");
          ResultSet rset2 = stmt2.executeQuery();
          rsetSize = 0;
          
          while( rset2.next() )
          {
            rsetSize++;
          }
          
          rset2.close();
          stmt2.close();

          if ( rsetSize > 1 )
          {
            mLogger.fatal("queryPackageVersions rsetSize > 1 " + pkg_id + " " + pkg_version);
            // show stopper
            throw new Exception("queryPackageVersions rsetSize > 1 " + pkg_id + " " + pkg_version);
          }
          
          if ( rsetSize == 1 )
          {
            retVal = true;
          }
        }
      }
      catch ( SQLException e )
      {
        if ( mConnection == null || ( mConnection != null && !mConnection.isValid(10) ) )
        {
          mLogger.error("queryPackageVersions database access error only");
          throw new SQLException();
        }
        else
        {
          mLogger.fatal("queryPackageVersions show stopper");
          throw new Exception("queryPackageVersions show stopper");
        }
      }
    }
    
    mLogger.info("queryPackageVersions returned " + retVal);
    return retVal;
  }

  /**only used in daemon mode
   *  insert into release_manager.planned_versions (pkg_id, pkg_version) values (<pkg_id>, <pkg_version>);
   *  update
   *  (
   *  select current_pkg_id_being_built from release_manager.run_level rl, release_manager.release_config rc
   *  where rc.rtag_id=<rtag_id> and rl.rcon_id=rc.rcon_id
   *  )
   *  set current_pkg_id_being_built=<pkg_id>
   */
  void claimVersion(int pkg_id, String pkg_version, int rtag_id) throws SQLException, Exception
  {
    mLogger.debug("claimVersion " + pkg_id + " " + pkg_version);
    if ( mUseDatabase )
    {
      try
      {
        if (isRtagIdConfigured( rtag_id ))
        {
          CallableStatement stmt3 = mConnection.prepareCall("insert into release_manager.planned_versions (pkg_id, pkg_version, planned_time) values (" + pkg_id + ", '" + pkg_version + "', sysdate)");
          stmt3.executeUpdate();
          stmt3.close();
          CallableStatement stmt4 = mConnection.prepareCall(
          "update " +
          "(" +
          "select current_pkg_id_being_built from release_manager.run_level rl, release_manager.release_config rc " +
          "where rc.rtag_id=" + rtag_id + " and rl.rcon_id=rc.rcon_id" +
          ")" +
          "set current_pkg_id_being_built=" + pkg_id);
          stmt4.executeUpdate();
          stmt4.close();
          mPlannedPkgId = new String();
          mPlannedPkgId += pkg_id;
          mPlannedPkgVersion = new String( pkg_version );
        }
      }
      catch ( SQLException e )
      {
        if ( mConnection == null || ( mConnection != null && !mConnection.isValid(10) ) )
        {
          mLogger.error("claimVersion database access error only");
          throw new SQLException();
        }
        else
        {
          mLogger.fatal("claimVersion show stopper");
          throw new Exception("claimVersion show stopper");
        }
      }
    }
  }

  /**only used in daemon mode
   * delete from release_manager.planned_versions where pkg_id=<pkg_id> and pkg_version=<pkg_version>;
   */
  public void discardVersion() throws SQLException, Exception
  {
    mLogger.debug("discardVersion");
    if ( mPlannedPkgId != null && mPlannedPkgVersion != null )
    {
      try
      {
        CallableStatement stmt = mConnection.prepareCall("delete from release_manager.planned_versions where pkg_id=" + mPlannedPkgId + " and pkg_version='" + mPlannedPkgVersion + "'");
        stmt.executeUpdate();
        stmt.close();
        commit();
        mPlannedPkgId = null;
        mPlannedPkgVersion = null;
      }
      catch ( SQLException e )
      {
        if ( mConnection == null || ( mConnection != null && !mConnection.isValid(10) ) )
        {
          mLogger.error("discardVersion database access error only");
          throw new SQLException();
        }
        else
        {
          mLogger.fatal("discardVersion show stopper");
          throw new Exception("discardVersion show stopper");
        }
      }
    }
  }

  /**only used in daemon mode
   * delete planned versions over 24 hours old (rounded to the nearest hour that is)
   * delete from release_manager.planned_versions where planned_time < trunc(sysdate, 'hh') - 1");
   */
  private void discardVersions() throws SQLException, Exception
  {
    mLogger.debug("discardVersions");
    try
    {
      // housekeep whilst the daemon has the mutex
      // trunc(sysdate, 'hh') returns the time now rounded to the nearest hour
      // trunc(sysdate, 'hh') - 1 returns the time 24 hours ago rounded to the nearest hour
      // this statement does not return any rows when planned_time is null, though this should never be the case
      CallableStatement stmt = mConnection.prepareCall("delete from release_manager.planned_versions where planned_time < trunc(sysdate, 'hh') - 1");
      stmt.executeUpdate();
      stmt.close();
    }
    catch ( SQLException e )
    {
      if ( mConnection == null || ( mConnection != null && !mConnection.isValid(10) ) )
      {
        mLogger.error("discardVersions database access error only");
        throw new SQLException();
      }
      else
      {
        mLogger.fatal("discardVersions show stopper");
        throw new Exception("discardVersions show stopper");
      }
    }
  }

  /**only used in daemon mode
   *  update
   *  (
   *  select current_pkg_id_being_built from release_manager.run_level
   *  where rcon_id=<rcon_id>
   *  )
   *  set current_pkg_id_being_built=null
   */
  public void clearCurrentPackageBeingBuilt(int rcon_id) throws SQLException, Exception
  {
    mLogger.debug("clearCurrentPackageBeingBuilt " + rcon_id);
    if ( mUseDatabase )
    {
      try
      {
        connect();
        
        if ( isRconIdConfigured( rcon_id ))
        {
          CallableStatement stmt4 = mConnection.prepareCall(
          "update " +
          "(" +
          "select current_pkg_id_being_built from release_manager.run_level " +
          "where rcon_id=" + rcon_id +
          ")" +
          "set current_pkg_id_being_built=null" );
          stmt4.executeUpdate();
          stmt4.close();
          commit();
        }
      }
      catch ( SQLException e )
      {
        if ( mConnection == null || ( mConnection != null && !mConnection.isValid(10) ) )
        {
          mLogger.error("clearCurrentPackageBeingBuilt database access error only");
          throw new SQLException();
        }
        else
        {
          mLogger.fatal("clearCurrentPackageBeingBuilt show stopper");
          throw new Exception("clearCurrentPackageBeingBuilt show stopper");
        }
      }
      finally
      {
        // this block is executed regardless of what happens in the try block
        // even if an exception is thrown
        // ensure disconnect
        disconnect();
      }
    }
  }

  /**handles database connection/disconnection
   * executes the AutoMakeRelease stored procedure with the passed parameters
   */
  public boolean autoMakeRelease(String rtagId,
                              String packageName,
                              String packageExtension, 
                              String packageVersion,
                              String packageVcsTag,
                              String packageDepends,
                              String isRipple) throws SQLException, Exception
  {
    mAutoMakeReleaseCause = null;
    mLogger.debug("autoMakeRelease " + packageName);
    if ( mUseDatabase )
    {
      try
      {
        connect();
        CallableStatement stmt = mConnection.prepareCall( "begin ? := PK_RMAPI.AUTO_MAKE_VCSRELEASE(?,?,?,?,?,?,?,?); end;" );
        stmt.registerOutParameter( 1, Types.INTEGER);
        stmt.setString( 2, rtagId );
        stmt.setString( 3, packageName );
        stmt.setString( 4, packageExtension );
        stmt.setString( 5, packageVersion );
        stmt.setString( 6, packageVcsTag );
        stmt.setString( 7, packageDepends );
        stmt.setString( 8, isRipple );
        stmt.setString( 9, "buildadm" );
        stmt.executeUpdate();
        int result = stmt.getInt( 1 );

        //
        //  Return values
        //      >0 PVID of package
        //      -1 Package not found
        //      -2 Package already exists
        //      -3 Not approved for auto build
        //      -4 Package Migrated to SVN being built from CC tag
        //  Sql Application Errors cause an SQLException
        //         Rtagid is NULL
        //         No Package Name
        //         No Package Version
        //         No Package VCS
        //         Bad IsRipple value
        //         No User Name
        //         Malformed VCS Tag
        //         Database missing VCS tag
        //         Invalid UserName
        //

        //
        //  Report per-package errors directly
        //  Exceptions are for errors that need to halt the entire system
        //
        if ( result <= 0 )
        {
            mLogger.fatal("autoMakeRelease PK_RMAPI.AUTO_MAKE_RELEASE failed, returned " + result);
            if ( result == -4 ) {
                mAutoMakeReleaseCause = "Package migrated to SVN being built from CC tag";
            } else if ( result == -3 ) {
                mAutoMakeReleaseCause = "Package not approved for autobuild";
            } else if ( result == -2 ) {
                // This is OK
            } else {
                // Don't know this error - so its fatal
                throw new Exception("autoMakeRelease show stopper PK_RMAPI.AUTO_MAKE_RELEASE failed, returned " + result);
            }
        }
        stmt.close();
        commit();
      }
      catch( SQLException e )
      {
        if ( mConnection == null || ( mConnection != null && !mConnection.isValid(10) ) )
        {
          mLogger.error("autoMakeRelease database access error only");
          throw new SQLException();
        }
        else

        {
          mLogger.fatal("autoMakeRelease show stopper");
          throw new Exception("autoMakeRelease show stopper");
        }
      }
      finally
      {
        // this block is executed regardless of what happens in the try block
        // even if an exception is thrown
        // ensure disconnect
        disconnect();
      }
    }

    return (mAutoMakeReleaseCause != null);
  }

  /**handles database connection/disconnection
   * executes the insertPackageMetrics stored procedure with the passed parameters
   */
  public void insertPackageMetrics(String rtagId, String packageName, 
                                         String packageExtension, String metrics) throws SQLException, Exception
  {
    mLogger.debug("insertPackageMetrics " + packageName);
    if ( mUseDatabase )
    {
      try
      {
        connect();
        CallableStatement stmt = mConnection.prepareCall( "begin ? := PK_RMAPI.INSERT_PACKAGE_METRICS(?,?,?,?); end;" );
        stmt.registerOutParameter( 1, Types.INTEGER);
        stmt.setString( 2, rtagId );
        stmt.setString( 3, packageName );
        stmt.setString( 4, packageExtension );
        stmt.setString( 5, metrics );
        stmt.executeUpdate();
        int result = stmt.getInt( 1 );
        
        if ( result != 0 )
        {
          // flag build failure
          mLogger.fatal("insertPackageMetrics show stopper PK_RMAPI.INSERT_PACKAGE_METRICS failed, returned" + result);
          throw new Exception("insertPackageMetrics show stopper PK_RMAPI.INSERT_PACKAGE_METRICS failed, returned" + result);
        }
        stmt.close();
        commit();
      }
      catch( SQLException e )
      {
        if ( mConnection == null || ( mConnection != null && !mConnection.isValid(10) ) )
        {
          mLogger.error("insertPackageMetrics database access error only");
          throw new SQLException();
        }
        else
        {
          mLogger.fatal("insertPackageMetrics show stopper");
          throw new Exception("insertPackageMetrics show stopper");
        }
      }
      finally
      {
        // this block is executed regardless of what happens in the try block
        // even if an exception is thrown
        // ensure disconnect
        disconnect();
      }
    }
  }

  /**attempts to execute the Exclude_Indirect_From_Build stored procedure
   * NB Execute_Indirect_From_Build will delete matching do_not_ripple rows prior to an insertion
   * this is crucial!!
   * 
   * parameters:
   * packageVersionId IN passed to Exclude_Indirect_From_Build 
   * packageVersion   IN passed to Exclude_Indirect_From_Build 
   * rtagId           IN passed to Exclude_Indirect_From_Build
   * rootPvId         IN passed to Exclude_Indirect_From_Build
   * rootCause        IN passed to Exclude_Indirect_From_Build
   * rootFile         IN passed to Exclude_Indirect_From_Build
   * supercede        IN checks for a row with a matching packageVersionId and rtagId when false
   *                     such a row will prevent the execution of Exclude_Indirect_From_Build
   * testBuildInstruction IN will prevent the execution of Exclude_Indirect_From_Build when > 0
   * 
   * returns:
   * none
   */
  public void excludeFromBuild(String packageVersionId, 
                               String packageVersion, String rtagId, String rootPvId,
                               String rootCause, String rootFile,
                               boolean supercede, int testBuildInstruction) throws SQLException, Exception
  {
    mLogger.debug("excludeFromBuild " + packageVersionId);
    if ( testBuildInstruction > 0 )
    {
      return;
    }
    
    if ( mUseDatabase )
    {
      try
      {
        connect();
        
        boolean exist = false;
        
        if ( !supercede )
        {
          // do not exclude a package already excluded ie let the first build failure count
          // there is a window of opportunity here, but it is worth doing
          // scenario 1
          // 1 this query indicates no build failure exists on this version
          // 2 another build machine reports a build failure on this version
          // 3 this is then overridden by this thread
          // does not matter
          // doing this works well for the following
          // scenario 2
          // 1 this query (run by a slave) indicates no build failure exists on this version
          // 2 build failure is reported
          // 3 master build machine detects slave in state waiting
          // 4 master daemon discovers slave did not deliver artifacts
          // 5 master daemon is prevented from overriding the build failure
          CallableStatement stmt = mConnection.prepareCall("select pv_id from release_manager.do_not_ripple where pv_id=" + packageVersionId + "and rtag_id=" + rtagId);
          ResultSet rset = stmt.executeQuery();
          
          while( rset.next() )
          {
            exist = true;
            break;
          }
  
          rset.close();
          stmt.close();
        }
        
        if ( !exist )
        {
          CallableStatement stmt = mConnection.prepareCall( "begin ? := PK_RMAPI.EXCLUDE_INDIRECT_FROM_BUILD(?,?,?,?,?,?,?); end;" );
          stmt.registerOutParameter( 1, Types.INTEGER);
          stmt.setString( 2, packageVersionId );
          stmt.setString( 3, packageVersion );
          stmt.setString( 4, rtagId );
          stmt.setString( 5, "buildadm" );
          stmt.setString( 6, rootPvId);
          stmt.setString( 7, rootCause);
          stmt.setString( 8, rootFile);
          stmt.executeUpdate();
          int result = stmt.getInt( 1 );
        
          if ( result != 0 )
          {
            // flag build failure
            mLogger.fatal( "excludeFromBuild show stopper PK_RMAPI.EXCLUDE_INDIRECT_FROM_BUILD failed, returned " + result );
            throw new Exception("excludeFromBuild show stopper PK_RMAPI.EXCLUDE_INDIRECT_FROM_BUILD failed, returned " + result);
          }
          stmt.close();
          commit();
        }
      }
      catch( SQLException e )
      {
        if ( mConnection == null || ( mConnection != null && !mConnection.isValid(10) ) )
        {
          mLogger.error("excludeFromBuild database access error only");
          throw new SQLException();
        }
        else
        {
          mLogger.fatal("excludeFromBuild show stopper");
          throw new Exception("excludeFromBuild show stopper");
        }
      }
      finally
      {
        // this block is executed regardless of what happens in the try block
        // even if an exception is thrown
        // ensure disconnect
        disconnect();
      }
    }
  }

  /**executes the get_daemon_inst function with the passed parameters
   * returns true when an instruction exists
   */
  private boolean getDaemonInst(final int rtagId, MutableInt instruction, 
                               final int opCode, MutableInt pvId, MutableInt userId ) throws SQLException, Exception
  {
    mLogger.debug("getDaemonInst " + instruction);
    boolean retVal = false;
    
    if ( mUseDatabase )
    {
      try
      {
        CallableStatement stmt = mConnection.prepareCall( "begin ? := PK_BUILDAPI.GET_DAEMON_INST(?,?,?,?,?,?); end;" );
        stmt.registerOutParameter(1, Types.INTEGER);
        stmt.registerOutParameter(3, Types.INTEGER);
        stmt.registerOutParameter(4, Types.INTEGER);
        stmt.registerOutParameter(5, Types.INTEGER);
        stmt.registerOutParameter(6, Types.INTEGER);
        stmt.registerOutParameter(7, Types.INTEGER);
        stmt.setInt(2, rtagId );
        stmt.setInt( 3, instruction.value );
        stmt.setInt( 4, opCode );
        stmt.execute();
        int result = stmt.getInt( 1 );
        
        if ( result == 1 )
        {
          retVal = true;
          instruction.value = stmt.getInt( 3 );
          pvId.value = stmt.getInt( 5 );
          userId.value = stmt.getInt( 6 );
        }
        
        stmt.close();
      }
      catch( SQLException e )
      {
        if ( mConnection == null || ( mConnection != null && !mConnection.isValid(10) ) )
        {
          mLogger.error("getDaemonInst database access error only");
          throw new SQLException();
        }
        else
        {
          mLogger.fatal("getDaemonInst show stopper");
          throw new Exception("getDaemonInst show stopper");
        }
      }
    }
    
    return retVal;
  }

  /**executes the mark_daemon_inst_in_progress function with the passed parameters
   */
  public void markDaemonInstInProgress(final int instruction) throws SQLException, Exception
  {
    mLogger.debug("markDaemonInstInProgress " + instruction);
    
    if ( mUseDatabase )
    {
      try
      {
        CallableStatement stmt = mConnection.prepareCall( "call PK_BUILDAPI.MARK_DAEMON_INST_IN_PROGRESS(?)" );
        stmt.setInt( 1, instruction );
        stmt.executeUpdate();
        stmt.close();
      }
      catch( SQLException e )
      {
        if ( mConnection == null || ( mConnection != null && !mConnection.isValid(10) ) )
        {
          mLogger.error("markDaemonInstInProgress database access error only");
          throw new SQLException();
        }
        else
        {
          mLogger.fatal("markDaemonInstInProgress show stopper");
          throw new Exception("markDaemonInstInProgress show stopper");
        }
      }
    }
  }

  /**executes the mark_daemon_inst_completed function with the passed parameters
   */
  public void markDaemonInstCompleted(final int instruction) throws SQLException, Exception
  {
    mLogger.debug("markDaemonInstCompleted " + instruction);
    
    if ( mUseDatabase )
    {
      try
      {
        CallableStatement stmt = mConnection.prepareCall( "call PK_BUILDAPI.MARK_DAEMON_INST_COMPLETED(?)" );
        stmt.setInt( 1, instruction );
        stmt.executeUpdate();
        stmt.close();
      }
      catch( SQLException e )
      {
        if ( mConnection == null || ( mConnection != null && !mConnection.isValid(10) ) )
        {
          mLogger.error("markDaemonInstCompleted database access error only");
          throw new SQLException();
        }
        else
        {
          mLogger.fatal("markDaemonInstCompleted show stopper");
          throw new Exception("markDaemonInstCompleted show stopper");
        }
      }
    }
  }

  /**handles database connection/disconnection
   * executes the mark_daemon_inst_completed function with the passed parameters
   */
  public void markDaemonInstCompletedConnect(final int instruction) throws SQLException, Exception
  {
    mLogger.debug("markDaemonInstCompletedConnect " + instruction);
    
    try
    {
      connect();
      markDaemonInstCompleted(instruction);
      commit();
    }
    catch( SQLException e )
    {
      if ( mConnection == null || ( mConnection != null && !mConnection.isValid(10) ) )
      {
        mLogger.error("markDaemonInstCompletedConnect database access error only");
        throw new SQLException();
      }
      else
      {
        mLogger.fatal("markDaemonInstCompletedConnect show stopper");
        throw new Exception("markDaemonInstCompletedConnect show stopper");
      }
    }
    finally
    {
      // this block is executed regardless of what happens in the try block
      // even if an exception is thrown
      // ensure disconnect
      disconnect();
    }
  }

  /**removes an excluded package from the do_not_ripple table
   */
  public void includeToBuild(String packageVersionId, String rtagId) throws SQLException, Exception
  {
    mLogger.debug("includeToBuild " + packageVersionId);
    if ( mUseDatabase )
    {
      try
      {
        CallableStatement stmt = mConnection.prepareCall("delete from release_manager.do_not_ripple where rtag_id=" + rtagId + " and pv_id=" + packageVersionId);
        stmt.executeUpdate();
        stmt.close();
      }
      catch( SQLException e )
      {
        if ( mConnection == null || ( mConnection != null && !mConnection.isValid(10) ) )
        {
          mLogger.error("includeToBuild database access error only");
          throw new SQLException();
        }
        else
        {
          mLogger.fatal("includeToBuild show stopper");
          throw new Exception("includeToBuild show stopper");
        }
      }
    }
  }

   
  

  /**constructor
   */
  public ReleaseManager(final String connectionString, final String username, 
                        final String password)
  {
    mLogger.debug("ReleaseManager " + connectionString);
    mConnectionString = connectionString;
    mUsername = username;
    mPassword = password;

    String gbeBtDebug = System.getenv("GBE_BUILDTOOL_DEBUG");
    if ( gbeBtDebug != null )
    {
      mLogger.fatal("GBE_BUILDTOOL_DEBUG set - Use of database mutex supressed");
      mUseMutex = false;
    }
  }

  /**constructor used when schema information is unknown eg location, username, password
   */
  public ReleaseManager()
  {
    // inherit mConnectionString, mUsername, mPassword
     mLogger.debug("ReleaseManager");
  }

  /**connect to oracle
   */
  public void connect() throws SQLException, Exception
  {
    mLogger.debug("connect");
    mNonPlanningConnection = connect( mSession, mNonPlanningConnection );
  }

  /**connect to oracle
   */
  public void connectForPlanning( boolean priority ) throws SQLException, Exception
  {
    mLogger.debug("connectForPlanning");
    
    if ( !priority )
    {
      // limit only one thread with a low priority build requirement to connect
      if ( mLowPriorityQueue.isHeldByCurrentThread() )
      {
        // by design a thread must NOT connect multiple times
        // this is to ensure the lock is claimed only once
        mLogger.error("connectForPlanning thread already has the lock");
      }
      else
      {
        mLogger.warn("connectForPlanning calling lock");
        mLowPriorityQueue.lock();
        mLogger.warn("connectForPlanning called lock");
      }
    }
    
    // threads with a high priority build requirement are not subject to the mLowPriorityQueue
    mPlanningConnection = connect( mPlanningSession, mPlanningConnection );    
  }

  /**connect to oracle
   */
  private Connection connect( ReentrantLock session, Connection connection ) throws SQLException, Exception
  {
    mLogger.debug("connect");

    try
    {
      if ( session.isHeldByCurrentThread() )
      {
        // by design a thread must NOT connect multiple times
        // this is to ensure the lock is claimed only once
        mLogger.error("connect thread already has the lock");
      }
      else
      {
        mLogger.warn("connect calling lock");
        session.lock();
        mLogger.warn("connect called lock");
      }
      
      if ( !mUseDatabase )
      {
        mLogger.info("connect !mUseDatabase");
      }
      else
      {
        // DEVI 46868
        // loop indefinitely until a connection attempt succeeds
        // unless the failure is on the first attempt
        boolean problemConnecting;
        
        do
        {
          mLogger.warn("connect check connection");
          problemConnecting = false;
          
          try
          {
            if ( connection == null || ( connection != null && !connection.isValid(10) ) )
            {
              mLogger.warn("connect calling getConnection");
              connection = DriverManager.getConnection(mConnectionString, mUsername, mPassword);
              // when connection to the database is established, the connection, by default, is in auto-commit mode
              // to adhere to the design in the use of select for update, it is crucial to turn auto-commit off
              // this also improves performance
              connection.setAutoCommit(false);
            }
          }
          catch(SQLException e)
          {
            mLogger.warn("connect determined problem connecting");
            problemConnecting = true;
            try
            {
              // sleep 30 secs
              mLogger.warn("connect getConnection failed. sleep 30secs");
              Thread.sleep(30000);
            }
            catch (InterruptedException f)
            {
              mLogger.warn("connect caught InterruptedException");
            }
  
            if ( connection == null )
            {
              // failed on first connection attempt - unlikely due to database loading - likely bad connection parameters
              throw new SQLException();
            }
          }
        } while ( problemConnecting );
          mLogger.warn("connect checked connection");
      }
    }
    finally
    {
      mConnection = connection;
mLogger.warn("connect finally connection");
    }
    return connection;

  }

  /**disconnect from oracle
   */
  public void disconnect() throws Exception
  {
    mLogger.debug("disconnect");
    
    disconnect( mSession );
  }

  /**disconnect from oracle
   */
  public void disconnectForPlanning( boolean priority ) throws Exception
  {
    mLogger.warn("disconnectForPlanning");
    
    if ( !priority )
    {
      // allow another low priority thread to connect
      mLowPriorityQueue.unlock();
    }
    
    disconnect( mPlanningSession );
  }

  /**disconnect from oracle
   */
  private void disconnect( ReentrantLock session ) throws Exception
  {
    mLogger.debug("disconnect");
    
    // by design, a thread may call disconnect multiple times
    // this is a technique used in finally blocks
    // it is to ensure the lock is released in all cases
    // only unlock if it is held by this thread
    // when unlock is called on a ReentrantLock held by this thread
    // the hold count is decremented
    // connect should only let the hold count be incremented to 1
    // when the hold count is 0 the lock is released
    // and the ReentrantLock is no longer held by this thread
    // only call unlock when the lock is held by this thread
    if ( session.isHeldByCurrentThread() )
    {
      mLogger.warn("disconnected calling unlock");
      session.unlock();
      mLogger.warn("disconnected called unlock");
    }
  }

  /**queries the RUN_LEVEL table using the rcon_id primary key
   * returns false if the query returns a result set containing one row with a non NULL pause column
   * returns false if the rcon_id is no longer configured
   * (indicating intent to pause the thread)
   * refer to sequence diagram allowed to proceed
   */
  public boolean queryDirectedRunLevel(final int rcon_id) throws SQLException, Exception
  {
    mLogger.debug("queryDirectedRunLevel " + rcon_id);
    boolean retVal = true;
    
    if ( mUseDatabase )
    {
      try
      {
        if ( isRconIdConfigured( rcon_id ))
        {
          CallableStatement stmt = mConnection.prepareCall("select pause from release_manager.run_level where rcon_id=" + rcon_id);
          ResultSet rset = stmt.executeQuery();
          int rsetSize = 0;
          
          while( rset.next() )
          {
            rsetSize++;
            rset.getInt("pause");
            
            if ( !rset.wasNull() )
            {
              retVal = false;
            }
          }
          
          rset.close();
          stmt.close();
  
          if ( rsetSize > 1 )
          {
            mLogger.fatal("queryDirectedRunLevel rsetSize > 1");
            // show stopper
            throw new Exception("queryDirectedRunLevel rsetSize > 1");
          }
        }
        else
        {
          retVal = false;
        }
      }
      catch ( SQLException e )
      {
        if ( mConnection == null || ( mConnection != null && !mConnection.isValid(10) ) )
        {
          mLogger.error("queryDirectedRunLevel database access error only");
          throw new SQLException();
        }
        else
        {
          mLogger.fatal("queryDirectedRunLevel show stopper");
          throw new Exception("queryDirectedRunLevel show stopper");
        }
      }
    }
   
    mLogger.info("queryDirectedRunLevel returning " + retVal);
    return retVal;
  }

  /**queries the RELEASE_CONFIG table using the rcon_id primary key, rtag_id, daemon_hostname, daemon_mode
   * return true if the query contains a result set containing one row
   * (indicating the rcon_id is still configured and its configuration is unchanged, aside from the gbe_buildfilter)
   * the gbe_buildfilter is queried prior to usage
   * refer to sequence diagram allowed to proceed
   */
  public boolean queryReleaseConfig(final int rtag_id, final int rcon_id, 
                                    final String daemon_hostname, 
                                    final char daemon_mode) throws SQLException, Exception
  {
    mLogger.debug("queryReleaseConfig 1");
    boolean retVal = false;
    
    if ( !mUseDatabase )
    {
      mLogger.info("queryReleaseConfig 1 !mUseDatabase");
      
      if ( mConnectionString.compareTo("unit test exit") != 0 )
      {
        retVal = true;
      }
    }
    else
    {
      try
      {
        String sql = new String(
            "select rc.gbe_buildfilter, rl.pause " +
            "from release_manager.release_config rc, release_manager.release_tags rt, release_manager.run_level rl " +
            " where rc.rtag_id=" + rtag_id +
            " and rc.rcon_id=" + rcon_id +
            " and rc.daemon_hostname='" + daemon_hostname + "'" +
            " and rc.daemon_mode='" + daemon_mode + "'" +
            " and rl.rcon_id=" + rcon_id +
            " and rt.rtag_id=rc.rtag_id and (rt.official = 'N' or rt.official='R' or rt.official='C')" );

        CallableStatement stmt = mConnection.prepareCall( sql );
        ResultSet rset = stmt.executeQuery();
        int rsetSize = 0;
        
        while( rset.next() )
        {
          rsetSize++;

          //
          //  Pause: null -> 0 == Run
          //         1         == Pause
          //         2         == Disabled
          //
          int pause = rset.getInt("pause");
          if ( rset.wasNull() )
          {
            pause = 0;
          }
          mLogger.info("queryReleaseConfig 1: " + rtag_id + ", " + rcon_id + ", "+ daemon_mode + ", " + pause );


          if ( pause <= 1 )
          {
            retVal = true;
          }
        }
        
        rset.close();
        stmt.close();

        if ( rsetSize > 1 )
        {
          mLogger.fatal("queryReleaseConfig 1 rsetSize > 1");
          // show stopper
          throw new Exception("queryReleaseConfig 1 rsetSize > 1");
        }
      }
      catch ( SQLException e )
      {
        if ( mConnection == null || ( mConnection != null && !mConnection.isValid(10) ) )
        {
          mLogger.error("queryReleaseConfig 1 database access error only");
          throw new SQLException();
        }
        else
        {
          mLogger.fatal("queryReleaseConfig 1 show stopper");
          throw new Exception("queryReleaseConfig 1 show stopper");
        }
      }
    }
    
    mLogger.info("queryReleaseConfig 1 returning " + retVal);
    return retVal;
  }

  /**removes all elements from the mReleaseConfigCollection
   * handles database connection and disconnection
   * queries the RELEASE_CONFIG table using the rtag_id
   * populates the mReleaseConfigCollection with the query result set
   * partially implements the sequence diagrams coordinate slave threads generate build files 
   *  
   * Used by Master Thread to determine the build machines that will be a part 
   * of the Slave-Sync process. 
   */
  public void queryReleaseConfig(final int rtag_id) throws SQLException, Exception
  {
    mLogger.debug("queryReleaseConfig 2");
    mReleaseConfigCollection.removeAllElements();
    
    if ( !mUseDatabase )
    {
      mLogger.info("queryReleaseConfig 2 !mUseDatabase");
      ReleaseConfig releaseConfig = new ReleaseConfig(1,1,'M', "DummyHost1","DummyTarget1", "DummyMachtype1", "Win32");
      mReleaseConfigCollection.add(releaseConfig);
      releaseConfig = new ReleaseConfig(1,2,'S', "DummyHost2","DummyTarget2", "DummyMachtype1", "Linux");
      mReleaseConfigCollection.add(releaseConfig);
    }
    else
    {
      try
      {
        connect();
        
        CallableStatement stmt = mConnection.prepareCall(
            " select rc.rcon_id, rc.daemon_mode, rl.pause, bc.machine_hostname, rc.gbe_buildfilter, mt.gbe_value, bm.bm_name" +
            "    from release_manager.release_config rc, " +
            "         release_manager.run_level rl, " +
            "         release_manager.build_machine_config bc, " +
            "         release_manager.gbe_machtype mt," +
            "         release_manager.build_machines bm" +
            "    where rc.rtag_id=" + rtag_id +
            "        and rl.rcon_id=rc.rcon_id " +
            "        and bc.machine_hostname=rc.daemon_hostname " +
            "        and mt.gbe_id=bc.gbe_id" +
            "        and mt.bm_id=bm.bm_id"
            );

        ResultSet rset = stmt.executeQuery();
        
        while( rset.next() )
        {
          int rcon_id = rset.getInt("rcon_id");
          
          if ( rset.wasNull() )
          {
            mLogger.fatal("queryReleaseConfig 2 null rcon_id " + rtag_id);
            // show stopper
            throw new Exception("queryReleaseConfig 2 null rcon_id " + rtag_id);
          }

          char dm = 'S';          
          String daemon_mode = rset.getString("daemon_mode");
          
          if ( daemon_mode != null )
          {
            mLogger.info("queryReleaseConfig 2 daemon_mode " + daemon_mode + ".");
            
            if ( daemon_mode.compareTo("M") == 0 )
            {
              dm = 'M';
            }
          }

          String machine_hostname = rset.getString("machine_hostname");
          if (machine_hostname == null)
          {
              mLogger.fatal("queryReleaseConfig 2 null machine_hostname " + rtag_id);
              throw new Exception("queryReleaseConfig 2 null machine_hostname " + rtag_id);
          }

          String gbe_buildfilter = rset.getString("gbe_buildfilter");

          String gbe_machtype = rset.getString("gbe_value");
          if (gbe_machtype == null)
          {
              mLogger.fatal("queryReleaseConfig 2 null gbe_value " + rtag_id);
              throw new Exception("queryReleaseConfig 2 null gbe_value " + rtag_id);
          }

          String gbe_machclass = rset.getString("bm_name");
          if (gbe_machclass == null)
          {
              mLogger.fatal("queryReleaseConfig 2 null bm_name " + rtag_id);
              throw new Exception("queryReleaseConfig 2 null bm_name " + rtag_id);
          }

          //
          //  Pause: null -> 0 == Run
          //         1         == Pause
          //         2         == Disabled
          //
          int pause = rset.getInt("pause");
          if ( rset.wasNull() )
          {
            pause = 0;
          }
          mLogger.info("queryReleaseConfig 2: " + rtag_id + ", " + rcon_id + ", "+ dm + ", " + pause + 
                       ", " + machine_hostname + ", " + gbe_buildfilter + ", " + gbe_machtype + ", + " + gbe_machclass );

          //
          // Do not include build daemons that are disabled
          //
          if ( pause <= 1 )
          {
            ReleaseConfig releaseConfig = new ReleaseConfig( rtag_id, rcon_id, dm, machine_hostname, gbe_buildfilter, gbe_machtype, gbe_machclass);
            mReleaseConfigCollection.add(releaseConfig);
          }
        }
        
        
        rset.close();
        stmt.close();
      }
      catch ( SQLException e )
      {
        if ( mConnection == null || ( mConnection != null && !mConnection.isValid(10) ) )
        {
          mLogger.error("queryReleaseConfig 2 daemon_mode database access error only");
          throw new SQLException();
        }
        else
        {
          mLogger.fatal("queryReleaseConfig 2 show stopper");
          throw new Exception("queryReleaseConfig 2 show stopper");
        }
      }
      finally
      {
        // this block is executed regardless of what happens in the try block
        // even if an exception is thrown
        // ensure disconnect
        disconnect();
      }
    }
  }

  /**removes all elements from the mReleaseConfigCollection
   * handles database connection and disconnection
   * queries the RELEASE_CONFIG table using the daemon_hostname
   * populates the mReleaseConfigCollection with the query result set
   * partially implements the sequence diagram spawn thread 
   *  
   * Used by each build thread to determine daemons to start and stop
   */
  public void queryReleaseConfig(final String hostname) throws SQLException, Exception
  {
    mLogger.debug("queryReleaseConfig 3 " + hostname);
    mReleaseConfigCollection.removeAllElements();
    
    if ( mConnectionString.compareTo("unit test spawn thread") == 0)
    {
      mLogger.info("queryReleaseConfig 3 unit test spawn thread");
      // specifying a gbebuildfilter of unit test is designed to invoke a benign thread for unit test purposes
      ReleaseConfig releaseConfig = new ReleaseConfig(1,1,'M', "DummyHost1","DummyTarget1", "DummyMachtype1", "Win32");
      mReleaseConfigCollection.add(releaseConfig);
      releaseConfig = new ReleaseConfig(2,2,'S', "DummyHost2","DummyTarget2", "DummyMachtype2", "Linux");
      mReleaseConfigCollection.add(releaseConfig);
    }
    else
    {
      try
      {
        connect();
        CallableStatement stmt = mConnection.prepareCall(
            "select rc.rtag_id, rc.rcon_id, rc.daemon_mode, rl.pause, bc.machine_hostname, rc.gbe_buildfilter, mt.gbe_value, bm.bm_name" +
            "    from release_manager.release_config rc," +
            "       release_manager.release_tags rt," +
            "       release_manager.run_level rl," +
            "       release_manager.build_machine_config bc," +
            "       release_manager.gbe_machtype mt," +
            "       release_manager.build_machines bm " +
            "    where rc.daemon_hostname='"+ hostname +"'" +
            "      and rt.rtag_id=rc.rtag_id" +
            "      and rl.rcon_id=rc.rcon_id" +
            "      and bc.machine_hostname=rc.daemon_hostname" +
            "      and mt.gbe_id=bc.gbe_id" +
            "      and mt.bm_id=bm.bm_id" +
            "      and (rt.official = 'N' or rt.official='R' or rt.official='C')"
            );


        ResultSet rset = stmt.executeQuery();
        
        while( rset.next() )
        {
          int rtag_id = rset.getInt("rtag_id");
          
          if ( rset.wasNull() )
          {
            mLogger.fatal("queryReleaseConfig 3 null rtag_id");
            // show stopper
            throw new Exception("queryReleaseConfig 3 null rtag_id");
          }

          int rcon_id = rset.getInt("rcon_id");
          
          if ( rset.wasNull() )
          {
            mLogger.fatal("queryReleaseConfig 3 null rcon_id");
            throw new Exception("queryReleaseConfig 3 null rcon_id");
          }

          char dm = 'S';          
          String daemon_mode = rset.getString("daemon_mode");
          
          if ( daemon_mode != null )
          {
            mLogger.info("queryReleaseConfig 3 daemon_mode " + daemon_mode + ".");
          
            if ( daemon_mode.compareTo("M") == 0 )
            {
              dm = 'M';
            }
          }

          String machine_hostname = rset.getString("machine_hostname");
          if (machine_hostname == null)
          {
              mLogger.fatal("queryReleaseConfig 3 null machine_hostname " + rtag_id);
              throw new Exception("queryReleaseConfig 3 null machine_hostname " + rtag_id);
          }

          String gbe_buildfilter = rset.getString("gbe_buildfilter");

          String gbe_machtype = rset.getString("gbe_value");
          if (gbe_machtype == null)
          {
              mLogger.fatal("queryReleaseConfig 3 null gbe_value " + rtag_id);
              throw new Exception("queryReleaseConfig 3 null gbe_value " + rtag_id);
          }

          String gbe_machclass = rset.getString("bm_name");
          if (gbe_machclass == null)
          {
              mLogger.fatal("queryReleaseConfig 3 null bm_name " + rtag_id);
              throw new Exception("queryReleaseConfig 3 null bm_name " + rtag_id);
          }
          
          //
          //  Pause: null -> 0 == Run
          //         1         == Pause
          //         2         == Disabled
          //
          int pause = rset.getInt("pause");
          if ( rset.wasNull() )
          {
            pause = 0;
          }

          mLogger.info("queryReleaseConfig 3: " + rtag_id + ", " + rcon_id + ", "+ dm + ", " + pause + 
                       ", " + machine_hostname + ", " + gbe_buildfilter + ", " + gbe_machtype + ", + " + gbe_machclass );

          //
          // Do not include build daemons that are disabled
          // Only those that are running or paused
          //
          if ( pause <= 1 )
          {
            ReleaseConfig releaseConfig = new ReleaseConfig( rtag_id, rcon_id, dm, machine_hostname, gbe_buildfilter, gbe_machtype, gbe_machclass);
            mReleaseConfigCollection.add(releaseConfig);
          }
        }
        
        rset.close();
        stmt.close();
      }
      catch ( SQLException e )
      {
        if ( mConnection == null || ( mConnection != null && !mConnection.isValid(10) ) )
        {
          mLogger.error("queryReleaseConfig 3 database access error only");
          throw new SQLException();
        }
        else
        {
          mLogger.fatal("queryReleaseConfig 3 show stopper");
          throw new Exception("queryReleaseConfig 3 show stopper");
        }
      }
      finally
      {
        // this block is executed regardless of what happens in the try block
        // even if an exception is thrown
        // ensure disconnect
        disconnect();
      }
    }
  }

  /**queries the RUN_LEVEL table using the rcon_id primary key
   * handles database connection and disconnection
   * returns the current_build_files
   * implements the sequence diagram consume build files 
   *  
   * Used by the Slave Daemon 
   */
  public void queryBuildFile(int rcon_id, MutableString currentBuildFiles) throws SQLException, Exception
  {
    mLogger.debug("queryRunLevel 1 rcon_id " + rcon_id);
    if ( !mUseDatabase )
    {
      mLogger.info("queryRunLevel 1 !mUseDatabase");
      currentBuildFiles.value = "unit test build file content";
    }
    else
    {
      try
      {
        connect();
        CallableStatement stmt = mConnection.prepareCall("select current_build_files from release_manager.run_level where rcon_id=" + rcon_id);
        ResultSet rset = stmt.executeQuery();
        int rsetSize = 0;
        
        while( rset.next() )
        {
          rsetSize++;
          currentBuildFiles.value = rset.getString("current_build_files");
          if (rset.wasNull())
          {
            currentBuildFiles.value = "";
          }
        }

        if ( rsetSize > 1 )
        {
          mLogger.fatal("queryRunLevel 1 rsetSize > 1");
          // show stopper
          throw new Exception("queryRunLevel 1 rsetSize > 1");
        }
        
        rset.close();
        stmt.close();
      }
      catch ( SQLException e )
      {
        if ( mConnection == null || ( mConnection != null && !mConnection.isValid(10) ) )
        {
          mLogger.error("queryRunLevel 1 database access error only");
          throw new SQLException();
        }
        else
        {
          mLogger.fatal("queryRunLevel 1 show stopper");
          throw new Exception("queryRunLevel 1 show stopper");
        }
      }
      finally
      {
        // this block is executed regardless of what happens in the try block
        // even if an exception is thrown
        // ensure disconnect
        disconnect();
      }
    }
  }

  /**removes all elements from the mRunLevelCollection
   * handles database connection and disconnection
   *   select rl.rcon_id, rl.current_run_level from release_manager.release_config rc, release_manager.run_level rl
   *   where rc.rtag_id=<rtag_id> and rl.rcon_id=rc.rcon_id;
   * populates the mRunLevelCollection with the query result set
   * refer to sequence diagram coordinate slave threads 
   *  
   * Used by the Master Daemon 
   */
  public void queryRunLevel(final int rtag_id) throws SQLException, Exception
  {
    mLogger.debug("queryRunLevel 2 rtag_id " + rtag_id);
    if ( mConnectionString.compareTo("unit test coordinate slave threads") == 0)
    {
      mLogger.info("queryRunLevel 2 unit test coordinate slave threads");
      
      if ( mRunLevelCollection.size() == 0)
      {
        // first time not all slave threads are waiting
        RunLevelData runLevel = new RunLevelData(1, DB_WAITING);
        mRunLevelCollection.add(runLevel);
        runLevel = new RunLevelData(2, DB_IDLE);
        mRunLevelCollection.add(runLevel);
      }
      else
      {
        // subsequent times all slave threads are waiting
        mRunLevelCollection.removeAllElements();
        RunLevelData runLevel = new RunLevelData(1, DB_WAITING);
        mRunLevelCollection.add(runLevel);
        runLevel = new RunLevelData(2, DB_WAITING);
        mRunLevelCollection.add(runLevel);
      }
    }
    
    if ( mUseDatabase )
    {
      mRunLevelCollection.removeAllElements();

      try
      {
        connect();
        CallableStatement stmt = mConnection.prepareCall(
            "select rl.rcon_id, rl.current_run_level from release_manager.release_config rc, release_manager.run_level rl " +
            "where rc.rtag_id=" +rtag_id + " and rl.rcon_id=rc.rcon_id");
        ResultSet rset = stmt.executeQuery();
        int rcon_id = 0;
        int current_run_level = 0;
        
        while( rset.next() )
        {
          rcon_id = rset.getInt("rcon_id");
          
          if ( rset.wasNull() )
          {
            mLogger.fatal("queryRunLevel 2 null rcon_id");
            // show stopper
            throw new Exception("queryRunLevel 2 null rcon_id");
          }
          
          current_run_level = rset.getInt("current_run_level");

          if ( rset.wasNull() )
          {
            // slave may never have started to insert run level
            // use idle
            current_run_level = DB_IDLE;
          }
          
          RunLevelData runLevel = new RunLevelData(rcon_id, current_run_level);
          mRunLevelCollection.add(runLevel);
        }

        rset.close();
        stmt.close();
      }
      catch ( SQLException e )
      {
        if ( mConnection == null || ( mConnection != null && !mConnection.isValid(10) ) )
        {
          mLogger.error("queryRunLevel 2 database access error only");
          throw new SQLException();
        }
        else
        {
          mLogger.fatal("queryRunLevel 2 show stopper");
          throw new Exception("queryRunLevel 2 show stopper");
        }
      }
      finally
      {
        // this block is executed regardless of what happens in the try block
        // even if an exception is thrown
        // ensure disconnect
        disconnect();
      }
    }
  }

  /**removes all elements from the mRunLevelCollection
   * handles database connection and disconnection
   *   select rcon_id, current_run_level from release_manager.run_level
   *   where rcon_id=<rcon_id>;
   * populates the mRunLevelCollection with the query result set
   */
  public void querySingleRunLevel(final int rcon_id) throws SQLException, Exception
  {
    mLogger.debug("querySingleRunLevel rcon_id " + rcon_id);
    if ( !mUseDatabase )
    {
      mLogger.info("querySingleRunLevel !mUseDatabase");
      
      mRunLevelCollection.removeAllElements();
      RunLevelData runLevel = new RunLevelData(rcon_id, DB_ACTIVE);
      mRunLevelCollection.add(runLevel);
    }
    else
    {
      mRunLevelCollection.removeAllElements();

      try
      {
        connect();
        
        if (isRconIdConfigured( rcon_id ))
        {
          CallableStatement stmt = mConnection.prepareCall(
          "select rcon_id, current_run_level from release_manager.run_level " +
          "where rcon_id=" +rcon_id);
          ResultSet rset = stmt.executeQuery();
          int rsetSize = 0;
          int current_run_level = 0;
          
          while( rset.next() )
          {
            rsetSize++;
            current_run_level = rset.getInt("current_run_level");
  
            if ( rset.wasNull() )
            {
              mLogger.fatal("querySingleRunLevel null current_run_level");
              // show stopper
              throw new Exception("querySingleRunLevel null current_run_level");
            }
            
            RunLevelData runLevel = new RunLevelData(rcon_id, current_run_level);
            mRunLevelCollection.add(runLevel);
          }
  
          rset.close();
          stmt.close();
  
          if ( rsetSize != 1 )
          {
            mLogger.fatal("querySingleRunLevel rsetSize != 1");
            // show stopper
            throw new Exception("querySingleRunLevel rsetSize != 1");
          }
        }
      }
      catch ( SQLException e )
      {
        if ( mConnection == null || ( mConnection != null && !mConnection.isValid(10) ) )
        {
          mLogger.error("querySingleRunLevel database access error only");
          throw new SQLException();
        }
        else
        {
          mLogger.fatal("querySingleRunLevel show stopper");
          throw new Exception("querySingleRunLevel show stopper");
        }
      }
      finally
      {
        // this block is executed regardless of what happens in the try block
        // even if an exception is thrown
        // ensure disconnect
        disconnect();
      }
    }
  }

  /**queries the RUN_LEVEL_SCHEDULE table
   * when recover is true, checks for archive existence and runs resume when both archives exist
   * this should delete rows with a non NULL indefinite pause
   * returns false if a row in the query result set indicates build service downtime is scheduled
   * returns false if a row in the query result set has a non NULL indefinite_pause
   * refer to the sequence diagram allowed to proceed
   */
  public boolean queryRunLevelSchedule(Date resumeTime, boolean recover) throws SQLException, Exception
  {
    mLogger.debug("queryRunLevelSchedule");
    boolean retVal = true;
    
    if ( !mUseDatabase )
    {
      mLogger.info("queryRunLevelSchedule !mUseDatabase");
      
      if ( mConnectionString.compareTo("unit test not allowed to proceed") == 0 )
      {
        // schedule a 100ms max wait
        resumeTime.setTime( resumeTime.getTime() + 100 );
        retVal = false;
      }
    }
    else
    {
      try
      {
        if ( recover )
        {
          if ( Package.recover() )
          {
            // dpkg and deploy archives exist
            // clear the indefinite pause condition
            resume();
          }
        }
        CallableStatement stmt = mConnection.prepareCall("select scheduled_pause, scheduled_resume, repeat, indefinite_pause from release_manager.run_level_schedule");
        ResultSet rset = stmt.executeQuery();
        Date now = new Date();


        //
        //  Scan the database information and determine if there is any reason
        //  to pause. Terminate the loop on the first excuse to pause
        //  as indefinite pause may have multiple (lots) of entries in the data
        //  base.
        //
        while( retVal == true && rset.next() )
        {
          //
          //  Examine the current row from the data base
          //  Expect one of two forms:
          //    1) scheduled_pause
          //       Must also have a scheduled_resume and a repeat
          //    2) indefinite_pause
          //

          //  Look for scheduled_pause style of entry
          //
          Timestamp sp = rset.getTimestamp("scheduled_pause");
          if ( sp != null )
          {
            Date scheduled_pause = new Date( sp.getTime() );
            Timestamp sr = rset.getTimestamp("scheduled_resume");
            
            if ( sr != null )
            {
              Date scheduled_resume = new Date( sr.getTime() );
              int repeat = rset.getInt("repeat");
              mLogger.info("queryRunLevelSchedule repeat " + repeat);

              //
              //  Have scheduled_pause and scheduled_resume
              //  Examine the repeat field and determine how these are used
              //  Supported repeat:
              //      Once Only
              //      Daily           Year, Month and Day information is ignored
              //      Weekly          Only day of week is utilised
              //
              if ( !rset.wasNull() )
              {
                switch( repeat )
                {
                  case 0:
                  {
                    // one off
                    if ( scheduled_pause.before(now) && scheduled_resume.after(now) )
                    {
                      mLogger.warn("queryRunLevelSchedule one off scheduled downtime");
                      resumeTime = scheduled_resume;
                      retVal = false;
                    }
                    break;
                  }
                  case 1:
                  {
                    //  daily
                    //  Create start and end fimes, then massage some fields
                    //  to reflect todays date
                    //
                    GregorianCalendar startOfDowntime = new GregorianCalendar();
                    startOfDowntime.setTime(scheduled_pause);
                    GregorianCalendar endOfDowntime = new GregorianCalendar();
                    endOfDowntime.setTime(scheduled_resume);
                    GregorianCalendar clock = new GregorianCalendar();
                    clock.setTime(now);

                    // Force date fields to todays date
                    endOfDowntime.set  ( clock.get(Calendar.YEAR), clock.get(Calendar.MONTH), clock.get(Calendar.DAY_OF_MONTH) );
                    startOfDowntime.set( clock.get(Calendar.YEAR), clock.get(Calendar.MONTH), clock.get(Calendar.DAY_OF_MONTH) );

                    if ( startOfDowntime.before(clock) && endOfDowntime.after(clock) )
                    {
                      mLogger.warn("queryRunLevelSchedule daily scheduled downtime");
                      resumeTime.setTime(endOfDowntime.getTimeInMillis());
                      retVal = false;
                    }
                    break;
                  }
                  case 7:
                  {
                    // weekly
                    // Create start and end times, then massage some fields
                    // to reflect todays date
                    //
                    GregorianCalendar startOfDowntime = new GregorianCalendar();
                    startOfDowntime.setTime(scheduled_pause);
                    GregorianCalendar endOfDowntime = new GregorianCalendar();
                    endOfDowntime.setTime(scheduled_resume);
                    GregorianCalendar clock = new GregorianCalendar();
                    clock.setTime(now);

                    // Only interested in one day of the week
                    if ( startOfDowntime.get(Calendar.DAY_OF_WEEK) == clock.get(Calendar.DAY_OF_WEEK) )
                    {
                      endOfDowntime.set  ( clock.get(Calendar.YEAR), clock.get(Calendar.MONTH), clock.get(Calendar.DAY_OF_MONTH) );
                      startOfDowntime.set( clock.get(Calendar.YEAR), clock.get(Calendar.MONTH), clock.get(Calendar.DAY_OF_MONTH) );
                       
                      if ( startOfDowntime.before(clock) && endOfDowntime.after(clock) )
                      {
                        mLogger.warn("queryRunLevelSchedule weekly scheduled downtime");
                        resumeTime.setTime(endOfDowntime.getTimeInMillis());
                        retVal = false;
                      }
                    }
                    break;
                  }
                }
              }
            }
          }

          //
          //  Look for indefinite_pause style of entry
          //  Note: due to an implemenation error there may be many
          //        rows that match. We only need one. The scan will
          //        be terminated if we find any
          //  
          //
          String ip = rset.getString("indefinite_pause");
          if ( ip != null )
          {
            // indefinite pause is non null
            mLogger.warn("queryRunLevelSchedule indefinite pause");
            GregorianCalendar clock = new GregorianCalendar();
            clock.setTime(now);
            // wait a minute
            resumeTime.setTime(clock.getTimeInMillis() + 60000);
            retVal = false;
          }
        }
        
        rset.close();
        stmt.close();
      }
      catch ( SQLException e )
      {
        if ( mConnection == null || ( mConnection != null && !mConnection.isValid(10) ) )
        {
          mLogger.error("queryRunLevelSchedule database access error only");
          throw new SQLException();
        }
        else
        {
          mLogger.fatal("queryRunLevelSchedule show stopper");
          throw new Exception("queryRunLevelSchedule show stopper");
        }
      }
    }
    
    mLogger.info("queryRunLevelSchedule returning " + retVal);
    return retVal;
  }

  /**returns true if the rcon_id is configured
   */
  private boolean isRconIdConfigured(final int rcon_id) throws SQLException, Exception
  {
    mLogger.debug("isRconIdConfigured");
    boolean retVal = false;
    
    try
    {
      // check if the rcon_id is still configured
      CallableStatement stmt = mConnection.prepareCall("select rcon_id from release_manager.release_config where rcon_id=" + rcon_id);
      ResultSet rset = stmt.executeQuery();
      
      while( rset.next() )
      {
        retVal = true;
      }
      
      rset.close();
      stmt.close();
    }
    catch( SQLException e )
    {
      if ( mConnection == null || ( mConnection != null && !mConnection.isValid(10) ) )
      {
        mLogger.fatal("isRconIdConfigured database access error only");
        throw new Exception("isRconIdConfigured database access error only");
      }
      else
      {
        mLogger.fatal("isRconIdConfigured show stopper");
        throw new Exception("isRconIdConfigured show stopper");
      }
    }
    mLogger.info("isRconIdConfigured returning " + retVal);
    return retVal;
  }
  
  /**returns true if the rcon_id is configured
   */
  private boolean isRtagIdConfigured(final int rtag_id) throws SQLException, Exception
  {
    mLogger.debug("isRtagIdConfigured");
    boolean retVal = false;
    
    try
    {
      // check if the rcon_id is still configured
      CallableStatement stmt = mConnection.prepareCall("select rtag_id from release_manager.release_config where rtag_id=" + rtag_id);
      ResultSet rset = stmt.executeQuery();
      
      while( rset.next() )
      {
        retVal = true;
      }
      
      rset.close();
      stmt.close();
    }
    catch( SQLException e )
    {
      if ( mConnection == null || ( mConnection != null && !mConnection.isValid(10) ) )
      {
        mLogger.fatal("isRtagIdConfigured database access error only");
        throw new Exception("isRtagIdConfigured database access error only");
      }
      else
      {
        mLogger.fatal("isRtagIdConfigured show stopper");
        throw new Exception("isRtagIdConfigured show stopper");
      }
    }
    mLogger.info("isRtagIdConfigured returning " + retVal);
    return retVal;
  }
  
    /**persists the runLevel in the RUN_LEVEL table for the rcon_id primary key
   * refer to sequence diagrams generate build files, allowed to proceed, not allowed to proceed, exit, check environment
   */
  public void updateCurrentRunLevel(final int rcon_id, final int runLevel, final boolean insert) throws SQLException, Exception
  {
    mLogger.debug("updateCurrentRunLevel");
    if ( !mUseDatabase )
    {
      mLogger.info("updateCurrentRunLevel !mUseDatabase");
      Integer i = new Integer(runLevel);
      mPersistedRunLevelCollection.add(i);
    }
    else
    {
      try
      {
        connect();
        boolean update = false;
        {
          // check if the rcon_id exists in the table
          CallableStatement stmt = mConnection.prepareCall("select rcon_id from release_manager.run_level where rcon_id=" + rcon_id);
          ResultSet rset = stmt.executeQuery();
mLogger.warn("updateCurrentRunLevel: checked existance: " + rcon_id);
          
          while( rset.next() )
          {
            update = true;
          }
          
          rset.close();
          stmt.close();
        }
        
        // the insert flag ensures the insertion is controlled
        // it should only be set initially in the BuildThread run methods
        if ( !update && insert )
        {
          
          if (isRconIdConfigured( rcon_id ))
          {
mLogger.warn("updateCurrentRunLevel: Must insert: " + rcon_id);
            CallableStatement stmt = mConnection.prepareCall("insert into release_manager.run_level (rcon_id) values (" + rcon_id + ")" );
            stmt.executeUpdate();
            stmt.close();
          }
        }

        {
          // DEVI 52589 provide a keep alive indication
mLogger.warn("updateCurrentRunLevel: Set Runlevel:" + runLevel + ", rcon_id: " + rcon_id);
          PreparedStatement stmt = mConnection.prepareCall("update release_manager.run_level set current_run_level=" + runLevel + ", keep_alive=SYSDATE where rcon_id=" + rcon_id);
          stmt.executeUpdate();
          stmt.close();
        }
mLogger.warn("updateCurrentRunLevel: committing");
        commit();
mLogger.warn("updateCurrentRunLevel: committed");
      }
      catch( SQLException e )
      {
        if ( mConnection == null || ( mConnection != null && !mConnection.isValid(10) ) )
        {
          mLogger.fatal("updateCurrentRunLevel database access error only");
          throw new SQLException("updateCurrentRunLevel database access error only");
        }
        else
        {
          mLogger.fatal("updateCurrentRunLevel show stopper");
          throw new Exception("updateCurrentRunLevel show stopper");
        }
      }
      finally
      {
        // this block is executed regardless of what happens in the try block
        // even if an exception is thrown
        // ensure disconnect
        disconnect();
      }
    }
  }

  public void queryBuildExclusions(Vector<BuildExclusion> buildExclusionCollection, int baseline) throws SQLException, Exception
  {
    mLogger.debug("queryBuildExclusions " + baseline);
    
    if ( !mUseDatabase )
    {
      mLogger.info("queryBuildExclusions !mUseDatabase");
    }
    else
    {
      try
      {
        CallableStatement stmt = mConnection.prepareCall("select pv_id, root_pv_id, root_cause from release_manager.do_not_ripple where rtag_id=" + baseline);
        ResultSet rset = stmt.executeQuery();
        
        while( rset.next() )
        {
          int pvId = rset.getInt("pv_id");
          
          if ( rset.wasNull() )
          {
            mLogger.fatal("queryBuildExclusions rset null pv_id");
            // show stopper
            throw new Exception("queryBuildExclusions rset null pv_id");
          }
          
          int rootPvId = rset.getInt("root_pv_id");
          
          if ( rset.wasNull() )
          {
            // quite acceptable
            rootPvId = -1;
          }
          
          // again, a null root_cause is quite acceptable
          String rootCause = rset.getString("root_cause");
          
          // force email notification by using a zero test build instruction
          BuildExclusion buildExclusion = new BuildExclusion(pvId, rootPvId, rootCause, 0);
          buildExclusionCollection.add(buildExclusion);
        }

        rset.close();
        stmt.close();
      }
      catch ( SQLException e )
      {
        if ( mConnection == null || ( mConnection != null && !mConnection.isValid(10) ) )
        {
          mLogger.error("queryBuildExclusions database access error only");
          throw new SQLException();
        }
        else
        {
          mLogger.fatal("queryBuildExclusions show stopper");
          throw new Exception("queryBuildExclusions show stopper");
        }
      }
    }
  }
}