#!/usr/bin/perl
package ColleagueCurationMod_base;
#
# Author:           Shuai Weng
# Date:             Sept. 1999
# Description:      This package contains all colleague submission
#                   related subroutines for SDEV and dictyBase databases
##################           RCS INFORMATION          ################
# $Author: emj466 $
# $Date: 2010/08/31 18:58:19 $
# $Header: /projects/dicty/build/source_files/db/lib/site_name/curation/ColleagueCurationMod_base.pm,v 1.4 2010/08/31 18:58:19 emj466 Exp $
# $Log: ColleagueCurationMod_base.pm,v $
# Revision 1.4  2010/08/31 18:58:19  emj466
# merged HEAD with release-2-18
# Committed on the Free edition of March Hare Software CVSNT Server.
# Upgrade to CVS Suite for more features and support:
# http://march-hare.com/cvsnt/
#
# Revision 1.3.20.1  2010/08/31 16:54:19  emj466
# merged with no-prepare-cache branch
# Committed on the Free edition of March Hare Software CVSNT Server.
# Upgrade to CVS Suite for more features and support:
# http://march-hare.com/cvsnt/
#
# Revision 1.3.24.1  2010/08/30 21:04:12  emj466
# changed prepare_cached to prepare
# Committed on the Free edition of March Hare Software CVSNT Server.
# Upgrade to CVS Suite for more features and support:
# http://march-hare.com/cvsnt/
#
# Revision 1.3  2007/06/19 15:11:12  emj466
# substitute @@_dbuser_ @@ for cgm_ddb
#
# Revision 1.2  2006/10/26 15:46:51  emj466
# replaced is_dictyBase_contact with 'is_subscribed'
#
# Revision 1.1  2006/10/25 18:29:11  emj466
# new build directory
#
# Revision 1.1.1.2  2003/08/18 22:50:40  emj466
# no message
#
# Revision 1.1.1.1  2003/08/15 20:18:40  emj466
# initial load of dicty/build
#
# Revision 1.22  2003/03/20 19:04:25  shuai
# *** empty log message ***
#
# Revision 1.21  2003/03/20 17:34:32  shuai
# *** empty log message ***
#
# Revision 1.22  2003/01/23 21:34:56  shuai
# *** empty log message ***
#
# Revision 1.21  2003/01/22 21:26:16  shuai
# *** empty log message ***
#
# Revision 1.20  2003/01/09 00:36:14  kara
# added new subroutine dictyBasecontact to deal with new is_subscribed column
# in colleague table
#
# $Revision: 1.4 $
# $Source: /projects/dicty/build/source_files/db/lib/site_name/curation/ColleagueCurationMod_base.pm,v $
# $State: Exp $
# $Locker:  $
######################################################################
#
use strict;
use DBI;
use CGI qw/:standard :html3/;
use LWP::UserAgent;
use lib "/usr/local/dicty/www_dictybase/db/lib/common"; 
use Login  qw (ConnectToDatabase);
use lib "/usr/local/dicty/www_dictybase/db/lib/dictyBase"; 
use dictyBaseCentralMod qw(:formatPage :getInfo);
use lib "/usr/local/dicty/www_dictybase/db/lib/dictyBase/Objects";
use ConfigURLdictyBase;
use Locus;


use Exporter();
use vars qw ($VERSION @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS);

$VERSION = 1.00;
@ISA = qw( Exporter );

%EXPORT_TAGS = (formSub => [qw/subtitle smalltitle newEntryHeader updateHeader arrow dictyBasecontact lastName firstName suffix otherName email jobTitle profession institution address city state region country zipCode phone webPage associate4pi pi associate interest keyword comment newCuratorNote delayDelete deleteFile delayFile returnForm submitReset researchTopics associatedLoci/],
		insertUpdateInfo => [qw/insertEmails insertUrls insertPi insertAssocsBYpi insertAssocs insertKeywords insertComments insertCuratorNote updateCuratorNote updateGenericAssociate insertAssociatedLoci/],
		deleteInfo => [qw/deleteColleagueEntryBYid deleteAssocsBYpi deleteAssocs deletePi deleteKeywords/]
);

#  add all tags to @EXPORT_OK
Exporter::export_ok_tags('formSub');
Exporter::export_ok_tags('insertUpdateInfo');
Exporter::export_ok_tags('deleteInfo');

our $database = "dictyBase";
our $configUrl = ConfigURLdictyBase->new;
our $dblink = $configUrl->dblink($database);

########################################################################
sub subtitle {
########################################################################
    my ($subtitle) = @_;
    return table({-border=>'0',
		  -cellpadding=>'4',
		  -cellspacing=>'3',
		  -width=>'650'},
		 Tr(td({-width=>'100%',
			-bgcolor=>'#a4abc2'},
		       font({-size=>'+2'},
			    b($subtitle)))));
}

########################################################################
sub submitReset {
########################################################################
    return p,
	   table({-border=>'0',
		  -cellpadding=>'0',
		  -cellspacing=>'0',
		  -width=>'650',
		  -bgcolor=>'#a4abc2'},
		 Tr(td({-width=>'15%'},
		       font({-size=>'+2'},
			    submit(-name=>'submit',
				   -value=>'Submit'))).
		    td({-width=>'10%'},
		       font({-size=>'+2'},
			    submit(-name=>'reset',
				   -value=>'Reset'))).
		    td({-width=>'75%'},
		       br)));
}

########################################################################
sub smalltitle {
########################################################################
    my ($smalltitle) = @_;
    return table({-border=>'0',
		  -cellpadding=>'4',
		  -cellspacing=>'3',
		  -width=>'650'},
		 Tr(td({-width=>'100%',
			-bgcolor=>'#a4abc2'},
		       font({-size=>'+1'},
			    b($smalltitle)))));


}

########################################################################
sub newEntryHeader {
########################################################################
    return Tr({-bgcolor=>'#CCCCCC'},
	      td().
	      th({-bgcolor=>'#a4abc2'},
		 "new entry").
	      td());
}

########################################################################
sub updateHeader {
########################################################################
    return Tr({-bgcolor=>'#CCCCCC'},
	      td().
	      th({-bgcolor=>'#CCCCCC'},
		 "prior entry").
	      th({-bgcolor=>'#a4abc2'},
		 "new entry"));
}

########################################################################
sub arrow {
########################################################################
    return td({-align=>'left'},
	      img({-src=>$configUrl->dictyBaseImages."delta.gif",
		   -width=>"27",
		   -height=>"18"}));

}

########################################################################
sub dictyBasecontact {
########################################################################
    ## KD: added for dictyBase contact stuff
    my ($new, $type, $old) = @_;
    my $entry = td({-width=>'140',
		  -bgcolor=>'#ACBDCC'},
		 "contact? ".
		 font({-color=>'red',
		       -size=>'2'},
		      b("[required]")));
    my $arrow;
    if ($type =~ /update/i) {
	if ($old ne $new) { $arrow = "yes"; }
	if (!$old) { $old = br;}
	$entry .= td({-width=>'250',
		      -bgcolor=>"#d8d8d8"},
		     $old);
    }
    $entry .= td(textfield(-name=>'dictyBasecontact', 
			   -value=>"$new", 
			   -size=>'20'));
    if (!$type) {
	$entry .= td("(Y or N)");
    }
    elsif ($arrow) {
	$entry .= &arrow;
    }
    else {
	$entry .= td(br);
    }
    return Tr($entry);
}

########################################################################
sub lastName {
########################################################################
    my ($new, $type, $old) = @_;
    my $entry = td({-width=>'140',
		  -bgcolor=>'#ACBDCC'},
		 "Last Name ".
		 font({-color=>'red',
		       -size=>'2'},
		      b("[required]")));
    my $arrow;
    if ($type =~ /update/i) {
	if ($old ne $new) { $arrow = "yes"; }
	if (!$old) { $old = br;}
	$entry .= td({-width=>'250',
		      -bgcolor=>"#d8d8d8"},
		     $old);
    }
    $entry .= td(textfield(-name=>'lname', 
			   -value=>"$new", 
			   -size=>'20'));
    if (!$type) {
	$entry .= td("(e.g., Jones, Smyth)");
    }
    elsif ($arrow) {
	$entry .= &arrow;
    }
    else {
	$entry .= td(br);
    }
    return Tr($entry);
}

########################################################################
sub firstName {
########################################################################
    my ($new, $type, $old) = @_;

    my $entry = td({-width=>'140',
		  -bgcolor=>'#ACBDCC'},
		 "First Name ".
		 font({-color=>'red',
		       -size=>'2'},
		      b("[required]")));
    my $arrow;
    if ($type =~ /update/i) {
	if ($old ne $new) { $arrow = "yes"; }
	if (!$old) { $old = br;}
	$entry .= td({-width=>'250',
		      -bgcolor=>"#d8d8d8"},
		     $old);
    }
    $entry .= td(textfield(-name=>'fname', 
			   -value=>"$new", 
			   -size=>'20'));
    if (!$type) {
	$entry .= td("(e.g., John, C. David, Linda M.)");
    }
    elsif ($arrow) {
	$entry .= &arrow;
    }
    else {
	$entry .= td(br);
    }
    return Tr($entry);
}

