### Eclipse Workspace Patch 1.0
#P scmbugg
Index: src/lib/product/Daemon/Bugzilla.pm.in
===================================================================
RCS file: /projects/scmbug/cvsroot/system/src/lib/product/Daemon/Bugzilla.pm.in,v
retrieving revision 1.50
diff -u -r1.50 Bugzilla.pm.in
--- src/lib/product/Daemon/Bugzilla.pm.in	28 Dec 2007 10:38:20 -0000	1.50
+++ src/lib/product/Daemon/Bugzilla.pm.in	29 Dec 2007 08:23:14 -0000
@@ -26,31 +26,91 @@
 
 my $bugzilla_bug_status_map = {
     "ASSIGNED" => { name => "ASSIGNED",
-		    active => 1,
-                    accepts_data_as_resolution => 1,
-		    possible_resolution_states => [ "RESOLVED" ],
-		    possible_resolutions => [ ] },
+            active => 1,
+            accepts_data_as_resolution => 1,
+            possible_resolution_states => [ "RESOLVED" ],
+            possible_resolutions => [ ] },
     "REOPENED" => { name => "REOPENED",
-		    active => 1,
-                    accepts_data_as_resolution => 0,
-		    possible_resolution_states => [ "ASSIGNED",
-						    "RESOLVED" ],
-		    possible_resolutions => [ ] },
+            active => 1,
+            accepts_data_as_resolution => 0,
+            possible_resolution_states => [ "ASSIGNED", "RESOLVED" ],
+            possible_resolutions => [ ] },
     "RESOLVED" => { name => "RESOLVED",
-		    active => 0,
-                    accepts_data_as_resolution => 0,
-		    possible_resolution_states => [ "REOPENED" ],
-		    possible_resolutions => [ "FIXED",
-					      "INVALID",
-					      "WONTFIX",
-					      "LATER",
-					      "REMIND",
-					      "DUPLICATE",
-					      "WORKSFORME" ] }
+            active => 0,
+            accepts_data_as_resolution => 0,
+            possible_resolution_states => [ "REOPENED" ],
+            possible_resolutions => [ "FIXED",
+                    "INVALID",
+                    "WONTFIX",
+                    "LATER",
+                    "REMIND",
+                    "DUPLICATE",
+                    "WORKSFORME" ] }
 };
 
 
 
+# Returns (creates lazily) the bug status map.
+# RETURNS:
+# - the map dependent on bugzilla's version
+sub bugzilla_status_map {
+    my $self = shift;
+    
+    if ( $self->is_version_latest() ) {
+
+        my $bz3_map = {};
+        my $status = Bugzilla::Field::get_legal_field_values('bug_status');
+        foreach my $s (@$status) {
+            $bz3_map->{ $s } = {};
+            $bz3_map->{ $s }->{ name } = $s;
+            $bz3_map->{ $s }->{ active } = 0; #Bugzilla::Bug::is_open_state($s);
+            $bz3_map->{ $s }->{ possible_resolution_states } = [];
+            $bz3_map->{ $s }->{ possible_resolutions } = [];
+        }
+        
+        $bz3_map->{ 'NEW'      }->{ possible_resolution_states } = [ 'ASSIGNED', 'RESOLVED' ];
+        
+        $bz3_map->{ 'ASSIGNED' }->{ active } = 1;
+        $bz3_map->{ 'ASSIGNED' }->{ accepts_data_as_resolution } = 1;
+        # ASSIGNED -> ASSIGNED for reassignment to other user
+        $bz3_map->{ 'ASSIGNED' }->{ possible_resolution_states } = [ 'ASSIGNED', 'RESOLVED' ];
+        
+        $bz3_map->{ 'REOPENED' }->{ active } = 1;
+        $bz3_map->{ 'REOPENED' }->{ possible_resolution_states } = [ 'ASSIGNED', 'RESOLVED' ];
+        
+        # RESOLVED -> RESOLVED for resolution change only
+        $bz3_map->{ 'RESOLVED' }->{ possible_resolution_states } = [ 'RESOLVED', 'REOPENED' ];
+        
+        $bz3_map->{ 'VERIFIED' }->{ possible_resolution_states } = [ 'REOPENED' ];
+        $bz3_map->{ 'CLOSED'   }->{ possible_resolution_states } = [ 'REOPENED' ];
+        
+        
+        my $resolutions = Bugzilla::Field::get_legal_field_values('resolution');
+        my $pos = Bugzilla::Util::lsearch($resolutions, '');
+        if ($pos >= 0) {
+            splice(@$resolutions, $pos, 1);
+        }
+        
+        # We don't support movements of bugs yet.
+        $pos = Bugzilla::Util::lsearch($resolutions, 'MOVED');
+        if ($pos >= 0) {
+            splice(@$resolutions, $pos, 1);
+        }
+        
+        my @res = grep ($_, @{$resolutions});
+        $bz3_map->{ 'RESOLVED' }->{ possible_resolutions } = \@res;
+        
+        return $bz3_map;
+        
+    } else {
+        # Return static map
+        return $bugzilla_bug_status_map;
+    
+    }
+}
+
+
+
 sub is_version_up_to_2_16 {
     my $self = shift;
 
@@ -190,6 +250,24 @@
 	    return ( 3, "Package '" . $package_name . "' not found in installation directory '" .
 		     $self->installation_directory() . "'.\n" );
 	}
