[bugzilla] Upgrade from 3.0 to 3.0.2 .

Jan Zerebecki jan.wine at zerebecki.de
Sun Oct 7 14:54:41 CDT 2007


---
See http://www.bugzilla.org/releases/3.0.2/release-notes.html and
http://www.bugzilla.org/status/changes.html for information about
the changes.
---
If this patch is rejected from inclusion, please tell me why, as
I would have to ask anyway.

 Bugzilla.pm                                        |   14 +
 Bugzilla/Attachment.pm                             |    9 +
 Bugzilla/Bug.pm                                    |    2 
 Bugzilla/Config/Common.pm                          |   11 +
 Bugzilla/Config/MTA.pm                             |    6 
 Bugzilla/Config/Query.pm                           |   10 +
 Bugzilla/Constants.pm                              |    6 
 Bugzilla/DB.pm                                     |    2 
 Bugzilla/DB/Pg.pm                                  |    3 
 Bugzilla/DB/Schema.pm                              |   32 +-
 Bugzilla/Error.pm                                  |   18 +
 Bugzilla/Flag.pm                                   |   10 +
 Bugzilla/Install/DB.pm                             |    2 
 Bugzilla/Install/Filesystem.pm                     |   21 +-
 Bugzilla/Mailer.pm                                 |   23 +-
 Bugzilla/Search/Quicksearch.pm                     |   17 +
 Bugzilla/Search/Saved.pm                           |    2 
 Bugzilla/Template.pm                               |    4 
 Bugzilla/User.pm                                   |   45 +++
 Bugzilla/User/Setting/Skin.pm                      |    4 
 Bugzilla/WebService/Bug.pm                         |    9 +
 Bugzilla/WebService/Constants.pm                   |    3 
 Bugzilla/WebService/User.pm                        |    5 
 QUICKSTART                                         |   12 -
 buglist.cgi                                        |   31 ++
 chart.cgi                                          |    2 
 collectstats.pl                                    |   22 +-
 contrib/README                                     |    7 -
 contrib/bz_webservice_demo.pl                      |   37 ++-
 contrib/bzdbcopy.pl                                |    6 
 docs/rel_notes.txt                                 |   34 +-
 docs/xml/Bugzilla-Guide.xml                        |    6 
 docs/xml/about.xml                                 |    6 
 docs/xml/administration.xml                        |    9 -
 docs/xml/customization.xml                         |    6 
 docs/xml/dbschema.mysql                            |    1 
 docs/xml/faq.xml                                   |  247 +++++++-----------
 docs/xml/filetemp.patch                            |   18 -
 docs/xml/glossary.xml                              |    4 
 docs/xml/introduction.xml                          |    2 
 docs/xml/patches.xml                               |    2 
 docs/xml/security.xml                              |   29 --
 docs/xml/using.xml                                 |    8 -
 duplicates.cgi                                     |    8 +
 editcomponents.cgi                                 |    2 
 editparams.cgi                                     |    4 
 editproducts.cgi                                   |   11 +
 email_in.pl                                        |   13 +
 process_bug.cgi                                    |  101 +++++--
 sanitycheck.cgi                                    |   10 +
 showdependencygraph.cgi                            |    8 -
 skins/standard/global.css                          |    4 
 t/009bugwords.t                                    |    4 
 .../en/default/account/auth/login-small.html.tmpl  |    3 
 template/en/default/account/auth/login.html.tmpl   |    4 
 template/en/default/account/prefs/email.html.tmpl  |   10 +
 .../default/account/prefs/saved-searches.html.tmpl |   45 ++++
 .../en/default/account/prefs/settings.html.tmpl    |    2 
 .../default/admin/classifications/edit.html.tmpl   |    2 
 .../en/default/admin/components/edit.html.tmpl     |    6 -
 .../default/admin/custom_fields/create.html.tmpl   |    2 
 .../en/default/admin/custom_fields/edit.html.tmpl  |    2 
 .../en/default/admin/custom_fields/list.html.tmpl  |    4 
 template/en/default/admin/keywords/list.html.tmpl  |    2 
 template/en/default/admin/params/core.html.tmpl    |    3 
 template/en/default/admin/params/mta.html.tmpl     |    5 
 template/en/default/admin/params/query.html.tmpl   |    5 
 .../en/default/admin/settings/updated.html.tmpl    |    2 
 .../default/admin/users/confirm-delete.html.tmpl   |    2 
 template/en/default/admin/users/userdata.html.tmpl |    6 
 .../en/default/bug/create/create-guided.html.tmpl  |    2 
 template/en/default/bug/edit.html.tmpl             |   14 +
 .../bug/process/verify-new-product.html.tmpl       |   44 +++-
 template/en/default/bug/summarize-time.html.tmpl   |    4 
 .../en/default/bug/votes/list-for-user.html.tmpl   |    2 
 template/en/default/email/newchangedmail.txt.tmpl  |    2 
 template/en/default/email/sudo.txt.tmpl            |    2 
 template/en/default/filterexceptions.pl            |    1 
 template/en/default/flag/list.html.tmpl            |    9 -
 template/en/default/global/code-error.html.tmpl    |   26 +-
 template/en/default/global/header.html.tmpl        |    2 
 template/en/default/global/messages.html.tmpl      |   12 -
 template/en/default/global/setting-descs.none.tmpl |    4 
 template/en/default/global/useful-links.html.tmpl  |    2 
 template/en/default/global/user-error.html.tmpl    |   54 ++--
 template/en/default/index.html.tmpl                |    4 
 template/en/default/list/list.csv.tmpl             |    6 
 template/en/default/list/table.html.tmpl           |    6 
 template/en/default/pages/bug-writing.html.tmpl    |  273 ++++----------------
 template/en/default/pages/release-notes.html.tmpl  |  129 +++++++++
 template/en/default/reports/chart.png.tmpl         |    2 
 .../en/default/reports/report-simple.html.tmpl     |    2 
 template/en/default/reports/report-table.html.tmpl |   13 -
 template/en/default/request/email.txt.tmpl         |   10 -
 template/en/default/search/knob.html.tmpl          |    2 
 template/en/default/search/search-help.html.tmpl   |    2 
 .../default/search/search-report-graph.html.tmpl   |    2 
 .../en/default/search/search-specific.html.tmpl    |    9 +
 template/en/default/sidebar.xul.tmpl               |    2 
 template/en/default/whine/schedule.html.tmpl       |    2 
 userprefs.cgi                                      |   21 +-
 votes.cgi                                          |    7 -
 whineatnews.pl                                     |    9 -
 103 files changed, 951 insertions(+), 747 deletions(-)

