/*
 * Copyright (c) 2021 Oracle and/or its affiliates. All rights reserved.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v. 2.0, which is available at
 * http://www.eclipse.org/legal/epl-2.0.
 *
 * This Source Code may also be made available under the following Secondary
 * Licenses when the conditions for such availability set forth in the
 * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
 * version 2 with the GNU Classpath Exception, which is available at
 * https://www.gnu.org/software/classpath/license.html.
 *
 * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
 */

/**
 * Classes specific to Internet mail systems.
 * This package supports features that are specific to Internet mail systems
 * based on the MIME standard
 * (<A HREF="http://www.ietf.org/rfc/rfc2045.txt" TARGET="_top">RFC 2045</A>,
 * <A HREF="http://www.ietf.org/rfc/rfc2045.txt" TARGET="_top">RFC 2046</A>, and
 * <A HREF="http://www.ietf.org/rfc/rfc2045.txt" TARGET="_top">RFC 2047</A>).
 * The IMAP, SMTP, and POP3 protocols use
 * {@link jakarta.mail.internet.MimeMessage MimeMessages}.
 *
 * <A ID="properties"><STRONG>Properties</STRONG></A>
 * <P>
 * The Jakarta Mail API supports the following standard properties,
 * which may be set in the <code>Session</code> object, or in the
 * <code>Properties</code> object used to create the <code>Session</code> object.
 * The {@link jakarta.mail.internet.MimeMessage MimeMessage} falls back to
 * System properties when created without a <code>Session</code> object.
 * The properties are always set as strings; the Type column describes
 * how the string is interpreted.  For example, use
 * </P>
 * <PRE>
 * session.setProperty("mail.mime.address.strict", "false");
 * </PRE>
 * <P>
 * to set the <CODE>mail.mime.address.strict</CODE> property,
 * which is of type boolean.
 * </P>
 * <TABLE BORDER="1">
 * <CAPTION>Jakarta Mail properties</CAPTION>
 * <TR>
 * <TH>Name</TH>
 * <TH>Type</TH>
 * <TH>Description</TH>
 * </TR>
 *
 * <TR>
 * <TD><A ID="mail.mime.address.strict">mail.mime.address.strict</A></TD>
 * <TD>boolean</TD>
 * <TD>
 * The <code>mail.mime.address.strict</code> property controls
 * the parsing of address headers.  By default, strict parsing of address
 * headers is done.  If this property is set to <code>"false"</code>,
 * strict parsing is not done and many illegal addresses that sometimes
 * occur in real messages are allowed.  See the <code>InternetAddress</code>
 * class for details.
 * </TD>
 * </TR>
 *
 * <TR>
 * <TD><A ID="mail.mime.allowutf8">mail.mime.allowutf8</A></TD>
 * <TD>boolean</TD>
 * <TD>
 * If set to <code>"true"</code>, UTF-8 strings are allowed in message headers,
 * e.g., in addresses.  This should <b>only</b> be set if the mail server also
 * supports UTF-8.
 * </TD>
 * </TR>
 * </TABLE>
 * <P>
 * The Jakarta Mail API specification requires support for the following properties,
 * which must be set in the <code>System</code> properties.
 * The properties are always set as strings; the Type column describes
 * how the string is interpreted.  For example, use
 * </P>
 * <PRE>
 * System.setProperty("mail.mime.decodetext.strict", "false");
 * </PRE>
 * <P>
 * to set the <CODE>mail.mime.decodetext.strict</CODE> property,
 * which is of type boolean.
 * </P>
 * <TABLE BORDER="1">
 * <CAPTION>Jakarta Mail System properties</CAPTION>
 * <TR>
 * <TH>Name</TH>
 * <TH>Type</TH>
 * <TH>Description</TH>
 * </TR>
 *
 * <TR>
 * <TD><A ID="mail.mime.charset">mail.mime.charset</A></TD>
 * <TD>String</TD>
 * <TD>
 * The <code>mail.mime.charset</code> System property can
 * be used to specify the default MIME charset to use for encoded words
 * and text parts that don't otherwise specify a charset.  Normally, the
 * default MIME charset is derived from the default Java charset, as
 * specified in the <code>file.encoding</code> System property.  Most
 * applications will have no need to explicitly set the default MIME
 * charset.  In cases where the default MIME charset to be used for
 * mail messages is different than the charset used for files stored on
 * the system, this property should be set.
 * </TD>
 * </TR>
 *
 * <TR>
 * <TD><A ID="mail.mime.decodetext.strict">mail.mime.decodetext.strict</A></TD>
 * <TD>boolean</TD>
 * <TD>
 * The <code>mail.mime.decodetext.strict</code> property controls
 * decoding of MIME encoded words.  The MIME spec requires that encoded
 * words start at the beginning of a whitespace separated word.  Some
 * mailers incorrectly include encoded words in the middle of a word.
 * If the <code>mail.mime.decodetext.strict</code> System property is
 * set to <code>"false"</code>, an attempt will be made to decode these
 * illegal encoded words. The default is true.
 * </TD>
 * </TR>
 *
 * <TR>
 * <TD><A ID="mail.mime.encodeeol.strict">mail.mime.encodeeol.strict</A></TD>
 * <TD>boolean</TD>
 * <TD>
 * The <code>mail.mime.encodeeol.strict</code> property controls the
 * choice of Content-Transfer-Encoding for MIME parts that are not of
 * type "text".  Often such parts will contain textual data for which
 * an encoding that allows normal end of line conventions is appropriate.
 * In rare cases, such a part will appear to contain entirely textual
 * data, but will require an encoding that preserves CR and LF characters
 * without change.  If the <code>mail.mime.encodeeol.strict</code>
 * System property is set to <code>"true"</code>, such an encoding will
 * be used when necessary.  The default is false.
 * </TD>
 * </TR>
 *
 * <TR>
 * <TD><A ID="mail.mime.decodefilename">mail.mime.decodefilename</A></TD>
 * <TD>boolean</TD>
 * <TD>
 * If set to <code>"true"</code>, the <code>getFileName</code> method
 * uses the <code>MimeUtility</code>
 * method <code>decodeText</code> to decode any
 * non-ASCII characters in the filename.  Note that this decoding
 * violates the MIME specification, but is useful for interoperating
 * with some mail clients that use this convention.
 * The default is false.
 * </TD>
 * </TR>
 *
 * <TR>
 * <TD><A ID="mail.mime.encodefilename">mail.mime.encodefilename</A></TD>
 * <TD>boolean</TD>
 * <TD>
 * If set to <code>"true"</code>, the <code>setFileName</code> method
 * uses the <code>MimeUtility</code>
 * method <code>encodeText</code> to encode any
 * non-ASCII characters in the filename.  Note that this encoding
 * violates the MIME specification, but is useful for interoperating
 * with some mail clients that use this convention.
 * The default is false.
 * </TD>
 * </TR>
 *
 * <TR>
 * <TD><A ID="mail.mime.decodeparameters">mail.mime.decodeparameters</A></TD>
 * <TD>boolean</TD>
 * <TD>
 * If set to <code>"false"</code>, non-ASCII parameters in a
 * <code>ParameterList</code>, e.g., in a Content-Type header,
 * will <b>not</b> be decoded as specified by
 * <A HREF="http://www.ietf.org/rfc/rfc2231.txt" TARGET="_top">RFC 2231</A>.
 * The default is true.
 * </TD>
 * </TR>
 *
 * <TR>
 * <TD><A ID="mail.mime.encodeparameters">mail.mime.encodeparameters</A></TD>
 * <TD>boolean</TD>
 * <TD>
 * If set to <code>"false"</code>, non-ASCII parameters in a
 * <code>ParameterList</code>, e.g., in a Content-Type header,
 * will <b>not</b> be encoded as specified by
 * <A HREF="http://www.ietf.org/rfc/rfc2231.txt" TARGET="_top">RFC 2231</A>.
 * The default is true.
 * </TD>
 * </TR>
 *
 * <TR>
 * <TD><A ID="mail.mime.multipart.ignoremissingendboundary">mail.mime.multipart. ignoremissingendboundary</A></TD>
 * <TD>boolean</TD>
 * <TD>
 * Normally, when parsing a multipart MIME message, a message that is
 * missing the final end boundary line is not considered an error.
 * The data simply ends at the end of the input.  Note that messages
 * of this form violate the MIME specification.  If the property
 * <code>mail.mime.multipart.ignoremissingendboundary</code> is set
 * to <code>false</code>, such messages are considered an error and a
 * <code>MesagingException</code> will be thrown when parsing such a
 * message.
 * </TD>
 * </TR>
 *
 * <TR>
 * <TD><A ID="mail.mime.multipart.ignoremissingboundaryparameter">mail.mime.multipart. ignoremissingboundaryparameter</A></TD>
 * <TD>boolean</TD>
 * <TD>
 * If the Content-Type header for a multipart content does not have
 * a <code>boundary</code> parameter, the multipart parsing code
 * will look for the first line in the content that looks like a
 * boundary line and extract the boundary parameter from the line.
 * If this property is set to <code>"false"</code>, a
 * <code>MessagingException</code> will be thrown if the Content-Type
 * header doesn't specify a boundary parameter.
 * The default is true.
 * </TD>
 * </TR>
 *
 * <TR>
 * <TD><A ID="mail.mime.multipart.ignoreexistingboundaryparameter">mail.mime.multipart. ignoreexistingboundaryparameter</A></TD>
 * <TD>boolean</TD>
 * <TD>
 * Normally the boundary parameter in the Content-Type header of a multipart
 * body part is used to specify the separator between parts of the multipart
 * body.  This System property may be set to <code>"true"</code> to cause
 * the parser to look for a line in the multipart body that looks like a
 * boundary line and use that value as the separator between subsequent parts.
 * This may be useful in cases where a broken anti-virus product has rewritten
 * the message incorrectly such that the boundary parameter and the actual
 * boundary value no longer match.
 * The default value of this property is false.
 * </TD>
 * </TR>
 *
 * <TR>
 * <TD><A ID="mail.mime.multipart.allowempty">mail.mime.multipart. allowempty</A></TD>
 * <TD>boolean</TD>
 * <TD>
 * Normally, when writing out a MimeMultipart that contains no body
 * parts, or when trying to parse a multipart message with no body parts,
 * a <code>MessagingException</code> is thrown.  The MIME spec does not allow
 * multipart content with no body parts.  This
 * System property may be set to <code>"true"</code> to override this behavior.
 * When writing out such a MimeMultipart, a single empty part will be
 * included.  When reading such a multipart, a MimeMultipart will be created
 * with no body parts.
 * The default value of this property is false.
 * </TD>
 * </TR>
 *
 * </TABLE>
 *
 *
 * <P>
 * The following properties are supported by the EE4J implementation of
 * Jakarta Mail, but are not currently a required part of the specification.
 * These must be set as <CODE>Session</CODE> properties.
 * The names, types, defaults, and semantics of these properties may
 * change in future releases.
 * </P>
 * <TABLE BORDER="1">
 * <CAPTION>Jakarta Mail implementation properties</CAPTION>
 * <TR>
 * <TH>Name</TH>
 * <TH>Type</TH>
 * <TH>Description</TH>
 * </TR>
 *
 * <TR>
 * <TD><A ID="mail.alternates">mail.alternates</A></TD>
 * <TD>String</TD>
 * <TD>
 * A string containing other email addresses that the current user is known by.
 * The <code>MimeMessage</code> <code>reply</code> method will eliminate any
 * of these addresses from the recipient list in the message it constructs,
 * to avoid sending the reply back to the sender.
 * </TD>
 * </TR>
 *
 * <TR>
 * <TD><A ID="mail.replyallcc">mail.replyallcc</A></TD>
 * <TD>boolean</TD>
 * <TD>
 * If set to <code>"true"</code>, the <code>MimeMessage</code>
 * <code>reply</code> method will put all recipients except the original
 * sender in the <code>Cc</code> list of the newly constructed message.
 * Normally, recipients in the <code>To</code> header of the original
 * message will also appear in the <code>To</code> list of the newly
 * constructed message.
 * </TD>
 * </TR>
 * </TABLE>
 *
 * <P>
 * The following properties are supported by the EE4J implementation of
 * Jakarta Mail, but are not currently a required part of the specification.
 * These must be set as <CODE>System</CODE> properties.
 * The names, types, defaults, and semantics of these properties may
 * change in future releases.
 * </P>
 * <TABLE BORDER="1">
 * <CAPTION>Jakarta Mail implementation System properties</CAPTION>
 * <TR>
 * <TH>Name</TH>
 * <TH>Type</TH>
 * <TH>Description</TH>
 * </TR>
 *
 * <TR>
 * <TD><A ID="mail.mime.base64.ignoreerrors">mail.mime.base64.ignoreerrors</A></TD>
 * <TD>boolean</TD>
 * <TD>
 * If set to <code>"true"</code>, the BASE64 decoder will ignore errors
 * in the encoded data, returning EOF.  This may be useful when dealing
 * with improperly encoded messages that contain extraneous data at the
 * end of the encoded stream.  Note however that errors anywhere in the
 * stream will cause the decoder to stop decoding so this should be used
 * with extreme caution.  The default is false.
 * </TD>
 * </TR>
 *
 * <TR>
 * <TD><A ID="mail.mime.foldtext">mail.mime.foldtext</A></TD>
 * <TD>boolean</TD>
 * <TD>
 * If set to <code>"true"</code>, header fields containing just text
 * such as the <code>Subject</code> and <code>Content-Description</code>
 * header fields, and long parameter values in structured headers such
 * as <code>Content-Type</code> will be folded (broken into 76 character lines)
 * when set and unfolded when read.  The default is true.
 * </TD>
 * </TR>
 *
 * <TR>
 * <TD><A ID="mail.mime.setcontenttypefilename">mail.mime.setcontenttypefilename</A></TD>
 * <TD>boolean</TD>
 * <TD>
 * If set to <code>"true"</code>, the <code>setFileName</code> method
 * will also set the <code>name</code> parameter on the <code>Content-Type</code>
 * header to the specified filename.  This supports interoperability with
 * some old mail clients.  The default is true.
 * </TD>
 * </TR>
 *
 * <TR>
 * <TD><A ID="mail.mime.setdefaulttextcharset">mail.mime.setdefaulttextcharset</A></TD>
 * <TD>boolean</TD>
 * <TD>
 * When updating the headers of a message, a body
 * part with a <code>text</code> content type but no <code>charset</code>
 * parameter will have a <code>charset</code> parameter added to it
 * if this property is set to <code>"true"</code>.
 * The default is true.
 * </TD>
 * </TR>
 *
 * <TR>
 * <TD><A ID="mail.mime.parameters.strict">mail.mime.parameters.strict</A></TD>
 * <TD>boolean</TD>
 * <TD>
 * If set to false, when reading a message, parameter values in header fields
 * such as <code>Content-Type</code> and <code>Content-Disposition</code>
 * are allowed to contain whitespace and other special characters without
 * being quoted; the parameter value ends at the next semicolon.
 * If set to true (the default), parameter values are required to conform
 * to the MIME specification and must be quoted if they contain whitespace
 * or special characters.
 * </TD>
 * </TR>
 *
 * <TR>
 * <TD><A ID="mail.mime.applefilenames">mail.mime.applefilenames</A></TD>
 * <TD>boolean</TD>
 * <TD>
 * Apple Mail incorrectly encodes filenames that contain spaces,
 * forgetting to quote the parameter value.  If this property is
 * set to <code>"true"</code>, Jakarta Mail will try to detect this
 * situation when parsing parameters and work around it.
 * The default is false.
 * Note that this property handles a subset of the cases handled
 * by setting the mail.mime.parameters.strict property to false.
 * This property will likely be removed in a future release.
 * </TD>
 * </TR>
 *
 * <TR>
 * <TD><A ID="mail.mime.windowsfilenames">mail.mime.windowsfilenames</A></TD>
 * <TD>boolean</TD>
 * <TD>
 * Internet Explorer 6 incorrectly includes a complete pathname
 * in the filename parameter of the Content-Disposition header
 * for uploaded files, and fails to properly escape the backslashes
 * in the pathname.  If this property is
 * set to <code>"true"</code>, Jakarta Mail will preserve all backslashes
 * in the "filename" and "name" parameters of any MIME header.
 * The default is false.
 * Note that this is a violation of the MIME specification but may
 * be useful when using Jakarta Mail to parse HTTP messages for uploaded
 * files sent by IE6.
 * </TD>
 * </TR>
 *
 * <TR>
 * <TD><A ID="mail.mime.ignoreunknownencoding">mail.mime. ignoreunknownencoding</A></TD>
 * <TD>boolean</TD>
 * <TD>
 * If set to <code>"true"</code>, an unknown value in the
 * <code>Content-Transfer-Encoding</code> header will be ignored
 * when reading a message and an encoding of "8bit" will be assumed.
 * If set to <code>"false"</code>, an exception is thrown for an
 * unknown encoding value.  The default is false.
 * </TD>
 * </TR>
 *
 * <TR>
 * <TD><A ID="mail.mime.uudecode.ignoreerrors">mail.mime.uudecode. ignoreerrors</A></TD>
 * <TD>boolean</TD>
 * <TD>
 * If set to <code>"true"</code>, errors in the encoded format of a
 * uuencoded document will be ignored when reading a message part.
 * If set to <code>"false"</code>, an exception is thrown for an
 * incorrectly encoded message part.  The default is false.
 * </TD>
 * </TR>
 *
 * <TR>
 * <TD><A ID="mail.mime.uudecode.ignoremissingbeginend">mail.mime.uudecode. ignoremissingbeginend</A></TD>
 * <TD>boolean</TD>
 * <TD>
 * If set to <code>"true"</code>, a missing "being" or "end" line in a
 * uuencoded document will be ignored when reading a message part.
 * If set to <code>"false"</code>, an exception is thrown for a
 * uuencoded message part without the required "begin" and "end" lines.
 * The default is false.
 * </TD>
 * </TR>
 *
 * <TR>
 * <TD><A ID="mail.mime.ignorewhitespacelines">mail.mime. ignorewhitespacelines</A></TD>
 * <TD>boolean</TD>
 * <TD>
 * Normally the header of a MIME part is separated from the body by an empty
 * line.  This System property may be set to <code>"true"</code> to cause
 * the parser to consider a line containing only whitespace to be an empty
 * line.  The default value of this property is false.
 * </TD>
 * </TR>
 *
 * <TR>
 * <TD><A ID="mail.mime.ignoremultipartencoding">mail.mime. ignoremultipartencoding</A></TD>
 * <TD>boolean</TD>
 * <TD>
 * The MIME spec does not allow body parts of type multipart/* to be encoded.
 * The Content-Transfer-Encoding header is ignored in this case.
 * Setting this System property to <code>"false"</code> will
 * cause the Content-Transfer-Encoding header to be honored for multipart
 * content.
 * The default value of this property is true.
 * </TD>
 * </TR>
 *
 * <TR>
 * <TD><A ID="mail.mime.allowencodedmessages">mail.mime.allowencodedmessages</A></TD>
 * <TD>boolean</TD>
 * <TD>
 * The MIME spec does not allow body parts of type message/* to be encoded.
 * The Content-Transfer-Encoding header is ignored in this case.
 * Some versions of Microsoft Outlook will incorrectly encode message
 * attachments.  Setting this System property to <code>"true"</code> will
 * cause the Content-Transfer-Encoding header to be honored for message
 * attachments.
 * The default value of this property is false.
 * </TD>
 * </TR>
 *
 * <TR>
 * <TD><A ID="mail.mime.contenttypehandler">mail.mime.contenttypehandler</A></TD>
 * <TD>String</TD>
 * <TD>
 * In some cases Jakarta Mail is unable to process messages with an invalid
 * Content-Type header.  The header may have incorrect syntax or other
 * problems.  This property specifies the name of a class that will be
 * used to clean up the Content-Type header value before Jakarta Mail uses it.
 * The class must have a method with this signature:
 * <CODE>public static String cleanContentType(MimePart mp, String contentType)</CODE>
 * Whenever Jakarta Mail accesses the Content-Type header of a message, it
 * will pass the value to this method and use the returned value instead.
 * The value may be null if the Content-Type header isn't present.
 * Returning null will cause the default Content-Type to be used.
 * The MimePart may be used to access other headers of the message part
 * to determine how to correct the Content-Type.
 * Note that the Content-Type handler doesn't affect the
 * <CODE>getHeader</CODE> method, which still returns the raw header value.
 * Note also that the handler doesn't affect the IMAP provider; the IMAP
 * server is responsible for returning pre-parsed, syntactically correct
 * Content-Type information.
 * </TD>
 * </TR>
 *
 * <TR>
 * <TD><A ID="mail.mime.address.usecanonicalhostname">mail.mime.address.usecanonicalhostname</A></TD>
 * <TD>boolean</TD>
 * <TD>
 * Use the
 * {@link java.net.InetAddress#getCanonicalHostName InetAddress.getCanonicalHostName}
 * method to determine the host name in the
 * {@link jakarta.mail.internet.InternetAddress#getLocalAddress InternetAddress.getLocalAddress}
 * method.
 * With some network configurations, InetAddress.getCanonicalHostName may be
 * slow or may return an address instead of a host name.
 * In that case, setting this System property to false will cause the
 * {@link java.net.InetAddress#getHostName() InetAddress.getHostName()}
 * method to be used instead.
 * The default is true.
 * </TD>
 * </TR>
 *
 * </TABLE>
 * <P>
 * The current
 * implementation of classes in this package log debugging information using
 * {@link java.util.logging.Logger} as described in the following table:
 * </P>
 * <TABLE BORDER="1">
 * <CAPTION>Jakarta Mail Loggers</CAPTION>
 * <TR>
 * <TH>Logger Name</TH>
 * <TH>Logging Level</TH>
 * <TH>Purpose</TH>
 * </TR>
 *
 * <TR>
 * <TD>jakarta.mail.internet</TD>
 * <TD>FINE</TD>
 * <TD>General debugging output</TD>
 * </TR>
 * </TABLE>
 */
package jakarta.mail.internet;