+	
+	$package_name = "Bugzilla::Field";
+	if ( package_exists($package_name) == 0 ) {
+	    return ( 3, "Package '" . $package_name . "' not found in installation directory '" .
+		     $self->installation_directory() . "'.\n" );
+	}
+	
+	$package_name = "Bugzilla::Util";
+	if ( package_exists($package_name) == 0 ) {
+	    return ( 3, "Package '" . $package_name . "' not found in installation directory '" .
+		     $self->installation_directory() . "'.\n" );
+	}
+	
+	$package_name = "Bugzilla::Constants";
+	if ( package_exists($package_name) == 0 ) {
+	    return ( 3, "Package '" . $package_name . "' not found in installation directory '" .
+		     $self->installation_directory() . "'.\n" );
+	}
     }
 
     # This is direct modification to bugzilla's internal variables
@@ -260,123 +338,12 @@
 
 
 
-# Do the bulk of the work required for integration_get_vdd
-#
-# PARAMETERS:
-# $1 - The VDD to categorize
-# $2 - The comment array
-# $3 - The bug id
-# $4 - The comment counter
-sub categorizeVDD {
-    my $self = shift;
-    my ( $vdd, %comment, $bugid, $comment_counter ) = ( @_ );
-
-        $comment{'author_username'} .= Param('emailsuffix');
-        $comment{'author_name'} = $comment{'author_name'} || $comment{'author_username'};
-	
-	# The resolution can be blank in the database
-	if ( !defined ($comment{'resolution'} ) ) {
-	    $comment{'resolution'} = "";
-	}
-	my $comment_counter_text;
-	$comment_counter_text = "inaccurate_" . $comment_counter;
-
-	$vdd->add_bug_comment( 'all',
-			       $bugid,
-			       $comment{ 'summary' },
-			       $comment{ 'status' },
-			       $comment{ 'resolution' },
-			       $comment{ 'severity' },
-			       $comment{ 'priority' },
-			       $comment_counter_text,
-			       $comment{ 'content' },
-			       $comment{ 'date' },
-			       $comment{ 'author_username' },
-			       $comment{ 'author_name' },
-			       $comment{ 'author_email' } );
-
-	#
-	# Categorize the bug even further
-	#
-
-	# If the bug is new or unconfirmed add it in the new list as
-	# well
-	if ( $comment{ 'status' } eq "NEW" ||
-	     $comment{ 'status' } eq "UNCONFIRMED" ) {
-	    $vdd->add_bug_comment( 'new',
-				   $bugid,
-				   $comment{ 'summary' },
-				   $comment{ 'status' },
-				   $comment{ 'resolution' },
-				   $comment{ 'severity' },
-				   $comment{ 'priority' },
-				   $comment_counter_text,
-				   $comment{ 'content' },
-				   $comment{ 'date' },
-				   $comment{ 'author_username' },
-				   $comment{ 'author_name' },
-				   $comment{ 'author_email' } );
-	} elsif ( $comment{ 'status' } eq "RESOLVED" ||
-		  $comment{ 'status' } eq "VERIFIED" ||
-		  $comment{ 'status' } eq "CLOSED" ) {
-	    # If the bug is resolved or verified or closed add it in
-	    # closed list as well
-	    $vdd->add_bug_comment( 'closed',
-				   $bugid,
-				   $comment{ 'summary' },
-				   $comment{ 'status' },
-				   $comment{ 'resolution' },
-				   $comment{ 'severity' },
-				   $comment{ 'priority' },
-				   $comment_counter_text,
-				   $comment{ 'content' },
-				   $comment{ 'date' },
-				   $comment{ 'author_username' },
-				   $comment{ 'author_name' },
-				   $comment{ 'author_email' } );
-
-	    # Also check if the bug was closed with no SCM activity
-	    if ( ! $comment{ 'content' } =~ m/$PRODUCT_AFFECTED_FILES_TOKEN/ ) {
-		$vdd->add_bug_comment( 'closed_untouched',
-				       $bugid,
-				       $comment{ 'summary' },
-				       $comment{ 'status' },
-				       $comment{ 'resolution' },
-				       $comment{ 'severity' },
-				       $comment{ 'priority' },
-				       $comment_counter_text,
-				       $comment{ 'content' },
-				       $comment{ 'date' },
-				       $comment{ 'author_username' },
-				       $comment{ 'author_name' },
-				       $comment{ 'author_email' } );
-	    }
-
-	} else {
-	    # The bug must have been worked on but is not yet finished
-	    $vdd->add_bug_comment( 'inprogress',
-				   $bugid,
-				   $comment{ 'summary' },
-				   $comment{ 'status' },
-				   $comment{ 'resolution' },
-				   $comment{ 'severity' },
-				   $comment{ 'priority' },
-				   $comment_counter_text,
-				   $comment{ 'content' },
-				   $comment{ 'date' },
-				   $comment{ 'author_username' },
-				   $comment{ 'author_name' },
-				   $comment{ 'author_email' } );
-	}
-}
-
-
-
 # -----------------------------------------------------------------------------
 # These functions are required by the Bugtracker interface
 # -----------------------------------------------------------------------------
 
 
