
=head1 NAME

Mail::Message::Head::Complete - the header of one message


=head1 INHERITANCE

 Mail::Message::Head::Complete
   is a Mail::Message::Head
   is a Mail::Reporter

 Mail::Message::Head::Complete is extended by
   Mail::Message::Head::Partial
   Mail::Message::Replace::MailHeader

 Mail::Message::Head::Complete is realized by
   Mail::Message::Head::Delayed
   Mail::Message::Head::Subset


=head1 SYNOPSIS

 my $head = Mail::Message::Head::Complete->new;
 See Mail::Message::Head


=head1 DESCRIPTION

E-mail's message can be in various states: unread, partially read, and
fully read.  The class stores a message of which all header lines are
known for sure.


=head1 OVERLOADED


overload: B<"">

=over 4

See L<Mail::Message::Head/"OVERLOADED">

=back

overload: B<bool>

=over 4

See L<Mail::Message::Head/"OVERLOADED">

=back


=head1 METHODS


=head2 Constructors


$obj-E<gt>B<build>(FIELDS)

=over 4

See L<Mail::Message::Head/"Constructors">

=back

$obj-E<gt>B<clone>([FIELDS])

=over 4

Make a copy of the header, optionally limited only to the header lines
specified by FIELDS.  The lines which are taken must start with one of the
list.  If no list is specified, all will be taken.

I<Example:> 

 my $newhead = $head->clone('Subject', 'Received');

=back

Mail::Message::Head::Complete-E<gt>B<new>(OPTIONS)

=over 4

See L<Mail::Message::Head/"Constructors">

=back

=head2 The header


$obj-E<gt>B<isDelayed>

=over 4

See L<Mail::Message::Head/"The header">

=back

$obj-E<gt>B<isEmpty>

=over 4

See L<Mail::Message::Head/"The header">

=back

$obj-E<gt>B<isModified>

=over 4

See L<Mail::Message::Head/"The header">

=back

$obj-E<gt>B<knownNames>

=over 4

See L<Mail::Message::Head/"The header">

=back

$obj-E<gt>B<message>([MESSAGE])

=over 4

See L<Mail::Message::Head/"The header">

=back

$obj-E<gt>B<modified>([BOOLEAN])

=over 4

See L<Mail::Message::Head/"The header">

=back

$obj-E<gt>B<nrLines>

=over 4

Return the number of lines needed to display this header (including
the trailing newline)

=back

$obj-E<gt>B<orderedFields>

=over 4

See L<Mail::Message::Head/"The header">

=back

$obj-E<gt>B<size>

=over 4

Return the number of bytes needed to display this header (including
the trailing newline).  On systems which use CRLF as line separator,
the number of lines in the header (see L<nrLines()|Mail::Message::Head::Complete/"The header">) must be added to
find the actual size in the file.

=back

=head2 Access to the header


$obj-E<gt>B<add>(FIELD | LINE | (NAME,BODY[,ATTRS]))

=over 4

Add a field to the header.  If a field is added more than once, all values
are stored in the header, in the order they are added.

When a FIELD object is specified (some L<Mail::Message::Field|Mail::Message::Field> instance), that
will be added.  Another possibility is to specify a raw header LINE, or a
header line nicely split-up in NAME and BODY, in which case the
field constructor is called for you.

LINE or BODY specifications which are terminated by a new-line are considered 
to be correctly folded.  Lines which are not terminated by a new-line will
be folded when needed: new-lines will be added where required.  It is strongly
adviced to let MailBox do the folding for you.

The return value of this method is the L<Mail::Message::Field|Mail::Message::Field> object
which is created (or was specified).

I<Example:> 

 my $head  = Mail::Message::Head->new;
 $head->add('Subject: hi!');
 $head->add(From => 'me@home');
 my $field = Mail::Message::Field->new('To: you@there');
 $head->add($field);
 my Mail::Message::Field $s = $head->add(Sender => 'I');

=back

$obj-E<gt>B<addListGroup>(OBJECT)

=over 4

A I<list group> is a set of header fields which contain data about a
mailing list which was used to transmit the message.  See
L<Mail::Message::Head::ListGroup|Mail::Message::Head::ListGroup> for details about the implementation
of the OBJECT.

When you have a list group prepared, you can add it later using this
method.  You will get your private copy of the list group data in
return, because the same group can be used for multiple messages.