diff --git a/Bugzilla.pm b/Bugzilla.pm
index 679695b..7be74b1 100644
--- a/Bugzilla.pm
+++ b/Bugzilla.pm
@@ -86,6 +86,20 @@ sub init_page {
     # PATH is undefined.
     $ENV{'PATH'} = '';
 
+    # IIS prints out warnings to the webpage, so ignore them, or log them
+    # to a file if the file exists.
+    if ($ENV{SERVER_SOFTWARE} && $ENV{SERVER_SOFTWARE} =~ /microsoft-iis/i) {
+        $SIG{__WARN__} = sub {
+            my ($msg) = @_;
+            my $datadir = bz_locations()->{'datadir'};
+            if (-w "$datadir/errorlog") {
+                my $warning_log = new IO::File(">>$datadir/errorlog");
+                print $warning_log $msg;
+                $warning_log->close();
+            }
+        };
+    }
+
     # If Bugzilla is shut down, do not allow anything to run, just display a
     # message to the user about the downtime and log out.  Scripts listed in 
     # SHUTDOWNHTML_EXEMPT are exempt from this message.
diff --git a/Bugzilla/Attachment.pm b/Bugzilla/Attachment.pm
index cf4f475..a08c0d5 100644
--- a/Bugzilla/Attachment.pm
+++ b/Bugzilla/Attachment.pm
@@ -748,6 +748,15 @@ sub insert_attachment_for_bug {
         # we now check the content type for image/bmp in _validate_data()
         unless ($cgi->param('ispatch')) {
             $class->validate_content_type($throw_error) || return 0;
+
+            # Set the ispatch flag to 1 if we're set to autodetect
+            # and the content type is text/x-diff or text/x-patch
+            if ($cgi->param('contenttypemethod') eq 'autodetect'
+                && $cgi->param('contenttype') =~ m{text/x-(?:diff|patch)})
+            {
+                $cgi->param('ispatch', 1);
+                $cgi->param('contenttype', 'text/plain');
+            }
         }
         $data = _validate_data($throw_error, $hr_vars);
         # If the attachment is stored locally, $data eq ''.
diff --git a/Bugzilla/Bug.pm b/Bugzilla/Bug.pm
index 8591a2f..ba96cb8 100644
--- a/Bugzilla/Bug.pm
+++ b/Bugzilla/Bug.pm
@@ -537,7 +537,7 @@ sub _check_bug_status {
 
 sub _check_cc {
     my ($invocant, $component, $ccs) = @_;
-    return [] unless $ccs;
+    return [map {$_->id} @{$component->initial_cc}] unless $ccs;
 
     my %cc_ids;
     foreach my $person (@$ccs) {
diff --git a/Bugzilla/Config/Common.pm b/Bugzilla/Config/Common.pm
index 0d6db52..c309059 100644
--- a/Bugzilla/Config/Common.pm
+++ b/Bugzilla/Config/Common.pm
@@ -285,17 +285,26 @@ sub check_image_converter {
 }
 
 sub check_languages {
-    my @languages = split /[,\s]+/, trim($_[0]);
+    my ($lang, $param) = @_;
+    my @languages = split(/[,\s]+/, trim($lang));
     if(!scalar(@languages)) {
        return "You need to specify a language tag."
     }
+    if (scalar(@languages) > 1 && $param && $param->{'name'} eq 'defaultlanguage') {
+        return "You can only specify one language tag";
+    }
     my $templatedir = bz_locations()->{'templatedir'};
+    my %lang_seen;
+    my @validated_languages;
     foreach my $language (@languages) {
        if(   ! -d "$templatedir/$language/custom" 
           && ! -d "$templatedir/$language/default") {
           return "The template directory for $language does not exist";
        }
+       push(@validated_languages, $language) unless $lang_seen{$language}++;
     }
+    # Rebuild the list of language tags, avoiding duplicates.
+    $_[0] = join(', ', @validated_languages);
     return "";
 }
 
diff --git a/Bugzilla/Config/MTA.pm b/Bugzilla/Config/MTA.pm
index 3415677..686d5b3 100644
--- a/Bugzilla/Config/MTA.pm
+++ b/Bugzilla/Config/MTA.pm
@@ -68,7 +68,11 @@ sub get_param_list {
    type => 't',
    default => 'localhost'
   },
-
+  {
+   name => 'smtp_debug',
+   type => 'b',
+   default => 0
+  },
   {
    name => 'whinedays',
    type => 't',
diff --git a/Bugzilla/Config/Query.pm b/Bugzilla/Config/Query.pm
index e3996a0..74e2650 100644
--- a/Bugzilla/Config/Query.pm
+++ b/Bugzilla/Config/Query.pm
@@ -72,7 +72,15 @@ sub get_param_list {
    type    => 't',
    default => '4',
    checker => \&check_numeric
-  } );
+  },
+  
+  {
+   name => 'specific_search_allow_empty_words',
+   type => 'b',
+   default => 0
+  }
+  
+  );
   return @param_list;
 }
 
diff --git a/Bugzilla/Constants.pm b/Bugzilla/Constants.pm
index 2a4dd92..9851859 100644
--- a/Bugzilla/Constants.pm
+++ b/Bugzilla/Constants.pm
@@ -146,7 +146,7 @@ use File::Basename;
 # CONSTANTS
 #
 # Bugzilla version
-use constant BUGZILLA_VERSION => "3.0";
+use constant BUGZILLA_VERSION => "3.0.2";
 
 #
 # ControlMap constants for group_control_map.
@@ -208,7 +208,7 @@ use constant contenttypes =>
    "atom"=> "application/atom+xml" ,
    "xml" => "application/xml" , 
    "js"  => "application/x-javascript" , 
-   "csv" => "text/plain" ,
+   "csv" => "text/csv" ,
    "png" => "image/png" ,
    "ics" => "text/calendar" ,
   };
@@ -426,7 +426,7 @@ sub bz_locations {
         'localconfig' => "$libpath/$localconfig",
         'datadir'     => "$libpath/$datadir",
         'attachdir'   => "$libpath/$datadir/attachments",
-        'skinsdir'    => "$libpath/skins/contrib",
+        'skinsdir'    => "$libpath/skins",
         # $webdotdir must be in the webtree somewhere. Even if you use a 
         # local dot, we output images to there. Also, if $webdotdir is 
         # not relative to the bugzilla root directory, you'll need to 
diff --git a/Bugzilla/DB.pm b/Bugzilla/DB.pm
index 4bfb3ae..b4f6596 100644
--- a/Bugzilla/DB.pm
+++ b/Bugzilla/DB.pm
@@ -321,7 +321,7 @@ sub sql_group_by {
     my ($self, $needed_columns, $optional_columns) = @_;
 
     my $expression = "GROUP BY $needed_columns";
-    $expression .= ", " . $optional_columns if defined($optional_columns);
+    $expression .= ", " . $optional_columns if $optional_columns;
     
     return $expression;
 }
diff --git a/Bugzilla/DB/Pg.pm b/Bugzilla/DB/Pg.pm
index f6a5209..9f5b677 100644
--- a/Bugzilla/DB/Pg.pm
+++ b/Bugzilla/DB/Pg.pm
@@ -60,7 +60,8 @@ sub new {
     $dbname ||= 'template1';
 
     # construct the DSN from the parameters we got
-    my $dsn = "DBI:Pg:host=$host;dbname=$dbname";
+    my $dsn = "DBI:Pg:dbname=$dbname";
+    $dsn .= ";host=$host" if $host;
     $dsn .= ";port=$port" if $port;
 
     # This stops Pg from printing out lots of "NOTICE" messages when
diff --git a/Bugzilla/DB/Schema.pm b/Bugzilla/DB/Schema.pm
index ff81d9c..f4c1c30 100644
--- a/Bugzilla/DB/Schema.pm
+++ b/Bugzilla/DB/Schema.pm
@@ -1211,22 +1211,26 @@ sub _initialize {
     my $self = shift;
     my $abstract_schema = shift;
 
-    $abstract_schema ||= ABSTRACT_SCHEMA;
-
-    # Let extensions add tables, but make sure they can't modify existing 
-    # tables. If we don't lock/unlock keys, lock_value complains.
-    lock_keys(%$abstract_schema);
-    lock_value(%$abstract_schema, $_) foreach (keys %$abstract_schema);
-    unlock_keys(%$abstract_schema);
-    Bugzilla::Hook::process('db_schema-abstract_schema', 
-                            { schema => $abstract_schema });
-    unlock_hash(%$abstract_schema);
+    if (!$abstract_schema) {
+        # While ABSTRACT_SCHEMA cannot be modified, $abstract_schema can be.
+        # So, we dclone it to prevent anything from mucking with the constant.
+        $abstract_schema = dclone(ABSTRACT_SCHEMA);
+
+        # Let extensions add tables, but make sure they can't modify existing
+        # tables. If we don't lock/unlock keys, lock_value complains.
+        lock_keys(%$abstract_schema);
+        foreach my $table (keys %{ABSTRACT_SCHEMA()}) {
+            lock_value(%$abstract_schema, $table) 
+                if exists $abstract_schema->{$table};
+        }
+        unlock_keys(%$abstract_schema);
+        Bugzilla::Hook::process('db_schema-abstract_schema', 
+                                { schema => $abstract_schema });
+        unlock_hash(%$abstract_schema);
+    }
 
     $self->{schema} = dclone($abstract_schema);
-    # While ABSTRACT_SCHEMA cannot be modified, 
-    # $self->{abstract_schema} can be. So, we dclone it to prevent
-    # anything from mucking with the constant.
-    $self->{abstract_schema} = dclone($abstract_schema);
+    $self->{abstract_schema} = $abstract_schema;
 
     return $self;
 
diff --git a/Bugzilla/Error.pm b/Bugzilla/Error.pm
index 9508885..18f9aae 100644
--- a/Bugzilla/Error.pm
+++ b/Bugzilla/Error.pm
@@ -19,6 +19,7 @@
 #
 # Contributor(s): Bradley Baetz <bbaetz at acm.org>
 #                 Marc Schumann <wurblzap at gmail.com>
+#                 Frédéric Buclin <LpSolit at gmail.com>
 
 package Bugzilla::Error;
 
@@ -32,6 +33,17 @@ use Bugzilla::WebService::Constants;
 use Bugzilla::Util;
 use Date::Format;
 
+# We cannot use $^S to detect if we are in an eval(), because mod_perl
+# already eval'uates everything, so $^S = 1 in all cases under mod_perl!
+sub _in_eval {
+    my $in_eval = 0;
+    for (my $stack = 1; my $sub = (caller($stack))[3]; $stack++) {
+        last if $sub =~ /^ModPerl/;
+        $in_eval = 1 if $sub =~ /^\(eval\)/;
+    }
+    return $in_eval;
+}
+
 sub _throw_error {
     my ($name, $error, $vars) = @_;
 
@@ -41,7 +53,9 @@ sub _throw_error {
 
     # Make sure any locked tables are unlocked
     # and the transaction is rolled back (if supported)
-    Bugzilla->dbh->bz_unlock_tables(UNLOCK_ABORT);
+    # If we are within an eval(), do not unlock tables as we are
+    # eval'uating some test on purpose.
+    Bugzilla->dbh->bz_unlock_tables(UNLOCK_ABORT) unless _in_eval();
 
     my $datadir = bz_locations()->{'datadir'};
     # If a writable $datadir/errorlog exists, log error details there.
@@ -173,7 +187,7 @@ Bugzilla::Error - Error handling utilities for Bugzilla
 
 Various places throughout the Bugzilla codebase need to report errors to the
 user. The C<Throw*Error> family of functions allow this to be done in a
-generic and localisable manner.
+generic and localizable manner.
 
 These functions automatically unlock the database tables, if there were any
 locked. They will also roll back the transaction, if it is supported by
diff --git a/Bugzilla/Flag.pm b/Bugzilla/Flag.pm
index c3981d9..19ecf7f 100644
--- a/Bugzilla/Flag.pm
+++ b/Bugzilla/Flag.pm
@@ -746,6 +746,7 @@ sub modify {
             my $requester;
             if ($flag->status eq '?') {
                 $requester = $flag->setter;
+                $flag->{'requester'} = $requester;
             }
             # Now update the flag object with its new values.
             $flag->{'setter'} = $setter;
@@ -905,6 +906,7 @@ sub clear {
     my $requester;
     if ($flag->status eq '?') {
         $requester = $flag->setter;
+        $flag->{'requester'} = $requester;
     }
 
     # Now update the flag object to its new values. The last
@@ -1045,9 +1047,13 @@ sub notify {
     # If there is nobody left to notify, return.
     return unless ($flag->{'addressee'} || $flag->type->cc_list);
 
+    my @recipients = split(/[, ]+/, $flag->type->cc_list);
+    # Only notify if the addressee is allowed to receive the email.
+    if ($flag->{'addressee'} && $flag->{'addressee'}->email_enabled) {
+        push @recipients, $flag->{'addressee'}->email;
+    }
     # Process and send notification for each recipient
-    foreach my $to ($flag->{'addressee'} ? $flag->{'addressee'}->email : '',
-                    split(/[, ]+/, $flag->type->cc_list))
+    foreach my $to (@recipients)
     {
         next unless $to;
         my $vars = { 'flag'       => $flag,
diff --git a/Bugzilla/Install/DB.pm b/Bugzilla/Install/DB.pm
index df8faa0..020646b 100644
--- a/Bugzilla/Install/DB.pm
+++ b/Bugzilla/Install/DB.pm
@@ -1906,7 +1906,7 @@ sub _copy_old_charts_into_database {
             qw(FIXED INVALID WONTFIX LATER REMIND DUPLICATE WORKSFORME MOVED);
         my @fields = (@statuses, @resolutions);
 
-        # We have a localisation problem here. Where do we get these values?
+        # We have a localization problem here. Where do we get these values?
         my $all_name = "-All-";
         my $open_name = "All Open";
 
diff --git a/Bugzilla/Install/Filesystem.pm b/Bugzilla/Install/Filesystem.pm
index c13df28..31944bc 100644
--- a/Bugzilla/Install/Filesystem.pm
+++ b/Bugzilla/Install/Filesystem.pm
@@ -34,6 +34,7 @@ use Bugzilla::Util;
 
 use File::Find;
 use File::Path;
+use File::Basename;
 use IO::File;
 use POSIX ();
 
@@ -61,6 +62,7 @@ sub FILESYSTEM {
     my $webdotdir     = bz_locations()->{'webdotdir'};
     my $templatedir   = bz_locations()->{'templatedir'};
     my $libdir        = bz_locations()->{'libpath'};
+    my $skinsdir      = bz_locations()->{'skinsdir'};
 
     my $ws_group      = Bugzilla->localconfig->{'webservergroup'};
 
@@ -199,17 +201,22 @@ sub FILESYSTEM {
     );
 
     # Each standard stylesheet has an associated custom stylesheet that
-    # we create.
-    foreach my $standard (<skins/standard/*.css>) {
-        my $custom = $standard;
-        $custom =~ s|^skins/standard|skins/custom|;
-        $create_files{$custom} = { perms => $ws_readable, contents => <<EOT
+    # we create. Also, we create placeholders for standard stylesheets
+    # for contrib skins which don't provide them themselves.
+    foreach my $skin_dir ("$skinsdir/custom", <$skinsdir/contrib/*>) {
+        next unless -d $skin_dir;
+        next if basename($skin_dir) =~ /^cvs$/i;
+        foreach (<$skinsdir/standard/*.css>) {
+            my $standard_css_file = basename($_);
+            my $custom_css_file = "$skin_dir/$standard_css_file";
+            $create_files{$custom_css_file} = { perms => $ws_readable, contents => <<EOT
 /*
- * Custom rules for $standard.
+ * Custom rules for $standard_css_file.
  * The rules you put here override rules in that stylesheet.
  */
 EOT
-        };
+            }
+        }
     }
 
     # Because checksetup controls the creation of index.html separately
diff --git a/Bugzilla/Mailer.pm b/Bugzilla/Mailer.pm
index d5ecb5a..03f370a 100644
--- a/Bugzilla/Mailer.pm
+++ b/Bugzilla/Mailer.pm
@@ -41,7 +41,10 @@ use Bugzilla::Constants;
 use Bugzilla::Error;
 use Bugzilla::Util;
 
+use Date::Format qw(time2str);
+
 use Encode qw(encode);
+use Email::Address;
 use Email::MIME;
 # Loading this gives us encoding_set.
 use Email::MIME::Modifier;
@@ -64,6 +67,7 @@ sub MessageToMTA {
     # Encode the headers correctly in quoted-printable
     foreach my $header qw(From To Cc Reply-To Sender Errors-To Subject) {
         if (my $value = $email->header($header)) {
+            $value = Encode::decode("UTF-8", $value) if Bugzilla->params->{'utf8'};
             my $encoded = encode('MIME-Q', $value);
             $email->header_set($header, $encoded);
         }
@@ -77,7 +81,14 @@ sub MessageToMTA {
             $Email::Send::Sendmail::SENDMAIL = SENDMAIL_EXE;
         }
         push @args, "-i";
-        push(@args, "-f$from") if $from;
+        # We want to make sure that we pass *only* an email address.
+        if ($from) {
+            my ($email_obj) = Email::Address->parse($from);
+            if ($email_obj) {
+                my $from_email = $email_obj->address;
+                push(@args, "-f$from_email") if $from_email;
+            }
+        }
         push(@args, "-ODeliveryMode=deferred")
             if !Bugzilla->params->{"sendmailnow"};
     }
@@ -85,15 +96,21 @@ sub MessageToMTA {
         # Sendmail will automatically append our hostname to the From
         # address, but other mailers won't.
         my $urlbase = Bugzilla->params->{'urlbase'};
-        $urlbase =~ m|//([^/]+)/?|;
+        $urlbase =~ m|//([^:/]+)[:/]?|;
         $hostname = $1;
         $from .= "\@$hostname" if $from !~ /@/;
         $email->header_set('From', $from);
+        
+        # Sendmail adds a Date: header also, but others may not.
+        if (!defined $email->header('Date')) {
+            $email->header_set('Date', time2str("%a, %e %b %Y %T %z", time()));
+        }
     }
 
     if ($method eq "SMTP") {
         push @args, Host  => Bugzilla->params->{"smtpserver"},
-                    Hello => $hostname;
+                    Hello => $hostname, 
+                    Debug => Bugzilla->params->{'smtp_debug'};
     }
 
     if ($method eq "Test") {
diff --git a/Bugzilla/Search/Quicksearch.pm b/Bugzilla/Search/Quicksearch.pm
index 83746ed..3328e1f 100644
--- a/Bugzilla/Search/Quicksearch.pm
+++ b/Bugzilla/Search/Quicksearch.pm
@@ -163,6 +163,7 @@ sub quicksearch {
             $#words < Bugzilla->params->{'quicksearch_comment_cutoff'};
         my @openStates = BUG_STATE_OPEN;
         my @closedStates;
+        my @unknownFields;
         my (%states, %resolutions);
 
         foreach (@$legal_statuses) {
@@ -273,8 +274,11 @@ sub quicksearch {
                         my @fields = split(/,/, $1);
                         my @values = split(/,/, $2);
                         foreach my $field (@fields) {
-                            # Be tolerant about unknown fields
-                            next unless defined(MAPPINGS->{$field});
+                            # Skip and record any unknown fields
+                            if (!defined(MAPPINGS->{$field})) {
+                                push(@unknownFields, $field);
+                                next;
+                            }
                             $field = MAPPINGS->{$field};
                             foreach (@values) {
                                 addChart($field, 'substring', $_, $negate);
@@ -376,8 +380,13 @@ sub quicksearch {
             $or = 0;
         } # foreach (@words)
 
-        # We've been very tolerant about invalid queries, so all that's left
-        # may be an empty query.
+        # Inform user about any unknown fields
+        if (scalar(@unknownFields)) {
+            ThrowUserError("quicksearch_unknown_field",
+                           { fields => \@unknownFields });
+        }
+
+        # Make sure we have some query terms left
         scalar($cgi->param())>0 || ThrowUserError("buglist_parameters_required");
     }
 
diff --git a/Bugzilla/Search/Saved.pm b/Bugzilla/Search/Saved.pm
index 8352840..9162276 100644
--- a/Bugzilla/Search/Saved.pm
+++ b/Bugzilla/Search/Saved.pm
@@ -197,7 +197,7 @@ __END__
 
 =head1 NAME
 
- Bugzilla::Search::Saved - A saved search
+Bugzilla::Search::Saved - A saved search
 
 =head1 SYNOPSIS
 
diff --git a/Bugzilla/Template.pm b/Bugzilla/Template.pm
index 2764afa..c05500e 100644
--- a/Bugzilla/Template.pm
+++ b/Bugzilla/Template.pm
@@ -62,7 +62,7 @@ sub _load_constants {
     foreach my $constant (@Bugzilla::Constants::EXPORT,
                           @Bugzilla::Constants::EXPORT_OK)
     {
-        if (defined &{$Bugzilla::Constants::{$constant}}) {
+        if (defined Bugzilla::Constants->$constant) {
             # Constants can be lists, and we can't know whether we're
             # getting a scalar or a list in advance, since they come to us
             # as the return value of a function call, so we have to
@@ -749,7 +749,7 @@ sub create {
                              my ($output) = "";
 
                              $var =~ s/[\r\n]/ /g;
-                             $var =~ s/([;\\\"])/\\$1/g;
+                             $var =~ s/([;\\\",])/\\$1/g;
 
                              if ($par) {
                                  $output = sprintf("%s:%s", $par, $var);
diff --git a/Bugzilla/User.pm b/Bugzilla/User.pm
index 3e952e5..ae05053 100644
--- a/Bugzilla/User.pm
+++ b/Bugzilla/User.pm
@@ -1142,16 +1142,26 @@ sub match_field {
                 # The field is a requestee field; in order for its name 
                 # to show up correctly on the confirmation page, we need 
                 # to find out the name of its flag type.
-                if ($field_name =~ /^requestee-(\d+)$/) {
-                    require Bugzilla::Flag;
-                    my $flag = new Bugzilla::Flag($1);
-                    $expanded_fields->{$field_name}->{'flag_type'} = 
-                      $flag->type;
-                }
-                elsif ($field_name =~ /^requestee_type-(\d+)$/) {
-                    require Bugzilla::FlagType;
-                    $expanded_fields->{$field_name}->{'flag_type'} = 
-                      new Bugzilla::FlagType($1);
+                if ($field_name =~ /^requestee(_type)?-(\d+)$/) {
+                    my $flag_type;
+                    if ($1) {
+                        require Bugzilla::FlagType;
+                        $flag_type = new Bugzilla::FlagType($2);
+                    }
+                    else {
+                        require Bugzilla::Flag;
+                        my $flag = new Bugzilla::Flag($2);
+                        $flag_type = $flag->type if $flag;
+                    }
+                    if ($flag_type) {
+                        $expanded_fields->{$field_name}->{'flag_type'} = $flag_type;
+                    }
+                    else {
+                        # No need to look for a valid requestee if the flag(type)
+                        # has been deleted (may occur in race conditions).
+                        delete $expanded_fields->{$field_name};
+                        $cgi->delete($field_name);
+                    }
                 }
             }
         }
@@ -1486,6 +1496,16 @@ sub is_insider {
     return $self->{'is_insider'};
 }
 
+sub is_global_watcher {
+    my $self = shift;
+
+    if (!defined $self->{'is_global_watcher'}) {
+        my @watchers = split(/[,\s]+/, Bugzilla->params->{'globalwatchers'});
+        $self->{'is_global_watcher'} = scalar(grep { $_ eq $self->login } @watchers) ? 1 : 0;
+    }
+    return  $self->{'is_global_watcher'};
+}
+
 sub get_userlist {
     my $self = shift;
 
@@ -2028,6 +2048,11 @@ moving is enabled.
 Returns true if the user can access private comments and attachments,
 i.e. if the 'insidergroup' parameter is set and the user belongs to this group.
 
+=item C<is_global_watcher>
+
+Returns true if the user is a global watcher,
+i.e. if the 'globalwatchers' parameter contains the user.
+
 =back
 
 =head1 CLASS FUNCTIONS
diff --git a/Bugzilla/User/Setting/Skin.pm b/Bugzilla/User/Setting/Skin.pm
index c485850..0b0adfd 100644
--- a/Bugzilla/User/Setting/Skin.pm
+++ b/Bugzilla/User/Setting/Skin.pm
@@ -33,7 +33,7 @@ sub legal_values {
 
     return $self->{'legal_values'} if defined $self->{'legal_values'};
 
-    my $dirbase = bz_locations()->{'skinsdir'};
+    my $dirbase = bz_locations()->{'skinsdir'} . '/contrib';
     # Avoid modification of the list BUILTIN_SKIN_NAMES points to by copying the
     # list over instead of simply writing $legal_values = BUILTIN_SKIN_NAMES.
     my @legal_values = @{(BUILTIN_SKIN_NAMES)};
@@ -60,8 +60,6 @@ __END__
 
 Bugzilla::User::Setting::Skin - Object for a user preference setting for skins
 
-=head1 SYNOPSIS
-
 =head1 DESCRIPTION
 
 Skin.pm extends Bugzilla::User::Setting and implements a class specialized for
diff --git a/Bugzilla/WebService/Bug.pm b/Bugzilla/WebService/Bug.pm
index a632ffa..14ed2e7 100644
--- a/Bugzilla/WebService/Bug.pm
+++ b/Bugzilla/WebService/Bug.pm
@@ -70,6 +70,13 @@ sub get_bugs {
         ValidateBugID($bug_id);
         my $bug = new Bugzilla::Bug($bug_id);
 
+        # Timetracking fields are deleted if the user doesn't belong to
+        # the corresponding group.
+        unless (Bugzilla->user->in_group(Bugzilla->params->{'timetrackinggroup'})) {
+            delete $bug->{'estimated_time'};
+            delete $bug->{'remaining_time'};
+            delete $bug->{'deadline'};
+        }
         # This is done in this fashion in order to produce a stable API.
         # The internals of Bugzilla::Bug are not stable enough to just
         # return them directly.
@@ -130,6 +137,8 @@ sub legal_values {
 
     my @custom_select =
         Bugzilla->get_fields({ type => FIELD_TYPE_SINGLE_SELECT });
+    # We only want field names.
+    @custom_select = map {$_->name} @custom_select;
 
     my $values;
     if (grep($_ eq $field, GLOBAL_SELECT_FIELDS, @custom_select)) {
diff --git a/Bugzilla/WebService/Constants.pm b/Bugzilla/WebService/Constants.pm
index 39d2529..0b73114 100644
--- a/Bugzilla/WebService/Constants.pm
+++ b/Bugzilla/WebService/Constants.pm
@@ -84,6 +84,7 @@ use constant WS_ERROR_CODE => {
     # User errors are 500-600.
     account_exists        => 500,
     illegal_email_address => 501,
+    account_creation_disabled   => 501,
     password_too_short    => 502,
     password_too_long     => 503,
     invalid_username      => 504,
@@ -105,7 +106,7 @@ use constant ERROR_GENERAL       => 999;
 use constant LOGIN_EXEMPT => {
     # Callers may have to know the Bugzilla version before logging in,
     # even on a requirelogin installation.
-    Bugzilla => ['version'],
+    Bugzilla => ['version', 'timezone'],
     User     => ['offer_account_by_email', 'login'],
 };
 
diff --git a/Bugzilla/WebService/User.pm b/Bugzilla/WebService/User.pm
index db02ff7..12ca0a4 100644
--- a/Bugzilla/WebService/User.pm
+++ b/Bugzilla/WebService/User.pm
@@ -74,6 +74,11 @@ sub offer_account_by_email {
     my $email = trim($params->{email})
         || ThrowCodeError('param_required', { param => 'email' });
 
+    my $createexp = Bugzilla->params->{'createemailregexp'};
+    if (!$createexp || $email !~ /$createexp/) {
+        ThrowUserError("account_creation_disabled");
+    }
+
     $email = Bugzilla::User->check_login_name_for_creation($email);
 
     # Create and send a token for this new account.
diff --git a/QUICKSTART b/QUICKSTART
index 7da834b..86d1131 100644
--- a/QUICKSTART
+++ b/QUICKSTART
@@ -9,16 +9,16 @@ and a Sendmail compatible MTA are available. For other configurations, please
 see Section 4 of the Bugzilla Guide in the docs/ directory. 
 
 1. Decide from which URL and directory under your webserver root you
-   will be serving the Bugzilla webpages from.
+   will be serving the Bugzilla webpages.
 
-2. Unpack distribution into the chosen directory (there is no copying or
+2. Unpack the distribution into the chosen directory (there is no copying or
    installation involved). 
 
-3. Run ./checksetup.pl, look for unsolved requirements, install them.
+3. Run ./checksetup.pl, look for unsolved requirements, and install them.
    You can run checksetup as many times as necessary to check if
-   everything required is installed.
+   everything required has been installed.
 
-   This will usually include assorted Perl modules, MySQL or PostgreSQL,
+   These will usually include assorted Perl modules, MySQL or PostgreSQL,
    and a MTA.
 
    After a successful dependency check, checksetup should complain that
@@ -41,7 +41,7 @@ see Section 4 of the Bugzilla Guide in the docs/ directory.
    in the Bugzilla Guide or PostgreSQL documentation.
 
 6. Run checksetup.pl once more; if all goes well, it should set up the
-   Bugzilla database for you. If not, move back to step 5.
+   Bugzilla database for you. If not, return to step 5.
 
    checksetup.pl should ask you, this time, for the administrator's
    email address and password. These will be used for the initial
diff --git a/buglist.cgi b/buglist.cgi
index a22a748..ddf31dd 100755
--- a/buglist.cgi
+++ b/buglist.cgi
@@ -74,9 +74,12 @@ if (defined($searchstring)) {
     # as if this had been a normal query from the beginning.
 }
 
-# Reject empty searches from the simple search form, including
-# words being a single or several consecutive whitespaces only.
-if (defined($cgi->param('content')) && $cgi->param('content') =~ /^\s*$/) {
+# If configured to not allow empty words, reject empty searches from the
+# Find a Specific Bug search form, including words being a single or 
+# several consecutive whitespaces only.
+if (!Bugzilla->params->{'specific_search_allow_empty_words'}
+    && defined($cgi->param('content')) && $cgi->param('content') =~ /^\s*$/)
+{
     ThrowUserError("buglist_parameters_required");
 }
 
@@ -508,17 +511,22 @@ elsif (($cgi->param('cmdtype') eq "doit") && defined $cgi->param('remtype')) {
             }
 
             my %bug_ids;
+            my $is_new_name = 0;
             if ($query_name) {
                 # Make sure this name is not already in use by a normal saved search.
                 if (LookupNamedQuery($query_name, undef, QUERY_LIST, !THROW_ERROR)) {
                     ThrowUserError('query_name_exists', {'name' => $query_name});
                 }
+                $is_new_name = 1;
             }
-            else {
-                # No new query name has been given. We retrieve bug IDs
-                # currently set in the selected saved search.
-                $query_name = $cgi->param('oldqueryname');
-                my $old_query = LookupNamedQuery($query_name, undef, LIST_OF_BUGS);
+            # If no new tag name has been given, use the selected one.
+            $query_name ||= $cgi->param('oldqueryname');
+
+            # Don't throw an error if it's a new tag name: if the tag already
+            # exists, add/remove bugs to it, else create it. But if we are
+            # considering an existing tag, then it has to exist and we throw
+            # an error if it doesn't (hence the usage of !$is_new_name).
+            if (my $old_query = LookupNamedQuery($query_name, undef, LIST_OF_BUGS, !$is_new_name)) {
                 # We get the encoded query. We need to decode it.
                 my $old_cgi = new Bugzilla::CGI($old_query);
                 foreach my $bug_id (split /[\s,]+/, scalar $old_cgi->param('bug_id')) {
@@ -534,12 +542,15 @@ elsif (($cgi->param('cmdtype') eq "doit") && defined $cgi->param('remtype')) {
                 $bug_ids{$bug_id} = $keep_bug;
                 $changes = 1;
             }
-            ThrowUserError('no_bug_ids', {'action' => $action}) unless $changes;
+            ThrowUserError('no_bug_ids',
+                           {'action' => $action,
+                            'tag' => $query_name})
+              unless $changes;
 
             # Only keep bug IDs we want to add/keep. Disregard deleted ones.
             my @bug_ids = grep { $bug_ids{$_} == 1 } keys %bug_ids;
             # If the list is now empty, we could as well delete it completely.
-            ThrowUserError('no_bugs_in_list', {'saved_search' => $query_name})
+            ThrowUserError('no_bugs_in_list', {'tag' => $query_name})
               unless scalar(@bug_ids);
 
             $new_query = "bug_id=" . join(',', sort {$a <=> $b} @bug_ids);
diff --git a/chart.cgi b/chart.cgi
index 1a08014..db48745 100755
--- a/chart.cgi
+++ b/chart.cgi
@@ -73,7 +73,7 @@ my $action = $cgi->param('action');
 my $series_id = $cgi->param('series_id');
 
 # Because some actions are chosen by buttons, we can't encode them as the value
-# of the action param, because that value is localisation-dependent. So, we
+# of the action param, because that value is localization-dependent. So, we
 # encode it in the name, as "action-<action>". Some params even contain the
 # series_id they apply to (e.g. subscribe, unsubscribe).
 my @actions = grep(/^action-/, $cgi->param());
diff --git a/collectstats.pl b/collectstats.pl
index 7bc2b61..80c70fe 100755
--- a/collectstats.pl
+++ b/collectstats.pl
@@ -38,6 +38,7 @@ use lib ".";
 
 use Bugzilla;
 use Bugzilla::Constants;
+use Bugzilla::Error;
 use Bugzilla::Util;
 use Bugzilla::Search;
 use Bugzilla::User;
@@ -574,22 +575,19 @@ sub CollectSeriesData {
         # We set up the user for Search.pm's permission checking - each series
         # runs with the permissions of its creator.
         my $user = new Bugzilla::User($serieses->{$series_id}->{'creator'});
-
         my $cgi = new Bugzilla::CGI($serieses->{$series_id}->{'query'});
-        my $search = new Bugzilla::Search('params' => $cgi,
-                                          'fields' => ["bugs.bug_id"],
-                                          'user'   => $user);
-        my $sql = $search->getSQL();
-        
         my $data;
-        
-        # We can't die if we get dodgy SQL back for whatever reason, so we
-        # eval() this and, if it fails, just ignore it and carry on.
-        # One day we might even log an error.
-        eval { 
+
+        # Do not die if Search->new() detects invalid data, such as an obsolete
+        # login name or a renamed product or component, etc.
+        eval {
+            my $search = new Bugzilla::Search('params' => $cgi,
+                                              'fields' => ["bugs.bug_id"],
+                                              'user'   => $user);
+            my $sql = $search->getSQL();
             $data = $shadow_dbh->selectall_arrayref($sql);
         };
-        
+
         if (!$@) {
             # We need to count the returned rows. Without subselects, we can't
             # do this directly in the SQL for all queries. So we do it by hand.
diff --git a/contrib/README b/contrib/README
index 1c1c3e0..a22a925 100644
--- a/contrib/README
+++ b/contrib/README
@@ -29,13 +29,6 @@ This directory includes:
                          database into a Bugzilla database.  Contributed by
                          Tom Schutter <tom at platte.com>
  
-        bug_email.pl --  A perl script that can receive email containing
-                         bug reports (email-interface). Contributed by
-                         Klaas Freitag <freitag at SuSE.de>
- 	
-       README.Mailif --  Readme describing the mail interface.
-   bugmail_help.html --  User help page for the mail interface.
- 
         yp_nomail.sh --  Script you can run via cron that regularly updates
                          the nomail file for terminated employees 
 
diff --git a/contrib/bz_webservice_demo.pl b/contrib/bz_webservice_demo.pl
index aa92d1d..70fb6c2 100755
--- a/contrib/bz_webservice_demo.pl
+++ b/contrib/bz_webservice_demo.pl
@@ -49,6 +49,7 @@ my $Bugzilla_remember;
 my $bug_id;
 my $product_name;
 my $create_file_name;
+my $legal_field_values;
 
 GetOptions('help|h|?'       => \$help,
            'uri=s'          => \$Bugzilla_uri,
@@ -57,7 +58,8 @@ GetOptions('help|h|?'       => \$help,
            'rememberlogin!' => \$Bugzilla_remember,
            'bug_id:s'       => \$bug_id,
            'product_name:s' => \$product_name,
-           'create:s'       => \$create_file_name
+           'create:s'       => \$create_file_name,
+           'field:s'        => \$legal_field_values
           ) or pod2usage({'-verbose' => 0, '-exitval' => 1});
 
 =head1 OPTIONS
@@ -105,6 +107,12 @@ test calls.
 
 Specify a file that contains settings for the creating of a new bug.
 
+=item --field
+
+Pass a field name to get legal values for this field. It must be either a
+global select field (such as bug_status, resolution, rep_platform, op_sys,
+priority, bug_severity) or a custom select field.
+
 =back
 
 =head1 DESCRIPTION
@@ -216,8 +224,16 @@ if ($bug_id) {
     _die_on_fault($soapresult);
     $result = $soapresult->result;
     my $bug = $result->{bugs}->[0];
-    foreach (keys(%$bug)) {
-        print "$_: $$bug{$_}\n";
+    foreach my $field (keys(%$bug)) {
+        my $value = $bug->{$field};
+        if (ref($value) eq 'HASH') {
+            foreach (keys %$value) {
+                print "$_: " . $value->{$_} . "\n";
+            }
+        }
+        else {
+            print "$field: $value\n";
+        }
     }
 }
 
@@ -269,6 +285,21 @@ if ($create_file_name) {
 
 }
 
+=head2 Getting Legal Field Values
+
+Call C<Bug.legal_values> with the name of the field (including custom
+select fields). The call will return a reference to an array with the
+list of legal values for this field.
+
+=cut
+
+if ($legal_field_values) {
+    $soapresult = $proxy->call('Bug.legal_values', {field => $legal_field_values} );
+    _die_on_fault($soapresult);
+    $result = $soapresult->result;
+
+    print join("\n", @{$result->{values}}) . "\n";
+}
 
 
 =head1 NOTES
diff --git a/contrib/bzdbcopy.pl b/contrib/bzdbcopy.pl
index ebfe3e4..4899098 100755
--- a/contrib/bzdbcopy.pl
+++ b/contrib/bzdbcopy.pl
@@ -53,6 +53,7 @@ print "Connecting to the '" . TARGET_DB_NAME . "' target database on "
       . TARGET_DB_TYPE . "...\n";
 my $target_db = Bugzilla::DB::_connect(TARGET_DB_TYPE, 'localhost', 
     TARGET_DB_NAME, undef, undef, TARGET_DB_USER, TARGET_DB_PASSWORD);
+my $ident_char = $target_db->get_info( 29 ); # SQL_IDENTIFIER_QUOTE_CHAR
 
 # We use the table list from the target DB, because if somebody
 # has customized their source DB, we still want the script to work,
@@ -74,6 +75,11 @@ foreach my $table (@table_list) {
     print "Reading data from the source '$table' table on " 
           . SOURCE_DB_TYPE . "...\n";
     my @table_columns = $target_db->bz_table_columns_real($table);
+    # The column names could be quoted using the quote identifier char
+    # Remove these chars as different databases use different quote chars
+    @table_columns = map { s/^\Q$ident_char\E?(.*?)\Q$ident_char\E?$/$1/; $_ }
+                         @table_columns;
+
     my $select_query = "SELECT " . join(',', @table_columns) . " FROM $table";
     my $data_in = $source_db->selectall_arrayref($select_query);
 
diff --git a/docs/rel_notes.txt b/docs/rel_notes.txt
index 64212a2..614fcb5 100644
--- a/docs/rel_notes.txt
+++ b/docs/rel_notes.txt
@@ -4,7 +4,7 @@ linked from the index page.
 
 bugzilla.org links for release notes
 ------------------------------------
-3.0: http://www.bugzilla.org/releases/3.0/release-notes.html
+3.0.2: http://www.bugzilla.org/releases/3.0.2/release-notes.html
 
 ***************************************
 *** The Bugzilla 2.22 Release Notes ***
@@ -274,11 +274,13 @@ It now:
   * Is much more forgiving about small problems in the XML
 
 
-Adding Individual Bugs to Saved Searches
-----------------------------------------
+Adding Individual Bugs to Saved Searches (Tagging)
+--------------------------------------------------
 Users now have the option of adding an individual bug to any
-particular Saved Search. If you don't like having the entry box in
-your footer for this feature, you can disable it in your Preferences.
+particular Saved Search. Individual users that disagree with the site
+default can add or remove this feature (which appears as an entry box
+visible in the footer) by changing the General Preferences setting
+called "Enable tags for bugs".
 
 
 Attach URLs
@@ -2387,7 +2389,7 @@ See also next section.
   'letsubmitterchoosepriority' was off.
   (bug 63018)
 
-- Most CGIs are now templatised.  This helps to make it
+- Most CGIs are now templatized.  This helps to make it
   easier to remember to HTML filter values and easier to spot
   when they are not, preventing cross site scripting attacks.
   (bug 86168)
@@ -2398,17 +2400,17 @@ See also next section.
 
 *** IMPORTANT CHANGES ***
 
-- 2.16 introduces "templatisation", a new feature that allows
-  administrators to easily customise the HTML output (the "look and feel")
+- 2.16 introduces "templatization", a new feature that allows
+  administrators to easily customize the HTML output (the "look and feel")
   of Bugzilla without altering Perl code.  Bugzilla uses the
-  "Template Toolkit" for this.  Please see the "Template Customisation"
+  "Template Toolkit" for this.  Please see the "Template Customization"
   section of the Bugzilla Guide for more details.
 
-  Administrators who ran the 2.15 development version and customised
+  Administrators who ran the 2.15 development version with custom
   templates should check the templates are still valid, as file names
   and file paths have changed.
 
-  Most output is now templatised.  This process will be complete next
+  Most output is now templatized.  This process will be complete next
   milestone.
 
   For speed, compiled templates are cached on disk.  If you modify the
@@ -2462,7 +2464,7 @@ See also next section.
   lengthy delays in future if this problem reoccurs.
   (bug 106377)
 
-- In parallel with templatisation, a lot of changes have been made to the HTML
+- In parallel with templatization, a lot of changes have been made to the HTML
   output of the Bugzilla CGIs.  This could break code that attempts to parse
   such code.  For example, this breaks mozbot.
   (no bug number)
@@ -2739,8 +2741,8 @@ known to us after the Bugzilla 2.14 release.
 
 *** SECURITY ISSUES RESOLVED ***
 
-- Multiple instances of unauthorised access to confidential
-  bugs has been fixed.
+- Multiple instances of unauthorized access to confidential
+  bugs have been fixed.
   (bug 39524, 39526, 39527, 39531, 39533, 70189, 82781)
 
 - Multiple instances of untrusted parameters not being
@@ -2751,7 +2753,7 @@ known to us after the Bugzilla 2.14 release.
 - After logging in passwords no longer appear in the URL.
   (bug 15980)
 
-- Procedures to prevent unauthorised access to confidential
+- Procedures to prevent unauthorized access to confidential
   files are now simpler.  In particular the shadow directory
   no longer exists and the data/comments file no longer needs
   to be directly accessible, so the entire data directory can
@@ -2762,7 +2764,7 @@ known to us after the Bugzilla 2.14 release.
 
 - If they do not already exist, checksetup.pl will attempt to
   write Apache .htaccess files by default, to prevent
-  unauthorised access to confidential files.  You can turn this
+  unauthorized access to confidential files.  You can turn this
   off in the localconfig file.
   (bug 76154)
 
diff --git a/docs/xml/Bugzilla-Guide.xml b/docs/xml/Bugzilla-Guide.xml
index baa5a93..57ec5da 100644
--- a/docs/xml/Bugzilla-Guide.xml
+++ b/docs/xml/Bugzilla-Guide.xml
@@ -34,12 +34,12 @@
      For a devel release, simple bump bz-ver and bz-date
 -->
 
-<!ENTITY bz-ver "3.0">
+<!ENTITY bz-ver "3.0.2">
 <!ENTITY bz-nextver "3.2">
-<!ENTITY bz-date "2007-05-09">
+<!ENTITY bz-date "2007-09-18">
 <!ENTITY current-year "2007">
 
-<!ENTITY landfillbase "http://landfill.bugzilla.org/bugzilla-tip/">
+<!ENTITY landfillbase "http://landfill.bugzilla.org/bugzilla-3.0-branch/">
 <!ENTITY bz "http://www.bugzilla.org/">
 <!ENTITY bzg-bugs "<ulink url='https://bugzilla.mozilla.org/enter_bug.cgi?product=Bugzilla&amp;component=Documentation'>Bugzilla Documentation</ulink>">
 <!ENTITY mysql "http://www.mysql.com/">
diff --git a/docs/xml/about.xml b/docs/xml/about.xml
index fd67bb9..48e6be7 100644
--- a/docs/xml/about.xml
+++ b/docs/xml/about.xml
@@ -1,6 +1,6 @@
 <!-- <!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook V4.1//EN" [
 <!ENTITY conventions SYSTEM "conventions.xml"> ] > -->
-<!-- $Id: about.xml,v 1.24.2.1 2007/05/09 22:47:17 mkanat%bugzilla.org Exp $ -->
+<!-- $Id: about.xml,v 1.24.2.3 2007/08/02 07:22:33 wurblzap%gmail.com Exp $ -->
 
 <chapter id="about">
 <title>About This Guide</title>
@@ -85,7 +85,7 @@
     </para>
     
     <para>  
-      In addition, there are Bugzilla template localisation projects in
+      In addition, there are Bugzilla template localization projects in
       the following languages. They may have translated documentation 
       available: 
       <ulink url="http://sourceforge.net/projects/bugzilla-ar/">Arabic</ulink>,
@@ -94,7 +94,7 @@
       <ulink url="http://sourceforge.net/projects/bugzilla-br/">Brazilian Portuguese</ulink>,
       <ulink url="http://sourceforge.net/projects/bugzilla-cn/">Chinese</ulink>,
       <ulink url="http://sourceforge.net/projects/bugzilla-fr/">French</ulink>,
-      <ulink url="http://germzilla.wurblzap.net/">German</ulink>,
+      <ulink url="http://germzilla.ganderbay.net/">German</ulink>,
       <ulink url="http://sourceforge.net/projects/bugzilla-it/">Italian</ulink>,
       <ulink url="http://www.bugzilla.jp/about/jp.html">Japanese</ulink>,
       <ulink url="http://sourceforge.net/projects/bugzilla-kr/">Korean</ulink>,
diff --git a/docs/xml/administration.xml b/docs/xml/administration.xml
index fbaeb3c..b78688a 100644
--- a/docs/xml/administration.xml
+++ b/docs/xml/administration.xml
@@ -1850,9 +1850,12 @@ Support: ENTRY, DEFAULT/MANDATORY, CANEDIT
         <literal>upgrade_notification</literal> parameter, see
         <xref linkend="parameters"/>. Administrators will see these
         notifications when they access the <filename>index.cgi</filename>
-        page, i.e. generally when logging in. Bugzilla will check once a
-        week for new releases, unless the parameter is set to
-        <quote>disabled</quote>.
+        page, i.e. generally when logging in. Bugzilla will check once per
+        day for new releases, unless the parameter is set to
+        <quote>disabled</quote>. If you are behind a proxy, you may have to set
+        the <literal>proxy_url</literal> parameter accordingly. If the proxy
+        requires authentication, use the
+        <literal>http://user:pass@proxy_url/</literal> syntax.
       </para>
     </section>
 
diff --git a/docs/xml/customization.xml b/docs/xml/customization.xml
index 5b9e99d..c8ef29c 100644
--- a/docs/xml/customization.xml
+++ b/docs/xml/customization.xml
@@ -1,6 +1,6 @@
 <!-- <!DOCTYPE appendix PUBLIC "-//OASIS//DTD DocBook V4.1//EN"> -->
 <chapter id="customization">
-  <title>Customising Bugzilla</title>
+  <title>Customizing Bugzilla</title>
 
   <section id="cust-skins">
     <title>Custom Skins</title>
@@ -501,8 +501,8 @@
     <para>
       Code hooks appear in Bugzilla source files as a single method call 
       in the format <literal role="code">Bugzilla::Hook->process("<varname>name</varname>");</literal>.
-      for instance, <filename>enter_bug.cgi</filename> may invoke the hook 
-      "<varname>enter_bug-defaultvars</varname>". Thus, a source file at 
+      For instance, <filename>enter_bug.cgi</filename> may invoke the hook 
+      "<varname>enter_bug-entrydefaultvars</varname>". Thus, a source file at 
       <filename>BUGZILLA_ROOT/extensions/EXTENSION_NAME/code/enter_bug-entrydefaultvars.pl</filename>
       will be automatically invoked when the code hook is reached. 
     </para>
diff --git a/docs/xml/dbschema.mysql b/docs/xml/dbschema.mysql
deleted file mode 100644
index 8b13789..0000000
--- a/docs/xml/dbschema.mysql
+++ /dev/null
@@ -1 +0,0 @@
-
diff --git a/docs/xml/faq.xml b/docs/xml/faq.xml
index 80f4113..22f0144 100644
--- a/docs/xml/faq.xml
+++ b/docs/xml/faq.xml
@@ -172,50 +172,34 @@
       </qandaentry>
 
       <qandaentry>
-        <question id="faq-general-mysql">
+        <question id="faq-general-db">
           <para>
-            Why MySQL?  I'm interested in seeing Bugzilla run on
-            PostgreSQL/Sybase/Oracle/Msql/MSSQL.
+            What databases does Bugzilla run on?
           </para>
         </question>
         <answer>
           <para>
-            MySQL was originally chosen because it is free, easy to install,
-            and was available for the hardware Netscape intended to run it on.
+            MySQL is the default database for Bugzilla. It was originally chosen 
+            because it is free, easy to install, and was available for the hardware 
+            Netscape intended to run it on.
           </para>
           <para>
-            Bugzilla 2.20 contains experimental support for PostgreSQL.
-            Bugzilla 2.22 contains complete, stable support for PostgreSQL.
-            As of this release, using PostgreSQL with Bugzilla should
-            be as stable as using MySQL. If you experience any problems
+            As of Bugzilla 2.22, complete support for PostgreSQL 
+            is included. With this release using PostgreSQL with Bugzilla 
+            should be as stable as using MySQL. If you experience any problems
             with PostgreSQL compatibility, they will be taken as
             seriously as if you were running MySQL.
           </para>
           <para>
-            Red Hat once ran a version of Bugzilla that worked on Oracle, 
-            but that was long, long ago; that version (Bugzilla 2.8) is
-            now obsolete, insecure, and totally unsupported.
-          </para>
-          <para>
-            In August of 2005, Wim Coekaerts (Director of Linux
-            Engineering at Oracle Corporation) wrote to Dave Miller
-            confirming that Oracle intends to implement and support
-            Bugzilla. Since then, no further information has been
-            forthcoming. Track progress at
+            There are plans to include an Oracle driver for Bugzilla 3.1.2. 
+            Track progress at
             <ulink url="https://bugzilla.mozilla.org/show_bug.cgi?id=189947">
             Bug 189947</ulink>.
           </para>
           <para>
-            Sybase support is no longer being worked on. Even if it
-            eventually happens, it's VERY unlikely to work without
-            the end-user-company having to stick a few developers on
-            making several manual changes. Sybase is just NOT very
-            standards-compliant (despite all the hype), and it turned
-            out that way too much had to be changed to make it work --
-            like moving half of the application logic into stored
-            procedures to get any kind of decent performance out of it.
-            <ulink url="https://bugzilla.mozilla.org/show_bug.cgi?id=173130">
-            Bug 173130</ulink> is the relevant bug.
+            Sybase support was worked on for a time. However, several 
+            complicating factors have prevented Sybase support from 
+            being realized. There are currently no plans to revive it.
           </para>
           <para>
             <ulink url="https://bugzilla.mozilla.org/show_bug.cgi?id=237862">
@@ -227,28 +211,6 @@
       </qandaentry>
 
       <qandaentry>
-        <question id="faq-general-bonsaitools">
-          <para>
-            What is <filename>/usr/bonsaitools/bin/perl</filename>?
-          </para>
-        </question>
-        <answer>
-          <para>
-            Bugzilla used to have the path to perl on the shebang line set
-            to <filename>/usr/bonsaitools/bin/perl</filename> because when
-            Terry first started writing the code for mozilla.org he needed a
-            version of Perl and other tools that were completely under his
-            control. This location was abandoned for the 2.18 release in favor
-            of the more sensible <filename>/usr/bin/perl</filename>. If you
-            installed an older version of Bugzilla and created the symlink we
-            suggested, you can remove it now (provided that you don't have
-            anything else, such as Bonsai, using it and you don't intend to
-            reinstall an older version of Bugzilla).
-          </para>
-        </answer>
-      </qandaentry>
-
-      <qandaentry>
         <question id="faq-general-perlpath">
           <para>
             My perl is located at <filename>/usr/local/bin/perl</filename>
@@ -293,7 +255,7 @@ C:\mysql\bin\replace "#!/usr/bin/perl" "#!C:\perl\bin\perl" -- *.cgi *.pl
             url="http://www.bugzilla.org/docs/developer.html#testsuite">Developers'
             Guide</ulink>.) Having done this, run the test itself:
             <programlisting>
-perl runtests.pl 2 --verbose
+            perl runtests.pl 2 --verbose
             </programlisting>
             to ensure that you've modified all the relevant files.
           </para>
@@ -327,23 +289,6 @@ perl runtests.pl 2 --verbose
       </qandaentry>
 
       <qandaentry>
-        <question id="faq-mod-perl">
-          <para>
-            Does bugzilla run under <filename>mod_perl</filename>?
-          </para>
-        </question>
-        <answer>
-          <para>
-            At present, no. Work is slowly taking place to remove global
-            variables, use $cgi, and use DBI. These are all necessary for
-            mod_perl (as well as being good for other reasons). Visit 
-            <ulink url="https://bugzilla.mozilla.org/show_bug.cgi?id=87406">
-            bug 87406</ulink> to view the discussion and progress.
-          </para>
-        </answer>
-      </qandaentry>
-
-      <qandaentry>
         <question id="faq-general-selinux">
           <para>
             How can Bugzilla be made to work under SELinux?
@@ -351,9 +296,16 @@ perl runtests.pl 2 --verbose
         </question>
         <answer>
           <para>
-            Unfortunately there are no step-by-step instructions,
-            but the following URL contains hints on how to do it:
-            <ulink url="http://fedora.redhat.com/docs/selinux-apache-fc3/sn-debugging-and-customizing.html" />
+            As a web application, Bugzilla simply requires its root
+            directory to have the httpd context applied for it to work
+            properly under SELinux. This should happen automatically
+            on distributions that use SELinux and that package Bugzilla
+            (if it is installed with the native package management tools).
+            Information on how to view and change SELinux file contexts
+            can be found at the 
+            <ulink url="http://docs.fedoraproject.org/selinux-faq-fc5/">
+            SELinux FAQ</ulink>.
+
           </para>
         </answer>
       </qandaentry>
@@ -392,9 +344,8 @@ perl runtests.pl 2 --verbose
             compensate for the change.
           </para>
           <para>
-            There is no GUI for adding fields to Bugzilla at this
-            time. You can follow development of this feature in 
-            <ulink url="https://bugzilla.mozilla.org/show_bug.cgi?id=91037">bug 91037</ulink>
+            As of Bugzilla 3.0 custom fields can be created via the
+            "Custom Fields" admin page.
           </para>
         </answer>
       </qandaentry>
@@ -442,8 +393,7 @@ perl runtests.pl 2 --verbose
       <qandaentry>
         <question id="faq-phb-emailapp">
           <para>
-            Do users have to have any particular
-            type of email application?
+            Do users have to have any particular type of email application?
           </para>
         </question>
         <answer>
@@ -548,10 +498,11 @@ perl runtests.pl 2 --verbose
         </question>
         <answer>
           <para>
-            MySQL, the database back-end for Bugzilla, allows hot-backup
-            of data. You can find strategies for dealing with backup
-            considerations at <ulink
-            url="http://www.mysql.com/doc/B/a/Backup.html"/>.
+            You should use the backup options supplied by your database platform.  
+            Vendor documentation for backing up a MySQL database can be found at 
+            <ulink url="http://www.mysql.com/doc/B/a/Backup.html"/>. 
+            PostgreSQL backup documentation can be found at
+            <ulink url="http://www.postgresql.org/docs/8.0/static/backup.html"/>.
           </para>
         </answer>
       </qandaentry>
@@ -617,9 +568,9 @@ perl runtests.pl 2 --verbose
           <para>
             No. Bugzilla, Perl, the Template Toolkit, and all other support
             software needed to make Bugzilla work can be downloaded for free.
-            MySQL -- the database used by Bugzilla -- is also open-source, but
-            they ask that if you find their product valuable, you purchase a
-            support contract from them that suits your needs.
+            MySQL and PostgreSQL -- the databases supported by Bugzilla -- 
+            are also open-source. MySQL asks that if you find their product 
+            valuable, you purchase a support contract from them that suits your needs.
           </para>
         </answer>
       </qandaentry>
@@ -672,13 +623,12 @@ perl runtests.pl 2 --verbose
         </question>
         <answer>
           <para>
-            Yes, but commits to the database must wait until the tables
-            are unlocked. Bugzilla databases are typically very small,
-            and backups routinely take less than a minute. If your database
-            is larger, you may want to look into alternate backup
-            techniques, such as database replication, or backing up from
-            a read-only mirror. (Read up on these in the MySQL docs
-            on the MySQL site.)
+            Refer to your database platform documentation for details on how to do hot
+            backups.  
+            Vendor documentation for backing up a MySQL database can be found at 
+            <ulink url="http://www.mysql.com/doc/B/a/Backup.html"/>. 
+            PostgreSQL backup documentation can be found at
+            <ulink url="http://www.postgresql.org/docs/8.0/static/backup.html"/>.
           </para>
         </answer>
       </qandaentry>
@@ -792,35 +742,14 @@ perl runtests.pl 2 --verbose
 
         <answer>
           <para>
-            Use mysqldump to make a backup of the bugs database. For a
-            typical Bugzilla setup, such a command might look like this:
-            <programlisting>
-/usr/bin/mysqldump -u(username) -p(password) --database bugs > bugzilla-backup.txt
-            </programlisting>
-            See the <ulink url="http://dev.mysql.com/doc/mysql/en/mysqldump.html">
-            mysqldump documentation</ulink> for more information on using 
-            the tool, including how to restore your copy onto the destination
-            machine.
+            Reference your database vendor's documentation for information on 
+            backing up and restoring your Bugzilla database on to a different server.
+            Vendor documentation for backing up a MySQL database can be found at 
+            <ulink url="http://dev.mysql.com/doc/mysql/en/mysqldump.html"/>.
+            PostgreSQL backup documentation can be found at
+            <ulink url="http://www.postgresql.org/docs/8.0/static/backup.html"/>.
           </para>
 
-          <warning>
-            <para>
-              Depending on the size of your database, and the power of your
-              machine, the mysqldump command could be running long enough
-              that the password would be visible to someone using the
-              <command>ps</command> command. If you are on a multi-user
-              machine, and this is a concern to you, create an entry in
-              the file <filename>~/.my.cnf</filename> that looks like this:
-              <programlisting>
-[mysqldump]
-user=bugs
-password=mypassword
-              </programlisting>
-              and then leave the 'user' and 'password' params out of the
-              command line.
-            </para>
-          </warning>
-
           <para>
             On your new machine, follow the instructions found in <xref 
             linkend="installing-bugzilla"/> as far as setting up the physical
@@ -838,7 +767,7 @@ password=mypassword
 
           <note>
             <para>
-              If the location or port number of your SQL server changed
+              If the hostname or port number of your database server changed
               as part of the move, you'll need to update the appropriate
               variables in localconfig before taking the next step.
             </para>
@@ -853,11 +782,27 @@ password=mypassword
         </answer>
       </qandaentry>
 
+      <qandaentry>
+        <question id="faq-admin-makeadmin">
+          <para>
+            How do I make a new Bugzilla administrator?
+            The previous administrator is gone...
+          </para>
+        </question>
+        <answer>
+          <para>
+            Run <command>checksetup.pl</command> with
+            <option>--make-admin</option> option.
+            Its usage is <option>--make-admin=user at example.org</option>.
+            The user account must be exist in the Bugzilla database.
+          </para>
+        </answer>
+      </qandaentry>
+
     </qandadiv>
 
     <qandadiv id="faq-security">
       <title>Bugzilla Security</title>
-
       <qandaentry>
         <question id="faq-security-mysql">
           <para>
@@ -866,24 +811,17 @@ password=mypassword
             section of this guide...)
           </para>
         </question>
-        <!-- Should we really even answer this question? -->
+
         <answer>
           <para>
-            Run MySQL like this: <command>mysqld --skip-grant-tables</command>.
-            Please remember that <emphasis>this makes MySQL as secure as
-            taping a $100 to the floor of a football stadium bathroom for
-            safekeeping.</emphasis>
-          </para>
-          <warning>
-            <para>
-              This can't be stressed enough. Doing this is a bad idea.
-              Please consult <xref linkend="security-mysql"/> of this guide
-              and the MySQL documentation for better solutions.
+            You can run MySQL like this: <command>mysqld --skip-grant-tables</command>.
+            However, doing so disables all MySQL security. This is a bad idea.
+            Please consult <xref linkend="security-mysql"/> of this guide
+            and the MySQL documentation for better solutions.
             </para>
-          </warning>
         </answer>
       </qandaentry>
-
+      
       <qandaentry>
         <question id="faq-security-knownproblems">
           <para>
@@ -1008,15 +946,18 @@ password=mypassword
       </qandaentry>
 
       <qandaentry>
-        <question id="faq-email-mailif">
+        <question id="faq-email-in">
           <para>
-            How do I set up the email interface to submit/change bugs via email?
+            How do I set up the email interface to submit or change bugs via email?
           </para>
         </question>
         <answer>
           <para>
-            You can find an updated README.mailif file in the contrib/ directory
-            of your Bugzilla distribution that walks you through the setup.
+            Bugzilla 3.0 and later offers the ability submit or change
+            bugs via email, using the <filename>email_in.pl</filename>
+            script within the root directory of the Bugzilla installation.
+            More information on the script can be found in
+            <ulink url="api/email_in.html">docs/html/api/email_in.html</ulink>.
           </para>
         </answer>
       </qandaentry>
@@ -1121,19 +1062,16 @@ password=mypassword
             There is no facility in Bugzilla itself to do this. It's also
             generally not a smart thing to do if you don't know exactly what
             you're doing. If you understand SQL, though, you can use the
-            <command>mysql</command> command line utility to manually insert,
-            delete and modify table information. There are also more intuitive
-            GUI clients available. Personal favorites of the Bugzilla team
-            are <ulink url="http://www.phpmyadmin.net/">phpMyAdmin</ulink>
-            and <ulink url="http://www.mysql.com/products/mysqlcc/">MySQL
-            Control Center</ulink>.
+            <command>mysql</command> or <command>psql</command> command line 
+            utilities to manually insert, delete and modify table information. 
+            There are also more intuitive GUI clients available for both MySQL 
+            and PostgreSQL. For MySQL, we recommend
+            <ulink url="http://www.phpmyadmin.net/">phpMyAdmin</ulink>.
           </para>
 
           <para>
             Remember, backups are your friend. Everyone makes mistakes, and
             it's nice to have a safety net in case you mess something up.
-            Consider using <command>mysqldump</command> to make a duplicate
-            of your database before altering it manually.
           </para>
 
         </answer>
@@ -1160,7 +1098,8 @@ password=mypassword
             <para>
               Running MySQL with this command line option is very insecure and
               should only be done when not connected to the external network
-              as a troubleshooting step.
+              as a troubleshooting step.  Please do not run your production
+              database in this mode.
             </para>
           </warning>
           <para>
@@ -1252,7 +1191,7 @@ password=mypassword
     </qandadiv>
 
     <qandadiv id="faq-nt">
-      <title>Bugzilla and Win32</title>
+      <title>Can Bugzilla run on a Windows server?</title>
 
       <qandaentry>
         <question id="faq-nt-easiest">
@@ -1262,11 +1201,7 @@ password=mypassword
         </question>
         <answer>
           <para>
-            Remove Windows. Install Linux. Install Bugzilla.
-            The boss will never know the difference. B^)
-          </para>
-          <para>
-            Seriously though, making Bugzilla work easily with Windows
+            Making Bugzilla work easily with Windows
             was one of the major goals of the 2.18 milestone. If the
             necessary components are in place (perl, a webserver, an MTA, etc.)
             then installation of Bugzilla on a Windows box should be no more
@@ -1346,7 +1281,7 @@ password=mypassword
             <orderedlist>
               <listitem>
                 <para>
-                  Hitting http://www.activestate.com/ActivePerl
+                  Hitting <ulink url="http://www.activestate.com/ActivePerl"/>
                 </para>
               </listitem>
               <listitem>
@@ -1390,8 +1325,10 @@ password=mypassword
         </question>
         <answer>
           <para>
-            New in 2.16 - go to the Account section of the Preferences. You
-            will be emailed at both addresses for confirmation.
+            You can change your email address from the Name and Password
+            section in Preferences. You will be emailed at both the old 
+            and new addresses for confirmation. 'Administrative Policies' 
+            must have the 'allowemailchange' parameter set to <quote>On</quote>.
           </para>
         </answer>
       </qandaentry>
diff --git a/docs/xml/filetemp.patch b/docs/xml/filetemp.patch
deleted file mode 100644
index 9fb70ad..0000000
--- a/docs/xml/filetemp.patch
+++ /dev/null
@@ -1,18 +0,0 @@
---- File/Temp.pm.orig   Thu Feb  6 16:26:00 2003
-+++ File/Temp.pm        Thu Feb  6 16:26:23 2003
-@@ -205,6 +205,7 @@
-     # eg CGI::Carp
-     local $SIG{__DIE__} = sub {};
-     local $SIG{__WARN__} = sub {};
-+    local *CORE::GLOBAL::die = sub {};
-     $bit = &$func();
-     1;
-   };
-@@ -226,6 +227,7 @@
-     # eg CGI::Carp
-     local $SIG{__DIE__} = sub {};
-     local $SIG{__WARN__} = sub {};
-+    local *CORE::GLOBAL::die = sub {};
-     $bit = &$func();
-     1;
-   };
diff --git a/docs/xml/glossary.xml b/docs/xml/glossary.xml
index 376b48c..5b6d1a6 100644
--- a/docs/xml/glossary.xml
+++ b/docs/xml/glossary.xml
@@ -215,9 +215,7 @@
       <glossdef>
         <para>A DOS, or Denial of Service attack, is when a user attempts to
         deny access to a web server by repeatedly accessing a page or sending
-        malformed requests to a webserver. This can be effectively prevented
-        by using <filename>mod_throttle</filename> as described in
-        <xref linkend="security-webserver-mod-throttle"/>. A D-DOS, or
+        malformed requests to a webserver. A D-DOS, or
         Distributed Denial of Service attack, is when these requests come
         from multiple sources at the same time. Unfortunately, these are much
         more difficult to defend against.
diff --git a/docs/xml/introduction.xml b/docs/xml/introduction.xml
index 5cf4a55..3968702 100644
--- a/docs/xml/introduction.xml
+++ b/docs/xml/introduction.xml
@@ -68,7 +68,7 @@
       </listitem>
 
       <listitem>
-        <para>Completely customisable and/or localisable web user
+        <para>Completely customizable and/or localizable web user
         interface</para>
       </listitem>
 
diff --git a/docs/xml/patches.xml b/docs/xml/patches.xml
index b1d9281..12efb0c 100644
--- a/docs/xml/patches.xml
+++ b/docs/xml/patches.xml
@@ -21,7 +21,7 @@
 
     <warning>
       <para>
-        These files pre-date the templatisation work done as part of the
+        These files pre-date the templatization work done as part of the
         2.16 release, and have not been updated.
       </para>
     </warning>
diff --git a/docs/xml/security.xml b/docs/xml/security.xml
index 751f2ed..d53afb8 100644
--- a/docs/xml/security.xml
+++ b/docs/xml/security.xml
@@ -1,5 +1,5 @@
 <!-- <!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN"> -->
-<!-- $Id: security.xml,v 1.16 2006/11/20 19:48:43 lpsolit%gmail.com Exp $ -->
+<!-- $Id: security.xml,v 1.16.2.1 2007/09/03 10:13:24 lpsolit%gmail.com Exp $ -->
 
 <chapter id="security">
 <title>Bugzilla Security</title>
@@ -310,33 +310,6 @@ skip-networking
     
     </section>
 
-
-    <section id="security-webserver-mod-throttle">
-      <title>Using <filename>mod_throttle</filename> to Prevent a DOS</title>
-
-      <note>
-        <para>This section only applies to people who have chosen the Apache
-        webserver. It may be possible to do similar things with other
-        webservers. Consult the documentation that came with your webserver
-        to find out.
-        </para>
-      </note>
-
-      <para>It is possible for a user, by mistake or on purpose, to access
-      the database many times in a row which can result in very slow access
-      speeds for other users (effectively, a
-      <glossterm linkend="gloss-dos">DOS</glossterm> attack). If your
-      Bugzilla installation is experiencing this problem, you may install
-      the Apache module <filename>mod_throttle</filename> which can limit
-      connections by IP address. You may download this module at 
-      <ulink url="http://www.snert.com/Software/mod_throttle/"/>.
-      Follow the instructions to install into your Apache install. 
-      The command you need is 
-      <command>ThrottleClientIP</command>. See the 
-      <ulink url="http://www.snert.com/Software/mod_throttle/">documentation</ulink>
-      for more information.</para>
-    </section>
-
       
   </section>
   
diff --git a/docs/xml/using.xml b/docs/xml/using.xml
index dbfed05..3c200a3 100644
--- a/docs/xml/using.xml
+++ b/docs/xml/using.xml
@@ -243,7 +243,7 @@
       <listitem>
         <para>
         <emphasis>Priority:</emphasis>
-        The bug assignee uses this field to prioritise his or her bugs.
+        The bug assignee uses this field to prioritize his or her bugs.
         It's a good idea not to change this on other people's bugs.</para>
       </listitem>
 
@@ -402,8 +402,8 @@
       have them show up in your personal Bugzilla footer along with your own
       Saved Searches.
       If somebody is sharing a Search with a group she or he is allowed to
-      <link linkend="groups">assign users to</link>, it will show up in the
-      group's direct members' footers by default.
+      <link linkend="groups">assign users to</link>, the sharer may opt to have
+      the Search show up in the group's direct members' footers by default.
     </para>
 
     <section id="boolean">
@@ -1064,7 +1064,7 @@
   <section id="userpreferences">
     <title>User Preferences</title>
 
-    <para>Once you have logged in, you can customise various aspects of
+    <para>Once you have logged in, you can customize various aspects of
     Bugzilla via the "Edit prefs" link in the page footer.
     The preferences are split into three tabs:</para>
 
diff --git a/duplicates.cgi b/duplicates.cgi
index 94b35df..e393d7c 100755
--- a/duplicates.cgi
+++ b/duplicates.cgi
@@ -266,7 +266,13 @@ my $format = $template->get_format("reports/duplicates",
                                    scalar($cgi->param('format')),
                                    scalar($cgi->param('ctype')));
 
-print $cgi->header($format->{'ctype'});
+# We set the charset in Bugzilla::CGI, but CGI.pm ignores it unless the
+# Content-Type is a text type. In some cases, such as when we are
+# generating RDF, it isn't, so we specify the charset again here.
+print $cgi->header(
+    -type => $format->{'ctype'},
+    (Bugzilla->params->{'utf8'} ? ('charset', 'utf8') : () )
+);
 
 # Generate and return the UI (HTML page) from the appropriate template.
 $template->process($format->{'template'}, $vars)
diff --git a/editcomponents.cgi b/editcomponents.cgi
index f28a87b..09acc0c 100755
--- a/editcomponents.cgi
+++ b/editcomponents.cgi
@@ -218,7 +218,7 @@ if ($action eq 'new') {
     my $prodcomp = "&product="   . url_quote($product->name) .
                    "&component=" . url_quote($comp_name);
 
-    # For localisation reasons, we get the title of the queries from the
+    # For localization reasons, we get the title of the queries from the
     # submitted form.
     my $open_name = $cgi->param('open_name');
     my $nonopen_name = $cgi->param('nonopen_name');
diff --git a/editparams.cgi b/editparams.cgi
index ca74df6..b4100a0 100755
--- a/editparams.cgi
+++ b/editparams.cgi
@@ -145,7 +145,9 @@ if ($action eq 'save' && $current_module) {
         # then we delete it (the user pref is reset to the default one).
         my @languages = split(/[\s,]+/, Bugzilla->params->{'languages'});
         map {trick_taint($_)} @languages;
-        add_setting('lang', \@languages, Bugzilla->params->{'defaultlanguage'}, undef, 1);
+        my $lang = Bugzilla->params->{'defaultlanguage'};
+        trick_taint($lang);
+        add_setting('lang', \@languages, $lang, undef, 1);
     }
 
     $vars->{'message'} = 'parameters_updated';
diff --git a/editproducts.cgi b/editproducts.cgi
index b458f60..9be85de 100755
--- a/editproducts.cgi
+++ b/editproducts.cgi
@@ -317,7 +317,7 @@ if ($action eq 'new') {
             push(@series, [$resolution, "resolution=" .url_quote($resolution)]);
         }
 
-        # For localisation reasons, we get the name of the "global" subcategory
+        # For localization reasons, we get the name of the "global" subcategory
         # and the title of the "open" query from the submitted form.
         my @openedstatuses = BUG_STATE_OPEN;
         my $query = 
@@ -408,9 +408,16 @@ if ($action eq 'delete') {
 
     $dbh->bz_lock_tables('products WRITE', 'components WRITE',
                          'versions WRITE', 'milestones WRITE',
-                         'group_control_map WRITE',
+                         'group_control_map WRITE', 'component_cc WRITE',
                          'flaginclusions WRITE', 'flagexclusions WRITE');
 
+    my $comp_ids = $dbh->selectcol_arrayref('SELECT id FROM components
+                                             WHERE product_id = ?',
+                                             undef, $product->id);
+
+    $dbh->do('DELETE FROM component_cc WHERE component_id IN
+              (' . join(',', @$comp_ids) . ')') if scalar(@$comp_ids);
+
     $dbh->do("DELETE FROM components WHERE product_id = ?",
              undef, $product->id);
 
diff --git a/email_in.pl b/email_in.pl
index 40474af..be9abad 100755
--- a/email_in.pl
+++ b/email_in.pl
@@ -340,6 +340,10 @@ sub die_handler {
     # the user-error or code-error template ended. So we don't really die.
     return if $msg->isa('Template::Exception') && $msg->type eq 'return';
 
+    # If this is inside an eval, then we should just act like...we're
+    # in an eval (instead of printing the error and exiting).
+    die(@_) if $^S;
+
     # We can't depend on the MTA to send an error message, so we have
     # to generate one properly.
     if ($input_email) {
@@ -497,9 +501,9 @@ send an email back to you. If your request succeeds, Bugzilla will
 not send you anything.
 
 If any part of your request fails, all of it will fail. No partial
-changes will happen. The only exception is attachments--one attachment
-may succeed, and be inserted into the database, and a later attachment
-may fail.
+changes will happen.
+
+There is no attachment support yet.
 
 =head1 CAUTION
 
@@ -524,7 +528,4 @@ will reject your email, saying that it doesn't contain any text. This
 is a bug in L<Email::MIME::Attachment::Stripper> that we can't work
 around.
 
-If you send multiple attachments in one email, they will all be attached,
-but Bugzilla may not send an email notice out for all of them.
-
 You cannot modify Flags through the email interface.
diff --git a/process_bug.cgi b/process_bug.cgi
index ffca2fa..0164657 100755
--- a/process_bug.cgi
+++ b/process_bug.cgi
@@ -92,16 +92,25 @@ sub BugInGroupId {
 # If so, then groups may have to be changed when bugs move from
 # one bug to another.
 sub AnyDefaultGroups {
+    my $product_id = shift;
     my $dbh = Bugzilla->dbh;
+    my $grouplist = Bugzilla->user->groups_as_string;
+
+    my $and_product = $product_id ? ' AND product_id = ? ' : '';
+    my @args = (CONTROLMAPDEFAULT);
+    unshift(@args, $product_id) if $product_id;
+
     my $any_default =
-        $dbh->selectrow_array('SELECT 1
+        $dbh->selectrow_array("SELECT 1
                                  FROM group_control_map
                            INNER JOIN groups
                                    ON groups.id = group_control_map.group_id
                                 WHERE isactive != 0
-                                  AND (membercontrol = ? OR othercontrol = ?) ' .
+                                 $and_product
+                                  AND membercontrol = ?
+                                  AND group_id IN ($grouplist) " .
                                  $dbh->sql_limit(1),
-                                 undef, (CONTROLMAPDEFAULT, CONTROLMAPDEFAULT));
+                                undef, @args);
     return $any_default;
 }
 
@@ -197,7 +206,7 @@ foreach my $field ("dependson", "blocked") {
             push @new, $id;
         }
         $cgi->param($field, join(",", @new));
-        my ($added, $removed) = Bugzilla::Util::diff_arrays(\@old, \@new);
+        my ($removed, $added) = diff_arrays(\@old, \@new);
         foreach my $id (@$added , @$removed) {
             # ValidateBugID is called without $field here so that it will
             # throw an error if any of the changed bugs are not visible.
@@ -385,8 +394,10 @@ if (((defined $cgi->param('id') && $cgi->param('product') ne $oldproduct)
     # shown. Also show the verification form if the product-specific fields
     # somehow still need to be verified, or if we need to verify whether or not
     # to add the bugs to their new product's group.
+    my $has_default_groups = AnyDefaultGroups($prod_obj->id);
+
     if (!$vok || !$cok || !$mok || !defined $cgi->param('confirm_product_change')
-        || (AnyDefaultGroups() && !defined $cgi->param('addtonewgroup'))) {
+        || ($has_default_groups && !defined $cgi->param('addtonewgroup'))) {
 
         if (Bugzilla->usage_mode == USAGE_MODE_EMAIL) {
             if (!$vok) {
@@ -449,10 +460,27 @@ if (((defined $cgi->param('id') && $cgi->param('product') ne $oldproduct)
         else {
             $vars->{'verify_fields'} = 0;
         }
-        
-        $vars->{'verify_bug_group'} = (AnyDefaultGroups() 
+
+        $vars->{'verify_bug_group'} = ($has_default_groups
                                        && !defined $cgi->param('addtonewgroup'));
-        
+
+        # Get the ID of groups which are no longer valid in the new product.
+        # If the bug was restricted to some group which still exists in the new
+        # product, leave it alone, independently of your privileges.
+        my $gids =
+          $dbh->selectcol_arrayref("SELECT bgm.group_id
+                                      FROM bug_group_map AS bgm
+                                     WHERE bgm.bug_id IN (" . join(', ', @idlist) . ")
+                                       AND bgm.group_id NOT IN
+                                           (SELECT gcm.group_id
+                                              FROM group_control_map AS gcm
+                                             WHERE gcm.product_id = ?
+                                               AND gcm.membercontrol IN (?, ?, ?))",
+                                     undef, ($prod_obj->id, CONTROLMAPSHOWN,
+                                             CONTROLMAPDEFAULT, CONTROLMAPMANDATORY));
+
+        $vars->{'old_groups'} = Bugzilla::Group->new_from_list($gids);
+
         $template->process("bug/process/verify-new-product.html.tmpl", $vars)
           || ThrowTemplateError($template->error());
         exit;
@@ -805,7 +833,16 @@ foreach my $group (@$groups) {
     # for single bug changes because non-checked checkboxes aren't present.
     # All the checkboxes should be shown in that case, though, so it isn't
     # an issue there
-    if (defined $cgi->param('id') || defined $cgi->param("bit-$b")) {
+    #
+    # For bug updates that come from email_in.pl there will not be any
+    # bit-X fields defined unless the user is explicitly changing the
+    # state of the specified group (by including lines such as @bit-XX = 1
+    # or @bit-XX = 0 in the body of the email).  Therefore if we are in
+    # USAGE_MODE_EMAIL we will only change the group setting if bit-XX
+    # is defined.
+     if ((defined $cgi->param('id') && Bugzilla->usage_mode != USAGE_MODE_EMAIL)
+         || defined $cgi->param("bit-$b"))
+     {
         if (!$cgi->param("bit-$b")) {
             push(@groupDel, $b);
         } elsif ($cgi->param("bit-$b") == 1 && $isactive) {
@@ -923,17 +960,17 @@ if (defined $cgi->param('id')) {
         q{SELECT group_id FROM bug_group_map WHERE bug_id = ?},
         undef, $cgi->param('id'));
     if ( $havegroup ) {
-        DoComma();
-        $cgi->param('reporter_accessible',
-                    $cgi->param('reporter_accessible') ? '1' : '0');
-        $::query .= "reporter_accessible = ?";
-        push(@values, $cgi->param('reporter_accessible'));
-
-        DoComma();
-        $cgi->param('cclist_accessible',
-                    $cgi->param('cclist_accessible') ? '1' : '0');
-        $::query .= "cclist_accessible = ?";
-        push(@values, $cgi->param('cclist_accessible'));
+        foreach my $field ('reporter_accessible', 'cclist_accessible') {
+            if ($bug->check_can_change_field($field, 0, 1, \$PrivilegesRequired)) {
+                DoComma();
+                $cgi->param($field, $cgi->param($field) ? '1' : '0');
+                $::query .= " $field = ?";
+                push(@values, $cgi->param($field));
+            }
+            else {
+                $cgi->delete($field);
+            }
+        }
     }
 }
 
@@ -1900,11 +1937,9 @@ foreach my $id (@idlist) {
             undef, $oldhash{'product_id'}, $product->id, $id);
         my @groupstoremove = ();
         my @groupstoadd = ();
-        my @defaultstoremove = ();
         my @defaultstoadd = ();
         my @allgroups = ();
         my $buginanydefault = 0;
-        my $buginanychangingdefault = 0;
         foreach my $group (@$groups) {
             my ($groupid, $isactive, $oldcontrol, $newcontrol,
                    $useringroup, $bugingroup) = @$group;
@@ -1916,12 +1951,6 @@ foreach my $id (@idlist) {
                 && ($oldcontrol == CONTROLMAPDEFAULT)) {
                 # Bug was in a default group.
                 $buginanydefault = 1;
-                if (($newcontrol != CONTROLMAPDEFAULT)
-                    && ($newcontrol != CONTROLMAPMANDATORY)) {
-                    # Bug was in a default group that no longer is.
-                    $buginanychangingdefault = 1;
-                    push (@defaultstoremove, $groupid);
-                }
             }
             if (($isactive) && (!$bugingroup)
                 && ($newcontrol == CONTROLMAPDEFAULT)
@@ -1938,14 +1967,11 @@ foreach my $id (@idlist) {
                 push(@groupstoadd, $groupid);
             }
         }
-        # If addtonewgroups = "yes", old default groups will be removed
-        # and new default groups will be added.
-        # If addtonewgroups = "yesifinold", old default groups will be removed
-        # and new default groups will be added only if the bug was in ANY
-        # of the old default groups.
-        # If addtonewgroups = "no", old default groups will be removed and not
-        # replaced.
-        push(@groupstoremove, @defaultstoremove);
+        # If addtonewgroups = "yes", new default groups will be added.
+        # If addtonewgroups = "yesifinold", new default groups will be
+        # added only if the bug was in ANY of the old default groups.
+        # If addtonewgroups = "no", old default groups are left alone
+        # and no new default group will be added.
         if (AnyDefaultGroups()
             && (($cgi->param('addtonewgroup') eq 'yes')
             || (($cgi->param('addtonewgroup') eq 'yesifinold')
@@ -2215,6 +2241,9 @@ elsif ($action eq 'next_bug') {
 
 # End the response page.
 unless (Bugzilla->usage_mode == USAGE_MODE_EMAIL) {
+    # The user pref is 'Do nothing', so all we need is the current bug ID.
+    $vars->{'bug'} = {bug_id => scalar $cgi->param('id')};
+
     $template->process("bug/navigate.html.tmpl", $vars)
         || ThrowTemplateError($template->error());
     $template->process("global/footer.html.tmpl", $vars)
diff --git a/sanitycheck.cgi b/sanitycheck.cgi
index bf8ba19..1722d2f 100755
--- a/sanitycheck.cgi
+++ b/sanitycheck.cgi
@@ -471,7 +471,8 @@ CrossCheck("profiles", "userid",
            ["tokens", "userid"],
            ["user_group_map", "user_id"],
            ["components", "initialowner", "name"],
-           ["components", "initialqacontact", "name"]);
+           ["components", "initialqacontact", "name"],
+           ["component_cc", "user_id"]);
 
 CrossCheck("products", "id",
            ["bugs", "product_id", "bug_id"],
@@ -482,6 +483,9 @@ CrossCheck("products", "id",
            ["flaginclusions", "product_id", "type_id"],
            ["flagexclusions", "product_id", "type_id"]);
 
+CrossCheck("components", "id",
+           ["component_cc", "component_id"]);
+
 # Check the former enum types -mkanat at bugzilla.org
 CrossCheck("bug_status", "value",
             ["bugs", "bug_status", "bug_id"]);
@@ -895,10 +899,10 @@ Status("Checking statuses/everconfirmed");
 
 BugCheck("bugs WHERE bug_status = 'UNCONFIRMED' AND everconfirmed = 1",
          "Bugs that are UNCONFIRMED but have everconfirmed set");
-# The below list of resolutions is hardcoded because we don't know if future
+# The below list of resolutions is hard-coded because we don't know if future
 # resolutions will be confirmed, unconfirmed or maybeconfirmed.  I suspect
 # they will be maybeconfirmed, e.g. ASLEEP and REMIND.  This hardcoding should
-# disappear when we have customised statuses.
+# disappear when we have customized statuses.
 BugCheck("bugs WHERE bug_status IN ('NEW', 'ASSIGNED', 'REOPENED') AND everconfirmed = 0",
          "Bugs with confirmed status but don't have everconfirmed set"); 
 
diff --git a/showdependencygraph.cgi b/showdependencygraph.cgi
index 7725918..0d74304 100755
--- a/showdependencygraph.cgi
+++ b/showdependencygraph.cgi
@@ -65,14 +65,12 @@ sub CreateImagemap {
             $default = qq{<area alt="" shape="default" href="$1">\n};
         }
 
-        if ($line =~ /^rectangle \((.*),(.*)\) \((.*),(.*)\) (http[^ ]*)(.*)?$/) {
-            my ($leftx, $rightx, $topy, $bottomy, $url) = ($1, $3, $2, $4, $5);
+        if ($line =~ /^rectangle \((.*),(.*)\) \((.*),(.*)\) (http[^ ]*) (\d+)(\\n.*)?$/) {
+            my ($leftx, $rightx, $topy, $bottomy, $url, $bugid) = ($1, $3, $2, $4, $5, $6);
 
             # Pick up bugid from the mapdata label field. Getting the title from
             # bugtitle hash instead of mapdata allows us to get the summary even
             # when showsummary is off, and also gives us status and resolution.
-
-            my ($bugid) = ($6 =~ /^\s*(\d+)/);
             my $bugtitle = value_quote($bugtitles{$bugid});
             $map .= qq{<area alt="bug $bugid" name="bug$bugid" shape="rect" } .
                     qq{title="$bugtitle" href="$url" } .
@@ -251,7 +249,7 @@ if ($webdotbase =~ /^https?:/) {
     # Under mod_perl, pngfilename will have an absolute path, and we
     # need to make that into a relative path.
     my $cgi_root = bz_locations()->{cgi_path};
-    $pngfilename =~ s/^\Q$cgi_root\E//;
+    $pngfilename =~ s#^\Q$cgi_root\E/?##;
     
     $vars->{'image_url'} = $pngfilename;
 
diff --git a/skins/standard/global.css b/skins/standard/global.css
index 80c2051..6aaf3fb 100644
--- a/skins/standard/global.css
+++ b/skins/standard/global.css
@@ -261,6 +261,10 @@ table#flags td {
     text-align: left;
 }
 
+.flag_select {
+    min-width: 3em;
+}
+
 .throw_error {
     background-color: #ff0000;
     color: black;
diff --git a/t/009bugwords.t b/t/009bugwords.t
index bf3d91f..8abbe16 100644
--- a/t/009bugwords.t
+++ b/t/009bugwords.t
@@ -68,7 +68,7 @@ foreach my $file (@testitems) {
         my $lineno = scalar(@lineno) + 1;
     
         # "a bug", "bug", "bugs"
-        if (grep /(a?[\s>]bugs?[\s.:;])/i, $text) {
+        if (grep /(a?[\s>]bugs?[\s.:;,])/i, $text) {
             # Exclude variable assignment.
             unless (grep /bugs =/, $text) {
                 push(@errors, [$lineno, $text]);
@@ -79,7 +79,7 @@ foreach my $file (@testitems) {
         # "Bugzilla"
         if (grep /(?<!X\-)Bugzilla(?!_|::|-&gt|\.pm)/, $text) {
             # Exclude JS comments, hyperlinks, USE, and variable assignment.
-            unless (grep /(\/\/.*|(org|api).*>|USE |= )Bugzilla/, $text) {
+            unless (grep /(\/\/.*|org.*>|api\/|USE |= )Bugzilla/, $text) {
                 push(@errors, [$lineno, $text]);
                 next;
             }
diff --git a/template/en/default/account/auth/login-small.html.tmpl b/template/en/default/account/auth/login-small.html.tmpl
index 0ea4df3..bb0f7a4 100644
--- a/template/en/default/account/auth/login-small.html.tmpl
+++ b/template/en/default/account/auth/login-small.html.tmpl
@@ -25,6 +25,9 @@
   # then we are accessing the home page. %]
 
 [% script_name = cgi.url(Relative => 1) %]
+[% IF !script_name %]
+ [% script_name = "index.cgi" %]
+[% END %]
 
 [%# If SSL is in use, use 'sslbase', else use 'urlbase'. %]
 [% IF Param("sslbase") != "" && Param("ssl") != "never" %]
diff --git a/template/en/default/account/auth/login.html.tmpl b/template/en/default/account/auth/login.html.tmpl
index f57efc1..55ec04c 100644
--- a/template/en/default/account/auth/login.html.tmpl
+++ b/template/en/default/account/auth/login.html.tmpl
@@ -24,6 +24,10 @@
   # target: string. URL to go to after login.
   #%]
 
+[% IF !target %]
+ [% target = "index.cgi" %]
+[% END %]
+  
 [% PROCESS global/variables.none.tmpl %]
 
 [% PROCESS global/header.html.tmpl
diff --git a/template/en/default/account/prefs/email.html.tmpl b/template/en/default/account/prefs/email.html.tmpl
index 1aa4dae..617bec8 100644
--- a/template/en/default/account/prefs/email.html.tmpl
+++ b/template/en/default/account/prefs/email.html.tmpl
@@ -100,6 +100,16 @@ document.write('<input type="button" value="Disable All Mail" onclick="SetCheckb
       <br>
     </td>
   </tr>
+[% IF user.is_global_watcher %]
+  <tr>
+    <td width="150"></td>
+    <td>
+      You are watching all [% terms.bugs %]. To be removed from this role,
+      contact
+      <a href="mailto:[% Param("maintainer") %]">[% Param("maintainer") %]</a>.
+    </td>
+  </tr>
+[% END %]
 </table>
 
 <hr>
diff --git a/template/en/default/account/prefs/saved-searches.html.tmpl b/template/en/default/account/prefs/saved-searches.html.tmpl
index 399f31b..4beb0e8 100644
--- a/template/en/default/account/prefs/saved-searches.html.tmpl
+++ b/template/en/default/account/prefs/saved-searches.html.tmpl
@@ -22,8 +22,35 @@
 [%# INTERFACE:
   # queryshare_groups: list of groups the user may share queries with
   #                    (id, name).
+  # bless_group_ids: list of group ids the user may bless.
   #%]
 
+[% IF user.can_bless %]
+  <script type="text/javascript"><!--
+    function update_checkbox(group) {
+      var bless_groups = [[% bless_group_ids.join(",") FILTER js %]];
+      var checkbox = document.getElementById(group.name.replace(/share_(\d+)/, "force_$1"));
+
+      // Check if the selected group is in the bless group array
+      var found = false;
+      for (var i = 0; i < bless_groups.length; i++) {
+        if (bless_groups[i] == group.value) {
+          found = true;
+          break;
+        }
+      }
+
+      // Enable or disable checkbox
+      if (found) {
+        checkbox.disabled = false;
+      } else {
+        checkbox.disabled = true;
+        checkbox.checked = false;
+      }
+    } //-->
+  </script>
+[% END %]
+
 <p>Your saved searches are as follows:</p>
 
 <blockquote>
@@ -53,7 +80,7 @@
       [% END %]
     </tr>
     <tr>
-      <td>My Bugs</td>
+      <td>My [% terms.Bugs %]</td>
       <td>
         [% filtered_username = user.login FILTER url_quote %]
         <a href="[% Param('mybugstemplate').replace('%userid%', filtered_username) %]">Run</a>
@@ -103,7 +130,8 @@
         </td>
         [% IF may_share %]
           <td>
-            <select name="share_[% q.id FILTER html %]">
+            <select name="share_[% q.id FILTER html %]"
+              [% IF user.can_bless %] onchange="update_checkbox(this);"[% END %]>
               <option value="">Don't share</option>
               [% FOREACH group = queryshare_groups %]
                 <option value="[% group.id %]"
@@ -112,11 +140,24 @@
                 >[% group.name FILTER html %]</option>
               [% END %]
             </select>
+            [% IF user.can_bless %]
+              <input type="checkbox" id="force_[% q.id FILTER html %]"
+                     name="force_[% q.id FILTER html %]" value="1"
+                     [% " disabled"
+                        IF !bless_group_ids.grep("^$q.shared_with_group.id\$").0
+                     %]>
+              <label for="force_[% q.id FILTER html %]">Add to footer</label>
+            [% END %]
           </td>
         [% END %]
       </tr>
     [% END %]
   </table>
+[% IF user.can_bless %]
+  <p>Note that for every search that has the "Add to footer" selected, a
+     link to the shared search is added to the footer of every user that is
+     a direct member of the group at the time you click Submit Changes.</p>
+[% END %]
 </blockquote>
 
 <p>You may use these searches saved and shared by others:</p>
diff --git a/template/en/default/account/prefs/settings.html.tmpl b/template/en/default/account/prefs/settings.html.tmpl
index 568dac0..c47615d 100644
--- a/template/en/default/account/prefs/settings.html.tmpl
+++ b/template/en/default/account/prefs/settings.html.tmpl
@@ -35,7 +35,7 @@
     <p class="criticalmessages">
       All user preferences have been disabled by the
       <a href="mailto:[% Param("maintainer") %]">maintainer</a>
-      of this installation, and so you cannot customise any.
+      of this installation, and so you cannot customize any.
     </p>
   [% END %]
 
diff --git a/template/en/default/admin/classifications/edit.html.tmpl b/template/en/default/admin/classifications/edit.html.tmpl
index 923a79f..5693945 100644
--- a/template/en/default/admin/classifications/edit.html.tmpl
+++ b/template/en/default/admin/classifications/edit.html.tmpl
@@ -49,7 +49,7 @@
     <tr valign=top>
       <th align="right">
         <a href="editproducts.cgi?classification=[% classification.name FILTER url_quote %]">
-        Edit products</a>
+        Edit Products</a>:
       </th>
       <td>
         [% IF classification.products.size > 0 %]
diff --git a/template/en/default/admin/components/edit.html.tmpl b/template/en/default/admin/components/edit.html.tmpl
index e7bd963..0e3415d 100644
--- a/template/en/default/admin/components/edit.html.tmpl
+++ b/template/en/default/admin/components/edit.html.tmpl
@@ -29,7 +29,9 @@
 
 [% PROCESS global/variables.none.tmpl %]
 
-[% title = BLOCK %]Edit Component '[% comp.name FILTER html %]'[% END %]
+[% title = BLOCK %]
+  Edit component '[% comp.name FILTER html %]' of product '[% product.name FILTER html %]'
+[% END %]
 [% PROCESS global/header.html.tmpl
   title = title
 %]
@@ -104,7 +106,7 @@
       <td>[% terms.Bugs %]:</td>
       <td>
 [% IF comp.bug_count > 0 %]
-        <a title="Bugs in component '[% comp.name FILTER html %]'"
+        <a title="[% terms.Bugs %] in component '[% comp.name FILTER html %]'"
            href="buglist.cgi?component=
                 [%- comp.name FILTER url_quote %]&amp;product=
                 [%- product.name FILTER url_quote %]">[% comp.bug_count %]</a>
diff --git a/template/en/default/admin/custom_fields/create.html.tmpl b/template/en/default/admin/custom_fields/create.html.tmpl
index 3fdb20f..f7ab722 100644
--- a/template/en/default/admin/custom_fields/create.html.tmpl
+++ b/template/en/default/admin/custom_fields/create.html.tmpl
@@ -72,7 +72,7 @@
       <td><input type="text" id="desc" name="desc" value="" size="40"></td>
 
       <th align="right">
-        <label for="new_bugmail">Displayed in bugmail for new [% terms.bugs %]:</label>
+        <label for="new_bugmail">Displayed in [% terms.bug %]mail for new [% terms.bugs %]:</label>
       </th>
       <td><input type="checkbox" id="new_bugmail" name="new_bugmail" value="1"></td>
     </tr>
diff --git a/template/en/default/admin/custom_fields/edit.html.tmpl b/template/en/default/admin/custom_fields/edit.html.tmpl
index 2165ac3..882b17b 100644
--- a/template/en/default/admin/custom_fields/edit.html.tmpl
+++ b/template/en/default/admin/custom_fields/edit.html.tmpl
@@ -62,7 +62,7 @@
                  value="[% field.description FILTER html %]"></td>
 
       <th align="right">
-        <label for="new_bugmail">Displayed in bugmail for new [% terms.bugs %]:</label>
+        <label for="new_bugmail">Displayed in [% terms.bug %]mail for new [% terms.bugs %]:</label>
       </th>
       <td><input type="checkbox" id="new_bugmail" name="new_bugmail" value="1"
                  [%- " checked" IF field.mailhead %]></td>
diff --git a/template/en/default/admin/custom_fields/list.html.tmpl b/template/en/default/admin/custom_fields/list.html.tmpl
index befd157..03c0401 100644
--- a/template/en/default/admin/custom_fields/list.html.tmpl
+++ b/template/en/default/admin/custom_fields/list.html.tmpl
@@ -42,11 +42,11 @@
      },
      {
        name => "enter_bug"
-       heading => "Editable on Bug Creation"
+       heading => "Editable on $terms.Bug Creation"
      },
      {
        name => "mailhead"
-       heading => "In Bugmail on Bug Creation"
+       heading => "In ${terms.Bug}mail on $terms.Bug Creation"
      },
      {
        name => "obsolete"
diff --git a/template/en/default/admin/keywords/list.html.tmpl b/template/en/default/admin/keywords/list.html.tmpl
index 1ffa0f2..90b079f 100644
--- a/template/en/default/admin/keywords/list.html.tmpl
+++ b/template/en/default/admin/keywords/list.html.tmpl
@@ -48,7 +48,7 @@
      },
      { 
        name => "bug_count"
-       heading => "Bugs"
+       heading => "$terms.Bugs"
        align => "right"
        contentlink => "buglist.cgi?keywords=%%name%%"
      },
diff --git a/template/en/default/admin/params/core.html.tmpl b/template/en/default/admin/params/core.html.tmpl
index 9ad312c..3fe66de 100644
--- a/template/en/default/admin/params/core.html.tmpl
+++ b/template/en/default/admin/params/core.html.tmpl
@@ -92,7 +92,8 @@
   proxy_url => "$terms.Bugzilla may have to access the web to get notifications about new " _
                "releases, see the <tt>upgrade_notification</tt> parameter. In case you are " _
                "behind a proxy, it may be necessary to enter its URL if the web server " _
-               "group cannot access the HTTP_PROXY environment variable.",
+               "group cannot access the HTTP_PROXY environment variable. If you have to " _
+               "authenticate, use the <code>http://user:pass@proxy_url/</code> syntax.",
 
   upgrade_notification => "<p>$terms.Bugzilla can inform you when a new release is available. " _
                           "The notification will appear on the $terms.Bugzilla homepage, " _
diff --git a/template/en/default/admin/params/mta.html.tmpl b/template/en/default/admin/params/mta.html.tmpl
index 778f81d..7af38ed 100644
--- a/template/en/default/admin/params/mta.html.tmpl
+++ b/template/en/default/admin/params/mta.html.tmpl
@@ -56,6 +56,11 @@
 
   smtpserver => "The SMTP server address (if using SMTP for mail delivery).",
 
+  smtp_debug => "If enabled, this will print detailed information to your" _
+                " web server's error log about the communication between" _
+                " $terms.Bugzilla and your SMTP server. You can use this to" _
+                " troubleshoot email problems.",
+
   whinedays => "The number of days that we'll let a $terms.bug sit untouched in a NEW " _
                "state before our cronjob will whine at the owner.<br> " _
                "Set to 0 to disable whining.",
diff --git a/template/en/default/admin/params/query.html.tmpl b/template/en/default/admin/params/query.html.tmpl
index ca4280f..cdc4847 100644
--- a/template/en/default/admin/params/query.html.tmpl
+++ b/template/en/default/admin/params/query.html.tmpl
@@ -54,5 +54,8 @@
 
   quicksearch_comment_cutoff => "The maximum number of search terms for a QuickSearch " _
                                 "to search comments. If the QuickSearch query contains " _
-                                "more terms than this value, QuickSearch will not search comments." }
+                                "more terms than this value, QuickSearch will not search comments.",
+
+  specific_search_allow_empty_words => "Whether to allow a search on the 'Find a Specific " _
+                                       "Bug' page with an empty 'Words' field." }
 %]
diff --git a/template/en/default/admin/settings/updated.html.tmpl b/template/en/default/admin/settings/updated.html.tmpl
index 4a569ab..0b83a27 100644
--- a/template/en/default/admin/settings/updated.html.tmpl
+++ b/template/en/default/admin/settings/updated.html.tmpl
@@ -16,7 +16,7 @@
   #%]
 
 [% PROCESS global/header.html.tmpl
-   title = "Preferences Updated"
+   title = "Default Preferences Updated"
  %]
 
 Your changes to the Default Preferences have been saved.<br>
diff --git a/template/en/default/admin/users/confirm-delete.html.tmpl b/template/en/default/admin/users/confirm-delete.html.tmpl
index 0fd4aaf..ef986fd 100644
--- a/template/en/default/admin/users/confirm-delete.html.tmpl
+++ b/template/en/default/admin/users/confirm-delete.html.tmpl
@@ -73,7 +73,7 @@
   <tr>
     <th>Group set:</th>
     <td>
-      [% IF groups.size %]
+      [% IF otheruser.groups.size %]
         <ul>
           [% FOREACH group = otheruser.groups.keys %]
             <li>[% group FILTER html %]</li>
diff --git a/template/en/default/admin/users/userdata.html.tmpl b/template/en/default/admin/users/userdata.html.tmpl
index f495eb0..e7afe66 100644
--- a/template/en/default/admin/users/userdata.html.tmpl
+++ b/template/en/default/admin/users/userdata.html.tmpl
@@ -64,12 +64,12 @@
     </td>
   </tr>
   <tr>
-    <th><label for="disable_mail">Bugmail Disabled:</label></th>
+    <th><label for="disable_mail">[% terms.Bug %]mail Disabled:</label></th>
     <td>
       <input type="checkbox" name="disable_mail" id="disable_mail" value="1" 
       [% IF otheruser.email_disabled %] checked="checked" [% END %] />
-      (This affects bugmail and whinemail, not password-reset or other 
-      non-bug-related emails)
+      (This affects [% terms.bug %]mail and whinemail, not password-reset or other 
+      non-[% terms.bug %]-related emails)
     </td>
   </tr>
   <tr>
diff --git a/template/en/default/bug/create/create-guided.html.tmpl b/template/en/default/bug/create/create-guided.html.tmpl
index 3bc459d..741f486 100644
--- a/template/en/default/bug/create/create-guided.html.tmpl
+++ b/template/en/default/bug/create/create-guided.html.tmpl
@@ -284,7 +284,7 @@ function PutDescription() {
       <b>Build Identifier</b>
     </td>
     <td valign="top">
-      <input type="text" size="80" name="buildid" value="[% buildid %]">
+      <input type="text" size="80" name="buildid" value="[% buildid FILTER html %]">
       <p>
         This should identify the exact version of the product you were using.  
         If the above field is blank or you know it is incorrect, copy the 
diff --git a/template/en/default/bug/edit.html.tmpl b/template/en/default/bug/edit.html.tmpl
index ddc79a7..521733a 100644
--- a/template/en/default/bug/edit.html.tmpl
+++ b/template/en/default/bug/edit.html.tmpl
@@ -260,6 +260,14 @@
         </fieldset>
       </td>
 
+      [%# Force the layout to be displayed now, before drawing the second column of the table.
+        # This should prevent bug 370739 when using Firefox 2. %]
+      <script type="text/javascript">
+        <!--
+        var v = document.body.offsetHeight;
+        //-->
+      </script>
+
       <td valign="top">
         [%# *** Reporter, owner and QA contact *** %]
         <fieldset>
@@ -539,11 +547,13 @@
       <p>
         <input type="checkbox" value="1"
                name="reporter_accessible" id="reporter_accessible"
-               [% " checked" IF bug.reporter_accessible %]>
+               [% " checked" IF bug.reporter_accessible %]
+               [% " disabled=\"disabled\"" UNLESS bug.check_can_change_field("reporter_accessible", 0, 1) %]>
         <label for="reporter_accessible">Reporter</label>
         <input type="checkbox" value="1"
                name="cclist_accessible" id="cclist_accessible"
-               [% " checked" IF bug.cclist_accessible %]>
+               [% " checked" IF bug.cclist_accessible %]
+               [% " disabled=\"disabled\"" UNLESS bug.check_can_change_field("cclist_accessible", 0, 1) %]>
         <label for="cclist_accessible">CC List</label>
       </p>
     [% END %]
diff --git a/template/en/default/bug/process/verify-new-product.html.tmpl b/template/en/default/bug/process/verify-new-product.html.tmpl
index b3ec732..1b62250 100644
--- a/template/en/default/bug/process/verify-new-product.html.tmpl
+++ b/template/en/default/bug/process/verify-new-product.html.tmpl
@@ -17,6 +17,7 @@
   # Rights Reserved.
   #
   # Contributor(s): Myk Melez <myk at mozilla.org>
+  #                 Frédéric Buclin <LpSolit at gmail.com>
   #%]
 
 [%# INTERFACE:
@@ -31,6 +32,8 @@
   #   if they want to add the bug to its new product's group
   # use_target_milestone: boolean; whether or not to use
   #   the target milestone field
+  # old_groups: a list of group objects which are not available
+  #   for the new product.
   #%]
 
 [%# The global Bugzilla->cgi object is used to obtain form variable values. %]
@@ -99,22 +102,37 @@
 
 [% END %]
 
-[% IF verify_bug_group %]
+[% IF verify_bug_group || old_groups.size %]
   <h3>Verify [% terms.Bug %] Group</h3>
 
-  <p>
-    Do you want to add the [% terms.bug %] to its new product's default groups (if any)?
-  </p>
+  [% IF old_groups.size %]
+    <p>The following groups are not legal for the <b>[% cgi.param("product") FILTER html %]</b>
+    product or you are not allowed to restrict [% terms.bugs %] to these groups:</p>
+    <ul>
+      [% FOREACH group = old_groups %]
+        <li>[% group.name FILTER html %]: [% group.description FILTER html %]</li>
+      [% END %]
+    </ul>
+    <p><b>[%+ terms.Bugs %] will no longer be restricted to these groups and may become
+    public if no other group applies.</b></p>
+  [% END %]
 
-  <p>
-    <input type="radio" name="addtonewgroup" value="no"><b>no</b><br>
-    <input type="radio" name="addtonewgroup" value="yes"><b>yes</b><br>
-    <input type="radio" name="addtonewgroup" value="yesifinold" checked="checked">
-      <b>yes, but only if the [% terms.bug %] was in any of its old product's default groups</b><br>
-  </p>
+  [% IF verify_bug_group %]
+    <p>
+      This new product has default groups associated to it. Do you want to add the
+      [%+ terms.bug %] to them?<br>
+      <input type="radio" id="add_no" name="addtonewgroup" value="no"><label for="add_no">no</label><br>
+      <input type="radio" id="add_yes" name="addtonewgroup" value="yes"><label for="add_yes">yes</label><br>
+      <input type="radio" id="add_yesifinold" name="addtonewgroup" value="yesifinold" checked="checked">
+        <label for="add_yesifinold">yes, but only if the [% terms.bug %] was in any of
+        its old product's default groups</label>
+    </p>
+  [% END %]
 [% END %]
 
-<input type="submit" id="change_product" value="Commit">
+<p>
+  <input type="submit" id="change_product" value="Commit">
+</p>
 
 </form>
 <hr>
@@ -124,9 +142,9 @@
 
 [% IF cgi.param('id') AND cgi.param('id').match('^\d+$') %]
   [% id = cgi.param('id') %]
-  [% "Cancel and Return to $terms.bug $id" FILTER bug_link(id) FILTER none %]
+  Cancel and Return to [% "$terms.bug $id" FILTER bug_link(id) FILTER none %]
 [% ELSE %]
-  <a href="buglist.cgi?regetlastlist=1">Cancel and Return to the last search results</a>
+  Cancel and Return to <a href="buglist.cgi?regetlastlist=1">the last search results</a>
 [% END %]
 
 [% PROCESS global/footer.html.tmpl %]
diff --git a/template/en/default/bug/summarize-time.html.tmpl b/template/en/default/bug/summarize-time.html.tmpl
index 76a3858..47f381b 100644
--- a/template/en/default/bug/summarize-time.html.tmpl
+++ b/template/en/default/bug/summarize-time.html.tmpl
@@ -16,7 +16,7 @@
 
 [% USE date %]
 
-[% PROCESS global/variables.none.tmpl %]
+[% PROCESS "global/field-descs.none.tmpl" %]
 
 [% title = "Time Summary " %]
 [% IF do_depends %]
@@ -193,7 +193,7 @@
     <tr class="bug_header[% '2' IF cid % 2 %]">
         <td width="10" valign="top">
         [% INCLUDE buglink id=id %]</td>
-        <td width="10"><b>[% bug_status FILTER html %]</b></td>
+        <td width="10"><b>[% status_descs.${bug_status} FILTER html %]</b></td>
         <td colspan="2">[% short_desc FILTER html %]</td>
         [% extra FILTER none %]
     </tr>
diff --git a/template/en/default/bug/votes/list-for-user.html.tmpl b/template/en/default/bug/votes/list-for-user.html.tmpl
index 6a0e90e..1a8153c 100644
--- a/template/en/default/bug/votes/list-for-user.html.tmpl
+++ b/template/en/default/bug/votes/list-for-user.html.tmpl
@@ -125,7 +125,7 @@
             </td>
             <td>
               [% bug.summary FILTER html %]
-              (<a href="votes.cgi?action=show_bug&amp;bug_id=[% bug.id %]">Voters</a>)
+              (<a href="votes.cgi?action=show_bug&amp;bug_id=[% bug.id %]">Show Votes</a>)
             </td>
           </tr>
         [% END %]
diff --git a/template/en/default/email/newchangedmail.txt.tmpl b/template/en/default/email/newchangedmail.txt.tmpl
index cbe162e..ecdf426 100644
--- a/template/en/default/email/newchangedmail.txt.tmpl
+++ b/template/en/default/email/newchangedmail.txt.tmpl
@@ -43,7 +43,7 @@ X-Bugzilla-Changed-Fields: [% changedfields %]
 [%+ diffs %]
 
 -- 
-Configure bugmail: [% Param('urlbase') %]userprefs.cgi?tab=email
+Configure [% terms.bug %]mail: [% Param('urlbase') %]userprefs.cgi?tab=email
 ------- You are receiving this mail because: -------
 [% FOREACH relationship = reasons %]
   [% SWITCH relationship %]
diff --git a/template/en/default/email/sudo.txt.tmpl b/template/en/default/email/sudo.txt.tmpl
index 758c67b..b6841e4 100644
--- a/template/en/default/email/sudo.txt.tmpl
+++ b/template/en/default/email/sudo.txt.tmpl
@@ -39,6 +39,6 @@ X-Bugzilla-Type: admin
     [%+ sudoer.identity %] did not provide a reason for doing this.
 [% END %]
 
-    If you feel that this action was inappropiate, please contact 
+    If you feel that this action was inappropriate, please contact 
 [%+ Param("maintainer") %].  For more information on this feature, 
 visit <[% Param("urlbase") %]page.cgi?id=sudo.html>.
diff --git a/template/en/default/filterexceptions.pl b/template/en/default/filterexceptions.pl
index 3a25da7..1ea527c 100644
--- a/template/en/default/filterexceptions.pl
+++ b/template/en/default/filterexceptions.pl
@@ -394,7 +394,6 @@
 'bug/create/create-guided.html.tmpl' => [
   'matches.0', 
   'tablecolour',
-  'buildid',
   'sel',
   'productstring', 
 ],
diff --git a/template/en/default/flag/list.html.tmpl b/template/en/default/flag/list.html.tmpl
index 6b75b08..61ecf2d 100644
--- a/template/en/default/flag/list.html.tmpl
+++ b/template/en/default/flag/list.html.tmpl
@@ -105,7 +105,8 @@
         <td>
           <select id="flag-[% flag.id %]" name="flag-[% flag.id %]" 
                   title="[% type.description FILTER html %]"
-                  onchange="toggleRequesteeField(this);">
+                  onchange="toggleRequesteeField(this);"
+                  class="flag_select">
             [%# Only display statuses the user is allowed to set. %]
             [% IF user.can_request_flag(type) %]
               <option value="X"></option>
@@ -156,7 +157,8 @@
           <select id="flag_type-[% type.id %]" name="flag_type-[% type.id %]" 
                   title="[% type.description FILTER html %]"
                   [% " disabled=\"disabled\"" UNLESS user.can_request_flag(type) %]
-                  onchange="toggleRequesteeField(this);">
+                  onchange="toggleRequesteeField(this);"
+                  class="flag_select">
             <option value="X"></option>
             [% IF type.is_requestable && user.can_request_flag(type) %]
               <option value="?">?</option>
@@ -199,7 +201,8 @@
         <select id="flag_type-[% type.id %]" name="flag_type-[% type.id %]" 
                 title="[% type.description FILTER html %]"
                 [% " disabled=\"disabled\"" UNLESS user.can_request_flag(type) %]
-                onchange="toggleRequesteeField(this);">
+                onchange="toggleRequesteeField(this);"
+                class="flag_select">
           <option value="X"></option>
           [% IF type.is_requestable && user.can_request_flag(type) %]
             <option value="?">?</option>
diff --git a/template/en/default/global/code-error.html.tmpl b/template/en/default/global/code-error.html.tmpl
index a4a9df9..303c732 100644
--- a/template/en/default/global/code-error.html.tmpl
+++ b/template/en/default/global/code-error.html.tmpl
@@ -40,7 +40,7 @@
 [% error_message = BLOCK %]
   [% IF    error == "action_unrecognized" %]
     [% docslinks = {'query.html' => "Searching for $terms.bugs",
-                    'list.html'  => "$terms.Bug lists"} %]
+                    'query.html#list' => "$terms.Bug lists"} %]
     I don't recognize the value (<em>[% action FILTER html %]</em>)
     of the <em>action</em> variable.
   
@@ -132,9 +132,9 @@
       This means that the '[% Param("auth_env_email") FILTER html %]'
       environment variable was empty or did not exist.
     [% ELSE %]
-      You need to set the "auth_env_email" environment variable to
-      the name of the environment variable that will contain the
-      user's email address.
+      You need to set the "auth_env_email" parameter to the name of
+      the environment variable that will contain the user's email
+      address.
     [% END %]
 
   [% ELSIF error == "extension_invalid" %]
@@ -429,12 +429,18 @@
     Invalid setting for post_bug_submit_action
 
   [% ELSE %]
-    [% title = "Internal error" %]
-    An internal error has occurred, but [% terms.Bugzilla %] doesn't know
-    what <code>[% error FILTER html %]</code> means.
-
-    If you are a [% terms.Bugzilla %] end-user seeing this message, please save
-    this page and send it to [% Param('maintainer') %].
+    [%# Try to find hooked error messages %]
+    [% error_message = Hook.process("errors") %]
+    [% IF NOT error_message %]
+      [% title = "Internal error" %]
+      An internal error has occurred, but [% terms.Bugzilla %] doesn't know
+      what <code>[% error FILTER html %]</code> means.
+
+      If you are a [% terms.Bugzilla %] end-user seeing this message, please save
+      this page and send it to [% Param('maintainer') %].
+    [% ELSE %]
+      [% error_message FILTER none %]
+    [% END %]
   [% END %]
 [% END %]
 
diff --git a/template/en/default/global/header.html.tmpl b/template/en/default/global/header.html.tmpl
index e02eb48..b404648 100644
--- a/template/en/default/global/header.html.tmpl
+++ b/template/en/default/global/header.html.tmpl
@@ -35,7 +35,7 @@
   # style: string. CSS style.
   # style_urls: list. List of URLs to CSS style sheets.
   # message: string. A message to display to the user. May contain HTML.
-  # atomlink: Atom link url, May contain HTML
+  # atomlink: Atom link URL, May contain HTML
   #%]
 
 [% IF message %]
diff --git a/template/en/default/global/messages.html.tmpl b/template/en/default/global/messages.html.tmpl
index ad56a35..cea7f6d 100644
--- a/template/en/default/global/messages.html.tmpl
+++ b/template/en/default/global/messages.html.tmpl
@@ -68,9 +68,9 @@
               The disable text has been modified.
             [% ELSIF field == 'disable_mail' %]
               [% IF otheruser.email_disabled %]
-                Bugmail has been disabled.
+                [% terms.Bug %]mail has been disabled.
               [% ELSE %]
-                Bugmail has been enabled.
+                [% terms.Bug %]mail has been enabled.
               [% END %]
             [% END %]
           </li>
@@ -141,12 +141,6 @@
     [% title = "Adding field to search page..." %]
     [% link  = "Click here if the page does not redisplay automatically." %]
 
-  [% ELSIF message_tag == "buglist_load_named_query" %]
-    [% title = BLOCK %]
-      Loading your search named [% namedcmd FILTER html %]
-    [% END %]
-    [% link  = "Click here if the page does not redisplay automatically." %]
-
   [% ELSIF message_tag == "buglist_updated_named_query" %]
     Your search named <code>[% queryname FILTER html %]</code> has been updated.
 
@@ -335,7 +329,7 @@
     Now that you have installed [% terms.Bugzilla %], you should visit the
     'Parameters' page (linked in the footer of the Administrator
     account) to ensure it is set up as you wish - this includes
-    setting the 'urlbase' option to the correct url.
+    setting the 'urlbase' option to the correct URL.
 
   [% ELSIF message_tag == "install_webservergroup_empty" %]
     ****************************************************************************
diff --git a/template/en/default/global/setting-descs.none.tmpl b/template/en/default/global/setting-descs.none.tmpl
index 3992e12..921b759 100644
--- a/template/en/default/global/setting-descs.none.tmpl
+++ b/template/en/default/global/setting-descs.none.tmpl
@@ -22,7 +22,7 @@
 [% setting_descs = { 
    "comment_sort_order"               => "When viewing $terms.abug, show comments in this order",
    "csv_colsepchar"                   => "Field separator character for CSV files",
-   "display_quips"                    => "Show a quip at the top of each bug list",
+   "display_quips"                    => "Show a quip at the top of each $terms.bug list",
    "zoom_textareas"                   => "Zoom textareas large when in use (requires JavaScript)",
    "newest_to_oldest"                 => "Newest to Oldest",
    "newest_to_oldest_desc_first"      => "Newest to Oldest, but keep Description at the top",
@@ -36,7 +36,7 @@
    "standard"                         => "Classic",
    "skin"                             => "$terms.Bugzilla's general appearance (skin)",
    "nothing"                          => "Do Nothing",
-   "state_addselfcc"                  => "Automatically add me to the CC list of bugs I change",
+   "state_addselfcc"                  => "Automatically add me to the CC list of $terms.bugs I change",
    "always"                           => "Always",
    "never"                            => "Never",
    "cc_unless_role"                   => "Only if I have no role on them",
diff --git a/template/en/default/global/useful-links.html.tmpl b/template/en/default/global/useful-links.html.tmpl
index 8118d94..56c5e6a 100644
--- a/template/en/default/global/useful-links.html.tmpl
+++ b/template/en/default/global/useful-links.html.tmpl
@@ -48,7 +48,7 @@
         [% IF user.groups.tweakparams %]
           <li>[% '<span class="separator">| </span>' IF print_pipe %]<a href="editparams.cgi">Parameters</a></li>
           [% print_pipe = 1 %]
-          <li>[% '<span class="separator">| </span>' IF print_pipe %]<a href="editsettings.cgi">User Preferences</a></li>
+          <li>[% '<span class="separator">| </span>' IF print_pipe %]<a href="editsettings.cgi">Default Preferences</a></li>
         [% END %]
         [% IF user.groups.editcomponents %]
           <li>[% '<span class="separator">| </span>' IF print_pipe %]<a href="sanitycheck.cgi">Sanity Check</a></li>
diff --git a/template/en/default/global/user-error.html.tmpl b/template/en/default/global/user-error.html.tmpl
index 7452ab8..5801396 100644
--- a/template/en/default/global/user-error.html.tmpl
+++ b/template/en/default/global/user-error.html.tmpl
@@ -225,7 +225,7 @@
   [% ELSIF error == "buglist_parameters_required" %]
     [% title = "Parameters Required" %]
     [% docslinks = {'query.html' => "Searching for $terms.bugs",
-                    'list.html'  => "$terms.Bug lists"} %]
+                    'query.html#list' => "$terms.Bug lists"} %]
     You may not search, or create saved searches, without any search terms.
 
   [% ELSIF error == "bugs_not_changed" %]
@@ -617,12 +617,12 @@
     You entered <tt>[% value FILTER html %]</tt>, which isn't.
     
   [% ELSIF error == "illegal_attachment_edit" %]
-    [% title = "Unauthorised Action" %]
-    You are not authorised to edit attachment [% attach_id FILTER html %].
+    [% title = "Unauthorized Action" %]
+    You are not authorized to edit attachment [% attach_id FILTER html %].
 
   [% ELSIF error == "illegal_attachment_edit_bug" %]
-    [% title = "Unauthorised Action" %]
-    You are not authorised to edit attachments on [% terms.bug %] 
+    [% title = "Unauthorized Action" %]
+    You are not authorized to edit attachments on [% terms.bug %] 
     [%+ bug_id FILTER html %].
          
   [% ELSIF error == "illegal_attachment_is_patch" %]
@@ -704,12 +704,12 @@
   [% ELSIF error == "illegal_series_creation" %]
     [% admindocslinks = {'groups.html' => 'Group security'} %]
     [% docslinks = {'reporting.html' => 'Reporting'} %]
-    You are not authorised to create series.
+    You are not authorized to create series.
         
   [% ELSIF error == "illegal_series_edit" %]
     [% admindocslinks = {'groups.html' => 'Group security'} %]
     [% docslinks = {'reporting.html' => 'Reporting'} %]
-    You are not authorised to edit this series. To do this, you must either
+    You are not authorized to edit this series. To do this, you must either
     be its creator, or an administrator.
         
   [% ELSIF error == "insufficient_data_points" %]
@@ -967,7 +967,7 @@
   [% ELSIF error == "missing_query" %]
     [% title = "Missing Search" %]
     [% docslinks = {'query.html' => "Searching for $terms.bugs",
-                    'list.html'  => "$terms.Bug lists"} %]
+                    'query.html#list' => "$terms.Bug lists"} %]
     The search named <em>[% queryname FILTER html %]</em>
     [% IF sharer_id && sharer_id != user.id %]
       has not been made visible to you.
@@ -1013,26 +1013,25 @@
     You didn't define any axes to plot.
 
   [% ELSIF error == "no_bugs_chosen" %]
-    [% title = BLOCK %]No [% terms.Bugs %] Chosen[% END %]
+    [% title = BLOCK %]No [% terms.Bugs %] Selected[% END %]
     You apparently didn't choose any [% terms.bugs %] to modify.
 
   [% ELSIF error == "no_bug_ids" %]
-    [% title = BLOCK %]No [% terms.Bugs %] Chosen[% END %]
+    [% title = BLOCK %]No [% terms.Bugs %] Selected[% END %]
     You didn't choose any [% terms.bugs %] to
     [% IF action == "add" %] add to [% ELSE %] remove from [% END %]
-    the saved search.
+    the [% tag FILTER html %] tag.
 
   [% ELSIF error == "no_bugs_in_list" %]
-    [% title = "Delete Saved Search?" %]
-    You are going to remove all [% terms.bugs %] from the '[% saved_search FILTER html %]'
-    saved search. This will delete this saved search completely. Click
+    [% title = "Delete Tag?" %]
+    This will remove all [% terms.bugs %] from the
+    [% tag FILTER html %] tag. This will delete the tag completely. Click
     <a href="buglist.cgi?cmdtype=dorem&amp;remaction=forget&amp;namedcmd=
-    [%- saved_search FILTER url_quote %]">here</a> if you really want to
-    remove it.
+    [%- tag FILTER url_quote %]">here</a> if you really want to delete it.
 
   [% ELSIF error == "no_bugs_to_remove" %]
-    [% title = "No Saved Search Selected" %]
-    You didn't select any saved search to remove [% terms.bugs %] from.
+    [% title = "No Tag Selected" %]
+    You didn't select a tag from which to remove [% terms.bugs %].
 
   [% ELSIF error == "no_component_change_for_multiple_products" %]
     [% title = "Action Not Permitted" %]
@@ -1261,13 +1260,27 @@
 
   [% ELSIF error == "query_name_missing" %]
     [% title = "No Search Name Specified" %]
-    [% docslinks = {'list.html' => "About $terms.bug lists"} %]
+    [% docslinks = {'query.html#list' => "$terms.Bug lists"} %]
     You must enter a name for your search.
 
   [% ELSIF error == "query_name_too_long" %]
     [% title = "Query Name Too Long" %]
     The name of the query must be less than 64 characters long.
 
+  [% ELSIF error == "quicksearch_unknown_field" %]
+    [% title = "Unknown QuickSearch Field" %]
+    [% IF fields.unique.size == 1 %]
+      Field <code>[% fields.first FILTER html %]</code> is not a known field.
+    [% ELSE %]
+      Fields
+      [% FOREACH field = fields.unique.sort %]
+         <code>[% field FILTER html %]</code>
+         [% ', ' UNLESS loop.last() %]
+      [% END %]
+      are not known fields.
+    [% END %]
+    The legal field names are <a href="page.cgi?id=quicksearchhack.html">listed here</a>.
+
   [% ELSIF error == "reassign_to_empty" %]
     [% title = "Illegal Reassignment" %]
     To reassign [% terms.abug %], you must provide an address for
@@ -1479,7 +1492,8 @@
 
   [% ELSIF error == "zero_length_file" %]
     [% title = "File Is Empty" %]
-    The file you are trying to attach is empty!
+    The file you are trying to attach is empty, does not exist, or you don't
+    have permission to read it.
 
   [% ELSIF error == "illegal_user_id" %]
     [% title = "Illegal User ID" %]
diff --git a/template/en/default/index.html.tmpl b/template/en/default/index.html.tmpl
index d1ba354..1a3aafc 100644
--- a/template/en/default/index.html.tmpl
+++ b/template/en/default/index.html.tmpl
@@ -80,7 +80,9 @@ function addSidebar() {
       <a href="editparams.cgi?section=core#upgrade_notification">notify you about new releases</a>.</p>
     [% ELSIF release.error == "cannot_download" %]
       <p>The local XML file '[% release.xml_file FILTER html %]' cannot be created.
-      Please make sure the web server can write in this directory.</p>
+      Please make sure the web server can write in this directory and that you can access
+      the web. If you are behind a proxy, set the
+      <a href="editparams.cgi?section=core#proxy_url">proxy_url</a> parameter correctly.</p>
     [% ELSIF release.error == "no_update" %]
       <p>The local XML file '[% release.xml_file FILTER html %]' cannot be updated.
       Please make sure the web server can edit this file.</p>
diff --git a/template/en/default/list/list.csv.tmpl b/template/en/default/list/list.csv.tmpl
index 76df4f4..4175088 100644
--- a/template/en/default/list/list.csv.tmpl
+++ b/template/en/default/list/list.csv.tmpl
@@ -20,7 +20,7 @@
   #                 Gervase Markham <gerv at gerv.net>
   #%]
 
-[% PROCESS global/variables.none.tmpl %]
+[% PROCESS "global/field-descs.none.tmpl" %]
 [% USE date %]
 
 [% colsepchar = user.settings.csv_colsepchar.value %]
@@ -37,6 +37,10 @@ bug_id
       [% IF column == "opendate" OR column == "changeddate" %]
         [% rawcolumn = column.replace("date", "time") %]
         [% bug.$column = date.format(bug.$rawcolumn, "%Y-%m-%d %H:%M:%S") %]
+      [% ELSIF column == 'bug_status' %]
+        [% bug.$column = status_descs.${bug.$column} %]
+      [% ELSIF column == 'resolution' %]
+        [%- bug.$column = get_resolution(bug.$column) %]
       [% END %]
       [% bug.$column FILTER csv %]
     [% END %]
diff --git a/template/en/default/list/table.html.tmpl b/template/en/default/list/table.html.tmpl
index 2918007..5889936 100644
--- a/template/en/default/list/table.html.tmpl
+++ b/template/en/default/list/table.html.tmpl
@@ -104,7 +104,11 @@
           [% PROCESS columnheader %]
         [% END %]
 
-        </tr><tr align="left"><th>&nbsp;</th>
+        </tr><tr align="left">
+        [% IF dotweak %]
+          <th>&nbsp;</th>
+        [% END %]
+        <th>&nbsp;</th>
 
         [% FOREACH id = displaycolumns %]
           [% NEXT IF loop.count() % 2 == 0 %]
diff --git a/template/en/default/pages/bug-writing.html.tmpl b/template/en/default/pages/bug-writing.html.tmpl
index 6df5d5f..6c6f27d 100644
--- a/template/en/default/pages/bug-writing.html.tmpl
+++ b/template/en/default/pages/bug-writing.html.tmpl
@@ -30,157 +30,79 @@
 
 [% INCLUDE global/header.html.tmpl title = "$terms.Bug Writing Guidelines" %]
 
-<h3>Contents</h3>
-<ul>
-<li><a href="#why">Why You Should Read This</a></li>
-<li><a href="#useful">What Makes [% terms.aBug %] Report Useful?</a></li>
-<li><a href="#before">Before You Start...</a></li>
-<li><a href="#reporting">Reporting a New [% terms.Bug %]</a></li>
-<li><a href="#more">More Information on Writing Good [% terms.Bugs %]</a></li>
-</ul>
-
-<h3><a name="why">Why You Should Read This</a></h3>
-
-<blockquote>
-  <p>Simply put, the more effectively you report [% terms.abug %], the more
-  likely an engineer will actually fix it. This tutorial teaches novice and
-  intermediate [% terms.bug %] reporters how to write effective 
-  [% terms.bug %] reports.</p>
-</blockquote>
-
-<h3><a name="useful">What Makes [% terms.aBug %] Report Useful?</a></h3>
+  <p>Effective [% terms.bug %] reports are the most likely to be fixed. 
+  These guidelines explain how to write such reports.
 
-<blockquote>
-  <p>Useful [% terms.bug %] reports get [% terms.bugs %] fixed. 
-  A useful [% terms.bug %] report has two qualities:</p>
+<h3>Principles</h3>
 
   <ul>
-    <li><b>It's Reproducible.</b> Engineers usually prefer to fix [% terms.bugs %]
-    they can actually see. If an engineer can't reproduce the [% terms.bug %],
-    it'll probably be stamped "[% get_resolution("WORKSFORME") FILTER html %]" or
-    "[% get_resolution("INVALID") FILTER html %]".<br>
-    <br>
-    </li>
-
-    <li><b>It's Specific.</b> The quicker an engineer isolates the 
-    [% terms.bug %] to a specific area, the more likely it'll be fixed. (If the
-    engineer must decipher your [% terms.bug %], 
-    he or she will waste time cursing you instead.)<br>
-        </li>
+    <li>Be precise</li>
+    <li>Be clear - explain it so others can reproduce the [% terms.bug %]</li>
+    <li>One [% terms.bug %] per report</li>
+    <li>No [% terms.bug %] is too trivial to report - 
+    small [% terms.bugs %] may hide big [% terms.bugs %]</li>
+    <li>Clearly separate fact from speculation</li>
   </ul>
 
-</blockquote>
-
-<h3><a name="before">Before You Start...</a></h3>
+<h3>Preliminaries</h3>
 
 <ol>
-  <li>Before you enter your [% terms.bug %], use [% terms.Bugzilla %]'s 
-  <a href="query.cgi?format=specific">search page</a> to determine whether
-  your [% terms.bug %] is known.</li>
-
-  <li>Reproduce your [% terms.bug %] using a recent build. 
-  Engineers tend to be most interested in problems affecting the code base 
-  on which they're actively working. The [% terms.bug %] you're 
-  reporting may already be fixed.</li>
+  <li>Reproduce your [% terms.bug %] using a recent build of the
+  software, to see whether it has already been fixed.
+  </li>
+
+  <li><a href="query.cgi?format=specific">Search</a> 
+  [% terms.Bugzilla %], to see whether your [% terms.bug %] has
+  already been reported.</li>
 </ol>
 
-<blockquote>
-Can't find your [% terms.bug %] in [% terms.Bugzilla %]? And you can reproduce
-it in a recent build? Let's report it.
-</blockquote>
+<h3>Reporting a New [% terms.Bug %]</h3>
 
-<h3><a name="reporting">Reporting a New [% terms.Bug %]</a></h3>
+<p>If you have reproduced the [% terms.bug %] in a recent build and 
+no-one else appears to have reported it, then:</p>
 
 <ol>
- <li>From [% terms.Bugzilla %]'s main page, choose 
- "<a href="enter_bug.cgi">Enter a new [% terms.bug %]</a>".</li>
-
- <li>Select the product in which you've found [% terms.abug %].</li>
-
- <li>Log into [% terms.Bugzilla %].</li>
-
- <li>Fill out the form. Here's what it all means:</li>
-
+ <li>Choose 
+ "<a href="enter_bug.cgi">Enter a new [% terms.bug %]</a>"</li>
+ <li>Select the product in which you've found the [% terms.bug %]</li>
+ <li>Fill out the form. Here is some help understanding it:</li>
 </ol>
 
-
-  <p><b>Where did you find the [% terms.bug %]?</b></p>
-
   <blockquote>
-    <p><b>Product:</b> In which product did you find it?<br>
-     You just specified this on the last page, so you can't edit it
-    here.</p>
-
-    <p><b>Version:</b> In which product version did you find 
-          it?<br>
-     (If applicable)</p>
-
-    <p><b>Component:</b> In which component does it 
+    <p><b>Component:</b> In which sub-part of the software does it 
           exist?<br>
-    [% terms.Bugzilla %] requires that you select a component to enter 
-    [% terms.abug %]. (Click the Component link to see a description of each 
-        component.)</p>
+    This field is required.
+    Click the word "Component" to see a description of each 
+    component. If none seems appropriate, look for a "General" component.</p>
 
     <p><b>OS:</b> On which operating system (OS) did you find 
           it?
     (e.g. Linux, Windows XP, Mac OS X.)<br>
-    If the [% terms.bug %] happens on all operating systems, choose "All". 
-    Otherwise, select the OS, or "Other" if your OS isn't listed.</p>
-  </blockquote>
-
-  <p><b>How important is the [% terms.bug %]?</b></p>
-
-  <blockquote>
-    <p><b>Severity:</b> How damaging is it?<br>
-     The default is 'normal' severity. (Click on the Severity link to see
-     a description of each severity rating.<br>
-    </p>
-  </blockquote>
-
-  <p><b>Who will be following up on the [% terms.bug %]?</b></p>
+    If you know the [% terms.bug %] happens on more than one type of 
+    operating system, choose "All". 
+    If your OS isn't listed, choose Other.</p>
 
-  <blockquote>
-    <p><b>Assigned To:</b> Which engineer should be responsible for fixing
-    it?<br>
-    [% terms.Bugzilla %] automatically assigns the [% terms.bug %] to a
-    default engineer upon submitting [% terms.abug %] report. If you'd prefer
-    to directly assign the [% terms.bug %] to someone else, enter the person's
-    e-mail address. (To see the list of default engineers for each
-    component, click the Component link.)</p>
-
-    <p><b>Cc:</b> Who else should receive e-mail updates on changes to this 
-    [% terms.bug %]?<br>
-    List the e-mail addresses of other people who should receive
-    an update whenever the [% terms.bug %] report changes. Enter as many e-mail 
-    addresses as you'd like, separating them by spaces or 
-    commas. Important: You can only enter people who have 
-    [% terms.Bugzilla %] accounts.</p>
-  </blockquote>
-
-  <p><b>What else can you tell the engineer about the [% terms.bug %]?</b></p>
-
-  <blockquote>
     <p><b>Summary:</b> How would you describe the [% terms.bug %], in 
     approximately 60 or fewer characters?<br>
      A good summary should <b>quickly and uniquely identify [% terms.abug %]
-    report</b>. If an engineer can't identify your
-    [% terms.bug %] by its summary, it may be ignored when skimming through a
-    10-page list.<br>
-    <br>
-     A useful summary is "<tt>Cancelling a File Copy dialog crashes Nautilus</tt>".
-     Examples of bad summaries would be "<tt>Software crashes</tt>" or "<tt>copy problem</tt>".<br>
-    <br>
-     <b>Description:</b><br>
-     Provide a detailed problem report. [% terms.aBug %]'s recipients usually
-     expect the following information:</p>
+    report</b>. It should explain the problem, not your suggested solution.<br>
+    <ul>
+     <li>Good: "<tt>Cancelling a File Copy dialog crashes 
+     File Manager</tt>"</li>
+     <li>Bad: "<tt>Software crashes</tt>"</li>
+     <li>Bad: "<tt>Browser should work with my web site</tt>"</li>
+    </ul>
+    
+    <b>Description:</b>
+    The details of your problem report, including:</p>
 
     <blockquote>
-      <p><b>Overview Description:</b> More detailed restatement of
+      <p><b>Overview:</b> More detailed restatement of
       summary.</p>
 
       <blockquote>
 <pre>
-Drag-selecting any page crashes Mac builds in NSGetFactory
+Drag-selecting any page crashes Mac builds in the NSGetFactory function.
 </pre>
       </blockquote>
 
@@ -189,7 +111,8 @@ Drag-selecting any page crashes Mac builds in NSGetFactory
 
       <blockquote>
 <pre>
-1) View any web page. (I used the default sample page, resource:/res/samples/test0.html)
+1) View any web page. (I used the default sample page, 
+resource:/res/samples/test0.html)
 
 2) Drag-select the page. (Specifically, while holding down 
 the mouse button, drag the mouse pointer downwards from any 
@@ -232,116 +155,28 @@ Build 2006-08-10 on Mac OS 10.4.3
 
       <blockquote>
 <pre>
-- Doesn't Occur On Build 2006-08-10 on Windows XP Home (Service Pack 2)
+Doesn't Occur On Build 2006-08-10 on Windows XP Home (Service Pack 2)
 </pre>
       </blockquote>
 
-      <p><b>Additional Information:</b> Any other debugging information.
-      For crashing [% terms.bugs %]:</p>
+      <p><b>Additional Information:</b> Any other useful information.
+      <br><br>For crashing [% terms.bugs %]:</p>
 
       <ul>
         <li><b>Windows:</b> Note the type of the crash, and the module that the
         application crashed in (e.g. access violation in apprunner.exe).</li>
 
-        <li><b>Mac OS X:</b> Attach the "Crash Reporter" log that appears upon crash.
-        Only include the section directly below the crashing thread, usually titled
-        "Thread 0 Crashed". Please do not paste the entire log!</li>
-
+        <li><b>Mac OS X:</b> Attach the "Crash Reporter" log that appears
+        upon crash.
+        Only include the section directly below the crashing thread, usually 
+        titled "Thread 0 Crashed". Please do not paste the entire log!</li>
       </ul>
-
     </blockquote>
 
-  <p>You're done!<br>
-  <br>
-   After double-checking your entries for any possible errors, press the
-  "Commit" button. Your [% terms.bug %] report will now be in 
+  <p>Double-check your report for errors and omissions, then press "Commit".
+  Your [% terms.bug %] report will now be in 
   the [% terms.Bugzilla %] database.<br>
   </p>
 </blockquote>
-<hr>
-
-<h3><a name="more">More Information on Writing Good [% terms.Bugs %]</a></h3>
-
-<blockquote>
-  <p><b><a name="tips"></a> 1. General Tips for a Useful [% terms.Bug %] 
-     Report</b></p>
-
-  <blockquote>
-    <p><b>Use an explicit structure, so your [% terms.bug %] reports are easy
-    to skim.</b> [% terms.Bug %] report users often need immediate access to 
-    specific sections of your [% terms.bug %]. Follow the structure 
-    recommended above.</p>
-
-    <p><b>Avoid cuteness if it costs clarity.</b> Nobody will be laughing
-    at your funny [% terms.bug %] title at 3:00 AM when they can't remember how 
-    to find your [% terms.bug %].</p>
-
-    <p><b>One [% terms.bug %] per report.</b> Completely different people 
-    typically fix, verify, and prioritize different [% terms.bugs %]. If you 
-    mix a handful of [% terms.bugs %] into a single report, the right people 
-    probably won't discover your [% terms.bugs %] in a timely fashion, if at 
-    all. Certain [% terms.bugs %] are also more important than others. It's 
-    impossible to prioritize [% terms.abug %] report when
-    it contains four different issues, all of differing importance.</p>
-
-    <p><b>No [% terms.bug %] is too trivial to report.</b> Unless you're 
-    reading the source code, you can't see actual software [% terms.bugs %], 
-    like a dangling pointer -- you'll see their visible manifestations, such 
-    as the segfault when the application finally crashes. Severe software 
-    problems can manifest themselves in superficially trivial ways. File them
-    anyway.<br>
-    </p>
-  </blockquote>
-
-  <p><b><a name="summary"></a>2. How and Why to Write Good [% terms.Bug %]
-  Summaries</b></p>
-
-  <blockquote>
-    <p><b>You want to make a good first impression on the [% terms.bug %]
-    recipient.</b> Just like a New York Times headline guides readers
-    towards a relevant article from dozens of choices, will 
-    your [% terms.bug %] summary suggest that your [% terms.bug %] report is 
-    worth reading from dozens or hundreds of choices?</p>
-
-    <p>Conversely, a vague [% terms.bug %] summary like <tt>install 
-    problem</tt> forces anyone reviewing installation [% terms.bugs %] to waste 
-    time opening up your [% terms.bug %] to determine whether it matters.</p>
-
-    <p><b>Your [% terms.bug %] will often be searched by its summary.</b> Just 
-    as you'd find web pages with Google by searching with keywords, so will other
-    people locate your [% terms.bugs %]. Descriptive [% terms.bug %] summaries are
-    naturally keyword-rich and easier to find.</p>
-
-    <p>For example, you'll find [% terms.abug %] titled "<tt>Dragging icons 
-    from List View to gnome-terminal doesn't paste path</tt>" if you search on
-    "List", "terminal", or "path". Those search keywords wouldn't have
-    found [% terms.abug %] titled "<tt>Dragging icons doesn't paste</tt>".</p>
-
-    <p>Ask yourself, "Would someone understand my [% terms.bug %] from just 
-    this summary?" If so, you've succeeded.</p>
-
-    <p><b>Don't write titles like these:</b></p>
-
-    <ol>
-      <li>"Can't install" - Why can't you install? What happens when you
-      try to install?</li>
-
-      <li>"Severe Performance Problems" - ...and they occur when you do
-      what?</li>
-
-      <li>"back button does not work" - Ever? At all?</li>
-    </ol>
-
-    <p><b>Good [% terms.bug %] titles:</b></p>
-
-    <ol>
-      <li>"Save button disabled after failed post attempt" -
-      Explains the problem and context.</li>
-
-      <li>"Enter &amp; Escape have no effect in 'Upload Photos' dialog" -
-      Also explains the problem and context.</li>
-    </ol>
-  </blockquote>
-</blockquote>
 
 [% INCLUDE global/footer.html.tmpl %]
diff --git a/template/en/default/pages/release-notes.html.tmpl b/template/en/default/pages/release-notes.html.tmpl
index 51d8e23..eb301c5 100644
--- a/template/en/default/pages/release-notes.html.tmpl
+++ b/template/en/default/pages/release-notes.html.tmpl
@@ -20,7 +20,7 @@
 
 [% PROCESS global/variables.none.tmpl %]
 [% INCLUDE global/header.html.tmpl 
-  title = "$terms.Bugzilla 3.0 Release Notes" 
+  title = "$terms.Bugzilla 3.0.2 Release Notes" 
   style_urls = ['skins/standard/release-notes.css'] 
 %]
 
@@ -28,9 +28,11 @@
 
 <ul class="bz_toc">
   <li><a href="#v30_introduction">Introduction</a></li>
+  <li><a href="#v30_point">Updates In This 3.0.x Release</a></li>
   <li><a href="#v30_req">Minimum Requirements</a></li>
   <li><a href="#v30_feat">New Features and Improvements</a></li>
-  <li><a href="#v30_issues">Outstanding Issues</a></li> 
+  <li><a href="#v30_issues">Outstanding Issues</a></li>
+  <li><a href="#v30_security">Security Fixes In This Release</a></li>
   <li><a href="#v30_upgrading">How to Upgrade From An Older Version</a></li>
   <li><a href="#v30_code_changes">Code Changes Which May Affect 
     Customizations</a></li>
@@ -51,6 +53,103 @@
   <a href="#v30_previous">previous versions</a> in between your version 
   and [% terms.Bugzilla %] 3.0.</p>
 
+<h2><a name="v30_point">Updates in this 3.0.x Release</a></h2>
+
+<p>This section describes what's changed in the most recent b<!-- -->ug-fix
+  releases of [% terms.Bugzilla %] after 3.0. We only list the
+  most important fixes in each release. If you want a detailed list of
+  <em>everything</em> that's changed in each version, you should use our
+  <a href="http://www.bugzilla.org/status/changes.html">Change Log Page</a>.</p>
+
+<h3>3.0.2</h3>
+
+<ul>
+  <li>[% terms.Bugzilla %] should now work on Perl 5.9.5 (and thus the
+    upcoming Perl 5.10.0).
+    (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=390442">[% terms.Bug %] 390442</a>)</li>
+</ul>
+
+<p>See also the <a href="#v30_security">Security Advisory</a> section for
+  information about an important security issue fixed in this release.</p>
+
+<h3>3.0.1</h3>
+
+<ul>
+  <li>For users of Firefox 2, the <code>show_bug.cgi</code> user interface
+    should no longer "collapse" after you modify a [% terms.bug %].
+    (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=370739">[% terms.Bug %] 370739</a>)</li>
+  <li>If you can bless a group, and you share a saved search with that
+    group, it will no longer automatically appear in all of that group's
+    footers unless you specifically request that it automatically appear
+    in their footers.
+    (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=365890">[% terms.Bug %] 365890</a>)</li>
+  <li>There is now a parameter to allow users to perform searches without
+    any search terms. (In other words, to search for just a Product
+    and Status on the Simple Search page.) The parameter is called
+    <code>specific_search_allow_empty_words</code>.
+    (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=385910">[% terms.Bug %] 385910</a>)</li>
+  <li>If you attach a file that has a MIME-type of <code>text/x-patch</code>
+    or <code>text/x-diff</code>, it will automatically be treated as a 
+    patch by [% terms.Bugzilla %].
+    (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=365756">[% terms.Bug %] 365756</a>)</li>
+  <li>Dependency Graphs now work correctly on all mod_perl installations.
+    There should now be no remaining signficant problems with running
+    [%+ terms.Bugzilla %] under mod_perl.
+    (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=370398">[% terms.Bug %] 370398</a>)</li>
+  <li>If moving a [% terms.bug %] between products would remove groups
+    from the [% terms.bug %], you are now warned.
+    (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=303183">[% terms.Bug %] 303183</a>)</li>
+  <li>On IIS, whenever [% terms.Bugzilla %] threw a warning, it would
+    actually appear on the web page. Now warnings are suppressed,
+    unless you have a file in the <code>data</code> directory called
+    <code>errorlog</code>, in which case warnings will be printed there.
+    (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=390148">[% terms.Bug %] 390148</a>)</li>
+  <li>If you used <kbd>email_in.pl</kbd> to edit [% terms.abug %] that was
+    protected by groups, all of the groups would be cleared.
+    (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=385453">[% terms.Bug %] 385453</a>)</li>
+  <li>PostgreSQL users: New Charts were failing to collect data over time.
+    They will now start collecting data correctly.
+    (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=257351">[% terms.Bug %] 257351</a>)</li>
+  <li>Some flag mails didn't specify who the requestee was. 
+    (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=379787">[% terms.Bug %] 379787</a>)</li>
+  <li>Instead of throwing real errors, <kbd>collectstats.pl</kbd> would
+    just say that it couldn't find <code>ThrowUserError</code>.
+    (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=380709">[% terms.Bug %] 380709</a>)</li>
+  <li>Logging into [% terms.Bugzilla %] from the home page works again
+    with IIS5. 
+    (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=364008">[% terms.Bug %] 364008</a>)</li>
+  <li>If you were using SMTP for sending email, sometimes emails would
+    be missing the <code>Date</code> header.
+    (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=304999">[% terms.Bug %] 304999</a>).</li>
+  <li>In the XML-RPC WebService, <code>B<!-- -->ug.legal_values</code> now
+    correctly returns values for custom fields if you request values 
+    for custom fields.
+    (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=381737">[% terms.Bug %] 381737</a>)</li>
+  <li>The "[% terms.Bug %]-Writing Guidelines" page has been shortened
+    and re-written.
+    (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=378590">[% terms.Bug %] 378590</a>)</li>
+  <li>If your <code>urlbase</code> parameter included a port number,
+    like <code>www.domain.com:8080</code>, SMTP might have failed.
+    (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=384501">[% terms.Bug %] 384501</a>)</li>
+  <li>For SMTP users, there is a new parameter, <code>smtp_debug</code>.
+    Turning on this parameter will log the full information about
+    every SMTP session to your web server's error log, to help with
+    debugging issues with SMTP.
+    (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=384497">[% terms.Bug %] 384497</a>)</li>
+  <li>If you are a "global watcher" (you get all mails from every 
+    [% terms.bug %]), you can now see that in your Email Preferences.
+    (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=365302">[% terms.Bug %] 365302</a>)</li>
+  <li>The Status and Resolution of [% terms.bugs %] are now correctly
+    localized in CSV search results.
+    (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=389517">[% terms.Bug %] 389517</a>)</li>
+  <li>The "Subject" line of an email was being mangled if it contained
+    non-Latin characters.
+    (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=387860">[% terms.Bug %] 387860</a>)</li>
+  <li>Editing the "languages" parameter using <kbd>editparams.cgi</kbd> would
+    sometimes fail, causing [% terms.Bugzilla %] to throw an error.
+    (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=335354">[% terms.Bug %] 335354</a>)</li>
+</ul>
+
 <h2><a name="v30_req"></a>Minimum Requirements</h2>
 
 <p>Any requirements that are new since 2.22 will look like
@@ -438,10 +537,6 @@
 <h2><a name="v30_issues"></a>Outstanding Issues</h2>
 
 <ul>
-  <li><a href="https://bugzilla.mozilla.org/show_bug.cgi?id=370739">
-    [%- terms.Bug %] 370739</a>: There is a problem in Firefox 2.0 that
-    sometimes causes the [% terms.bug %] editing page to render incorrectly
-    after editing a [% terms.bug %].</li>
   <li><a href="https://bugzilla.mozilla.org/show_bug.cgi?id=69621">
     [%- terms.Bug %] 69621</a>: If you rename or remove a keyword that is
     in use on [% terms.bugs %], you will need to rebuild the "keyword cache"
@@ -464,9 +559,8 @@
     groupings will not be updated if the group configuration
     for the Product changes.</li>
   <li><a href="https://bugzilla.mozilla.org/show_bug.cgi?id=370370">
-    [%- terms.Bug %] 370370</a>: mod_perl support may currently not
-    be working on Windows machines. Also, even when it does work,
-    editparams.cgi seems to crash on certain versions of mod_perl.</li>
+    [%- terms.Bug %] 370370</a>: mod_perl support is currently not
+    working on Windows machines.</li>
   <li><a href="https://bugzilla.mozilla.org/show_bug.cgi?id=361149">
     [%- terms.Bug %] 361149</a>: If you are using Perl 5.8.0, you may
     get a lot of warnings in your Apache error_log about "deprecated
@@ -480,6 +574,23 @@
     Search yourself.</li>
 </ul>
 
+<h2><a name="v30_security"></a>Security Updates in This Release</h2>
+
+<h3>3.0.2</h3>
+
+<p>[% terms.Bugzilla %] 3.0.1 had an important security fix that is
+  critical for public installations with "requirelogin" turned on.
+  For details, see the
+  <a href="http://www.bugzilla.org/security/3.0.1/">Security Advisory</a></p>
+
+<h3>3.0.1</h3>
+
+<p>[% terms.Bugzilla %] 3.0 had three security issues that have been
+  fixed in this release: one minor information leak, one hole only
+  exploitable by an admin or using <code>email_in.pl</code>, and one in an
+  uncommonly-used template. For details, see the 
+  <a href="http://www.bugzilla.org/security/2.20.4/">Security Advisory</a>.</p>
+
 <h2><a name="v30_upgrading"></a>How to Upgrade From An Older Version</h2>
 
 <h3>Notes For Upgraders</h3>
diff --git a/template/en/default/reports/chart.png.tmpl b/template/en/default/reports/chart.png.tmpl
index 119ff34..a3933e4 100644
--- a/template/en/default/reports/chart.png.tmpl
+++ b/template/en/default/reports/chart.png.tmpl
@@ -19,7 +19,7 @@
   # Contributor(s): Gervase Markham <gerv at gerv.net>
   #%]
 
-[% y_label = "Bugs" %]
+[% y_label = "$terms.Bugs" %]
 [% x_label = "Time" %]
 
 [% IF chart.cumulate %]
diff --git a/template/en/default/reports/report-simple.html.tmpl b/template/en/default/reports/report-simple.html.tmpl
index 04db73b..9ef8638 100644
--- a/template/en/default/reports/report-simple.html.tmpl
+++ b/template/en/default/reports/report-simple.html.tmpl
@@ -22,7 +22,7 @@
 
 <html>
 
-  [% title = "Bug List" %]
+  [% title = "$terms.Bug List" %]
 
   <head>
     <title>[% title FILTER html %]</title>
diff --git a/template/en/default/reports/report-table.html.tmpl b/template/en/default/reports/report-table.html.tmpl
index 60965d5..0456868 100644
--- a/template/en/default/reports/report-table.html.tmpl
+++ b/template/en/default/reports/report-table.html.tmpl
@@ -44,16 +44,11 @@
   [% tbl_field FILTER url_quote %]=[% tbl FILTER url_quote %][% END %]
 [% END %]
 
+[% IF tbl_field %]
+  <h2>[% tbl_disp FILTER html %]</h2>
+[% END %]
+
 <table>
-  [% IF tbl_field %]
-    <tr>
-      <td>
-      </td>
-      <td align="center">        
-        <h2>[% tbl_disp FILTER html %]</h2>
-      </td>
-    </tr>
-  [% END %]  
   <tr>
     <td>
     </td>
diff --git a/template/en/default/request/email.txt.tmpl b/template/en/default/request/email.txt.tmpl
index a5fd17b..7010f01 100644
--- a/template/en/default/request/email.txt.tmpl
+++ b/template/en/default/request/email.txt.tmpl
@@ -27,21 +27,23 @@
 [% attidsummary = attachment.id _ ': ' _ attachment.description %]
 [% statuses = { '+' => "granted" , '-' => 'denied' , 'X' => "canceled" ,
                 '?' => "asked" } %]
+
+[% to_identity = "" %]
 [% IF flag.status == '?' %]
-  [% to_identity = flag.addressee.identity _ " for" %]
+  [% to_identity = flag.requestee.identity _ " for" %]
   [% subject_status = "requested" %]
 [% ELSE %]
-  [% IF flag.addressee %]
-    [% to_identity = flag.addressee.identity _ "'s request for" %]
+  [% IF flag.requester %]
+    [% to_identity = flag.requester.identity _ "'s request for" %]
   [% END %]
   [% subject_status = statuses.${flag.status} %]
 [% END %]
 From: [% Param('mailfrom') %]
 To: [% to %]
 Subject: [% flag.type.name %] [%+ subject_status %]: [[% terms.Bug %] [%+ bug.bug_id %]] [% bug.short_desc %]
-X-Bugzilla-Type: request
 [%- IF attachment %] :
   [Attachment [% attachment.id %]] [% attachment.description %][% END %]
+X-Bugzilla-Type: request
 
 [%+ USE wrap -%]
 [%- FILTER bullet = wrap(80) -%]
diff --git a/template/en/default/search/knob.html.tmpl b/template/en/default/search/knob.html.tmpl
index 58c83fd..39ecaa1 100644
--- a/template/en/default/search/knob.html.tmpl
+++ b/template/en/default/search/knob.html.tmpl
@@ -32,7 +32,7 @@
         
 [% PROCESS global/variables.none.tmpl %]
 
-[%# This is not necessary for English templates, but useful for localisers. %]
+[%# This is not necessary for English templates, but useful for localizers. %]
 [% ordersdesc = {
    "Reuse same sort as last time" => "Reuse same sort as last time",
    "Bug Number"   => "$terms.Bug Number",
diff --git a/template/en/default/search/search-help.html.tmpl b/template/en/default/search/search-help.html.tmpl
index ef80fd3..3f39b97 100644
--- a/template/en/default/search/search-help.html.tmpl
+++ b/template/en/default/search/search-help.html.tmpl
@@ -70,7 +70,7 @@
 { id => "bug_severity", 
   html => "How severe the $terms.bug is, or whether it's an enhancement." },   
 { id => "priority", 
-  html => "Engineers prioritise their $terms.bugs using this field." },   
+  html => "Engineers prioritize their $terms.bugs using this field." },   
 { id => "rep_platform", 
   html => "The hardware platform the $terms.bug was observed on." },   
 { id => "op_sys", 
diff --git a/template/en/default/search/search-report-graph.html.tmpl b/template/en/default/search/search-report-graph.html.tmpl
index cfc585d..bab14ae 100644
--- a/template/en/default/search/search-report-graph.html.tmpl
+++ b/template/en/default/search/search-report-graph.html.tmpl
@@ -78,7 +78,7 @@ var queryform = "reportform"
         Individually<br>
         <input type="radio" name="cumulate" value="1"
         [% " checked" IF default.cumulate.0 == "1" %]>
-        Summed
+        Stacked
     </td>
     <td width="150" height="150">
       <table border="1" width="100%" height="100%">
diff --git a/template/en/default/search/search-specific.html.tmpl b/template/en/default/search/search-specific.html.tmpl
index d93abd8..5e3c938 100644
--- a/template/en/default/search/search-specific.html.tmpl
+++ b/template/en/default/search/search-specific.html.tmpl
@@ -109,12 +109,17 @@ for "crash secure SSL flash".
   <tr>
     <td></td>
     <td>
-      <input type="submit" id="search" value="Search"
+    
+      [% IF Param('specific_search_allow_empty_words') %]
+        <input type="submit" id="search" value="Search">
+      [% ELSE %]
+        <input type="submit" id="search" value="Search"
              onclick="if (this.form.content.value == '')
                       {alert('The Words field cannot be empty. You have to ' +
                              'enter at least one word in your search criteria.');
                        return false;} return true;">
-     </td>
+      [% END %]
+    </td>
   </tr>
 </table>
 </form>
diff --git a/template/en/default/sidebar.xul.tmpl b/template/en/default/sidebar.xul.tmpl
index 6742889..a93312f 100644
--- a/template/en/default/sidebar.xul.tmpl
+++ b/template/en/default/sidebar.xul.tmpl
@@ -72,7 +72,7 @@ function normal_keypress_handler( aEvent ) {
       <text class="text-link" onclick="load_relative_url('userprefs.cgi')" value="edit prefs"/>
   [%- IF user.groups.tweakparams %]
       <text class="text-link" onclick="load_relative_url('editparams.cgi')" value="edit params"/>
-      <text class="text-link" onclick="load_relative_url('editsettings.cgi')" value="edit user settings"/>
+      <text class="text-link" onclick="load_relative_url('editsettings.cgi')" value="edit default preferences"/>
   [%- END %]
   [%- IF user.groups.editusers || user.can_bless %]
       <text class="text-link" onclick="load_relative_url('editusers.cgi')" value="edit users"/>
diff --git a/template/en/default/whine/schedule.html.tmpl b/template/en/default/whine/schedule.html.tmpl
index 5994988..59a4096 100644
--- a/template/en/default/whine/schedule.html.tmpl
+++ b/template/en/default/whine/schedule.html.tmpl
@@ -86,7 +86,7 @@
 
 [% FOREACH event = events %]
 
-<table cellspacing="2px" cellpadding="2px" border="0" width="100%"
+<table cellspacing="2" cellpadding="2" width="100%"
        style="border: 1px solid;">
   <tr>
     <th align="left" bgcolor="#FFFFFF" colspan="2">
diff --git a/userprefs.cgi b/userprefs.cgi
index 564057e..8f2e69f 100755
--- a/userprefs.cgi
+++ b/userprefs.cgi
@@ -32,6 +32,7 @@ use Bugzilla::Search;
 use Bugzilla::Util;
 use Bugzilla::Error;
 use Bugzilla::User;
+use Bugzilla::Token;
 
 my $template = Bugzilla->template;
 local our $vars = {};
@@ -51,6 +52,9 @@ sub DoAccount {
 
     if(Bugzilla->params->{'allowemailchange'} 
        && Bugzilla->user->authorizer->can_change_email) {
+       # First delete old tokens.
+       Bugzilla::Token::CleanTokenTable();
+
         my @token = $dbh->selectrow_array(
             "SELECT tokentype, issuedate + " .
                     $dbh->sql_interval(MAX_TOKEN_AGE, 'DAY') . ", eventdata
@@ -78,8 +82,8 @@ sub SaveAccount {
     my $pwd1 = $cgi->param('new_password1');
     my $pwd2 = $cgi->param('new_password2');
 
-    if ($cgi->param('Bugzilla_password') ne "" || 
-        $pwd1 ne "" || $pwd2 ne "") 
+    if ($user->authorizer->can_change_password
+        && ($cgi->param('Bugzilla_password') ne "" || $pwd1 ne "" || $pwd2 ne ""))
     {
         my ($oldcryptedpwd) = $dbh->selectrow_array(
                         q{SELECT cryptpassword FROM profiles WHERE userid = ?},
@@ -111,7 +115,10 @@ sub SaveAccount {
         }
     }
 
-    if(Bugzilla->params->{"allowemailchange"} && $cgi->param('new_login_name')) {
+    if ($user->authorizer->can_change_email
+        && Bugzilla->params->{"allowemailchange"}
+        && $cgi->param('new_login_name'))
+    {
         my $old_login_name = $cgi->param('Bugzilla_login');
         my $new_login_name = trim($cgi->param('new_login_name'));
 
@@ -392,6 +399,7 @@ sub DoSavedSearches {
         $vars->{'queryshare_groups'} =
             Bugzilla::Group->new_from_list($user->queryshare_groups);
     }
+    $vars->{'bless_group_ids'} = [map {$_->{'id'}} @{$user->bless_groups}];
 }
 
 sub SaveSavedSearches {
@@ -451,10 +459,9 @@ sub SaveSavedSearches {
             }
 
             # If we're sharing our query with a group we can bless, we 
-            # subscribe direct group members to our search automatically.
-            # Otherwise, the group members need to opt in. This behaviour 
-            # is deemed most likely to fit users' needs.
-            if ($user->can_bless($group_id)) {
+            # have the ability to add link to our search to the footer of
+            # direct group members automatically.
+            if ($user->can_bless($group_id) && $cgi->param('force_' . $q->id)) {
                 my $group = new Bugzilla::Group($group_id);
                 my $members = $group->members_non_inherited;
                 foreach my $member (@$members) {
diff --git a/votes.cgi b/votes.cgi
index 43a693b..9805ae4 100755
--- a/votes.cgi
+++ b/votes.cgi
@@ -158,7 +158,7 @@ sub show_user {
 
         my $vote_list =
             $dbh->selectall_arrayref('SELECT votes.bug_id, votes.vote_count,
-                                             bugs.short_desc, bugs.bug_status
+                                             bugs.short_desc
                                         FROM votes
                                   INNER JOIN bugs
                                           ON votes.bug_id = bugs.bug_id
@@ -168,7 +168,7 @@ sub show_user {
                                       undef, ($who, $product->id));
 
         foreach (@$vote_list) {
-            my ($id, $count, $summary, $status) = @$_;
+            my ($id, $count, $summary) = @$_;
             $total += $count;
 
             # Next if user can't see this bug. So, the totals will be correct
@@ -179,8 +179,7 @@ sub show_user {
 
             push (@bugs, { id => $id, 
                            summary => $summary,
-                           count => $count,
-                           opened => is_open_state($status) });
+                           count => $count });
         }
 
         $onevoteonly = 1 if (min($product->votes_per_user,
diff --git a/whineatnews.pl b/whineatnews.pl
index 42df7be..12a86cb 100755
--- a/whineatnews.pl
+++ b/whineatnews.pl
@@ -20,6 +20,7 @@
 #
 # Contributor(s): Terry Weissman <terry at mozilla.org>
 #                 Joseph Heenan <joseph at heenan.me.uk>
+#                 Frédéric Buclin <LpSolit at gmail.com>
 
 
 # This is a script suitable for running once a day from a cron job.  It 
@@ -33,6 +34,7 @@ use lib '.';
 use Bugzilla;
 use Bugzilla::Mailer;
 use Bugzilla::Util;
+use Bugzilla::User;
 
 # Whining is disabled if whinedays is zero
 exit unless Bugzilla->params->{'whinedays'} >= 1;
@@ -68,9 +70,10 @@ foreach my $bug (@$slt_bugs) {
 
 
 foreach my $email (sort (keys %bugs)) {
-    my $vars = {
-        'email' => $email
-    };
+    my $user = new Bugzilla::User({name => $email});
+    next if $user->email_disabled;
+
+    my $vars = {'email' => $email};
 
     my @bugs = ();
     foreach my $i (@{$bugs{$email}}) {



More information about the wine-patches mailing list