+
 sub set_version_type {
     my $self = shift;
     my $version = $self->version();
@@ -501,11 +468,178 @@
     my $self = shift;
     my ( $bugid, $username, $status, $resolution, $resolution_data ) = ( @_ );
 
-    return ( 1, "Changing bug resolution is not yet implemented in this version of Bugzilla.\n");
-}
-
+    if ( $self->is_version_latest() ) {
 
+        my $PrivilegesRequired = 0;
+        my $bug = new Bugzilla::Bug($bugid);
+        my $user = Bugzilla::User->new({ name => $username });
+        Bugzilla->set_user($user);
+        
+        my $dbh = Bugzilla->dbh;
+        my $sql = "UPDATE bugs SET ";
+        my $has_changed = 0;
+        my @params = ();
+        if(!defined $status) {
+            $status = "none";
+        } else {
+            $status = lc $status;
+        }
+        
+        my $assignee = undef;
+        my $dupe_id = undef;
+
+        SWITCH: for ($status) {
+            /^none$/ && do {
+                
+                return ( 1, "Undefined status.\n");
+                
+            };
+            /^assigned$/ && do {
+                
+                if( defined($resolution) && ('' ne $resolution)) {
+                    # Reassign to given assignee
+                    
+                    $assignee = $dbh->selectrow_array("SELECT userid FROM profiles WHERE ".
+                                    $dbh->sql_istrcmp('login_name', '?'), undef, $resolution);
+                                    
+                    if( $assignee == 0) {
+                        return ( 1, "Unknown assignee $resolution.\n");
+                    }
+                    
+                    my %data = {'knob' => 'reassign'};
+                    if(!$bug->check_can_change_field('assigned_to', $bug->assigned_to, $assignee, \$PrivilegesRequired, \%data)) {
+                        return ( 1, "Missing permission to reassign bug.\n");
+                    }
+                    
+                    $sql .= "bug_status=?";
+                    push(@params, 'NEW'); # NOT ASSIGNED, this would break bz workflow
+                    $sql .= ", assigned_to = ?";
+                    push(@params, $assignee);
+                    
+                } else {
+                    # Accepting bug
+                    if($bug->assigned_to->id == 0) {
+                        return ( 1, "Bug '$bugid' was never confirmed. Can't change status to 'ASSIGNED'.\n");
+                    }
+                    
+                    if($bug->assigned_to->id != $user->id) {
+                        return ( 1, "You cannot accept a bug if you aren't the assignee.\n");
+                    }
+                    
+                    $sql .= "bug_status=?";
+                    push(@params, 'ASSIGNED');
+                }
+                
+                $has_changed = 1;
+                last SWITCH;
+                
+            };
+            /^reopened$/ && do {
+                if(!$bug->check_can_change_field('bug_status', $bug->bug_status, uc $status, \$PrivilegesRequired)) {
+                    return ( 1, "Missing permission to reopen bug.\n");
+                }
+                $sql .= "bug_status=?";
+                push(@params, uc $status);
+                $sql .= ", resolution=?";
+                push(@params, "");
+                $has_changed = 1;
+                last SWITCH;
+                
+            };
+            /^resolved$/ && do {
+                $resolution = lc $resolution;
+                if(!$bug->check_can_change_field('bug_status', $bug->bug_status, uc $status, \$PrivilegesRequired)) {
+                    return ( 1, "Missing permission to resolve bug.\n");
+                }
+                
+                if((!defined $resolution) || ('' eq $resolution)) {
+                    return ( 1, "Undefined resolution for status '$status'.\n");
+                }
+                
+                if($resolution eq "moved") {
+                    # Should never happen, anyway leave it here
+                    return ( 1, "Movement of bugs isn't supported.\n");
+                    
+                } elsif ($resolution eq "duplicate") {
+
+                    $dupe_id = $resolution_data;
+                    my $reporter = $dbh->selectrow_array( q{SELECT reporter FROM bugs WHERE bug_id = ?}, undef, $dupe_id);
+                    my $rep_user = Bugzilla::User->new($reporter);
+                    if (!$rep_user->can_see_bug($dupe_id)) {
+                        # We don't want to be verbose to the user here
+                        return ( 1, "Error while setting status to 'resolved duplicate $resolution_data'.\n");
+                    }
+                }
+                
+                $sql .= "remaining_time = 0";
+                $sql .= ", bug_status=?";
+                push(@params, uc $status);
+                $sql .= ", resolution=?";
+                push(@params, uc $resolution);
+                $has_changed = 1;
+                last SWITCH;
+                
+            };
+            
+            return ( 1, "Unknown status '$status'.\n");
+        }
+        
 
+        my $dbh = Bugzilla->dbh;
+        
+        $dbh->bz_lock_tables('bugs WRITE', 'bugs_activity WRITE', 'duplicates WRITE', 'longdescs WRITE', 'fielddefs READ', 'profiles READ');
+        my $timestamp = $dbh->selectrow_array("SELECT NOW()");
+        
+        $sql .= " WHERE bug_id = ?";
+        push(@params, $bugid);
+
+        if ($has_changed == 1) {
+            my $result = $dbh->do($sql, undef, @params);
+
+            if($result) {
+                
+                if ($resolution ne 'duplicate') {
+                    $dbh->do(q{DELETE FROM duplicates WHERE dupe = ?}, undef, $bugid);
+
+                } else {
+                    # Remove previous one if dupe has changed
+                    $dbh->do(q{DELETE FROM duplicates WHERE dupe = ?}, undef, $bugid);
+                    
+                    if($dbh->do(q{INSERT INTO duplicates VALUES (?, ?)}, undef, $dupe_id, $bugid)) {
+                        Bugzilla::Bug::AppendComment($bugid, $user->id, "", 0, $timestamp, 0, Bugzilla::Constants->CMT_DUPE_OF, $dupe_id);
+                        Bugzilla::Bug::AppendComment($dupe_id, $user->id, "", 0, $timestamp, 0, Bugzilla::Constants->CMT_HAS_DUPE, $bugid);
+                    }
+                }
+                
+                my $bug2 = new Bugzilla::Bug($bugid);
+                if( defined($assignee) && ( $bug->assigned_to->id != $bug2->assigned_to->id)) {
+                    my $old_value = Bugzilla::User::user_id_to_login($bug->assigned_to->id);
+                    my $new_value = Bugzilla::User::user_id_to_login($bug2->assigned_to->id);
+                    Bugzilla::Bug::LogActivityEntry($bugid, 'assigned_to', $old_value, $new_value, $user->id, $timestamp);
+                }
+                if($bug->bug_status ne $bug2->bug_status) {
+                    Bugzilla::Bug::LogActivityEntry($bugid, 'bug_status', $bug->bug_status, $bug2->bug_status, $user->id, $timestamp);
+                }
+                if($bug->resolution ne $bug2->resolution) {
+                    Bugzilla::Bug::LogActivityEntry($bugid, 'resolution', $bug->resolution, $bug2->resolution, $user->id, $timestamp);
+                }
+                
+            } else {
+                $dbh->bz_unlock_tables();
+                return ( 1, "Error while updating bug.\n");
+            }
+        }
+        $dbh->bz_unlock_tables();
+        
+        if($has_changed == 1){
+            return 0;
+        } else {
+            return ( 1, "Changing bug resolution wasn't successful. Nothing changed.\n");
+        }
+        
+    }
+    return ( 1, "Changing bug resolution is not yet implemented in this version of Bugzilla.\n");
+}
 
 
 