I<Example:> of adding a list group to a header


 my $lg = Mail::Message::Head::ListGroup->new(...);
 my $own_lg = $msg->head->addListGroup($lg);

=back

$obj-E<gt>B<addResentGroup>(RESENT-GROUP|DATA)

=over 4

Add a RESENT-GROUP (a L<Mail::Message::Head::ResentGroup|Mail::Message::Head::ResentGroup> object) to
the header.  If you specify DATA, that is used to create such group
first.  If no C<Received> line is specified, it will be created
for you.

These header lines have nothing to do with the user's sense
of C<reply> or C<forward> actions: these lines trace the e-mail
transport mechanism.

I<Example:> 

 my $rg = Mail::Message::Head::ResentGroup->new(head => $head, ...);
 $head->addResentGroup($rg);

 my $rg = $head->addResentGroup(From => 'me');

=back

$obj-E<gt>B<addSpamGroup>(OBJECT)

=over 4

A I<spam fighting group> is a set of header fields which contains data
which is used to fight spam.  See L<Mail::Message::Head::SpamGroup|Mail::Message::Head::SpamGroup>
for details about the implementation of the OBJECT.

When you have a spam group prepared, you can add it later using this
method.  You will get your private copy of the spam group data in
return, because the same group can be used for multiple messages.

I<Example:> of adding a spam group to a header


 my $sg = Mail::Message::Head::SpamGroup->new(...);
 my $own_sg = $msg->head->addSpamGroup($sg);

=back

$obj-E<gt>B<count>(NAME)

=over 4

Count the number of fields with this NAME.  Most fields will return 1:
only one occurance in the header.  As example, the C<Received> fields
are usually present more than once.

=back

$obj-E<gt>B<delete>(NAME)

=over 4

Remove the field with the specified name.  If the header contained
multiple lines with the same name, they will be replaced all together.
This method simply calls L<reset()|Mail::Message::Head::Complete/"Access to the header"> without replacement fields.

=back

$obj-E<gt>B<get>(NAME [,INDEX])

=over 4

See L<Mail::Message::Head/"Access to the header">

=back

$obj-E<gt>B<grepNames>([NAMES|ARRAY-OF-NAMES|REGEXS])

=over 4

Filter from all header fields the names which start will any of the
specified list.  When no names are specified, all names will be returned.
The list is ordered as they where read from file, or added later.

The NAMES are regular expressions, and will all be matched case insensitive
and attached to the front of the string only.  You may also specify
one or more prepared regexes.