########################################################################
sub suffix {
########################################################################
    my ($new, $type, $old) = @_;
    my @suffixList = ('', 'Sr.', 'Jr.', 'II', 'III', 'IV');
    
    my $entry = td({-width=>'140',
		  -bgcolor=>'#ACBDCC'},
		   "Suffix ");
    my $arrow;
    if ($type =~ /update/i) {
	if ($old ne $new) { $arrow = "yes"; }
	if (!$old) { $old = br;}
      	$entry .= td({-width=>'250',
		      -bgcolor=>"#d8d8d8"},
		     $old);
    }
    $entry .= td(popup_menu(-name=>'suffix', 
			    -"value"=>\@suffixList,
			    -default=>"$new"));
    if ($arrow) {
	$entry .= &arrow;
    }
    else {
	$entry .= td(br);
    }
    return Tr($entry);
}

########################################################################
sub otherName {
########################################################################
    my ($new, $type, $old) = @_;
   
    my $entry = td({-width=>'140',
		  -bgcolor=>'#ACBDCC'},
		   "Other Name ");
    my $arrow;
    if ($type =~ /update/i) {
	if ($old ne $new) { $arrow = "yes"; }
	if (!$old) { $old = br;}
	$entry .= td({-width=>'250',
		      -bgcolor=>"#d8d8d8"},
		     $old);
    }
    $entry .= td(textfield(-name=>'oname', 
			   -value=>"$new", 
			   -size=>'20'));
    if (!$type) {
	$entry .= td("(e.g., your maiden name)");
    }
    elsif ($arrow) {
	$entry .= &arrow;
    }
    else {
	$entry .= td(br);
    }
    return Tr($entry);

}

########################################################################
sub email {
########################################################################
    my ($new, $type, $old) = @_;
   
    my $entry = td({-width=>'140',
		  -bgcolor=>'#ACBDCC'},
		 "E-mail ".
		 font({-color=>'red',
		       -size=>'2'},
		      b("[required]")));
    my $arrow;
    if ($type =~ /update/i) {
	if ($old ne $new) { $arrow = "yes"; }
	if (!$old) { $old = br;}
	$entry .= td({-width=>'250',
		      -bgcolor=>"#d8d8d8"},
		     $old);
    }
    $entry .= td(textfield(-name=>'email', 
			   -value=>"$new", 
			   -size=>'30'));
    if (!$type) {
	$entry .= td("(if more than one, separate by space)");
    }
    elsif ($arrow) {
	$entry .= &arrow;
    }
    else {
	$entry .= td(br);
    }
    return Tr($entry);
}

#######################################################################
sub jobTitle {
#######################################################################
    my ($new, $type, $old) = @_;

    my $entry = td({-width=>'140',
		  -bgcolor=>'#ACBDCC'},
		   "Job Title ");
    my $arrow;
    if ($type =~ /update/i) {
	if ($old ne $new) { $arrow = "yes"; }
	if (!$old) { $old = br;}
	$entry .= td({-width=>'250',
		      -bgcolor=>"#d8d8d8"},
		     $old);
    }
    $entry .= td(textfield(-name=>'jobtitle', 
			   -value=>"$new", 
			   -size=>'30'));
    if (!$type) {
	$entry .= td("(e.g., Research Fellow, Post-Doc)");
    }
    elsif ($arrow) {
	$entry .= &arrow;
    }
    else {
	$entry .= td(br);
    }
    return Tr($entry);
}

#######################################################################
sub profession {
#######################################################################
    my ($new, $type, $old) = @_;

    my $entry = td({-width=>'140',
		    -bgcolor=>'#ACBDCC'},
		   "Profession ");
    my $arrow;
    if ($type =~ /update/i) {
	if ($old ne $new) { $arrow = "yes"; }
	if (!$old) { $old = br;}
	$entry .= td({-width=>'250',
		      -bgcolor=>"#d8d8d8"},
		     $old);
    }
    $entry .= td(textfield(-name=>'profession', 
			   -value=>"$new", 
			   -size=>'30'));
    if (!$type) {
	$entry .= td("(e.g., Dictyostelium Molecular Biologist)");
    }
    elsif ($arrow) {
	$entry .= &arrow;
    }
    else {
	$entry .= td(br);
    }
    return Tr($entry);
}

#######################################################################
sub institution {
#######################################################################
    my ($new, $type, $old) = @_;

    my $entry = td({-width=>'140',
		  -bgcolor=>'#ACBDCC'},
		   "Organization ".
		   font({-color=>'red',
			 -size=>'2'},
			b("[required]")));
    my $arrow;
    if ($type =~ /update/i) {
	if ($old ne $new) { $arrow = "yes"; }
	if (!$old) { $old = br;}
	$entry .= td({-width=>'250',
		      -bgcolor=>"#d8d8d8"},
		     $old);
    }
    $entry .= td(textfield(-name=>'institution', 
			   -value=>"$new", 
			   -size=>'30'));
    if (!$type) {
	$entry .= td("(e.g., Stanford University)");
    }
    elsif ($arrow) {
	$entry .= &arrow;
    }
    else {
	$entry .= td(br);
    }
    return Tr($entry);
}

#######################################################################
sub address {
#######################################################################
    my ($newRef, $type, $oldRef) = @_;
    my $address;
    for (my $i = 0; $i < 5; $i++) {
	my $j = $i+1;
	my $new = $$newRef[$i];
	my $old;
	if ($type) { $old = $$oldRef[$i]; }
	my $entry = td({-width=>'140',
		  -bgcolor=>'#ACBDCC'},
		   "Address ");
	my $arrow;
	if ($type =~ /update/i) {
	    if ($old ne $new) { $arrow = "yes"; }
	    if (!$old) { $old = br;}
	    $entry .= td({-width=>'250',
			  -bgcolor=>"#d8d8d8"},
			 $old);
	}
	$entry .= td(textfield(-name=>"addr$j", 
			       -value=>"$new", 
			       -size=>'30'));
	if ($arrow) {
	    $entry .= &arrow;
	}
	else {
	    $entry .= td(br);
	}
	$address .= Tr($entry);
    }
    return $address;
	      
}

#######################################################################
sub city {
#######################################################################
    my ($new, $type, $old) = @_;

    my $entry = td({-width=>'140',
		  -bgcolor=>'#ACBDCC'},
		   "City ");
    my $arrow;
    if ($type =~ /update/i) {
	if ($old ne $new) { $arrow = "yes"; }
	if (!$old) { $old = br;}
	$entry .= td({-width=>'250',
		      -bgcolor=>"#d8d8d8"},
		     $old);
    }
    $entry .= td(textfield(-name=>'city', 
			   -value=>"$new", 
			   -size=>'30'));
    if ($arrow) {
	$entry .= &arrow;
    }
    else {
	$entry .= td(br);
    }
    return Tr($entry);
}