@@ -527,8 +661,9 @@
     my ( $bugid, $proposed_status, $proposed_resolution, $case_sensitive_verification ) = ( @_ );
 
     my $bug_status = $self->integration_get_bug_status( $bugid );
+    my $rc = $self->resolution_change_check( $bug_status, $proposed_status, $proposed_resolution, $self->bugzilla_status_map() );
 
-    return ( $self->resolution_change_check( $bug_status, $proposed_status, $proposed_resolution, $bugzilla_bug_status_map ), $bug_status, $case_sensitive_verification );
+    return ($rc , $bug_status );
 }
 
 
@@ -539,7 +674,7 @@
     my $self = shift;
     my ( $bug_status_string ) = ( @_ );
 
-    return $self->valid_resolution_states_list( $bug_status_string, $bugzilla_bug_status_map );
+    return $self->valid_resolution_states_list( $bug_status_string, $self->bugzilla_status_map() );
 }
 
 
@@ -555,7 +690,7 @@
     my $self = shift;
     my ( $bug_status_string, $case_sensitive_verification ) = ( @_ );
 
-    return $self->valid_resolutions_list( $bug_status_string, $bugzilla_bug_status_map, $case_sensitive_verification );
+    return $self->valid_resolutions_list( $bug_status_string, $self->bugzilla_status_map(), $case_sensitive_verification );
 }
 
 
