+Gnus provides a few convenience functions and variables to allow
+easier insertion of X-Face headers in outgoing messages.
+
+@findex gnus-random-x-face
+@vindex gnus-convert-pbm-to-x-face-command
+@vindex gnus-x-face-directory
+@code{gnus-random-x-face} goes through all the @samp{pbm} files in
+@code{gnus-x-face-directory} and picks one at random, and then
+converts it to the X-Face format by using the
+@code{gnus-convert-pbm-to-x-face-command} shell command. The
+@samp{pbm} files should be 48x48 pixels big. It returns the X-Face
+header data as a string.
+
+@findex gnus-insert-random-x-face-header
+@code{gnus-insert-random-x-face-header} calls
+@code{gnus-random-x-face} and inserts a @samp{X-Face} header with the
+randomly generated data.
+
+@findex gnus-x-face-from-file
+@vindex gnus-convert-image-to-x-face-command
+@code{gnus-x-face-from-file} takes a GIF file as the parameter, and then
+converts the file to X-Face format by using the
+@code{gnus-convert-image-to-x-face-command} shell command.
+
+Here's how you would typically use the first function. Put something
+like the following in your @file{~/.gnus.el} file:
+
+@lisp
+(setq message-required-news-headers
+ (nconc message-required-news-headers
+ (list '(X-Face . gnus-random-x-face))))
+@end lisp
+
+Using the last function would be something like this:
+
+@lisp
+(setq message-required-news-headers
+ (nconc message-required-news-headers
+ (list '(X-Face . (lambda ()
+ (gnus-x-face-from-file
+ "~/My-face.gif"))))))
+@end lisp
+
+
+@node Face
+@subsection Face
+@cindex face
+
+@c #### FIXME: faces and x-faces'implementations should really be harmonized.
+
+@code{Face} headers are essentially a funkier version of @code{X-Face}
+ones. They describe a 48x48 pixel colored image that's supposed to
+represent the author of the message.
+
+@cindex face
+@findex gnus-article-display-face
+The contents of a @code{Face} header must be a base64 encoded PNG image.
+See @uref{http://quimby.gnus.org/circus/face/} for the precise
+specifications.
+
+The @code{gnus-face-properties-alist} variable affects the appearance of
+displayed Face images. @xref{X-Face}.
+
+Gnus provides a few convenience functions and variables to allow
+easier insertion of Face headers in outgoing messages.
+
+@findex gnus-convert-png-to-face
+@code{gnus-convert-png-to-face} takes a 48x48 PNG image, no longer than
+726 bytes long, and converts it to a face.
+
+@findex gnus-face-from-file
+@vindex gnus-convert-image-to-face-command
+@code{gnus-face-from-file} takes a JPEG file as the parameter, and then
+converts the file to Face format by using the
+@code{gnus-convert-image-to-face-command} shell command.
+
+Here's how you would typically use this function. Put something like the
+following in your @file{~/.gnus.el} file:
+
+@lisp
+(setq message-required-news-headers
+ (nconc message-required-news-headers
+ (list '(Face . (lambda ()
+ (gnus-face-from-file "~/face.jpg"))))))
+@end lisp
+
+
+@node Smileys
+@subsection Smileys
+@cindex smileys
+
+@iftex
+@iflatex
+\gnusfig{-3cm}{0.5cm}{\epsfig{figure=ps/BigFace,height=20cm}}
+\input{smiley}
+@end iflatex
+@end iftex
+
+@dfn{Smiley} is a package separate from Gnus, but since Gnus is
+currently the only package that uses Smiley, it is documented here.
+
+In short---to use Smiley in Gnus, put the following in your
+@file{~/.gnus.el} file:
+
+@lisp
+(setq gnus-treat-display-smileys t)
+@end lisp
+
+Smiley maps text smiley faces---@samp{:-)}, @samp{8-)}, @samp{:-(} and
+the like---to pictures and displays those instead of the text smiley
+faces. The conversion is controlled by a list of regexps that matches
+text and maps that to file names.
+
+@vindex smiley-regexp-alist
+The alist used is specified by the @code{smiley-regexp-alist}
+variable. The first item in each element is the regexp to be matched;
+the second element is the regexp match group that is to be replaced by
+the picture; and the third element is the name of the file to be
+displayed.
+
+The following variables customize where Smiley will look for these
+files:
+
+@table @code
+
+@item smiley-data-directory
+@vindex smiley-data-directory
+Where Smiley will look for smiley faces files.
+
+@item gnus-smiley-file-types
+@vindex gnus-smiley-file-types
+List of suffixes on smiley file names to try.
+
+@end table
+
+
+@node Picons
+@subsection Picons
+
+@iftex
+@iflatex
+\include{picons}
+@end iflatex
+@end iftex
+
+So@dots{} You want to slow down your news reader even more! This is a
+good way to do so. It's also a great way to impress people staring
+over your shoulder as you read news.
+
+What are Picons? To quote directly from the Picons Web site:
+
+@iftex
+@iflatex
+\margindex{}
+@end iflatex
+@end iftex
+
+@quotation
+@dfn{Picons} is short for ``personal icons''. They're small,
+constrained images used to represent users and domains on the net,
+organized into databases so that the appropriate image for a given
+e-mail address can be found. Besides users and domains, there are picon
+databases for Usenet newsgroups and weather forecasts. The picons are
+in either monochrome @code{XBM} format or color @code{XPM} and
+@code{GIF} formats.
+@end quotation
+
+@vindex gnus-picon-databases
+For instructions on obtaining and installing the picons databases,
+point your Web browser at
+@uref{http://www.cs.indiana.edu/picons/ftp/index.html}.
+
+If you are using Debian GNU/Linux, saying @samp{apt-get install
+picons.*} will install the picons where Gnus can find them.
+
+To enable displaying picons, simply make sure that
+@code{gnus-picon-databases} points to the directory containing the
+Picons databases.
+
+The following variables offer control over where things are located.
+
+@table @code
+
+@item gnus-picon-databases
+@vindex gnus-picon-databases
+The location of the picons database. This is a list of directories
+containing the @file{news}, @file{domains}, @file{users} (and so on)
+subdirectories. Defaults to @code{("/usr/lib/picon"
+"/usr/local/faces")}.
+
+@item gnus-picon-news-directories
+@vindex gnus-picon-news-directories
+List of subdirectories to search in @code{gnus-picon-databases} for
+newsgroups faces. @code{("news")} is the default.
+
+@item gnus-picon-user-directories
+@vindex gnus-picon-user-directories
+List of subdirectories to search in @code{gnus-picon-databases} for user
+faces. @code{("users" "usenix" "local" "misc")} is the default.
+
+@item gnus-picon-domain-directories
+@vindex gnus-picon-domain-directories
+List of subdirectories to search in @code{gnus-picon-databases} for
+domain name faces. Defaults to @code{("domains")}. Some people may
+want to add @samp{"unknown"} to this list.
+
+@item gnus-picon-file-types
+@vindex gnus-picon-file-types
+Ordered list of suffixes on picon file names to try. Defaults to
+@code{("xpm" "gif" "xbm")} minus those not built-in your Emacs.
+
+@end table
+
+
+@node XVarious
+@subsection Various XEmacs Variables
+
+@table @code
+@item gnus-xmas-glyph-directory
+@vindex gnus-xmas-glyph-directory
+This is where Gnus will look for pictures. Gnus will normally
+auto-detect this directory, but you may set it manually if you have an
+unusual directory structure.
+
+@item gnus-xmas-logo-color-alist
+@vindex gnus-xmas-logo-color-alist
+This is an alist where the key is a type symbol and the values are the
+foreground and background color of the splash page glyph.
+
+@item gnus-xmas-logo-color-style
+@vindex gnus-xmas-logo-color-style
+This is the key used to look up the color in the alist described above.
+Valid values include @code{flame}, @code{pine}, @code{moss},
+@code{irish}, @code{sky}, @code{tin}, @code{velvet}, @code{grape},
+@code{labia}, @code{berry}, @code{neutral}, and @code{september}.
+
+@item gnus-xmas-modeline-glyph
+@vindex gnus-xmas-modeline-glyph
+A glyph displayed in all Gnus mode lines. It is a tiny gnu head by
+default.
+
+@end table
+
+@subsubsection Toolbar
+
+@table @code
+
+@item gnus-use-toolbar
+@vindex gnus-use-toolbar
+If @code{nil}, don't display toolbars. If non-@code{nil}, it should be
+one of @code{default-toolbar}, @code{top-toolbar}, @code{bottom-toolbar},
+@code{right-toolbar}, or @code{left-toolbar}.
+
+@item gnus-group-toolbar
+@vindex gnus-group-toolbar
+The toolbar in the group buffer.
+
+@item gnus-summary-toolbar
+@vindex gnus-summary-toolbar
+The toolbar in the summary buffer.
+
+@item gnus-summary-mail-toolbar
+@vindex gnus-summary-mail-toolbar
+The toolbar in the summary buffer of mail groups.
+
+@end table
+
+@iftex
+@iflatex
+\margindex{}
+@end iflatex
+@end iftex
+
+
+@node Fuzzy Matching
+@section Fuzzy Matching
+@cindex fuzzy matching
+
+Gnus provides @dfn{fuzzy matching} of @code{Subject} lines when doing
+things like scoring, thread gathering and thread comparison.
+
+As opposed to regular expression matching, fuzzy matching is very fuzzy.
+It's so fuzzy that there's not even a definition of what @dfn{fuzziness}
+means, and the implementation has changed over time.
+
+Basically, it tries to remove all noise from lines before comparing.
+@samp{Re: }, parenthetical remarks, white space, and so on, are filtered
+out of the strings before comparing the results. This often leads to
+adequate results---even when faced with strings generated by text
+manglers masquerading as newsreaders.
+
+
+@node Thwarting Email Spam
+@section Thwarting Email Spam
+@cindex email spam
+@cindex spam
+@cindex UCE
+@cindex unsolicited commercial email
+
+In these last days of the Usenet, commercial vultures are hanging about
+and grepping through news like crazy to find email addresses they can
+foist off their scams and products to. As a reaction to this, many
+people have started putting nonsense addresses into their @code{From}
+lines. I think this is counterproductive---it makes it difficult for
+people to send you legitimate mail in response to things you write, as
+well as making it difficult to see who wrote what. This rewriting may
+perhaps be a bigger menace than the unsolicited commercial email itself
+in the end.
+
+The biggest problem I have with email spam is that it comes in under
+false pretenses. I press @kbd{g} and Gnus merrily informs me that I
+have 10 new emails. I say ``Golly gee! Happy is me!'' and select the
+mail group, only to find two pyramid schemes, seven advertisements
+(``New! Miracle tonic for growing full, lustrous hair on your toes!'')
+and one mail asking me to repent and find some god.
+
+This is annoying. Here's what you can do about it.
+
+@menu
+* The problem of spam:: Some background, and some solutions
+* Anti-Spam Basics:: Simple steps to reduce the amount of spam.
+* SpamAssassin:: How to use external anti-spam tools.
+* Hashcash:: Reduce spam by burning CPU time.
+* Filtering Spam Using The Spam ELisp Package::
+* Filtering Spam Using Statistics with spam-stat::
+@end menu
+
+@node The problem of spam
+@subsection The problem of spam
+@cindex email spam
+@cindex spam filtering approaches
+@cindex filtering approaches, spam
+@cindex UCE
+@cindex unsolicited commercial email
+
+First, some background on spam.
+
+If you have access to e-mail, you are familiar with spam (technically
+termed @acronym{UCE}, Unsolicited Commercial E-mail). Simply put, it
+exists because e-mail delivery is very cheap compared to paper mail,
+so only a very small percentage of people need to respond to an UCE to
+make it worthwhile to the advertiser. Ironically, one of the most
+common spams is the one offering a database of e-mail addresses for
+further spamming. Senders of spam are usually called @emph{spammers},
+but terms like @emph{vermin}, @emph{scum}, @emph{sociopaths}, and
+@emph{morons} are in common use as well.
+
+Spam comes from a wide variety of sources. It is simply impossible to
+dispose of all spam without discarding useful messages. A good
+example is the TMDA system, which requires senders
+unknown to you to confirm themselves as legitimate senders before
+their e-mail can reach you. Without getting into the technical side
+of TMDA, a downside is clearly that e-mail from legitimate sources may
+be discarded if those sources can't or won't confirm themselves
+through the TMDA system. Another problem with TMDA is that it
+requires its users to have a basic understanding of e-mail delivery
+and processing.
+
+The simplest approach to filtering spam is filtering, at the mail
+server or when you sort through incoming mail. If you get 200 spam
+messages per day from @samp{random-address@@vmadmin.com}, you block
+@samp{vmadmin.com}. If you get 200 messages about @samp{VIAGRA}, you
+discard all messages with @samp{VIAGRA} in the message. If you get
+lots of spam from Bulgaria, for example, you try to filter all mail
+from Bulgarian IPs.
+
+This, unfortunately, is a great way to discard legitimate e-mail. The
+risks of blocking a whole country (Bulgaria, Norway, Nigeria, China,
+etc.) or even a continent (Asia, Africa, Europe, etc.) from contacting
+you should be obvious, so don't do it if you have the choice.
+
+In another instance, the very informative and useful RISKS digest has
+been blocked by overzealous mail filters because it @strong{contained}
+words that were common in spam messages. Nevertheless, in isolated
+cases, with great care, direct filtering of mail can be useful.
+
+Another approach to filtering e-mail is the distributed spam
+processing, for instance DCC implements such a system. In essence,
+@var{N} systems around the world agree that a machine @var{X} in
+Ghana, Estonia, or California is sending out spam e-mail, and these
+@var{N} systems enter @var{X} or the spam e-mail from @var{X} into a
+database. The criteria for spam detection vary---it may be the number
+of messages sent, the content of the messages, and so on. When a user
+of the distributed processing system wants to find out if a message is
+spam, he consults one of those @var{N} systems.
+
+Distributed spam processing works very well against spammers that send
+a large number of messages at once, but it requires the user to set up
+fairly complicated checks. There are commercial and free distributed
+spam processing systems. Distributed spam processing has its risks as
+well. For instance legitimate e-mail senders have been accused of
+sending spam, and their web sites and mailing lists have been shut
+down for some time because of the incident.
+
+The statistical approach to spam filtering is also popular. It is
+based on a statistical analysis of previous spam messages. Usually
+the analysis is a simple word frequency count, with perhaps pairs of
+words or 3-word combinations thrown into the mix. Statistical
+analysis of spam works very well in most of the cases, but it can
+classify legitimate e-mail as spam in some cases. It takes time to
+run the analysis, the full message must be analyzed, and the user has
+to store the database of spam analyses. Statistical analysis on the
+server is gaining popularity. This has the advantage of letting the
+user Just Read Mail, but has the disadvantage that it's harder to tell
+the server that it has misclassified mail.
+
+Fighting spam is not easy, no matter what anyone says. There is no
+magic switch that will distinguish Viagra ads from Mom's e-mails.
+Even people are having a hard time telling spam apart from non-spam,
+because spammers are actively looking to fool us into thinking they
+are Mom, essentially. Spamming is irritating, irresponsible, and
+idiotic behavior from a bunch of people who think the world owes them
+a favor. We hope the following sections will help you in fighting the
+spam plague.
+
+@node Anti-Spam Basics
+@subsection Anti-Spam Basics
+@cindex email spam
+@cindex spam
+@cindex UCE
+@cindex unsolicited commercial email
+
+One way of dealing with spam is having Gnus split out all spam into a
+@samp{spam} mail group (@pxref{Splitting Mail}).
+
+First, pick one (1) valid mail address that you can be reached at, and
+put it in your @code{From} header of all your news articles. (I've
+chosen @samp{larsi@@trym.ifi.uio.no}, but for many addresses on the form
+@samp{larsi+usenet@@ifi.uio.no} will be a better choice. Ask your
+sysadmin whether your sendmail installation accepts keywords in the local
+part of the mail address.)
+
+@lisp
+(setq message-default-news-headers
+ "From: Lars Magne Ingebrigtsen <larsi@@trym.ifi.uio.no>\n")
+@end lisp
+
+Then put the following split rule in @code{nnmail-split-fancy}
+(@pxref{Fancy Mail Splitting}):
+
+@lisp
+(...
+ (to "larsi@@trym.ifi.uio.no"
+ (| ("subject" "re:.*" "misc")
+ ("references" ".*@@.*" "misc")
+ "spam"))
+ ...)
+@end lisp
+
+This says that all mail to this address is suspect, but if it has a
+@code{Subject} that starts with a @samp{Re:} or has a @code{References}
+header, it's probably ok. All the rest goes to the @samp{spam} group.
+(This idea probably comes from Tim Pierce.)
+
+In addition, many mail spammers talk directly to your @acronym{SMTP} server
+and do not include your email address explicitly in the @code{To}
+header. Why they do this is unknown---perhaps it's to thwart this
+thwarting scheme? In any case, this is trivial to deal with---you just
+put anything not addressed to you in the @samp{spam} group by ending
+your fancy split rule in this way:
+
+@lisp
+(
+ ...
+ (to "larsi" "misc")
+ "spam")
+@end lisp
+
+In my experience, this will sort virtually everything into the right
+group. You still have to check the @samp{spam} group from time to time to
+check for legitimate mail, though. If you feel like being a good net
+citizen, you can even send off complaints to the proper authorities on
+each unsolicited commercial email---at your leisure.
+
+This works for me. It allows people an easy way to contact me (they can
+just press @kbd{r} in the usual way), and I'm not bothered at all with
+spam. It's a win-win situation. Forging @code{From} headers to point
+to non-existent domains is yucky, in my opinion.
+
+Be careful with this approach. Spammers are wise to it.
+
+
+@node SpamAssassin
+@subsection SpamAssassin, Vipul's Razor, DCC, etc
+@cindex SpamAssassin
+@cindex Vipul's Razor
+@cindex DCC
+
+The days where the hints in the previous section were sufficient in
+avoiding spam are coming to an end. There are many tools out there
+that claim to reduce the amount of spam you get. This section could
+easily become outdated fast, as new products replace old, but
+fortunately most of these tools seem to have similar interfaces. Even
+though this section will use SpamAssassin as an example, it should be
+easy to adapt it to most other tools.
+
+Note that this section does not involve the @code{spam.el} package,
+which is discussed in the next section. If you don't care for all
+the features of @code{spam.el}, you can make do with these simple
+recipes.
+
+If the tool you are using is not installed on the mail server, you
+need to invoke it yourself. Ideas on how to use the
+@code{:postscript} mail source parameter (@pxref{Mail Source
+Specifiers}) follow.
+
+@lisp
+(setq mail-sources
+ '((file :prescript "formail -bs spamassassin < /var/mail/%u")
+ (pop :user "jrl"
+ :server "pophost"
+ :postscript
+ "mv %t /tmp/foo; formail -bs spamc < /tmp/foo > %t")))
+@end lisp
+
+Once you manage to process your incoming spool somehow, thus making
+the mail contain e.g.@: a header indicating it is spam, you are ready to
+filter it out. Using normal split methods (@pxref{Splitting Mail}):
+
+@lisp
+(setq nnmail-split-methods '(("spam" "^X-Spam-Flag: YES")
+ ...))
+@end lisp
+
+Or using fancy split methods (@pxref{Fancy Mail Splitting}):
+
+@lisp
+(setq nnmail-split-methods 'nnmail-split-fancy
+ nnmail-split-fancy '(| ("X-Spam-Flag" "YES" "spam")
+ ...))
+@end lisp
+
+Some people might not like the idea of piping the mail through various
+programs using a @code{:prescript} (if some program is buggy, you
+might lose all mail). If you are one of them, another solution is to
+call the external tools during splitting. Example fancy split method:
+
+@lisp
+(setq nnmail-split-fancy '(| (: kevin-spamassassin)
+ ...))
+(defun kevin-spamassassin ()
+ (save-excursion
+ (save-restriction
+ (widen)
+ (if (eq 1 (call-process-region (point-min) (point-max)
+ "spamc" nil nil nil "-c"))
+ "spam"))))
+@end lisp
+
+Note that with the nnimap backend, message bodies will not be
+downloaded by default. You need to set
+@code{nnimap-split-download-body} to @code{t} to do that
+(@pxref{Splitting in IMAP}).
+
+That is about it. As some spam is likely to get through anyway, you
+might want to have a nifty function to call when you happen to read
+spam. And here is the nifty function:
+
+@lisp
+ (defun my-gnus-raze-spam ()
+ "Submit SPAM to Vipul's Razor, then mark it as expirable."
+ (interactive)
+ (gnus-summary-show-raw-article)
+ (gnus-summary-save-in-pipe "razor-report -f -d")
+ (gnus-summary-mark-as-expirable 1))
+@end lisp
+
+@node Hashcash
+@subsection Hashcash
+@cindex hashcash
+
+A novel technique to fight spam is to require senders to do something
+costly for each message they send. This has the obvious drawback that
+you cannot rely on everyone in the world using this technique,
+since it is not part of the Internet standards, but it may be useful
+in smaller communities.
+
+While the tools in the previous section work well in practice, they
+work only because the tools are constantly maintained and updated as
+new form of spam appears. This means that a small percentage of spam
+will always get through. It also means that somewhere, someone needs
+to read lots of spam to update these tools. Hashcash avoids that, but
+instead prefers that everyone you contact through e-mail supports the
+scheme. You can view the two approaches as pragmatic vs dogmatic.
+The approaches have their own advantages and disadvantages, but as
+often in the real world, a combination of them is stronger than either
+one of them separately.
+
+@cindex X-Hashcash
+The ``something costly'' is to burn CPU time, more specifically to
+compute a hash collision up to a certain number of bits. The
+resulting hashcash cookie is inserted in a @samp{X-Hashcash:}
+header. For more details, and for the external application
+@code{hashcash} you need to install to use this feature, see
+@uref{http://www.cypherspace.org/~adam/hashcash/}. Even more
+information can be found at @uref{http://www.camram.org/}.
+
+If you wish to call hashcash for each message you send, say something
+like:
+
+@lisp
+(require 'hashcash)
+(add-hook 'message-send-hook 'mail-add-payment)
+@end lisp
+
+The @file{hashcash.el} library can be found in the Gnus development
+contrib directory or at
+@uref{http://users.actrix.gen.nz/mycroft/hashcash.el}.
+
+You will need to set up some additional variables as well:
+
+@table @code
+
+@item hashcash-default-payment
+@vindex hashcash-default-payment
+This variable indicates the default number of bits the hash collision
+should consist of. By default this is 0, meaning nothing will be
+done. Suggested useful values include 17 to 29.
+
+@item hashcash-payment-alist
+@vindex hashcash-payment-alist
+Some receivers may require you to spend burn more CPU time than the
+default. This variable contains a list of @samp{(@var{addr}
+@var{amount})} cells, where @var{addr} is the receiver (email address
+or newsgroup) and @var{amount} is the number of bits in the collision
+that is needed. It can also contain @samp{(@var{addr} @var{string}
+@var{amount})} cells, where the @var{string} is the string to use
+(normally the email address or newsgroup name is used).
+
+@item hashcash
+@vindex hashcash
+Where the @code{hashcash} binary is installed.
+
+@end table
+
+Currently there is no built in functionality in Gnus to verify
+hashcash cookies, it is expected that this is performed by your hand
+customized mail filtering scripts. Improvements in this area would be
+a useful contribution, however.
+
+@node Filtering Spam Using The Spam ELisp Package
+@subsection Filtering Spam Using The Spam ELisp Package
+@cindex spam filtering
+@cindex spam
+
+The idea behind @file{spam.el} is to have a control center for spam detection
+and filtering in Gnus. To that end, @file{spam.el} does two things: it
+filters new mail, and it analyzes mail known to be spam or ham.
+@dfn{Ham} is the name used throughout @file{spam.el} to indicate
+non-spam messages.
+
+First of all, you @strong{must} run the function
+@code{spam-initialize} to autoload @code{spam.el} and to install the
+@code{spam.el} hooks. There is one exception: if you use the
+@code{spam-use-stat} (@pxref{spam-stat spam filtering}) setting, you
+should turn it on before @code{spam-initialize}:
+
+@example
+(setq spam-use-stat t) ;; if needed
+(spam-initialize)
+@end example
+
+So, what happens when you load @file{spam.el}?
+
+First, some hooks will get installed by @code{spam-initialize}. There
+are some hooks for @code{spam-stat} so it can save its databases, and
+there are hooks so interesting things will happen when you enter and
+leave a group. More on the sequence of events later (@pxref{Spam
+ELisp Package Sequence of Events}).
+
+You get the following keyboard commands:
+
+@table @kbd
+
+@item M-d
+@itemx M s x
+@itemx S x
+@kindex M-d
+@kindex S x
+@kindex M s x
+@findex gnus-summary-mark-as-spam
+@code{gnus-summary-mark-as-spam}.
+
+Mark current article as spam, showing it with the @samp{$} mark.
+Whenever you see a spam article, make sure to mark its summary line
+with @kbd{M-d} before leaving the group. This is done automatically
+for unread articles in @emph{spam} groups.
+
+@item M s t
+@itemx S t
+@kindex M s t
+@kindex S t
+@findex spam-bogofilter-score
+@code{spam-bogofilter-score}.
+
+You must have Bogofilter installed for that command to work properly.
+
+@xref{Bogofilter}.
+
+@end table
+
+Also, when you load @file{spam.el}, you will be able to customize its
+variables. Try @code{customize-group} on the @samp{spam} variable
+group.
+
+@menu
+* Spam ELisp Package Sequence of Events::
+* Spam ELisp Package Filtering of Incoming Mail::
+* Spam ELisp Package Global Variables::
+* Spam ELisp Package Configuration Examples::
+* Blacklists and Whitelists::
+* BBDB Whitelists::
+* Gmane Spam Reporting::
+* Anti-spam Hashcash Payments::
+* Blackholes::
+* Regular Expressions Header Matching::
+* Bogofilter::
+* SpamAssassin backend::
+* ifile spam filtering::
+* spam-stat spam filtering::
+* SpamOracle::
+* Extending the Spam ELisp package::
+@end menu
+
+@node Spam ELisp Package Sequence of Events
+@subsubsection Spam ELisp Package Sequence of Events
+@cindex spam filtering
+@cindex spam filtering sequence of events
+@cindex spam
+
+You must read this section to understand how @code{spam.el} works.
+Do not skip, speed-read, or glance through this section.
+
+There are two @emph{contact points}, if you will, between
+@code{spam.el} and the rest of Gnus: checking new mail for spam, and
+leaving a group.
+
+Getting new mail is done in one of two ways. You can either split
+your incoming mail or you can classify new articles as ham or spam
+when you enter the group.
+
+Splitting incoming mail is better suited to mail backends such as
+@code{nnml} or @code{nnimap} where new mail appears in a single file
+called a @dfn{Spool File}. See @xref{Spam ELisp Package Filtering of
+Incoming Mail}.
+
+@vindex gnus-spam-autodetect
+@vindex gnus-spam-autodetect-methods
+For backends such as @code{nntp} there is no incoming mail spool, so
+an alternate mechanism must be used. This may also happen for
+backends where the server is in charge of splitting incoming mail, and
+Gnus does not do further splitting. The @code{spam-autodetect} and
+@code{spam-autodetect-methods} group parameters (accessible with
+@kbd{G c} and @kbd{G p} as usual), and the corresponding variables
+@code{gnus-spam-autodetect} and @code{gnus-spam-autodetect-methods}
+(accessible with @kbd{M-x customize-variable} as usual) can help.
+
+When @code{spam-autodetect} is used (you can turn it on for a
+group/topic or wholesale by regex, as needed), it hooks into the
+process of entering a group. Thus, entering a group with unseen or
+unread articles becomes the substitute for checking incoming mail.
+Whether only unseen articles or all unread articles will be processed
+is determined by the @code{spam-autodetect-recheck-messages}. When
+set to @code{t}, unread messages will be rechecked.
+
+@code{spam-autodetect} grants the user at once more and less control
+of spam filtering. The user will have more control over each group's
+spam methods, so for instance the @samp{ding} group may have
+@code{spam-use-BBDB} as the autodetection method, while the
+@samp{suspect} group may have the @code{spam-use-blacklist} and
+@code{spam-use-bogofilter} methods enabled. Every article detected to
+be spam will be marked with the spam mark @samp{$} and processed on
+exit from the group as normal spam. The user has less control over
+the @emph{sequence} of checks, as he might with @code{spam-split}.
+
+When the newly split mail goes into groups, or messages are
+autodetected to be ham or spam, those groups must be exited (after
+entering, if needed) for further spam processing to happen. It
+matters whether the group is considered a ham group, a spam group, or
+is unclassified, based on its @code{spam-content} parameter
+(@pxref{Spam ELisp Package Global Variables}). Spam groups have the
+additional characteristic that, when entered, any unseen or unread
+articles (depending on the @code{spam-mark-only-unseen-as-spam}
+variable) will be marked as spam. Thus, mail split into a spam group
+gets automatically marked as spam when you enter the group.
+
+So, when you exit a group, the @code{spam-processors} are applied, if
+any are set, and the processed mail is moved to the
+@code{ham-process-destination} or the @code{spam-process-destination}
+depending on the article's classification. If the
+@code{ham-process-destination} or the @code{spam-process-destination},
+whichever is appropriate, are @code{nil}, the article is left in the
+current group.
+
+If a spam is found in any group (this can be changed to only non-spam
+groups with @code{spam-move-spam-nonspam-groups-only}), it is
+processed by the active @code{spam-processors} (@pxref{Spam ELisp
+Package Global Variables}) when the group is exited. Furthermore, the
+spam is moved to the @code{spam-process-destination} (@pxref{Spam
+ELisp Package Global Variables}) for further training or deletion.
+You have to load the @code{gnus-registry.el} package and enable the
+@code{spam-log-to-registry} variable if you want spam to be processed
+no more than once. Thus, spam is detected and processed everywhere,
+which is what most people want. If the
+@code{spam-process-destination} is @code{nil}, the spam is marked as
+expired, which is usually the right thing to do.
+
+If spam can not be moved---because of a read-only backend such as
+@acronym{NNTP}, for example, it will be copied.
+
+If a ham mail is found in a ham group, as determined by the
+@code{ham-marks} parameter, it is processed as ham by the active ham
+@code{spam-processor} when the group is exited. With the variables
+@code{spam-process-ham-in-spam-groups} and
+@code{spam-process-ham-in-nonham-groups} the behavior can be further
+altered so ham found anywhere can be processed. You have to load the
+@code{gnus-registry.el} package and enable the
+@code{spam-log-to-registry} variable if you want ham to be processed
+no more than once. Thus, ham is detected and processed only when
+necessary, which is what most people want. More on this in
+@xref{Spam ELisp Package Configuration Examples}.
+
+If ham can not be moved---because of a read-only backend such as
+@acronym{NNTP}, for example, it will be copied.
+
+If all this seems confusing, don't worry. Soon it will be as natural
+as typing Lisp one-liners on a neural interface@dots{} err, sorry, that's
+50 years in the future yet. Just trust us, it's not so bad.
+
+@node Spam ELisp Package Filtering of Incoming Mail
+@subsubsection Spam ELisp Package Filtering of Incoming Mail
+@cindex spam filtering
+@cindex spam filtering incoming mail
+@cindex spam
+
+To use the @file{spam.el} facilities for incoming mail filtering, you
+must add the following to your fancy split list
+@code{nnmail-split-fancy} or @code{nnimap-split-fancy}:
+
+@example
+(: spam-split)
+@end example
+
+Note that the fancy split may be called @code{nnmail-split-fancy} or
+@code{nnimap-split-fancy}, depending on whether you use the nnmail or
+nnimap back ends to retrieve your mail.
+
+Also, @code{spam-split} will not modify incoming mail in any way.
+
+The @code{spam-split} function will process incoming mail and send the
+mail considered to be spam into the group name given by the variable
+@code{spam-split-group}. By default that group name is @samp{spam},
+but you can customize @code{spam-split-group}. Make sure the contents
+of @code{spam-split-group} are an @emph{unqualified} group name, for
+instance in an @code{nnimap} server @samp{your-server} the value
+@samp{spam} will turn out to be @samp{nnimap+your-server:spam}. The
+value @samp{nnimap+server:spam}, therefore, is wrong and will
+actually give you the group
+@samp{nnimap+your-server:nnimap+server:spam} which may or may not
+work depending on your server's tolerance for strange group names.
+
+You can also give @code{spam-split} a parameter,
+e.g. @code{spam-use-regex-headers} or @code{"maybe-spam"}. Why is
+this useful?
+
+Take these split rules (with @code{spam-use-regex-headers} and
+@code{spam-use-blackholes} set):
+
+@example
+ nnimap-split-fancy '(|
+ (any "ding" "ding")
+ (: spam-split)
+ ;; @r{default mailbox}
+ "mail")
+@end example
+
+Now, the problem is that you want all ding messages to make it to the
+ding folder. But that will let obvious spam (for example, spam
+detected by SpamAssassin, and @code{spam-use-regex-headers}) through,
+when it's sent to the ding list. On the other hand, some messages to
+the ding list are from a mail server in the blackhole list, so the
+invocation of @code{spam-split} can't be before the ding rule.
+
+You can let SpamAssassin headers supersede ding rules, but all other
+@code{spam-split} rules (including a second invocation of the
+regex-headers check) will be after the ding rule:
+
+@example
+nnimap-split-fancy
+ '(|
+ ;; @r{all spam detected by @code{spam-use-regex-headers} goes to @samp{regex-spam}}
+ (: spam-split "regex-spam" 'spam-use-regex-headers)
+ (any "ding" "ding")
+ ;; @r{all other spam detected by spam-split goes to @code{spam-split-group}}
+ (: spam-split)
+ ;; @r{default mailbox}
+ "mail")
+@end example
+
+This lets you invoke specific @code{spam-split} checks depending on
+your particular needs, and to target the results of those checks to a
+particular spam group. You don't have to throw all mail into all the
+spam tests. Another reason why this is nice is that messages to
+mailing lists you have rules for don't have to have resource-intensive
+blackhole checks performed on them. You could also specify different
+spam checks for your nnmail split vs. your nnimap split. Go crazy.
+
+You should still have specific checks such as
+@code{spam-use-regex-headers} set to @code{t}, even if you
+specifically invoke @code{spam-split} with the check. The reason is
+that when loading @file{spam.el}, some conditional loading is done
+depending on what @code{spam-use-xyz} variables you have set. This
+is usually not critical, though.
+
+@emph{Note for IMAP users}
+
+The boolean variable @code{nnimap-split-download-body} needs to be
+set, if you want to split based on the whole message instead of just
+the headers. By default, the nnimap back end will only retrieve the
+message headers. If you use @code{spam-check-bogofilter},
+@code{spam-check-ifile}, or @code{spam-check-stat} (the splitters that
+can benefit from the full message body), you should set this variable.
+It is not set by default because it will slow @acronym{IMAP} down, and
+that is not an appropriate decision to make on behalf of the user.
+
+@xref{Splitting in IMAP}.
+
+@emph{TODO: spam.el needs to provide a uniform way of training all the
+statistical databases. Some have that functionality built-in, others
+don't.}
+
+@node Spam ELisp Package Global Variables
+@subsubsection Spam ELisp Package Global Variables
+@cindex spam filtering
+@cindex spam filtering variables
+@cindex spam variables
+@cindex spam
+
+@vindex gnus-spam-process-newsgroups
+The concepts of ham processors and spam processors are very important.
+Ham processors and spam processors for a group can be set with the
+@code{spam-process} group parameter, or the
+@code{gnus-spam-process-newsgroups} variable. Ham processors take
+mail known to be non-spam (@emph{ham}) and process it in some way so
+that later similar mail will also be considered non-spam. Spam
+processors take mail known to be spam and process it so similar spam
+will be detected later.
+
+The format of the spam or ham processor entry used to be a symbol,
+but now it is a @sc{cons} cell. See the individual spam processor entries
+for more information.
+
+@vindex gnus-spam-newsgroup-contents
+Gnus learns from the spam you get. You have to collect your spam in
+one or more spam groups, and set or customize the variable
+@code{spam-junk-mailgroups} as appropriate. You can also declare
+groups to contain spam by setting their group parameter
+@code{spam-contents} to @code{gnus-group-spam-classification-spam}, or
+by customizing the corresponding variable
+@code{gnus-spam-newsgroup-contents}. The @code{spam-contents} group
+parameter and the @code{gnus-spam-newsgroup-contents} variable can
+also be used to declare groups as @emph{ham} groups if you set their
+classification to @code{gnus-group-spam-classification-ham}. If
+groups are not classified by means of @code{spam-junk-mailgroups},
+@code{spam-contents}, or @code{gnus-spam-newsgroup-contents}, they are
+considered @emph{unclassified}. All groups are unclassified by
+default.
+
+@vindex gnus-spam-mark
+@cindex $
+In spam groups, all messages are considered to be spam by default:
+they get the @samp{$} mark (@code{gnus-spam-mark}) when you enter the
+group. If you have seen a message, had it marked as spam, then
+unmarked it, it won't be marked as spam when you enter the group
+thereafter. You can disable that behavior, so all unread messages
+will get the @samp{$} mark, if you set the
+@code{spam-mark-only-unseen-as-spam} parameter to @code{nil}. You
+should remove the @samp{$} mark when you are in the group summary
+buffer for every message that is not spam after all. To remove the
+@samp{$} mark, you can use @kbd{M-u} to ``unread'' the article, or
+@kbd{d} for declaring it read the non-spam way. When you leave a
+group, all spam-marked (@samp{$}) articles are sent to a spam
+processor which will study them as spam samples.
+
+Messages may also be deleted in various other ways, and unless
+@code{ham-marks} group parameter gets overridden below, marks @samp{R}
+and @samp{r} for default read or explicit delete, marks @samp{X} and
+@samp{K} for automatic or explicit kills, as well as mark @samp{Y} for
+low scores, are all considered to be associated with articles which
+are not spam. This assumption might be false, in particular if you
+use kill files or score files as means for detecting genuine spam, you
+should then adjust the @code{ham-marks} group parameter.
+
+@defvar ham-marks
+You can customize this group or topic parameter to be the list of
+marks you want to consider ham. By default, the list contains the
+deleted, read, killed, kill-filed, and low-score marks (the idea is
+that these articles have been read, but are not spam). It can be
+useful to also include the tick mark in the ham marks. It is not
+recommended to make the unread mark a ham mark, because it normally
+indicates a lack of classification. But you can do it, and we'll be
+happy for you.
+@end defvar
+
+@defvar spam-marks
+You can customize this group or topic parameter to be the list of
+marks you want to consider spam. By default, the list contains only
+the spam mark. It is not recommended to change that, but you can if
+you really want to.
+@end defvar
+
+When you leave @emph{any} group, regardless of its
+@code{spam-contents} classification, all spam-marked articles are sent
+to a spam processor, which will study these as spam samples. If you
+explicit kill a lot, you might sometimes end up with articles marked
+@samp{K} which you never saw, and which might accidentally contain
+spam. Best is to make sure that real spam is marked with @samp{$},
+and nothing else.
+
+@vindex gnus-ham-process-destinations
+When you leave a @emph{spam} group, all spam-marked articles are
+marked as expired after processing with the spam processor. This is
+not done for @emph{unclassified} or @emph{ham} groups. Also, any
+@strong{ham} articles in a spam group will be moved to a location
+determined by either the @code{ham-process-destination} group
+parameter or a match in the @code{gnus-ham-process-destinations}
+variable, which is a list of regular expressions matched with group
+names (it's easiest to customize this variable with @kbd{M-x
+customize-variable @key{RET} gnus-ham-process-destinations}). Each
+group name list is a standard Lisp list, if you prefer to customize
+the variable manually. If the @code{ham-process-destination}
+parameter is not set, ham articles are left in place. If the
+@code{spam-mark-ham-unread-before-move-from-spam-group} parameter is
+set, the ham articles are marked as unread before being moved.
+
+If ham can not be moved---because of a read-only backend such as
+@acronym{NNTP}, for example, it will be copied.
+
+Note that you can use multiples destinations per group or regular
+expression! This enables you to send your ham to a regular mail
+group and to a @emph{ham training} group.
+
+When you leave a @emph{ham} group, all ham-marked articles are sent to
+a ham processor, which will study these as non-spam samples.
+
+@vindex spam-process-ham-in-spam-groups
+By default the variable @code{spam-process-ham-in-spam-groups} is
+@code{nil}. Set it to @code{t} if you want ham found in spam groups
+to be processed. Normally this is not done, you are expected instead
+to send your ham to a ham group and process it there.
+
+@vindex spam-process-ham-in-nonham-groups
+By default the variable @code{spam-process-ham-in-nonham-groups} is
+@code{nil}. Set it to @code{t} if you want ham found in non-ham (spam
+or unclassified) groups to be processed. Normally this is not done,
+you are expected instead to send your ham to a ham group and process
+it there.
+
+@vindex gnus-spam-process-destinations
+When you leave a @emph{ham} or @emph{unclassified} group, all
+@strong{spam} articles are moved to a location determined by either
+the @code{spam-process-destination} group parameter or a match in the
+@code{gnus-spam-process-destinations} variable, which is a list of
+regular expressions matched with group names (it's easiest to
+customize this variable with @kbd{M-x customize-variable @key{RET}
+gnus-spam-process-destinations}). Each group name list is a standard
+Lisp list, if you prefer to customize the variable manually. If the
+@code{spam-process-destination} parameter is not set, the spam
+articles are only expired. The group name is fully qualified, meaning
+that if you see @samp{nntp:servername} before the group name in the
+group buffer then you need it here as well.
+
+If spam can not be moved---because of a read-only backend such as
+@acronym{NNTP}, for example, it will be copied.
+
+Note that you can use multiples destinations per group or regular
+expression! This enables you to send your spam to multiple @emph{spam
+training} groups.
+
+@vindex spam-log-to-registry
+The problem with processing ham and spam is that Gnus doesn't track
+this processing by default. Enable the @code{spam-log-to-registry}
+variable so @code{spam.el} will use @code{gnus-registry.el} to track
+what articles have been processed, and avoid processing articles
+multiple times. Keep in mind that if you limit the number of registry
+entries, this won't work as well as it does without a limit.
+
+@vindex spam-mark-only-unseen-as-spam
+Set this variable if you want only unseen articles in spam groups to
+be marked as spam. By default, it is set. If you set it to
+@code{nil}, unread articles will also be marked as spam.
+
+@vindex spam-mark-ham-unread-before-move-from-spam-group
+Set this variable if you want ham to be unmarked before it is moved
+out of the spam group. This is very useful when you use something
+like the tick mark @samp{!} to mark ham---the article will be placed
+in your @code{ham-process-destination}, unmarked as if it came fresh
+from the mail server.
+
+@vindex spam-autodetect-recheck-messages
+When autodetecting spam, this variable tells @code{spam.el} whether
+only unseen articles or all unread articles should be checked for
+spam. It is recommended that you leave it off.
+
+@node Spam ELisp Package Configuration Examples
+@subsubsection Spam ELisp Package Configuration Examples
+@cindex spam filtering
+@cindex spam filtering configuration examples
+@cindex spam configuration examples
+@cindex spam
+
+@subsubheading Ted's setup
+
+From Ted Zlatanov <tzz@@lifelogs.com>.
+@example
+;; @r{for @code{gnus-registry-split-fancy-with-parent} and spam autodetection}
+;; @r{see @file{gnus-registry.el} for more information}
+(gnus-registry-initialize)
+(spam-initialize)
+
+;; @r{I like @kbd{C-s} for marking spam}
+(define-key gnus-summary-mode-map "\C-s" 'gnus-summary-mark-as-spam)
+
+(setq
+ spam-log-to-registry t ; @r{for spam autodetection}
+ spam-use-BBDB t
+ spam-use-regex-headers t ; @r{catch X-Spam-Flag (SpamAssassin)}
+ ;; @r{all groups with @samp{spam} in the name contain spam}
+ gnus-spam-newsgroup-contents
+ '(("spam" gnus-group-spam-classification-spam))
+ ;; @r{see documentation for these}
+ spam-move-spam-nonspam-groups-only nil
+ spam-mark-only-unseen-as-spam t
+ spam-mark-ham-unread-before-move-from-spam-group t
+ nnimap-split-rule 'nnimap-split-fancy
+ ;; @r{understand what this does before you copy it to your own setup!}
+ nnimap-split-fancy '(|
+ ;; @r{trace references to parents and put in their group}
+ (: gnus-registry-split-fancy-with-parent)
+ ;; @r{this will catch server-side SpamAssassin tags}
+ (: spam-split 'spam-use-regex-headers)
+ (any "ding" "ding")
+ ;; @r{note that spam by default will go to @samp{spam}}
+ (: spam-split)
+ ;; @r{default mailbox}
+ "mail"))
+
+;; @r{my parameters, set with @kbd{G p}}
+
+;; @r{all nnml groups, and all nnimap groups except}
+;; @r{@samp{nnimap+mail.lifelogs.com:train} and}
+;; @r{@samp{nnimap+mail.lifelogs.com:spam}: any spam goes to nnimap training,}
+;; @r{because it must have been detected manually}
+
+((spam-process-destination . "nnimap+mail.lifelogs.com:train"))
+
+;; @r{all @acronym{NNTP} groups}
+;; @r{autodetect spam with the blacklist and ham with the BBDB}
+((spam-autodetect-methods spam-use-blacklist spam-use-BBDB)
+;; @r{send all spam to the training group}
+ (spam-process-destination . "nnimap+mail.lifelogs.com:train"))
+
+;; @r{only some @acronym{NNTP} groups, where I want to autodetect spam}
+((spam-autodetect . t))
+
+;; @r{my nnimap @samp{nnimap+mail.lifelogs.com:spam} group}
+
+;; @r{this is a spam group}
+((spam-contents gnus-group-spam-classification-spam)
+
+ ;; @r{any spam (which happens when I enter for all unseen messages,}
+ ;; @r{because of the @code{gnus-spam-newsgroup-contents} setting above), goes to}
+ ;; @r{@samp{nnimap+mail.lifelogs.com:train} unless I mark it as ham}
+
+ (spam-process-destination "nnimap+mail.lifelogs.com:train")
+
+ ;; @r{any ham goes to my @samp{nnimap+mail.lifelogs.com:mail} folder, but}
+ ;; @r{also to my @samp{nnimap+mail.lifelogs.com:trainham} folder for training}
+
+ (ham-process-destination "nnimap+mail.lifelogs.com:mail"
+ "nnimap+mail.lifelogs.com:trainham")
+ ;; @r{in this group, only @samp{!} marks are ham}
+ (ham-marks
+ (gnus-ticked-mark))
+ ;; @r{remembers senders in the blacklist on the way out---this is}
+ ;; @r{definitely not needed, it just makes me feel better}
+ (spam-process (gnus-group-spam-exit-processor-blacklist)))
+
+;; @r{Later, on the @acronym{IMAP} server I use the @samp{train} group for training}
+;; @r{SpamAssassin to recognize spam, and the @samp{trainham} group fora}
+;; @r{recognizing ham---but Gnus has nothing to do with it.}
+
+@end example
+
+@subsubheading Using @file{spam.el} on an IMAP server with a statistical filter on the server
+From Reiner Steib <reiner.steib@@gmx.de>.
+
+My provider has set up bogofilter (in combination with @acronym{DCC}) on
+the mail server (@acronym{IMAP}). Recognized spam goes to
+@samp{spam.detected}, the rest goes through the normal filter rules,
+i.e. to @samp{some.folder} or to @samp{INBOX}. Training on false
+positives or negatives is done by copying or moving the article to
+@samp{training.ham} or @samp{training.spam} respectively. A cron job on
+the server feeds those to bogofilter with the suitable ham or spam
+options and deletes them from the @samp{training.ham} and
+@samp{training.spam} folders.
+
+With the following entries in @code{gnus-parameters}, @code{spam.el}
+does most of the job for me:
+
+@lisp
+ ("nnimap:spam\\.detected"
+ (gnus-article-sort-functions '(gnus-article-sort-by-chars))
+ (ham-process-destination "nnimap:INBOX" "nnimap:training.ham")
+ (spam-contents gnus-group-spam-classification-spam))
+ ("nnimap:\\(INBOX\\|other-folders\\)"
+ (spam-process-destination . "nnimap:training.spam")
+ (spam-contents gnus-group-spam-classification-ham))
+@end lisp
+
+@itemize
+
+@item @b{The Spam folder:}
+
+In the folder @samp{spam.detected}, I have to check for false positives
+(i.e. legitimate mails, that were wrongly judged as spam by
+bogofilter or DCC).
+
+Because of the @code{gnus-group-spam-classification-spam} entry, all
+messages are marked as spam (with @code{$}). When I find a false
+positive, I mark the message with some other ham mark (@code{ham-marks},
+@ref{Spam ELisp Package Global Variables}). On group exit, those
+messages are copied to both groups, @samp{INBOX} (where I want to have
+the article) and @samp{training.ham} (for training bogofilter) and
+deleted from the @samp{spam.detected} folder.
+
+The @code{gnus-article-sort-by-chars} entry simplifies detection of
+false positives for me. I receive lots of worms (sweN, @dots{}), that all
+have a similar size. Grouping them by size (i.e. chars) makes finding
+other false positives easier. (Of course worms aren't @i{spam}
+(@acronym{UCE}, @acronym{UBE}) strictly speaking. Anyhow, bogofilter is
+an excellent tool for filtering those unwanted mails for me.)
+
+@item @b{Ham folders:}
+
+In my ham folders, I just hit @kbd{S x}
+(@code{gnus-summary-mark-as-spam}) whenever I see an unrecognized spam
+mail (false negative). On group exit, those messages are moved to
+@samp{training.ham}.
+@end itemize
+
+@subsubheading Reporting spam articles in Gmane groups with @code{spam-report.el}
+
+From Reiner Steib <reiner.steib@@gmx.de>.
+
+With following entry in @code{gnus-parameters}, @kbd{S x}
+(@code{gnus-summary-mark-as-spam}) marks articles in @code{gmane.*}
+groups as spam and reports the to Gmane at group exit:
+
+@lisp
+ ("^gmane\\."
+ (spam-process (gnus-group-spam-exit-processor-report-gmane)))
+@end lisp
+
+Additionally, I use @code{(setq spam-report-gmane-use-article-number nil)}
+because I don't read the groups directly from news.gmane.org, but
+through my local news server (leafnode). I.e. the article numbers are
+not the same as on news.gmane.org, thus @code{spam-report.el} has to check
+the @code{X-Report-Spam} header to find the correct number.
+
+@node Blacklists and Whitelists
+@subsubsection Blacklists and Whitelists
+@cindex spam filtering
+@cindex whitelists, spam filtering
+@cindex blacklists, spam filtering
+@cindex spam
+
+@defvar spam-use-blacklist
+
+Set this variable to @code{t} if you want to use blacklists when
+splitting incoming mail. Messages whose senders are in the blacklist
+will be sent to the @code{spam-split-group}. This is an explicit
+filter, meaning that it acts only on mail senders @emph{declared} to
+be spammers.
+
+@end defvar
+
+@defvar spam-use-whitelist
+
+Set this variable to @code{t} if you want to use whitelists when
+splitting incoming mail. Messages whose senders are not in the
+whitelist will be sent to the next spam-split rule. This is an
+explicit filter, meaning that unless someone is in the whitelist, their
+messages are not assumed to be spam or ham.
+
+@end defvar
+
+@defvar spam-use-whitelist-exclusive
+
+Set this variable to @code{t} if you want to use whitelists as an
+implicit filter, meaning that every message will be considered spam
+unless the sender is in the whitelist. Use with care.
+
+@end defvar
+
+@defvar gnus-group-spam-exit-processor-blacklist
+
+Add this symbol to a group's @code{spam-process} parameter by
+customizing the group parameters or the
+@code{gnus-spam-process-newsgroups} variable. When this symbol is
+added to a group's @code{spam-process} parameter, the senders of
+spam-marked articles will be added to the blacklist.
+
+@emph{WARNING}
+
+Instead of the obsolete
+@code{gnus-group-spam-exit-processor-blacklist}, it is recommended
+that you use @code{'(spam spam-use-blacklist)}. Everything will work
+the same way, we promise.
+
+@end defvar
+
+@defvar gnus-group-ham-exit-processor-whitelist
+
+Add this symbol to a group's @code{spam-process} parameter by
+customizing the group parameters or the
+@code{gnus-spam-process-newsgroups} variable. When this symbol is
+added to a group's @code{spam-process} parameter, the senders of
+ham-marked articles in @emph{ham} groups will be added to the
+whitelist.
+
+@emph{WARNING}
+
+Instead of the obsolete
+@code{gnus-group-ham-exit-processor-whitelist}, it is recommended
+that you use @code{'(ham spam-use-whitelist)}. Everything will work
+the same way, we promise.
+
+@end defvar
+
+Blacklists are lists of regular expressions matching addresses you
+consider to be spam senders. For instance, to block mail from any
+sender at @samp{vmadmin.com}, you can put @samp{vmadmin.com} in your
+blacklist. You start out with an empty blacklist. Blacklist entries
+use the Emacs regular expression syntax.
+
+Conversely, whitelists tell Gnus what addresses are considered
+legitimate. All messages from whitelisted addresses are considered
+non-spam. Also see @ref{BBDB Whitelists}. Whitelist entries use the
+Emacs regular expression syntax.
+
+The blacklist and whitelist file locations can be customized with the
+@code{spam-directory} variable (@file{~/News/spam} by default), or
+the @code{spam-whitelist} and @code{spam-blacklist} variables
+directly. The whitelist and blacklist files will by default be in the
+@code{spam-directory} directory, named @file{whitelist} and
+@file{blacklist} respectively.
+
+@node BBDB Whitelists
+@subsubsection BBDB Whitelists
+@cindex spam filtering
+@cindex BBDB whitelists, spam filtering
+@cindex BBDB, spam filtering
+@cindex spam
+
+@defvar spam-use-BBDB
+
+Analogous to @code{spam-use-whitelist} (@pxref{Blacklists and
+Whitelists}), but uses the BBDB as the source of whitelisted
+addresses, without regular expressions. You must have the BBDB loaded
+for @code{spam-use-BBDB} to work properly. Messages whose senders are
+not in the BBDB will be sent to the next spam-split rule. This is an
+explicit filter, meaning that unless someone is in the BBDB, their
+messages are not assumed to be spam or ham.
+
+@end defvar
+
+@defvar spam-use-BBDB-exclusive
+
+Set this variable to @code{t} if you want to use the BBDB as an
+implicit filter, meaning that every message will be considered spam
+unless the sender is in the BBDB. Use with care. Only sender
+addresses in the BBDB will be allowed through; all others will be
+classified as spammers.
+
+@end defvar
+
+@defvar gnus-group-ham-exit-processor-BBDB
+
+Add this symbol to a group's @code{spam-process} parameter by
+customizing the group parameters or the
+@code{gnus-spam-process-newsgroups} variable. When this symbol is
+added to a group's @code{spam-process} parameter, the senders of
+ham-marked articles in @emph{ham} groups will be added to the
+BBDB.
+
+@emph{WARNING}
+
+Instead of the obsolete
+@code{gnus-group-ham-exit-processor-BBDB}, it is recommended
+that you use @code{'(ham spam-use-BBDB)}. Everything will work
+the same way, we promise.
+
+@end defvar
+
+@node Gmane Spam Reporting
+@subsubsection Gmane Spam Reporting
+@cindex spam reporting
+@cindex Gmane, spam reporting
+@cindex Gmane, spam reporting
+@cindex spam
+
+@defvar gnus-group-spam-exit-processor-report-gmane
+
+Add this symbol to a group's @code{spam-process} parameter by
+customizing the group parameters or the
+@code{gnus-spam-process-newsgroups} variable. When this symbol is
+added to a group's @code{spam-process} parameter, the spam-marked
+articles groups will be reported to the Gmane administrators via a
+HTTP request.
+
+Gmane can be found at @uref{http://gmane.org}.
+
+@emph{WARNING}