#######################################################################
sub state {
#######################################################################
    my ($dbh, $country, $new, $type, $old) = @_;
    my $sth = $dbh->prepare( "
        SELECT abbrev, country
        FROM   CGM_DDB.state
        ORDER BY  1
    ");
    $sth->execute;
    my @usaList;
    my @canadaList;
    push(@usaList, "USA State (none)");
    push(@canadaList, "Canadian Province (none)");
    while(my ($abbrev, $country) = $sth->fetchrow()) {
	if ($country eq "USA") {
	    push(@usaList, $abbrev); 
	}
	else {
	    push(@canadaList, $abbrev); 
	}    
    }
    $sth->finish;
##############
    my ($USAstate, $canadaPro);
    if ($country =~ /usa/i) {
	$USAstate = $new;
    }
    else {
	$canadaPro = $new;
    }
    my $entry = td({-width=>'140',
		  -bgcolor=>'#ACBDCC'},
		   " State/Provinces ");
    my $arrow;
    if ($type =~ /update/i) {
	if (($old ne $new) 
	    && !(($old eq "") 
		 && ($new eq "USA State (none)"))
	     && (($country =~ /us/i) || ($country =~ /canada/i))) { 
	    $arrow = "yes"; 
	}

	if (!$old) { $old = br;}
	$entry .= td({-width=>'250',
		      -bgcolor=>"#d8d8d8"},
		     $old);
    }
    $entry .= td(popup_menu(-name=>'USAstate', 
			    -value=>\@usaList, 
			    -default=>"$USAstate")." OR".
		 popup_menu(-name=>'CanadaPro', 
			    -value=>\@canadaList, 
			    -default=>"$canadaPro"));
    if ($arrow) {
	$entry .= &arrow;
    }
    else {
	$entry .= td(br);
    }
    return Tr($entry);

}

#######################################################################
sub region {
#######################################################################
    my ($new, $type, $old) = @_;

    my $entry = td({-width=>'140',
		  -bgcolor=>'#ACBDCC'},
		   "Region ");
    my $arrow;
    if ($type =~ /update/i) {
	if ($old ne $new) { $arrow = "yes"; }
	if (!$old) { $old = br;}
	$entry .= td({-width=>'250',
		      -bgcolor=>"#d8d8d8"},
		     $old);
    }
    $entry .= td(textfield(-name=>'region', 
			   -value=>"$new", 
			   -size=>'30'));
    if ($arrow) {
	$entry .= &arrow;
    }
    else {
	$entry .= td(br);
    }
    return Tr($entry);
}

########################################################################
sub country {
########################################################################
    my ($new, $type, $old) = @_;

    my $entry = td({-width=>'140',
		  -bgcolor=>'#ACBDCC'},
		   "Country ");
    my $arrow;
    if ($type =~ /update/i) {
	if ($old ne $new) { $arrow = "yes"; }
	if (!$old) { $old = br;}
	$entry .= td({-width=>'250',
		      -bgcolor=>"#d8d8d8"},
		     $old);
    }
    $entry .= td(textfield(-name=>'country', 
			   -value=>"$new", 
			   -size=>'30'));
    if ($arrow) {
	$entry .= &arrow;
    }
    else {
	$entry .= td(br);
    }
    return Tr($entry);
}

########################################################################
sub zipCode {
########################################################################
    my ($new, $type, $old) = @_;

    my $entry = td({-width=>'140',
		  -bgcolor=>'#ACBDCC'},
		   " Postal Code/Zip Code ");
    my $arrow;
    if ($type =~ /update/i) {
	if ($old ne $new) { $arrow = "yes"; }
	if (!$old) { $old = br;}
	$entry .= td({-width=>'250',
		      -bgcolor=>"#d8d8d8"},
		     $old);
    }
    $entry .= td(textfield(-name=>'zip_code', 
			   -value=>"$new", 
			   -size=>'30'));
    if ($arrow) {
	$entry .= &arrow;
    }
    else {
	$entry .= td(br);
    }
    return Tr($entry);
}

########################################################################
sub phone {
########################################################################
    my ($PhoneTypeNumRef, $oldPhoneTypeNumRef, $type) = @_;
    my @thisPhoneTypeNum = @$PhoneTypeNumRef;
    my @oldPhoneTypeNum;
    if ($type =~ /update/) {
       @oldPhoneTypeNum = @$oldPhoneTypeNumRef;
    }
    my @DisplayOrder = ("Lab Phone", "Office Phone", "Department Phone", 
			 "Phone", "Lab Fax", "Office Fax", "Department Fax", 
			 "Fax", "Mobile", "Pager", "Telex");
    if ($#thisPhoneTypeNum >= 1) {
	my @tmplist;
	for (my $i = 0; $i <= 10; $i++) {
	    for (my $j = 0; $j <= $#thisPhoneTypeNum; $j++) {
		if ($thisPhoneTypeNum[$j] =~ /^$DisplayOrder[$i]/i) {
		    push(@tmplist, $thisPhoneTypeNum[$j]);
		}
	    }
	}
	undef @thisPhoneTypeNum;
	@thisPhoneTypeNum = @tmplist;
    }  
    if ($#oldPhoneTypeNum >= 1) {
	my @tmplist;
	for (my $i = 0; $i <= 10; $i++) {
	    for (my $j = 0; $j <= $#oldPhoneTypeNum; $j++) {
		if ($oldPhoneTypeNum[$j] =~ /^$DisplayOrder[$i]/i) {
		    push(@tmplist, $oldPhoneTypeNum[$j]);
		}
	    }
	}
	undef @oldPhoneTypeNum;
	@oldPhoneTypeNum = @tmplist;
    }  

    my @phoneTypeList = ("Please specify", "Lab Phone", "Lab Fax", 
		      "Office Phone", "Office Fax", "Department Phone", 
		      "Department Fax", "Phone", "Fax", "Mobile", "Pager", 
		      "Telex");

    my $entry = Tr(td({-width=>'140',
		       -bgcolor=>'#ACBDCC',
		       -rowspan=>'6'},
		      "Phone/Fax/Telex Numbers"));
    for (my $i = 1; $i <= 5 ; $i++) {
          my ($phoneType, $phoneNum) 
                 = split(/ = /, $thisPhoneTypeNum[$i-1]);
	  my $item;
	  if ($type =~ /update/i) {
	      my ($oldPhoneType, $oldPhoneNum) 
		  = split(/ = /, $oldPhoneTypeNum[$i-1]);
	      $item = td({-width=>'160',
			  -bgcolor=>"#d8d8d8"},
			 $oldPhoneType.br$oldPhoneNum);
	  }
	  $item .= td(textfield(-name=>"phone$i",
				-value=>"$phoneNum",
				-size=>'30').br.
		      popup_menu(-name=>"phone_type$i",
				       -value=>\@phoneTypeList,
				       -default=>"$phoneType"));
	           
	  if ($type =~ /update/i) { 
	      if ($oldPhoneTypeNum[$i-1] =~ /^ *= *$/) {
		  $oldPhoneTypeNum[$i-1] = "";
	      }
	      if ($oldPhoneTypeNum[$i-1] ne $thisPhoneTypeNum[$i-1]) {
		  $item .= &arrow;
	      }  
	  }
	  $entry .= Tr($item);
    }
    return $entry;
}

########################################################################
sub webPage {
########################################################################

    my ($URLTypeRef, $oldURLTypeRef, $type) = @_;
    my @thisURLType = @$URLTypeRef;
    my @oldURLType;

    my $maxNumURLs = 3;

    if ($type =~ /update/) {
	@oldURLType = @$oldURLTypeRef;
    }

    my @urlTypeDisplayOrder = ("Lab", "Research summary", "Other");
    my @urlTypeList = ("Please specify", "Lab", "Research summary", "Other");

    # put the URLs into order
    my @tempNewURLType = ();
    my @tempOldURLType = ();
    my %movedToTempOldList;
    foreach my $currentURLType (@urlTypeDisplayOrder) {
	my $index = 0;
	foreach my $urlObject (@thisURLType) {

	    (undef, undef, my $urlType) =
		 split(/\t/, $urlObject);
	    if ($urlType =~ /$currentURLType/) {
		push(@tempNewURLType, $urlObject);
		push(@tempOldURLType, $oldURLType[$index]);
		$movedToTempOldList{$oldURLType[$index]} = 1;
	    }
	    $index++;
 	}
    }
    @thisURLType = @tempNewURLType;

    # this loop is used to capture oldURLs that are do not appear in the
    #  thisURL list (ie. they are deletions, and not updates or insertions)
    for (my $counter = 0; $counter < @oldURLType; $counter++) {
	if (!defined $movedToTempOldList{$oldURLType[$counter]}) {
	    push (@tempOldURLType, $oldURLType[$counter]);
	}
    }
    @oldURLType = @tempOldURLType;

    my $entry = Tr(td({-width=>'140',
		       -bgcolor=>'#ACBDCC',
		       -rowspan=>'6'},
		      "Web Pages"));

    for (my $i = 0; $i < $maxNumURLs ; $i++) {
          my ($url, $wwwNm, $url_type) 
                 = split(/\t/, $thisURLType[$i]);
	  my $item;

	  my ($oldURL, $oldWWWNm, $oldURLType);
	  if ($type =~ /update/i) {
	      ($oldURL, $oldWWWNm, $oldURLType) 
		  = split(/\t/, $oldURLType[$i]);

	      my $oldURLDisplay;
	      my $dots;
	      if (length($oldURL) > 50) {
		  $oldURLDisplay = substr($oldURL, 0, 39);
		  $dots = "... <FONT SIZE=\"1\"><B>[More]</B></FONT>";
	      }
	      else {
		  $oldURLDisplay = $oldURL;
		  $dots = "";
	      }

	      my $lblURLType = "";
	      if (length($oldURLDisplay) != 0) {
		  $lblURLType = "URL Type: ";
	      }

	      $oldURLType =~ s/ +/&nbsp\;/g;

	      $item = td({-width=>'160',
			  -bgcolor=>"#d8d8d8"},
			 "<NOBR><A HREF=\"$oldURL\" ALT=\"$oldURL\">"
			 .$oldURLDisplay."</A>$dots</NOBR>".br
			 ."<NOBR>".$lblURLType . $oldURLType."</NOBR>".br
			 ."<NOBR>".$oldWWWNm."</NOBR>"

			 . hidden(-name=>"oldUrl$i",
				  -value=>"$oldURL")
			 . hidden(-name=>"oldWebTitle$i",
				  -value=>"$oldWWWNm")
			 . hidden(-name=>"oldurl_type$i",
				  -value=>"$oldURLType")
			);
	  }

	  my $go;
	  if (length($url) != 0) {
	      $go = "<A HREF=\"$url\" ALT=\"Visit $url\">[Go]</A>";
	  }
	  else {
	      $go = "";
	  }
	  $item .= td(textfield(-name=>"url$i",
				-value=>"$url",
				-size=>'30')
		      ."&nbsp;"
		      .font({-size=>"-1"}, b("URL"))
		      .br.
		      popup_menu(-name=>"url_type$i",
				 -value=>\@urlTypeList,
				 -default=>"$url_type").$go
		      .br.
		      textfield(-name=>"WebTitle$i",
			       -value=>"$wwwNm",
			       -size=>'30')
		      ."&nbsp;"
		      .font({-size=>"-1"}, b("Title"))
		     );
	  if ($type =~ /update/i) { 
	      if ($oldURLType[$i] =~ /^ *= *$/) {
		  $oldURLType[$i] = "";
	      }
	      if (($oldURLType[$i] eq $thisURLType[$i]) 
		  || ((length($oldURL) == 0) 
		      && (length($url) == 0))) {
		  # $item .= &arrow;
	      }
	      else {
		  $item .= &arrow;
	      }
	  }
	  $entry .= Tr({-valign=>"top"}, $item);
    }
    return $entry;
}

########################################################################
sub associate4pi {
########################################################################
    my ($newAssocRef, $type, $oldAssocRef, $oldPIOnly, $newPIOnly) = @_;
    my (@newAssoc, @oldAssoc);
    ($oldAssocRef, $newAssocRef) = orderAssociates($oldAssocRef, $newAssocRef);

    if ($newAssocRef) { @newAssoc = @$newAssocRef; }
    if ($oldAssocRef) { @oldAssoc = @$oldAssocRef; }

    my %boolean = (1 => "true",
		   0 => "false");

    $oldPIOnly = $boolean{$oldPIOnly};
    $newPIOnly = $boolean{$newPIOnly};

    print "If you ".b("are")." a supervisor, advisor or P.I., you may enter the names of your students, post-docs, technicians, etc.; otherwise proceed to the next entry.".br;
    my $return;
    if ($type) {
	$return = th("prior entry");
    }
    $return .= th({-bgcolor=>'#a4abc2'}, "new entry");
    $return = Tr({-bgcolor=>'#CCCCCC'}, $return);
    if ($type) {
	$return .= Tr(th("Last name, First name").
		      th("Last name, First name"));
    }
    else {
	$return .= Tr(th("Last name, First name"));
    }
    my $newAssocsCount = 0;
    my $oldAssocsCount = 0;
    for (my $i = 0; $i <= 9; $i += 1) {
	my $j = $i+1;
	if (!$type) {
	    $return .= Tr(td(textfield(-name=>"associate$j",
				   -value=>"$newAssoc[$i]",
				   -size=>'30')));
	}
	else {
	    my $arrow = "";
	    if (($oldAssoc[$i] ne $newAssoc[$i]) 
                && !((length($oldAssoc[$i]) == 0) 
		     && (length($newAssoc[$i]) == 0))){
                $arrow = &arrow;
            }

	    if (!$oldAssoc[$i]) { $oldAssoc[$i] = br; }
	    else { $oldAssocsCount++; }
	    $return .= Tr(td($oldAssoc[$i]).
			  td(textfield(-name=>"associate$j",
				   -value=>"$newAssoc[$i]",
				   -size=>'30'), $arrow));
	    if ($newAssoc[$i]) { $newAssocsCount++; }

	}
    }

    # if PI with no associates:
    my $row = "";
    my $arrow = "";
    if (!$type) {
    }
    else {
	if (!defined $oldPIOnly) {
	    $oldPIOnly = "false";
	}
	# this is an override; if this PI has at least one student
	#   post-doc or technicians, then there is no need to check off
	#   the "PI Only" box
	if ($newAssocsCount > 0) {
	    $newPIOnly = "false";
	}
	if ($newPIOnly ne $oldPIOnly) {
	    $arrow = &arrow;
	}
	if ($oldPIOnly eq "false") {
 	    $row .= td({-align=>"center",
			-bgcolor=>"#CCCCCC"
		       },
	 	       "PI w/o lab members? ", 
		       input({-type=>"checkbox",
			      -name=>"oldPIOnly",
			      -disabled=>"true"})
		      );
	}
	else {
	    $row .= td({-align=>"center",
			-bgcolor=>"#CCCCCC"
		       },
		       "PI w/o lab members? ", 
		       input({-type=>"checkbox",
			      -name=>"oldPIOnly",
			      -checked=>"true",
			      -disabled=>"true"})
		      );
	}
    }

    if (!defined $newPIOnly) {
	$newPIOnly = "false";
    }
    if ($newPIOnly eq "false") {
	$row .= td({-align=>"center",
		    -bgcolor=>"#a4abc2"
		   },
		   "PI w/o lab members? ", input({-type=>"checkbox",
				       -value=>"ON",
				       -name=>"newPIOnly"}), $arrow);
    }
    else {
	$row .= td({-align=>"center",
		    -bgcolor=>"#a4abc2"
		   },
		   "PI w/o lab members? ", input({-type=>"checkbox",
						  -name=>"newPIOnly",
						  -value=>"ON",
						  -checked=>"true"}), $arrow);
    }

    $return .= (Tr($row));


    return table({-border=>'2'},
		 $return),p;
}

########################################################################
sub pi {
########################################################################
    my ($newPiRef, $type, $oldPiRef) = @_;
    my (@newPi, @oldPi);
    ($oldPiRef, $newPiRef) = orderAssociates($oldPiRef, $newPiRef);
    if ($newPiRef) { @newPi = @$newPiRef; }
    if ($oldPiRef) { @oldPi = @$oldPiRef; }
    print "If you ".b("have")." a supervisor, advisor, or P.I., you may enter your supervisor's name below.  Please use the second entry field if you have an additional supervisor:".br;
    my $entry;
    my $arrow0 = "";
    my $arrow1 = "";
    if ($type) {
	if (($oldPi[0] ne $newPi[0]) 
	    && !((length $newPi[0] eq 0) && (length $oldPi[0] eq 0))
	   ) {
	    $arrow0 = &arrow;
	}

	if (!$oldPi[0]) { $oldPi[0] = br; }

	if (($oldPi[1] ne $newPi[1]) 
	    && !((length $newPi[1] eq 0) && (length $oldPi[1] eq 0))
	   ) {
	    $arrow1 = &arrow;
	}

	if (!$oldPi[1]) { $oldPi[1] = br; }

	$entry = Tr({-bgcolor=>'#CCCCCC'}, 
		    th("prior entry").
		    th({-bgcolor=>'#a4abc2'}, "new entry")).
		 Tr(th("Last name, First name").
		    th("Last name, First name")).
		 Tr(td($oldPi[0]).
		    td(textfield(-name=>'PILIST0',
				 -value=>"$newPi[0]",
				 -size=>'30'), $arrow0)).
		 Tr(td($oldPi[1]).		    
		    td(textfield(-name=>'PILIST1',
				 -value=>"$newPi[1]",
				 -size=>'30'), $arrow1));
    }
    else {
	$entry = Tr({-bgcolor=>'#CCCCCC'}, 
		    th({-bgcolor=>'#a4abc2'}, "new entry")).
		 Tr(th("Last name, First name")).
		 Tr(td(textfield(-name=>'PILIST0',
				 -value=>"$newPi[0]",
				 -size=>'30'))).
		 Tr(td(textfield(-name=>'PILIST1',
				 -value=>"$newPi[1]",
				 -size=>'30')));
    }
    return table({-border=>'2'}, $entry);
}

########################################################################
sub associate {
########################################################################
    my ($newAssocRef, $type, $oldAssocRef) = @_;
    my (@newAssoc, @oldAssoc);
    ($oldAssocRef, $newAssocRef) = orderAssociates($oldAssocRef, $newAssocRef);
    if ($newAssocRef) { @newAssoc = @$newAssocRef; }
    if ($oldAssocRef) { @oldAssoc = @$oldAssocRef; }

    print p."Please enter below any collaborators or associates (not listed above) whom you wish to include:", br;
    my $return;
    if ($type) {
	$return = th("prior entry");
    }
    $return .= th({-bgcolor=>'#a4abc2'}, "new entry");
    $return = Tr({-bgcolor=>'#CCCCCC'}, $return);
    if ($type) {
	$return .= Tr(th("Last name, First name").
		      th("Last name, First name"));
    }
    else {
	$return .= Tr(th("Last name, First name"));
    }
    for (my $i = 0; $i <= 9; $i += 1) {
	my $j = $i+11;
	if (!$type) {
	    $return .= Tr(td(textfield(-name=>"associate$j",
				   -value=>"$newAssoc[$i]",
				   -size=>'30')));
	}
	else {
	    my $arrow = "";
	    if (($oldAssoc[$i] ne $newAssoc[$i]) 
		&& !((length($oldAssoc[$i]) == 0) 
		    && (length($newAssoc[$i]) == 0))){
		$arrow = &arrow;
	    }

	    if (!$oldAssoc[$i]) { $oldAssoc[$i] = br; } 


	    $return .= Tr(td("$oldAssoc[$i]").
			  td(textfield({-name=>"associate$j",
				   -value=>"$newAssoc[$i]",
				   -size=>'30'}), $arrow)
			    );
	}
    }
    return table({-border=>'2'},
		 $return),p;

}

########################################################################
sub interest {
########################################################################
    my ($new, $type, $old) = @_;
    print "Please enter a general description of your scientific research interests.".br.font({-color=>'red'}, "Note").": Please do not enter more than 250 words. Thanks!".br;
    if ($type) {
	print table({-width=>'650'},
		    Tr(th({-bgcolor=>'#CCCCCC'}, 
			  "Prior interests")).
		    Tr(td({-bgcolor=>'#d8d8d8'},
			  $old.br.br.br)));
    }
    return textarea(-name=>'interests',
		    -value=>"$new",
		    -rows=>4,
		    -columns=>60);
}

########################################################################
sub keyword {
########################################################################
    my ($newKwRef, $type, $oldKwRef) = @_;
    my (@newKw, @oldKw);
    if ($newKwRef) { @newKw = @$newKwRef; }
    if ($oldKwRef) { @oldKw = @$oldKwRef; }
    print p,"A list of keywords can also be associated with your Colleague entry.".br."For example: actin, transposon, protein translocation".br;
    my $return;
    if ($type) {
	$return = th("Previous Keywords");
    }
    $return .= th({-bgcolor=>'#a4abc2'}, "Current Keywords");
    $return = Tr({-bgcolor=>'#CCCCCC'}, $return);
    for (my $i = 0; $i <= 9; $i += 1) {
	my $j = $i+1;
	if (!$type) {
	    $return .= Tr(td(textfield(-name=>"keyword$j",
				   -value=>"$newKw[$i]",
				   -size=>'30')));
	}
	else {
	    if (!$oldKw[$i]) { $oldKw[$i] = br; }
	    $return .= Tr(td($oldKw[$i]).
			  td(textfield(-name=>"keyword$j",
				   -value=>"$newKw[$i]",
				   -size=>'30')));
	}
    }
    return table({-border=>'2'},
		 $return),p;
}

########################################################################
sub researchTopics {
########################################################################
    my ($collRT, $type, $oldCollRT, $dbh) = @_;

    print p,"Please select any and all areas of research relevant to your expertise.", br;

    my $return;
    if ($type) {
	$return = th(font(
			  "prior entry"));
    }
    $return .= th({-bgcolor=>'#a4abc2'}, font("current entry"));
    $return = Tr({-bgcolor=>'#CCCCCC'}, $return);

    $collRT = "\t" . $collRT . "\t";
    $collRT =~ s/\t+/\t/g;
    $oldCollRT .= "\t";

    # print "Current: $collRT<BR>\n";
    # print "Old: $oldCollRT<BR>";

    foreach my $researchTopic (split(/\t/, &getCDKeywords($dbh))) {
	my $oldEntry = "";
	my $changed = 0;
	if ($type) {
	    if ($oldCollRT =~ /\t$researchTopic\t/) {
		$oldEntry .= checkbox(-name=>"old$researchTopic",
				      -label=>"",
				      -checked=>"checked") . "\n";
		$changed++;
	    }
	    else {
		$oldEntry .= checkbox(-name=>"$researchTopic",
				      -label=>""
				     )."\n";
		$changed--;
	    }
	    $oldEntry = td({-bgcolor=>'#CCCCCC',
			    -align=>'center'}, $oldEntry);
	}

	my  $newEntry = "";
	if ($collRT =~ /\t$researchTopic\t/) {
	    $newEntry .= checkbox({-name=>"$researchTopic",
				   -label=>"",
				   -checked=>"checked"}) . "\n";
	    $changed--;
	}
	else {
	    $newEntry .= checkbox(-name=>"$researchTopic",
				  -label=>""
				 )."\n";
	    $changed++;
	}

	my $label = $researchTopic;
	if (($changed != 0) && ($type)){
	    $label = font({-color=>"black"}, b($researchTopic)) . &arrow;
	}
	else {
	    $label = $researchTopic;
	}

	$newEntry = td({-bgcolor=>'#a4abc2',
			-align=>'center'}, $newEntry);

	my $singleRow = Tr($oldEntry 
			   . $newEntry 
			   . td($label)) . "\n";
	$return .= $singleRow;
    }

    return table({-border=>'0'},
		 $return),p;
}

########################################################################
sub associatedLoci {
########################################################################
    my ($new, $type, $old, $dbh) = @_;

    print "This colleague is associated with the following genes: ";


    my $tempOld = "";
    my $tempNew = "";

    my $locusPageURL = $configUrl->dictyBaseCGIRoot."$dblink/locus.pl?locusNo=";


    my $txtAreaWidth = 60;
    my $lineLength = 0;
    foreach my $associatedLocusNo (split(/\|/, $old)) {
	my $locusObj = Locus->new(dbh=>$dbh,
				  locus_no=>$associatedLocusNo);
	$tempOld .= (
		     a({-href=>"$locusPageURL".$associatedLocusNo},
		       $locusObj->locus_name())
		     . "&nbsp;" . font({-size=>"-1"},
					"[".$associatedLocusNo."]") . ", "
		    );
	$tempNew .= $locusObj->locus_name() . "|";

	$lineLength += length($locusObj->locus_name()."|");
	if ($lineLength > $txtAreaWidth - 10) {
	    $lineLength = 0;
	    $tempNew .= "\n";
	}
    }

    $tempOld =~ s/, $//;
    $tempNew =~ s/\|$//;


    my $returnHTML = "";
    if ($type) {
	# $old =~ s/\|/, /g;
	$returnHTML .= table({-width=>'650'},
			     Tr(th({-bgcolor=>'#CCCCCC'}, 
				   "Prior Association")).
			     Tr(td({-bgcolor=>'#d8d8d8'},
				   $tempOld,br,
				  hidden({-name=>'oldAssociatedLoci',
					  -value=>$old}))));
    }
    $returnHTML .= table({-width=>'650'},
			 Tr(th({-bgcolor=>'#a4abc2'}, 
			       "Current Association")).
			 Tr(td(
			       textarea({-rows=>4,
					 -cols=>$txtAreaWidth,
					 -name=>'associatedLoci',
					 -value=>$tempNew}),br
			      font({-size=>"-1"},
				   "Separate multiple loci with the pipe ".
				   "\"|\" symbol, do not use any spaces.".
				   "  Use LOCUS_NO or LOCUS_NAME to identify".
				   " loci only.")
				  )));

    $returnHTML .= p . "\n";

    return $returnHTML;
}

########################################################################
sub comment {
########################################################################
    my ($new, $type, $old) = @_;
    print "Anything else we did not ask about but that you wish to have included in the database.", br;

    # allow for multi-line comments in text area where newlines may be 
    #  marked off by a <BR> tag
    $new =~ s/\<BR\>/\n/g;

    if ($type) {
	# allow for multi-line comments in HTML where newlines may marked by
	#   a \n code
	$old =~ s/\n/\<BR\>/g;
	print table({-width=>'650'},
		    Tr(th({-bgcolor=>'#CCCCCC'}, 
			  "Prior comments")).
		    Tr(td({-bgcolor=>'#d8d8d8'},
			  $old.br.br.br)));
    }
    return textarea(-name=>'Comments',
		    -value=>"$new",
		    -rows=>4,
		    -columns=>60);
}

#########################################################################
sub newCuratorNote {
#########################################################################
    return textarea(-name=>'note',
		    -rows=>4,
		    -columns=>60).br.
	   font({-size=>'-1'}, "If this note should be shared with another item in the DB, enter the table name(s) and primary key(s) (eg. Locus,10 Colleague,15)").br.
	   textfield(-name=>'idList', 
		     -size=>'30').
	   font({-size=>'-1'}, "Do you want the note to be public? ").
	   radio_group(-name=>'isPublic',
		       -'values'=>['Yes','No'],
		       -default=>'No');
}

#########################################################################
sub delayDelete {
#########################################################################
    my ($matchIDs) = @_;
    my $entry = Tr(td({-bgcolor=>'#b7d8e4',
		       -colspan=>'2'},
		      "Delay this submission? ".
		      checkbox(-name=>'delayCB',
			       -label=>'')." Reason:".
		      textfield(-name=>'delayComment', 
				-size=>'40'))).
		Tr(td({-bgcolor=>'#FF9999',
		       -colspan=>'2'},
		   "Delete this submission? ".
		   checkbox(-name=>'deleteCB',
			    -label=>'')));
    if ($matchIDs) {
	my @ids = split(/:/, $matchIDs);
	unshift(@ids, 'colleague_no');
	$entry .= Tr(td({-bgcolor=>'#b7d8e4',
			 -colspan=>'2'},
			"Convert this entry to update? ".
		        checkbox(-name=>'convertCB',
				 -label=>'').
		        popup_menu(-name=>'DBid',
				   -value=>\@ids)));
				
    }
    return table({-width=>'650'}, $entry);
}

####################################################################
sub deleteFile {
####################################################################
        my ($dir, $file) = @_;
	my $err = system("/bin/rm $dir/$file");
	if ($err != 0) {
	    print "<p><b>delete $dir/$file failed: $!</b><br>";
	}
	else {
	    print "<p><b>$file has been deleted from $dir directory.</b><br>"; 
	}
}

#####################################################################
sub delayFile {
#####################################################################
        my ($id, $dir, $delayComment, $user) = @_;
     	my $delayfile = "$dir/delay.list";
	if (open(OUT, ">>$delayfile")) {
	    print OUT "${id}\tdelay by ${user}";
	    if ($delayComment) {
		print OUT ", $delayComment";
	    }
	    print OUT "\n";
	    print p, b("The data has been returned to the list with delay mark."), br;
	}
	else {
	    print p,b("Can't open '$delayfile' for appending: ".$!), br; 
	}   
}

#####################################################################
sub returnForm {
#####################################################################
    my ($user, $dblink) = @_;
    $user = "\L$user";
    $user =~ tr/[a-z]/[A-Z]/;

    my $btnURL = $configUrl->dictyBaseCGIRoot."$dblink/curatorLogin";

    print start_form(-action=>$configUrl->dictyBaseCGIRoot."$dblink/curatorLogin",
		     -method=>"post"),
	  hidden(-name=>'type',
		 -value=>'colleague'),
	  hidden(-name=>'user',
		 -value=>"$user"),
	  submit(-name=>'Submit',
		 -value=>'Go back to list of entries'),
          input({-type=>"button",
		 -value=>"Return to Curator Central",
		 -onClick=>"window.location\='$btnURL?user=${user}';"}),
          endform;

}


########################################################################
###### deleteColleagueEntryBYid() is used to delete all related colleague 
###### info for specified colleague_no 
###### Usage : &deleteColleagueEntryBYid($dbh, $colleague_id);
###### 
########################################################################
sub deleteColleagueEntryBYid {
#########################################################################
    my ($dbh, $id) = @_;
    my $sth = $dbh->prepare("
        DELETE from CGM_DDB.colleague 
        WHERE  colleague_no = ?
    ");
    $sth->execute($id);
}


########################################################################
##### insertEmails() is used to insert new email addresses into coll_email
##### and email tables
##### usage: insertEmails($dbh, $colleague_no, $user, @emails);
########################################################################
sub insertEmails {
########################################################################
    my ($dbh, $colleague_id, $dbuser, @emails) = @_;
    if ($#emails < 0) { return; }
    foreach my $email (@emails) {
	$email =~ s/[\t\n\r\f]//g;
	my $TMPemail = "\U$email";
	my $sth = $dbh->prepare( "
             SELECT  email_no
             FROM    CGM_DDB.email
	     WHERE   upper(email) = ? 
        ");
	$sth->execute($TMPemail);
	my $email_no = $sth->fetchrow;
	if (!$email_no) {
	    my $sth = $dbh->prepare("
                INSERT INTO CGM_DDB.email(email_no, email, created_by)
                VALUES (CGM_DDB.emailno_seq.nextval,?,?)
            ");
	    $sth->execute($email, $dbuser);
	    $dbh->commit;
	    $sth = $dbh->prepare("
                INSERT INTO CGM_DDB.coll_email(colleague_no, email_no) 
                VALUES (?, CGM_DDB.emailno_seq.currval)
            ");
	    $sth->execute($colleague_id);
	}
	else {
	    my $sth = $dbh->prepare("
                INSERT INTO CGM_DDB.coll_email(colleague_no, email_no) 
                VALUES (?,?)
            ");
	    $sth->execute($colleague_id, $email_no);
	}
    }
}

#######################################################################
##### insertUrls() is used to insert new url addresses into coll_url
##### and url tables
##### usage: insertUrls($dbh, $colleague_no, $user, @urls);
#######################################################################
sub insertUrls {
#######################################################################

      my ($dbh, $colleague_id, $dbuser, $urlObject) = @_;
      # if ($#urls < 0) { return; }

      my ($url, $www, $url_type) = split(/\t/, $urlObject);
      $url =~ s/[\t\n\r\f]//g;
      my $sth = $dbh->prepare( "
                 SELECT  url_no
                 FROM    CGM_DDB.url
	         WHERE   url = ?
                 AND     url_type = ?
            ");
      $sth->execute($url, $url_type);
      my $url_no = $sth->fetchrow;
      if (!$url_no) {
	  my $sth = $dbh->prepare("
                      INSERT INTO CGM_DDB.url(url_no, url, www_name, 
                                           url_type, created_by)
                      VALUES (CGM_DDB.urlno_seq.nextval, ?, ?, 
                             ?, ?)
                ");
	  if ($url_type ne "Please specify") {
	      $sth->execute($url, $www, $url_type, $dbuser);
	      $dbh->commit;
	      $sth = $dbh->prepare("
                      INSERT INTO CGM_DDB.coll_url(colleague_no, url_no) 
                      VALUES (?, CGM_DDB.urlno_seq.currval)
                ");
	      $sth->execute($colleague_id);
	  }
      }
      else {
	  my $sth = $dbh->prepare("
                      INSERT INTO CGM_DDB.coll_url(colleague_no, url_no) 
                      VALUES (?,?)
                ");
	  $sth->execute($colleague_id, $url_no);
      }
  }


########################################################################
##### insertPi() is used to insert pi info into colleague, pi and 
##### associate tables
##### usage: insertPi($dbh, $colleague_no, $user, $pi);
########################################################################
sub insertPi {
########################################################################
            my ($dbh, $colleague_id, $dbuser, $pi, $isdictyBaseContact) = @_; 
	    $pi =~ s/\, */\,/g;
            my ($pilname, $pifname, $pisuffix) = split(/\,/, $pi);
	    my $sth;
	    my @id = &getColleagueNoBYname($dbh, $pilname, 
					   $pifname, $pisuffix);

	    if (!$isdictyBaseContact) { $isdictyBaseContact = 'N'; }

	    my $picolleague_no = $id[0];
	    if (!$picolleague_no) {
		 $sth = $dbh->prepare("
                        INSERT INTO CGM_DDB.colleague(colleague_no, 
                               last_name, first_name, suffix, 
                               date_modified, date_created,
                               created_by, source, is_subscribed) 
                        VALUES (CGM_DDB.collno_seq.nextval, ?,?,?,
                               sysdate, sysdate, ?, 'Associate', ?)
                 ");
		 $sth->execute($pilname, $pifname, $pisuffix, $dbuser, 
			       $isdictyBaseContact);
		 $dbh->commit;
		 $sth = $dbh->prepare("
                        INSERT INTO CGM_DDB.pi(colleague_no, pi_no, 
                                created_by) 
                        VALUES (?, CGM_DDB.collno_seq.currval, ?)
                 ");
		 $sth->execute($colleague_id, $dbuser);
	    }
	    else {
		 $sth = $dbh->prepare( "
                        SELECT pi_no
                        FROM   CGM_DDB.pi
                        WHERE  colleague_no = ?
                 ");
		 $sth->execute($colleague_id);
		 my $found = 0;
		 while(my ($number) = $sth->fetchrow()) {
		     if ($number == $picolleague_no) {
			 $found = 1;
		     }
		 }
		 if ($found == 0) {
		     my $sth = $dbh->prepare("
                         INSERT INTO CGM_DDB.pi(colleague_no, pi_no, 
                                      created_by) 
                         VALUES (?,?,?)
                     ");
		     $sth->execute($colleague_id,$picolleague_no,$dbuser);
		 }
	    }
}


######################################################################
##### insertAssocsBYpi() is used to insert associates info into 
##### colleague, pi and associate tables
##### usage: insertAssocsBYpi($dbh, $colleague_no, $user, @assocs);
######################################################################
sub insertAssocsBYpi {
######################################################################
       my ($dbh, $colleague_id, $dbuser, @assocs) = @_;
       if ($#assocs < 0) { return; }
       foreach my $assoc (@assocs) {
	        $assoc =~ s/\, */\,/g;
		my ($alname, $afname, $asuffix) = split(/\,/, $assoc);
		my $sth;
		my @id = &getColleagueNoBYname($dbh, $alname, 
					       $afname, $asuffix);
	        my $Acolleague_no = $id[0];
		if (!$Acolleague_no) {
		     my $sth = $dbh->prepare("
                        INSERT INTO CGM_DDB.colleague(colleague_no, 
                               last_name, first_name, suffix, 
                               date_modified, date_created,
                               created_by, source, is_subscribed) 
                        VALUES (CGM_DDB.collno_seq.nextval, ?,?,?,
                                sysdate, sysdate, ?,'Associate', 'N')
                     ");
		     $sth->execute($alname, $afname, $asuffix, $dbuser);
		     $dbh->commit;
		     $sth = $dbh->prepare("
                        INSERT INTO CGM_DDB.pi(colleague_no, pi_no, 
                                created_by) 
                        VALUES (CGM_DDB.collno_seq.currval,?,?)
                     ");
		     $sth->execute($colleague_id, $dbuser);
		}
		else {
		     my $sth = $dbh->prepare( "
                           SELECT pi_no
                           FROM   CGM_DDB.pi
                           WHERE  colleague_no = ?
                      ");
		     $sth->execute($Acolleague_no);
		     my $found = 0;
		     while(my ($number) = $sth->fetchrow()) {
			 if ($number == $colleague_id) {
			      $found = 1;
			 }
		     }		    
		     if ($found == 0) {
			  $sth = $dbh->prepare("
                              INSERT INTO CGM_DDB.pi(colleague_no, pi_no, 
                                      created_by) 
                              VALUES (?,?,?)
                          ");
			  $sth->execute($Acolleague_no, $colleague_id, 
                                        $dbuser);
		     }
		}
       }    
}


########################################################################
##### insertAssocs() is used to insert associates info into colleague 
##### and associate tables
##### usage: insertAssocs($dbh, $colleague_no, $user, @assocs);
########################################################################
sub insertAssocs {
########################################################################
       my ($dbh, $colleague_id, $dbuser, @assocs) = @_;
       if ($#assocs < 0) { return; }
       foreach my $assoc (@assocs) {
	        $assoc =~ s/\, */\,/g;
	        my ($alname, $afname, $asuffix) = split(/\,/, $assoc);
		my $sth;
		my @id = &getColleagueNoBYname($dbh, $alname, 
					       $afname, $asuffix);
	        my $Acolleague_no = $id[0];
		if (!$Acolleague_no) {
		     my $sth = $dbh->prepare("
                           INSERT INTO CGM_DDB.colleague(colleague_no, 
                               last_name, first_name, suffix, 
                               date_modified, date_created,
                               created_by, source, is_subscribed) 
                           VALUES (CGM_DDB.collno_seq.nextval, ?,?,?, 
                               sysdate, sysdate, ?, 'Associate', 'N')
                     ");
		     $sth->execute($alname, $afname, $asuffix, $dbuser);
		     $dbh->commit;
		     $sth = $dbh->prepare("
                           INSERT INTO CGM_DDB.associate(colleague_no, 
                                   associate_no, created_by) 
                           VALUES (CGM_DDB.collno_seq.currval, ?,?)
                     ");
		     $sth->execute($colleague_id, $dbuser);
		     $dbh->commit;
		     $sth = $dbh->prepare("
                           INSERT INTO CGM_DDB.associate(colleague_no, 
                                   associate_no, created_by) 
                           VALUES (?, CGM_DDB.collno_seq.currval, ?)
                     ");
		     $sth->execute($colleague_id, $dbuser);
		}
		else {
		     my $sth = $dbh->prepare( "
                           SELECT associate_no
                           FROM   CGM_DDB.associate
                           WHERE  colleague_no = ?
                      ");
		     $sth->execute($Acolleague_no);
		     my $found = 0;
		     while(my ($number) = $sth->fetchrow()) {
			  if ($number == $colleague_id) {
			      $found = 1;
			  }
		     } 
		     if ($found == 0) {
			  $sth = $dbh->prepare("
                              INSERT INTO CGM_DDB.associate(colleague_no, 
                                      associate_no, created_by) 
                              VALUES (?,?,?)
                          ");
			  $sth->execute($Acolleague_no, $colleague_id, 
					$dbuser);
			  $sth = $dbh->prepare("
                              INSERT INTO CGM_DDB.associate(colleague_no, 
                                      associate_no, created_by) 
                              VALUES (?,?,?)
                          ");
			  $sth->execute($colleague_id, $Acolleague_no, 
					$dbuser);
		     }
		}    
       }
}


########################################################################
##### updateGenericAssociate() is used to associate a given 
#####   colleague with the associate named "~Generic ~Associate", as a
#####   student, post-doc or technician.  This treats the colleague as
#####   as PI in the database; and allows them to be displayed on the
#####   Dictyostelium Labs page.
########################################################################
sub updateGenericAssociate {
########################################################################
    my ($dbh, $colleague_id, $dbuser, $setFlag, @assocs) = @_;

    ### Local variable declaration
    my $sth;
    my $genericAssociateColleagueNo;


    ### Check to see if this PI has any lab members.
    # if this PI already has lab members, then no need to associate him
    #  with ~Generic ~Associate

    if (scalar @assocs > 0) {
	$setFlag = "false"; # remove existing association with ~Generic ~Assoc
    }

    ### determine the colleague number of ~Generic ~Associate
    $sth = $dbh->prepare("
       SELECT colleague_no
       FROM   CGM_DDB.colleague
       WHERE  last_name = '~Associate'
       AND    first_name = '~Generic'
    ");

    $sth->execute();

    if (($genericAssociateColleagueNo) = $sth->fetchrow()) {
    }
    else {
	# Unable to locate the colleague_id for ~Generic ~Associate
	# An error message should be thrown here
	return;
    }

    ### Error testing
    # should not be attempting to add ~Generic ~Associate as a member of its
    #   own lab.
    if ($colleague_id == $genericAssociateColleagueNo) {
	return;
    }

    my $returnCode = 0;
    ### Determine if the current PI is already associted with ~Generic ~Associ
    #     or not
    $sth = $dbh->prepare("
       SELECT *
       FROM   CGM_DDB.pi
       WHERE  colleague_no = ?
       AND    pi_no = ?
    ");
    $sth->execute($genericAssociateColleagueNo, $colleague_id);

    if (my $dummy = $sth->fetchrow) {
	# Already associated with ~G~A
	if ($setFlag eq "false") {
	    # remove this row of CGM_DDB.pi

	    $sth = $dbh->prepare("
               DELETE
               FROM   CGM_DDB.pi
               WHERE  colleague_no = ?
               AND    pi_no = ?
            ");
	    $sth->execute($genericAssociateColleagueNo, $colleague_id);
	    $returnCode++;
	}
	else {
	    # no need to reassociate this PI with ~G~A
	}
    }
    else {
	# Not already associated with ~G~A
	if ($setFlag eq "true") {
	    # Add an association between this PI and ~G~A
	    $sth = $dbh->prepare("
               INSERT INTO CGM_DDB.pi(colleague_no, pi_no)
               VALUES  (?, ?)
            ");
	    $sth->execute($genericAssociateColleagueNo, $colleague_id);
	    $returnCode++;
	}
	else {
	    # no need to remove a non-existant associate between this PI and
	    #  ~G~A
	}
    }

    return $returnCode;
}


########################################################################
##### insertKeywords() is used to insert keyword info into coll_keyword 
##### and keyword tables
##### usage: insertKeywords($dbh, $colleague_no, $user, @keywords);
########################################################################
sub insertKeywords {
########################################################################
       my ($dbh, $colleague_id, $dbuser, @keywords) = @_;
       if ($#keywords < 0) { return; }
       foreach my $keyword (@keywords) {
		my $tmpkeyword = "\U$keyword";
		my $sth = $dbh->prepare( "
                      SELECT keyword_no
                      FROM   CGM_DDB.keyword
                      WHERE  upper(keyword) = ?
                      AND    source = 'Colleague Keyword'
                ");
		$sth->execute($tmpkeyword);
		my $found = 0;
		my $keyword_no;
	        while(my ($number) = $sth->fetchrow()) {
		    $found = 1;
		    $keyword_no = $number;
	        }
		my $tmpsource = "Colleague Keyword";
		if ($found == 0) {
		      $sth = $dbh->prepare("
                           INSERT INTO CGM_DDB.keyword(keyword_no, 
                                      keyword, source, created_by) 
                           VALUES (CGM_DDB.kwno_seq.nextval, ?,
                                      'Colleague Keyword', ?)
                      ");
		      $sth->execute($keyword, $dbuser);
		      $dbh->commit;
		      $sth = $dbh->prepare("
                           INSERT INTO CGM_DDB.coll_keyword(colleague_no, 
                                      keyword_no) 
                           VALUES (?, CGM_DDB.kwno_seq.currval)
                      ");
		      $sth->execute($colleague_id);
		}
		else {
		      $sth = $dbh->prepare("
                              INSERT INTO CGM_DDB.coll_keyword(colleague_no, 
                                     keyword_no) 
                              VALUES (?,?)
                      "); 
		      $sth->execute($colleague_id, $keyword_no);
		}    
       }
}

#######################################################################
##### insertComments() is used to insert user comments or research 
##### interest into colleague_remark table
##### usage: insertComments($dbh, $colleague_no, $user, $comments, 
#####                       $type);
#######################################################################
sub insertComments {
#######################################################################
      my ($dbh, $colleague_id, $dbuser, $comment, $type) = @_;
      $comment =~ s/\n/\\n/g;
      my $sth = $dbh->prepare("
            INSERT INTO CGM_DDB.colleague_remark(remark_no, remark, 
                    remark_type, colleague_no, created_by)
            VALUES (CGM_DDB.remarkno_seq.nextval, ?,?,?,?)
      ");
      $sth->execute($comment, $type, $colleague_id, $dbuser);
}

#######################################################################
##### insertAssociatedLoci() is used to insert associated loci
##### into the coll_locus table
##### usage: insertComments($dbh, $colleague_no, @associatedLoci );
#######################################################################
sub insertAssociatedLoci {
#######################################################################
    my ($dbh, $colleague_id, @associatedLoci) = @_;
    if ($#associatedLoci < 0 ) { return; }
    foreach my $locusNo (@associatedLoci) {
	# print "\$locus_no = ", $locusNo, " -- \$colleague_no = ", $colleague_id, "\n", br;
	my $sth = $dbh->prepare("
              INSERT INTO CGM_DDB.coll_locus(LOCUS_NO, COLLEAGUE_NO)
              VALUES (?, ?)
        ");
	$sth->execute($locusNo, $colleague_id);
    }
}



#######################################################################
##### insertCuratorNote() is used to insert curator note into 
##### curator_not and coll_cn tables
##### usage: insertCuratorNote($dbh, $colleague_no, $user, $note);
#######################################################################
sub insertCuratorNote{
#######################################################################
      my ($dbh, $colleague_id, $dbuser, $note, $is_public) = @_;
      my $sth = $dbh->prepare("
            INSERT INTO CGM_DDB.curator_note(curator_note_no, note, 
                    is_public, created_by)
            VALUES (CGM_DDB.cnno_seq.nextval, ?,?,?)
      ");
      $sth->execute($note, $is_public, $dbuser);
      $dbh->commit;
      $sth = $dbh->prepare("
            INSERT INTO CGM_DDB.coll_cn(curator_note_no, colleague_no) 
            VALUES (CGM_DDB.cnno_seq.currval,?)
      ");
      $sth->execute($colleague_id);
}

#######################################################################
##### updateCuratorNote() is used to update curator note in curator_note
##### and coll_cn tables
##### usage: updateCuratorNote($dbh, $colleague_no, $user, $newnote, 
#####                          $oldnote, $isPublic);
#######################################################################
sub updateCuratorNote{
#######################################################################
    my ($dbh, $colleague_id, $dbuser, $newnote, $oldnote,
	  $is_public)= @_;
     if ($oldnote) {
	    my $sth = $dbh->prepare( "
                      SELECT N.curator_note_no
                      FROM   CGM_DDB.coll_cn CN, CGM_DDB.curator_note N
                      WHERE  CN.colleague_no = ?
                      AND    N.note = ?
                      AND    N.curator_note_no = CN.curator_note_no
            ");
	    $sth->execute($colleague_id, $oldnote);
	    my $found = 0;
	    my $curator_note_no;
	    while(my ($number) = $sth->fetchrow()) {
		$found++;
		$curator_note_no = $number;
	    }
	    if ($found != 0) {
		if ($newnote) {
		      $sth = $dbh->prepare("
                          UPDATE CGM_DDB.curator_note 
                          SET    note = ?, 
                                 is_public = ?
                          WHERE  curator_note_no = ?
                      ");
		      $sth->execute($newnote, $is_public, 
				    $curator_note_no);
		}
		else {
		      $sth = $dbh->prepare("
                          DELETE from CGM_DDB.coll_cn 
                          WHERE  coll_cn.colleague_no = ? 
                      ");
		      $sth->execute($colleague_id);
	              $dbh->commit;
	              $sth = $dbh->prepare("
                          DELETE from CGM_DDB.curator_note 
                          WHERE  curator_note_no = ?
                      ");
		      $sth->execute($curator_note_no);
		}
            }
      }
      elsif ($newnote) {
	    my $sth = $dbh->prepare("
                      INSERT INTO CGM_DDB.curator_note(curator_note_no, note, 
                              is_public, created_by)
                      VALUES (CGM_DDB.cnno_seq.nextval, ?,?,?)
            ");
	    $sth->execute($newnote, $is_public, $dbuser);
	    $dbh->commit;
	    $sth = $dbh->prepare("
                      INSERT INTO CGM_DDB.coll_cn(curator_note_no, 
                              colleague_no) 
                      VALUES (CGM_DDB.cnno_seq.currval, ?)
            ");
	    $sth->execute($colleague_id);
      }
}

########################################################################
##### deleteAssocsBYpi() is used to delete associates info from pi and 
##### colleague table
##### usage: deleteAssocsBYpi($dbh, $colleague_no, @assocs);
########################################################################
sub deleteAssocsBYpi {
########################################################################
       my ($dbh, $colleague_id, $Acolleague_no) = @_;
       if (!$Acolleague_no) { return; }
       my $sth = $dbh->prepare("
            DELETE from CGM_DDB.pi 
            WHERE  colleague_no = ? 
            AND    pi_no = ?
       ");
       $sth->execute($Acolleague_no, $colleague_id);
       $dbh->commit;
       #### check if this associate info is still in the pi 
       #### or associate tables or if it has an email address 
       #### associated with. If not, delete it from 
       #### colleague table, else keep it.
       my $found = 0;
       $sth = $dbh->prepare( "
           SELECT colleague_no
           FROM   CGM_DDB.pi
           WHERE  colleague_no = ? 
           OR     pi_no = ?
       ");    
       $sth->execute($Acolleague_no, $Acolleague_no);
       while(my ($number) = $sth->fetchrow()) {
	   $found++;
       }
       if ($found == 0) {
	   my $sth = $dbh->prepare( "
               SELECT colleague_no
               FROM   CGM_DDB.associate
               WHERE  colleague_no = ? 
               OR     associate_no = ?
           ");    
	   $sth->execute($Acolleague_no, $Acolleague_no);
	   while(my ($number) = $sth->fetchrow()) {
	       $found++;
	   }
       }
       if ($found == 0) {
	   my $sth = $dbh->prepare( "
               SELECT email_no
               FROM   CGM_DDB.coll_email
               WHERE  colleague_no = ?
           ");    
	   $sth->execute($Acolleague_no);
	   while(my ($number) = $sth->fetchrow()) {
	       $found++;
	   }
       }
       #### if no any info associated with this associate, 
       #### i.e., 
       #### # not a pi and not associated with any other 
       #### colleague and no any email address, DELETE it from
       #### colleague table
       if ($found == 0) {
	   my $sth = $dbh->prepare("
               DELETE from CGM_DDB.colleague
               WHERE  colleague_no = ?
           ");
	   $sth->execute($Acolleague_no);
	   $dbh->commit;
       }
}


##########################################################################
##### deleteAssocs() is used to delete associates info from associate and 
##### colleague table
##### usage: deleteAssocs($dbh, $colleague_no, @assocs);
##########################################################################
sub deleteAssocs {
##########################################################################
       my ($dbh, $colleague_id, $Acolleague_no) = @_;
       if (!$Acolleague_no) { return; }
       my $sth = $dbh->prepare("
            DELETE from CGM_DDB.associate 
            WHERE  (colleague_no = ? and
                    associate_no = ?) or 
                   (colleague_no = ? and
                    associate_no = ?)
       ");
       $sth->execute($Acolleague_no, $colleague_id,
		     $colleague_id, $Acolleague_no);
       $dbh->commit;
       #### check if this associate info is still in the pi 
       #### or associate tables or if it has an email address 
       #### associated with. If not, delete it from 
       #### colleague table, else keep it.
       my $found = 0;
       $sth = $dbh->prepare( "
           SELECT colleague_no
           FROM   CGM_DDB.pi
           WHERE  colleague_no = ? or
                  pi_no = ?
       ");    
       $sth->execute($Acolleague_no, $Acolleague_no);
       while(my($number) = $sth->fetchrow()) {
	   $found++;
       }
       if ($found == 0) {
	   my $sth = $dbh->prepare( "
                SELECT colleague_no
                FROM   CGM_DDB.associate
                WHERE  colleague_no = ? or
                       associate_no = ?
           ");    
	   $sth->execute($Acolleague_no, $Acolleague_no);
	   while(my ($number) = $sth->fetchrow()) {
		$found++;
	   }
       }
       if ($found == 0) {
	   my $sth = $dbh->prepare( "
                SELECT email_no
                FROM   CGM_DDB.coll_email
                WHERE  colleague_no = ?
           ");    
	   $sth->execute($Acolleague_no);
	   while(my ($number) = $sth->fetchrow()) {
		$found++;
    	   }
       }
       #### if no any info associated with this associate, i.e., 
       #### # not a pi and not associated with any other 
       #### colleague and no any email address, DELETE it from
       #### colleague table
       if ($found == 0) {
	   my $sth = $dbh->prepare("
                 DELETE from CGM_DDB.colleague
                 WHERE  colleague_no = ?
           ");
	   $sth->execute($Acolleague_no);
	   $dbh->commit;
       }
}

#################################################################
sub deletePi {
#################################################################
        my ($dbh, $colleague_id, $alname, $afname, $asuffix) = @_;
          
        my @id = &getColleagueNoBYname($dbh, $alname, 
				      $afname, $asuffix);
        my $PIcolleague_no = $id[0];
        if (!$PIcolleague_no) { return;}
	my $sth = $dbh->prepare("
            DELETE from CGM_DDB.pi 
            WHERE  pi_no = ? 
            AND    colleague_no = ?
        ");
	$sth->execute($PIcolleague_no, $colleague_id);
	$dbh->commit;
	#### check if this pi info is still in the pi table 
        #### or associate table or if it has an email address 
        #### associated with. If not, delete it from 
        #### colleague table, else keep it.
	my $found;
	$sth = $dbh->prepare( "
            SELECT colleague_no
            FROM   CGM_DDB.pi
            WHERE  pi_no = ?
        ");
	$sth->execute($PIcolleague_no);
	while(my ($number) = $sth->fetchrow()) {
	    $found++;
	}
	if (!$found) {
	    my $sth = $dbh->prepare( "
                SELECT colleague_no
                FROM   CGM_DDB.associate
                WHERE  colleague_no = ?
                OR     associate_no = ?
            ");    
	    $sth->execute($PIcolleague_no, $PIcolleague_no);
	    while(my ($number) = $sth->fetchrow()) {
		$found++;
	    }
	}
        if (!$found) {
	    my $sth = $dbh->prepare( "
                SELECT email_no
                FROM   CGM_DDB.coll_email
                WHERE  colleague_no = ?
            ");    
	    $sth->execute($PIcolleague_no);
	    while(my ($number) = $sth->fetchrow()) {
		$found++;
	    }
	    #### if no any info associated with this pi, i.e., 
	    #### # not a pi anymore and not associated with any other 
            #### colleague and no any email address, DELETE it from
            #### colleague table
	    if (!$found) {
		$sth = $dbh->prepare("
                     DELETE from CGM_DDB.colleague
                     WHERE  colleague_no = ?
                ");
	        $sth->execute($PIcolleague_no);
	        $dbh->commit;
	    }
	}     
}

#########################################################################
##### deleteKeywords() is used to delete keyword info from coll_keyword 
##### and keyword tables
##### usage: deleteKeywords($dbh, $colleague_no, @keywords);
#########################################################################
sub deleteKeywords {
#########################################################################
       my ($dbh, $colleague_id, @keywords) = @_;
       if ($#keywords < 0) { return; }
       foreach my $keyword (@keywords) {
		my $tmpkeyword = "\U$keyword";
		my $sth = $dbh->prepare( "
                      SELECT keyword_no
                      FROM   CGM_DDB.keyword
                      WHERE  upper(keyword) = ?
                             and source = 'Colleague Keyword'
                ");
		$sth->execute($tmpkeyword);
		my $found = 0;
		my $keyword_no;
		while(my ($number) = $sth->fetchrow()) {
		     $found = 1;
		     $keyword_no = $number;
	        }
		if ($found != 0) {
		      $sth = $dbh->prepare("
                              DELETE from CGM_DDB.coll_keyword
                              WHERE  colleague_no = ? and
                                     keyword_no = ?
                      ");
		      $sth->execute($colleague_id, $keyword_no);
		      $dbh->commit;
		}
       }
}

########################################################################
##### orderAssociates() is used to put two lists of associates so that
##### matching associates are in the correct position.
##### usage: insertAssocs(\@oldAssoc, \@assocs);
########################################################################
sub orderAssociates {
########################################################################

    my ($oldAssocRef, $newAssocRef) = @_;
    my (@newAssoc, @oldAssoc);

    if (!$$oldAssocRef[0] || !$$newAssocRef[0]) {
	return ($oldAssocRef, $newAssocRef);
    }
    @newAssoc = @$newAssocRef;
    @oldAssoc = @$oldAssocRef;

    my %allAssocs;

    foreach my $newAssoc (@newAssoc) {
	$allAssocs{$newAssoc} = 1;
    }
    @newAssoc = ();

    foreach my $oldAssoc(@oldAssoc) {
	$allAssocs{$oldAssoc} = defined $allAssocs{$oldAssoc} ? 11 : 10;
    }
    @oldAssoc = ();

    my @sameAssocs = ();
    my @addedAssocs = ();
    my @removedAssocs = ();

    foreach my $assoc (sort keys %allAssocs) {
	if ($allAssocs{$assoc} eq 10) {
	    push (@removedAssocs, $assoc);
	}
	elsif ($allAssocs{$assoc} eq 01) {
	    push (@addedAssocs, $assoc);
	}
	else {
	    push (@sameAssocs, $assoc);
	}
    }

    foreach my $sameAssoc (@sameAssocs) {
	push (@newAssoc, $sameAssoc);
	push (@oldAssoc, $sameAssoc);
    }

    foreach my $addAssoc (@addedAssocs) {
	push (@newAssoc, $addAssoc);
    }

    foreach my $remAssoc (@removedAssocs) {
	push (@oldAssoc, $remAssoc);
    }

    return (\@oldAssoc, \@newAssoc);
}
#####################################################################
1;  ##### Return it to the calling program
#####################################################################