@@ -755,7 +890,7 @@
     my $bug_status = $self->integration_get_bug_status( $bugid );
     
     # Verify that the bug is in the assigned or reopened state
-    if ( $bugzilla_bug_status_map->{ $bug_status }->{ active } == 1 ) {
+    if ( $self->bugzilla_status_map()->{ $bug_status }->{ active } == 1 ) {
 	return (1, $bug_status);
     } else {
 	return (0, $bug_status);
@@ -769,7 +904,7 @@
 sub integration_active_states_list {
     my $self = shift;
 
-    return $self->active_states_list( $bugzilla_bug_status_map );
+    return $self->active_states_list( $self->bugzilla_status_map() );
 }
 
 
@@ -1012,7 +1147,7 @@
     my $sql;
 
     if ( is_version_up_to_2_16() ) {
-	$sql = "SELECT profiles.login_name AS author_username,
+        $sql = "SELECT profiles.login_name AS author_username,
                       profiles.realname AS author_name,
                       profiles.login_name AS author_email,
                       longdescs.bug_id AS bug_id,
@@ -1030,7 +1165,7 @@
                AND    longdescs.bug_id = bugs.bug_id
                AND    bugs.product = '$product_name'";
     } else {
-	$sql = "SELECT profiles.login_name AS author_username,
+        $sql = "SELECT profiles.login_name AS author_username,
                       profiles.realname AS author_name,
                       profiles.login_name AS author_email,
                       longdescs.bug_id AS bug_id,
@@ -1053,11 +1188,13 @@
     my $comment_counter = 1;
 
     if ( $self->is_version_latest() ) {
+        
         my $dbh = Bugzilla->dbh;
         my $sth = $dbh->prepare($sql);
         $sth->execute();
-        my $result;
-        while ($result = $sth->fetchrow_arrayref()) {
+        
+        my $list = $dbh->selectall_arrayref($sql, undef);
+        foreach my $entry (@$list) {
             my %comment;
             my $bugid;
             ($comment{'author_username'},
@@ -1070,11 +1207,12 @@
              $comment{'severity'},
              $comment{'priority'},
              $comment{'date'},
-             $comment{'content'}) = $result;
+             $comment{'content'}) = @$entry;
     
-            $self->categorizeVDD( $vdd, %comment, $bugid, $comment_counter );
-	    $comment_counter++;
+             $self->categorizeVDD( $vdd, \%comment, $bugid, $comment_counter );
+             $comment_counter++;
         }
+        
     } else {
         PushGlobalSQLState();
         SendSQL( $sql );
@@ -1093,9 +1231,9 @@
              $comment{'date'},
              $comment{'content'}) = FetchSQLData();
 
-            $self->categorizeVDD( $vdd, %comment, $bugid, $comment_counter );
-	    $comment_counter++;
-	}
+             $self->categorizeVDD( $vdd, \%comment, $bugid, $comment_counter );
+             $comment_counter++;
+        }
     }
 
     return $vdd;