I<Example:> 

 print $head->grepNames();         # same as $head->names
 print $head->grepNames('X-', 'Subject', ');
 print $head->grepNames('To\b');   # will only select To

=back

$obj-E<gt>B<listGroup>

=over 4

Returns a I<list group> description: the set of headers which form
the information about mailing list software used to transport the
message.  See also L<addListGroup()|Mail::Message::Head::Complete/"Access to the header"> and L<removeListGroup()|Mail::Message::Head::Complete/"Access to the header">.

I<Example:> use of listGroup()


 if(my $lg = $msg->head->listGroup)
 {  $lg->print(\*STDERR);
    $lg->delete;
 }

 $msg->head->removeListGroup;

=back

$obj-E<gt>B<names>

=over 4

Returns a full ordered list of known field names, as defined in the
header.  Fields which were reset() to be empty will still be
listed here.

=back

$obj-E<gt>B<print>([FILEHANDLE])

=over 4

Print all headers to the specified FILEHANDLE, by default the selected
filehandle.  See L<printUndisclosed()|Mail::Message::Head::Complete/"Access to the header"> to limit the headers to include
only the public headers.

I<Example:> 

 $head->print(\*OUT);
 $head->print;

 my $fh = IO::File->new(...);
 $head->print($fh);

=back

$obj-E<gt>B<printUndisclosed>([FILEHANDLE])

=over 4

Like the usual L<print()|Mail::Message::Head::Complete/"Access to the header">, the header lines are printed to the specified
FILEHANDLE, by default the selected filehandle.  In this case, however,
C<Bcc> and C<Resent-Bcc> lines are included.

=back

$obj-E<gt>B<removeContentInfo>

=over 4

Remove all body related fields from the header.  The header will become
partial.

=back

$obj-E<gt>B<removeField>(FIELD)

=over 4

Remove the specified FIELD object from the header.  This is useful when
there are possible more than one fields with the same name, and you
need to remove exactly one of them.  Also have a look at L<delete()|Mail::Message::Head::Complete/"Access to the header">,
L<reset()|Mail::Message::Head::Complete/"Access to the header">, and L<set()|Mail::Message::Head::Complete/"Access to the header">.

See also L<Mail::Message::Head::Partial::removeFields()|Mail::Message::Head::Partial/"Access to the header"> (mind the 's'
at the end of the name), which accepts a string or regular expression
as argument to select the fields to be removed.

=back

$obj-E<gt>B<removeFields>(STRING|REGEXP, [STRING|REGEXP, ...])

=over 4

The header object is turned into a L<Mail::Message::Head::Partial|Mail::Message::Head::Partial> object
which has a set of fields removed.  Read about the implications and the
possibilities in L<Mail::Message::Head::Partial::removeFields()|Mail::Message::Head::Partial/"Access to the header">.

=back

$obj-E<gt>B<removeFieldsExcept>(STRING|REGEXP, [STRING|REGEXP, ...])

=over 4

The header object is turned into a L<Mail::Message::Head::Partial|Mail::Message::Head::Partial> object
which has a set of fields removed.  Read about the implications and the
possibilities in L<Mail::Message::Head::Partial::removeFieldsExcept()|Mail::Message::Head::Partial/"Access to the header">.

=back

$obj-E<gt>B<removeListGroup>

=over 4

Removes all fields related to mailing list administration at once.
The header object is turned into a L<Mail::Message::Head::Partial|Mail::Message::Head::Partial>
object.  Read about the implications and the possibilities in
L<Mail::Message::Head::Partial::removeListGroup()|Mail::Message::Head::Partial/"Access to the header">.

=back

$obj-E<gt>B<removeResentGroups>

=over 4

Removes all resent groups at once.  The header object is turned into
a L<Mail::Message::Head::Partial|Mail::Message::Head::Partial> object.  Read about the implications and the
possibilities in L<Mail::Message::Head::Partial::removeResentGroups()|Mail::Message::Head::Partial/"Access to the header">.

=back

$obj-E<gt>B<removeSpamGroups>

=over 4

Removes all fields which were added by various spam detection software
at once.  The header object is turned into a L<Mail::Message::Head::Partial|Mail::Message::Head::Partial>
object.  Read about the implications and the possibilities in
L<Mail::Message::Head::Partial::removeSpamGroups()|Mail::Message::Head::Partial/"Access to the header">.

=back

$obj-E<gt>B<resentGroups>

=over 4

Returns a list of L<Mail::Message::Head::ResentGroup|Mail::Message::Head::ResentGroup> objects which
each represent one intermediate point in the message's transmission in
the order as they appear in the header: the most recent one first.
See also L<addResentGroup()|Mail::Message::Head::Complete/"Access to the header"> and L<removeResentGroups()|Mail::Message::Head::Complete/"Access to the header">.

A resent group contains a set of header fields whose names start
with C<Resent->.  Before the first C<Resent> line is I<trace> information,
which is composed of an optional C<Return-Path> field and an required
C<Received> field.

=back

$obj-E<gt>B<reset>(NAME, FIELDS)

=over 4

Replace the values in the header fields named by NAME with the values
specified in the list of FIELDS. A single name can correspond to multiple
repeated fields.

Removing fields which are part of one of the predefined field groups is
not a smart idea.  You can better remove these fields as group, all
together.  For instance, the C<'Received'> lines are part of resent
groups, C<'X-Spam'> is past of a spam group, and C<List-Post> belongs
to a list group.  You can delete a whole group with
L<Mail::Message::Head::FieldGroup::delete()|Mail::Message::Head::FieldGroup/"The header">, or with methods which
are provided by L<Mail::Message::Head::Partial|Mail::Message::Head::Partial>.

If FIELDS is empty, the corresponding NAME fields will
be removed. The location of removed fields in the header order will be
remembered. Fields with the same name which are added later will appear at
the remembered position.  This is equivalent to the L<delete()|Mail::Message::Head::Complete/"Access to the header"> method.

I<Example:> 

 # reduce number of 'Keywords' lines to last 5)
 my @keywords = $head->get('Keywords');
 $head->reset('Keywords', @keywords[-5..-1]) if @keywords > 5;

 # Reduce the number of Received lines to only the last added one.
 my @rgs = $head->resentGroups;
 shift @rgs;     # keep this one (later is added in front)
 $_->delete foreach @rgs;

=back

$obj-E<gt>B<set>(FIELD | LINE | (NAME, BODY [,ATTRS]))

=over 4

The C<set> method is similar to the L<add()|Mail::Message::Head::Complete/"Access to the header"> method, and takes the same
options. However, existing values for fields will be removed before a new
value is added.

=back

$obj-E<gt>B<spamDetected>

=over 4

Returns whether one of the spam groups defines a report about spam.  If there
are not header fields in the message which relate to spam-detection
software, C<undef> is returned.  The spamgroups which report spam are returned.

I<Example:> 

 $message->delete if $message->spamDetected;

 call_spamassassin($message)
    unless defined $message->spamDetected;

=back

$obj-E<gt>B<spamGroups>([NAMES])

=over 4

Returns a list of L<Mail::Message::Head::SpamGroup|Mail::Message::Head::SpamGroup> objects, each collecting
some lines which contain spam fighting information.  When any NAMES are
given, then only these groups are returned.
See also L<addSpamGroup()|Mail::Message::Head::Complete/"Access to the header"> and L<removeSpamGroups()|Mail::Message::Head::Complete/"Access to the header">.

In scalar context, with exactly one NAME specified, that group will be
returned.  With more NAMES or without NAMES, a list will be returned
(which defaults to the length of the list in scalar context).

I<Example:> use of listGroup()


 my @sg = $msg->head->spamGroups;
 $sg[0]->print(\*STDERR);
 $sg[-1]->delete;

 my $sg = $msg->head->spamGroups('SpamAssassin');

=back

$obj-E<gt>B<string>

=over 4

Returns the whole header as one scalar (in scalar context) or list
of lines (list context).  Triggers completion.

=back

$obj-E<gt>B<study>(NAME [,INDEX])

=over 4

See L<Mail::Message::Head/"Access to the header">

=back

=head2 About the body


$obj-E<gt>B<guessBodySize>

=over 4

See L<Mail::Message::Head/"About the body">

=back

$obj-E<gt>B<guessTimeStamp>

=over 4

Make a guess about when the message was origanally posted, based on the
information found in the header's C<Date> field.

For some kinds of folders, L<Mail::Message::guessTimestamp()|Mail::Message/"The header"> may produce
a better result, for instance by looking at the modification time of the
file in which the message is stored.  Also some protocols, like POP can
supply that information.

=back

$obj-E<gt>B<isMultipart>

=over 4

See L<Mail::Message::Head/"About the body">

=back

$obj-E<gt>B<recvstamp>

=over 4

Returns an indication about when the message was sent, but only using the
C<Date> field in the header as last resort: we do not trust the sender of
the message to specify the correct date.  See L<timestamp()|Mail::Message::Head::Complete/"About the body"> when you do
trust the sender.

Many spam producers fake a date, which mess up the order of receiving
things.  The timestamp which is produced is derived from the Received
headers, if they are present, and C<undef> otherwise.

The timestamp is encoded as C<time> is on your system (see perldoc -f
time), and as such usable for the C<gmtime> and C<localtime> methods.

I<Example:> of time-sorting folders with received messages


 my $folder = $mgr->open('InBox');
 my @messages = sort {$a->recvstamp <=> $b->recvstamp}
                   $folder->messages;

I<Example:> of time-sorting messages of mixed origin


 my $folder = $mgr->open('MyFolder');

 # Pre-calculate timestamps to be sorted (for speed)
 my @stamps = map { [ ($_->timestamp || 0), $_ ] }
                     $folder->messages;

 my @sorted
   = map { $_->[1] }      # get the message for the stamp
       sort {$a->[0] <=> $b->[0]}   # stamps are numerics
          @stamps;

=back

$obj-E<gt>B<timestamp>

=over 4

Returns an indication about when the message was sent, with as
little guessing as possible.  In this case, the date as specified by the
sender is trusted.  See L<recvstamp()|Mail::Message::Head::Complete/"About the body"> when you do not want to trust the
sender.

The timestamp is encoded as C<time> is
on your system (see perldoc -f time), and as such usable for the C<gmtime>
and C<localtime> methods.

=back

=head2 Internals


$obj-E<gt>B<addNoRealize>(FIELD)

=over 4

See L<Mail::Message::Head/"Internals">

=back

$obj-E<gt>B<addOrderedFields>(FIELDS)

=over 4

See L<Mail::Message::Head/"Internals">

=back

$obj-E<gt>B<createFromLine>

=over 4

For some mail-folder types separate messages by a line starting with
'C<From >'.  If a message is moved to such folder from a folder-type
which does not support these separators, this method is called to produce
one.

=back

$obj-E<gt>B<createMessageId>

=over 4

Creates a message-id for this message.  This method will be run when
a new message is created, or a message is discovered without the
message-id header field.  Message-ids are required for detection of
message-threads.  See L<messageIdPrefix()|Mail::Message::Head::Complete/"Internals">.

=back

$obj-E<gt>B<fileLocation>

=over 4

See L<Mail::Message::Head/"Internals">

=back

$obj-E<gt>B<load>

=over 4

See L<Mail::Message::Head/"Internals">

=back

$obj-E<gt>B<messageIdPrefix>([STRING])

=over 4

Sets/returns the message-id start.  The rest of the message-id is an
integer which is derived from the current time and the local host.
See L<createMessageId()|Mail::Message::Head::Complete/"Internals">.

=back

$obj-E<gt>B<moveLocation>(DISTANCE)

=over 4

See L<Mail::Message::Head/"Internals">

=back

$obj-E<gt>B<read>(PARSER)

=over 4

See L<Mail::Message::Head/"Internals">

=back

$obj-E<gt>B<setNoRealize>(FIELD)

=over 4

See L<Mail::Message::Head/"Internals">

=back

=head2 Error handling


$obj-E<gt>B<AUTOLOAD>

=over 4

See L<Mail::Reporter/"Error handling">

=back

$obj-E<gt>B<addReport>(OBJECT)

=over 4

See L<Mail::Reporter/"Error handling">

=back

$obj-E<gt>B<defaultTrace>([LEVEL, [LEVEL])

Mail::Message::Head::Complete-E<gt>B<defaultTrace>([LEVEL, [LEVEL])

=over 4

See L<Mail::Reporter/"Error handling">

=back

$obj-E<gt>B<errors>

=over 4

See L<Mail::Reporter/"Error handling">

=back

$obj-E<gt>B<log>([LEVEL [,STRINGS]])

Mail::Message::Head::Complete-E<gt>B<log>([LEVEL [,STRINGS]])

=over 4

See L<Mail::Reporter/"Error handling">

=back

$obj-E<gt>B<logPriority>(LEVEL)

Mail::Message::Head::Complete-E<gt>B<logPriority>(LEVEL)

=over 4

See L<Mail::Reporter/"Error handling">

=back

$obj-E<gt>B<logSettings>

=over 4

See L<Mail::Reporter/"Error handling">

=back

$obj-E<gt>B<notImplemented>

=over 4

See L<Mail::Reporter/"Error handling">

=back

$obj-E<gt>B<report>([LEVEL])

=over 4

See L<Mail::Reporter/"Error handling">

=back

$obj-E<gt>B<reportAll>([LEVEL])

=over 4

See L<Mail::Reporter/"Error handling">

=back

$obj-E<gt>B<trace>([LEVEL])

=over 4

See L<Mail::Reporter/"Error handling">

=back

$obj-E<gt>B<warnings>

=over 4

See L<Mail::Reporter/"Error handling">

=back

=head2 Cleanup


$obj-E<gt>B<DESTROY>

=over 4

See L<Mail::Reporter/"Cleanup">

=back

$obj-E<gt>B<inGlobalDestruction>

=over 4

See L<Mail::Reporter/"Cleanup">

=back



=head1 DIAGNOSTICS

I<Warning:> Cannot remove field $name from header: not found.

You ask to remove a field which is not known in the header.  Using
L<delete()|Mail::Message::Head::Complete/"Access to the header">, L<reset()|Mail::Message::Head::Complete/"Access to the header">, or L<set()|Mail::Message::Head::Complete/"Access to the header"> to do the job will not result
in warnings: those methods check the existence of the field first.

I<Error:> Package $package does not implement $method.

Fatal error: the specific package (or one of its superclasses) does not
implement this method where it should. This message means that some other
related classes do implement this method however the class at hand does
not.  Probably you should investigate this and probably inform the author
of the package.


=head1 DETAILS






=head1 REFERENCES

See the MailBox website at L<http://perl.overmeer.net/mailbox/> for more details.

=head1 COPYRIGHTS

Distribution version 2.055.
Written by Mark Overmeer (mark@overmeer.net).  See the ChangeLog for
other contributors.

Copyright (c) 2001-2003 by the author(s). All rights reserved.
This program is free software; you can redistribute it and/or modify it
under the same terms as Perl itself.