@@ -1103,6 +1241,77 @@
 
 
 
+# Do the bulk of the work required for integration_get_vdd
+#
+# PARAMETERS:
+# $1 - The VDD to categorize
+# $2 - The comment array
+# $3 - The bug id
+# $4 - The comment counter
+sub categorizeVDD {
+    my $self = shift;
+    my ( $vdd, $comment, $bugid, $comment_counter ) = ( @_ );
+    
+    if($self->is_version_latest()) {
+        $comment->{'author_username'} .= Bugzilla->params->{'emailsuffix'}; 
+    } else {
+        $comment->{'author_username'} .= Param('emailsuffix');
+    }
+    $comment->{'author_name'} = $comment->{'author_name'} || $comment->{'author_username'};
+
+    # The resolution can be blank in the database
+    if ( !defined ($comment->{'resolution'} ) ) {
+        $comment->{'resolution'} = "";
+    }
+    
+    
+    my $comment_counter_text = "inaccurate_".$comment_counter;
+    
+    #aolifu: Let's use this array for redundant data
+    my @data = ( $bugid,
+        $comment->{ 'summary' },
+        $comment->{ 'status' },
+        $comment->{ 'resolution' },
+        $comment->{ 'severity' },
+        $comment->{ 'priority' },
+        $comment_counter_text,
+        $comment->{ 'content' },
+        $comment->{ 'date' },
+        $comment->{ 'author_username' },
+        $comment->{ 'author_name' },
+        $comment->{ 'author_email' } );
+    
+    $vdd->add_bug_comment( 'all', @data);
+
+    #
+    # Categorize the bug even further
+    #
+
+    # If the bug is new or unconfirmed add it in the new list as well
+    if ( $comment->{ 'status' } eq "NEW" || $comment->{ 'status' } eq "UNCONFIRMED" ) {
+        
+        $vdd->add_bug_comment( 'new', @data);
+            
+    } elsif ( $comment->{ 'status' } eq "RESOLVED" ||
+        $comment->{ 'status' } eq "VERIFIED" ||
+        $comment->{ 'status' } eq "CLOSED" ) {
+
+        # If the bug is resolved or verified or closed add it in closed list as well
+        $vdd->add_bug_comment( 'closed', @data);
+
+        # Also check if the bug was closed with no SCM activity
+        if ( ! $comment->{ 'content' } =~ m/$PRODUCT_AFFECTED_FILES_TOKEN/ ) {
+            $vdd->add_bug_comment( 'closed_untouched', @data);
+        }
+
+    } else {
+        # The bug must have been worked on but is not yet finished
+        $vdd->add_bug_comment( 'inprogress', @data);
+    }
+}
+
+
+
 # Runs a get bugs query
 #
 # PARAMETERS:
@@ -1139,73 +1348,96 @@
                AND    (";
     my $id_counter = 0;
     foreach my $id ( @{ $ids } ) {
-	if ( $id_counter >= 1) {
-	    $sql .= "\n               OR     ";
-	}
-	$sql .= "bugs.bug_id = $id";
-	$id_counter++;
+        if ( $id_counter >= 1) {
+            $sql .= "\n               OR     ";
+        }
+        $sql .= "bugs.bug_id = $id";
+        $id_counter++;
     }
     $sql .= ");";
-
-    PushGlobalSQLState();
-    SendSQL( $sql );
+    
+    print Dumper($sql);
+    my $list = undef;
+    if ( $self->is_version_latest() ) {
+        my $dbh = Bugzilla->dbh;
+        my $sth = $dbh->prepare($sql);
+        $sth->execute();
+        
+        $list = $dbh->selectall_arrayref($sql, undef);
+    
+    } else {
+        PushGlobalSQLState();
+        SendSQL( $sql );
+        
+        my @list = ();
+        while (MoreSQLData()) {
+            my @row = FetchSQLData();
+            push(@list, @row);
+        }
+        $list = \@list;
+        PopGlobalSQLState();
+    }
+    
+    
     my $comment_counter = 1;
-    while (MoreSQLData()) {
+    foreach my $entry (@$list) {
         my %comment;
-	my $bugid;
+        my $bugid;
         ($comment{'author_username'},
-	 $comment{'author_name'},
-	 $comment{'author_email'},
-	 $bugid,
-	 $comment{'summary'},
-	 $comment{'status'},
-	 $comment{'resolution'},
-	 $comment{'severity'},
-	 $comment{'priority'},
-	 $comment{'date'},
-	 $comment{'content'}) = FetchSQLData();
-	
-        $comment{'author_username'} .= Param('emailsuffix');
-        $comment{'author_name'} = $comment{'author_name'} || $comment{'author_username'};
-	
-	# The resolution can be blank in the database
-	if ( !defined ($comment{'resolution'} ) ) {
-	    $comment{'resolution'} = "";
-	}
-	my $comment_counter_text;
-	$comment_counter_text = "inaccurate_" . $comment_counter;
-
-	my ($is_an_integration_comment, $affected_files_description, $extracted_comment, $extracted_ret_val, $extracted_ret_message) = $self->extract_affected_files( $comment{ content }, $comment{ bug_id }, $comment_counter_text );
-
-	if ($is_an_integration_comment == 1) {
-
-	    if ($extracted_ret_val == 0) {
-		$mergelist->add_bug_comment( $bugid,
-					     $comment{ 'summary' },
-					     $comment{ 'status' },
-					     $comment{ 'resolution' },
-					     $comment{ 'severity' },
-					     $comment{ 'priority' },
-					     $comment_counter_text,
-					     $extracted_comment,
-					     $comment{ 'date' },
-					     $comment{ 'author_username' },
-					     $comment{ 'author_name' },
-					     $comment{ 'author_email' },
-					     $affected_files_description );
-	    } else {
-		# There was an error message detected. Should report it.
-		$ret_val = 1;
-		$ret_message .= $extracted_ret_message;
-	    }
-	} else {
-	    # This is just a user comment. Ignore it.
-	}
-	$comment_counter++;
-    }
-    PopGlobalSQLState();
-    close SOMEFILE;
+         $comment{'author_name'},
+         $comment{'author_email'},
+         $bugid,
+         $comment{'summary'},
+         $comment{'status'},
+         $comment{'resolution'},
+         $comment{'severity'},
+         $comment{'priority'},
+         $comment{'date'},
+         $comment{'content'}) = @$entry;
+
+         if($self->is_version_latest()) {
+             $comment{'author_username'} .= Bugzilla->params->{'emailsuffix'}; 
+         } else {
+             $comment{'author_username'} .= Param('emailsuffix');
+         }
+         $comment{'author_name'} = $comment{'author_name'} || $comment{'author_username'};
+
+         # The resolution can be blank in the database
+         if ( !defined ($comment{'resolution'} ) ) {
+             $comment{'resolution'} = "";
+         }
+         my $comment_counter_text;
+         $comment_counter_text = "inaccurate_" . $comment_counter;
+
+         my ($is_an_integration_comment, $affected_files_description, $extracted_comment, $extracted_ret_val, $extracted_ret_message) = $self->extract_affected_files( $comment{ content }, $comment{ bug_id }, $comment_counter_text );
+
+         if ($is_an_integration_comment == 1) {
+
+             if ($extracted_ret_val == 0) {
+                 $mergelist->add_bug_comment( $bugid,
+                 $comment{ 'summary' },
+                 $comment{ 'status' },
+                 $comment{ 'resolution' },
+                 $comment{ 'severity' },
+                 $comment{ 'priority' },
+                 $comment_counter_text,
+                 $extracted_comment,
+                 $comment{ 'date' },
+                 $comment{ 'author_username' },
+                 $comment{ 'author_name' },
+                 $comment{ 'author_email' },
+                 $affected_files_description );
+             } else {
+                 # There was an error message detected. Should report it.
+                 $ret_val = 1;
+                 $ret_message .= $extracted_ret_message;
+             }
+         } else {
+             # This is just a user comment. Ignore it.
+         }
 
+         $comment_counter++;
+    }
 
     return $mergelist, $ret_val, $ret_message;
 }
