PIRL.Messenger

## Class Messenger

- java.lang.Object
- - PIRL.Messenger.Messenger

    public class Messenger
    extends Object

A Messenger sends and receives Messages over a communication channel and routes received messages to their destination.

#### Client Communication

A Messenger has a client communication channel to which Messages may be sent and from which they may be received. Messages may be received synchronously or asynchronously. A message that is received synchronously is returned directly to the caller. A timeout for synchronous message receipt may be specified to prevent indefinate blocking if no message arrives. Because only one communication channel is used for receiving messages synchronous receiving of messages can not be done while messages are being received asynchronously. Messages are received asynchronously on a separate message reader thread which waits indefinately until a message arrives and then dispatches the message based on its address routing information.

Sending and receiving of messages is thread safe. A Message will be completely sent before another will be allowed to be sent. A Message will be completely received and delivered before another will be received. A Message may be sent by one thread while a Message is being received and delivered by another thread. While a Message is being sent or received and delivered another thread trying to do the same operation will be blocked until the current operation completes. Message level synchronization ensures that Messages will not collide and be corrupted during transmission.

The client communication channel may be closed at any time at either end of the channel. When the channel is closed an explanation may be provided which is then delivered in a Message to the Messenger Employer. This offers the employer an opportunity to take appropriate action. Once the client communication channel is closed in can not be reopened. To reopen communication with the client a new Messenger must be constructed.

#### Message Routing

Messages received asynchronously are examined for routing information. Each Messenger has a unique address which is always added to a Message's route-from list when it is sent. On receipt if the last entry of a Message's route-to list is the address of the receiving Messenger, or the route-to list is empty, the Message is delivered to the Messenger employer. If the address matches that of a forwarding Messenger it is used to send the Message. If the address is unknown the Message is sent back with an appropriate undeliverable notation.

#### Message Content

In addition to routing information contained in the Message label, the Message body may have any content that can be represented using Parameter Value Language (PVL) formatting.

The input stream that is read is assumed to have one character per byte. This is because a Message is based on PVL formatted syntax using US-ASCII encoded text. The `message start synchronization sequence`, which is critical for identifying the location of a message in the communication channel byte stream, must be composed of the required ASCII characters if it is to be recognized (this is done automatically by the Message class). Multi-byte message body characters and binary data may be transmitted in ASCII transcoded form such as standard HTML character references for multi-byte characters and hexadecimal value character pairs for binary bytes, but it is the responsibility of the application using the delivered Message to interpret transcoded sequences.

#### Message Statistics

A count of the total number of Messages successfully sent and received is maintained. Also a count of Messages dropped because they could not be sent or received for any reason is maintained. If a Message can not be sent or received due to a problem with the client communication channel the channel is closed and the Messenger employer is notified with a Done Message.

See Also:
  `Message`

### Field Summary

Fields
`static String` `ACTION_PARAMETER_NAME` Message parameter specifying the action associated with a Message.
`static String` `ADDRESS_PARAMETER_NAME` `Identity` Message parameter set to contain the Messenger Address.
`static char` `ADDRESS_SEGMENT_DELIMITER` The delimiter character separating the sections of a Messenger `address`.
`static SimpleDateFormat` `DATE_FORMAT` Date formatter used to represent the Messenger `start time`.
`static String` `DATE_FORMATTING` The `DATE_FORMAT` pattern.
`static int` `DEFAULT_BUFFER_INCREMENT` The read buffer size increment.
`static int` `DEFAULT_CLOSE_TIME` The amount of time, in seconds, to wait for closing a socket to complete.
`static int` `DEFAULT_CONNECT_TIMEOUT` The amount of time, in seconds, to wait for a server `connection`.
`static String` `EXCEPTION_PARAMETER_NAME` A parameter containing an exception description.
`static String` `EXPLANATION_PARAMETER_NAME` A parameter containing an explanation description.
`static String` `FORWARDING_MESSENGERS_PARAMETER_NAME` The name of the `forwarding Messengers` identities parameter group.
`static String` `ID` Class identification name with source code version and date.
`protected Message` `Identity` An optional Message containing parameters used to `identify` the Messenger by employer applications.
`static String` `IDENTITY_PARAMETER_NAME` The name given to an `Identity Message`.
`static int` `MAX_LABEL_LENGTH_DIGITS` Maximum number of digits in the message label length value sequence.
`static int` `MAX_RECONNECT_ATTEMPTS` The maximum number of repeated server reconnect tries.
`static String` `MESSENGER_ADDRESS_PARAMETER_NAME` Message `ACTION_PARAMETER_NAME` value sent in response to receiving an `ADDRESS_PARAMETER_NAME` action Message for `delivery`.
`static int` `MINIMUM_BUFFER_SIZE` The minimum size of the read buffer.
`static String` `NAME_PARAMETER_NAME` The name of the identity parameter that provides the name of the Messenger being identified.
`static String` `ORIGINAL_MESSAGE_PARAMETER_NAME` Group of parameters containing the bounced message in an `UNDELIVERABLE_ACTION` Message.
`static String` `ROUTE_FROM_PARAMETER_NAME` Message label parameter whose value is the message `route-from list`.
`static String` `ROUTE_TO_PARAMETER_NAME` Message label parameter whose value is the message `route-to list`.
`static String` `UNDELIVERABLE_ACTION` Bounced message due to unknown route-to address Message `ACTION_PARAMETER_NAME` value.

### Constructor Summary

Constructors
Constructor and Description
`Messenger(Message_Delivered_Listener employer, InetSocketAddress client_address)` Construct a Messenger on a client's connection address.
`Messenger(Message_Delivered_Listener employer, SocketChannel client_channel)` Construct a Messenger on a client's communication channel connection.
`Messenger(Message_Delivered_Listener employer, String host, int port)` Construct a Messenger to a client on a specified host and port.
`Messenger(String host, int port)` Construct a Messenger to a client on a specified host and port.

### Method Summary

Methods
`Messenger` `Add_Forwarding(Messenger messenger)` Add a Messenger to the Message forwarding list.
`String` `Address()` Get the address of this Messenger.
`int` `Buffer_Capacity()` Get the capacity of the read buffer.
`int` `Buffer_Increment()` Get the read buffer increment amount.
`Messenger` `Buffer_Increment(int amount)` Set the read buffer increment amount.
`SocketChannel` `Client_Channel()` Get the client communication channel.
`String` `Client_Hostname()` Get the connonical, fully qualified hostname for the remote host to which the Messenger communication channel is connected.
`int` `Client_Port()` Get the remote port number of the Message communication channel.
`static void` `Configure_Socket(Socket socket)` Configures a Socket.
`static int` `Connect_Timeout()` Get the amount of time, in seconds, to wait for the communication channel to connect.
`static void` `Connect_Timeout(int timeout)` Set the amount of time, in seconds, to wait for the communication channel to connect.
`static SocketChannel` `Connect(SocketAddress address)` Connect to a SocketAddress.
`static int` `Default_Buffer_Increment()` Get the current default read buffer increment amount.
`static int` `Default_Buffer_Increment(int amount)` Set the default size to use for the read buffer increment.
`protected void` `Deliver(Message message)` Deliver a Message locally.
`boolean` `Done()` Force the Messenger to close its client communication channel.
`void` `Done(String explanation)` Force the Messenger to close its communication channel and deliver a `Done` Message.
`void` `Done(String explanation, Exception exception)` Deliver a `Done` Message to the `employer` and close its communication channel.
`Message_Delivered_Listener` `Employer()` Get the Messenger employer.
`Messenger` `Employer(Message_Delivered_Listener employer)` Set the Messenger employer.
`Exception` `Error_Condition()` Get the most recent error exception.
`Messenger` `Forwarding_Messenger(String address)` Get the Messenger associated with a forwarding address.
`Message` `Forwarding_Messengers()` Get the identities of all Messengers in the forwarding list.
`Message` `Identity()` Get the Message describing the identity of this Messenger.
`Messenger` `Identity(Message identity)` Set the identity of this Messenger.
`boolean` `Is_Connected()` Test if the Messenger's communication channel is connected to the client.
`Thread` `Listen_for_Messages()` Start the Messenger thread listening for messages.
`boolean` `Listening_for_Messages()` Test if the Messenger thread is running and marked to continue `listening for messages`.
`long` `Message_Bytes_Received()` Get the number of message bytes `received`.
`long` `Message_Bytes_Sent()` Get the number of message bytes `sent`.
`static ThreadGroup` `Message_Listeners()` Get the group of all message listener threads.
`long` `Messages_Received_Corrupted()` Get the number of Messages received that were corrupted in transmission.
`long` `Messages_Received_Dropped()` Get the number of Messages that were dropped becasue they could not be completely `received`.
`long` `Messages_Received()` Get the number of Messages successfully `received`.
`long` `Messages_Sent_Corrupted()` Get the number of Messages to be `sent` that had content for which a PVL representation could not be generated.
`long` `Messages_Sent_Dropped()` Get the number of Messages that could not be `sent`.
`long` `Messages_Sent()` Get the number of Messages successfully `sent`.
`long` `Messages_Unforwardable()` Get the number of Messages that could not be `forwarded`.
`int` `Port()` Get the local port number used to communicate Messages.
`protected Message` `Read_Packet(int timeout)` Read a Message packet from the communication channel.
`Message` `Receive()` Receive a message synchronously.
`Message` `Receive(int timeout)` Receive a message synchronously.
`boolean` `Remove_Forwarding(Messenger messenger)` Remove a Messenger from the Message forwarding list.
`Messenger` `Reset_Error_Condition()` Clear the most recent error condition.
`protected void` `Route_Packet(Message message, ByteBuffer content)` Route a message packet to a recipient.
`protected void` `Send_Packet(Message message_label, ByteBuffer content)` Send the message packet.
`void` `Send(Message message)` Send a Message over the communication channel.
`Messenger` `Shrink_Buffer()` Shrink the read buffer size.
`long` `Start_Time()` Get the time when this Messenger was constructed.
`boolean` `Stop_Listening_for_Messages()` Flag the Messenger thread to stop `listening for messages`.
`String` `toString()` Get a description of this Messenger.
`protected void` `Update_Send_Routing(Message message)` Update the message send routing information of a Message.

### Methods inherited from class java.lang.Object

`clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait`

### Field Detail

#### ID

    public static final String ID

Class identification name with source code version and date.

See Also:
  Constant Field Values

#### DATE_FORMATTING

    public static final String DATE_FORMATTING

The `DATE_FORMAT` pattern.

The date format is:

d MMMMM yyyy kk:mm:ss.SSS Z

where d is the day number in the month (one or two digits), MMMMM is the full month name in the year, yyyy is the full year number, kk is the hour in the 24 hour day (two digits), mm is the minute in the hour (two digits), ss is the second in the minute (two digits), SSS is the millisecond in the second (three digits), and Z is the hours-minutes offset of the local time zone from the reference UTC zone.

See Also:
  Constant Field Values

#### DATE_FORMAT

    public static final SimpleDateFormat DATE_FORMAT

Date formatter used to represent the Messenger `start time`.

See Also:
  `DATE_FORMATTING`

#### ADDRESS_SEGMENT_DELIMITER

    public static final char ADDRESS_SEGMENT_DELIMITER

The delimiter character separating the sections of a Messenger `address`.

See Also:
  Constant Field Values

#### Identity

    protected Message Identity

An optional Message containing parameters used to `identify` the Messenger by employer applications.

The content of the message is determined by the application.

#### IDENTITY_PARAMETER_NAME

    public static final String IDENTITY_PARAMETER_NAME

The name given to an `Identity Message`.

See Also:
  Constant Field Values

#### NAME_PARAMETER_NAME

    public static final String NAME_PARAMETER_NAME

The name of the identity parameter that provides the name of the Messenger being identified.

See Also:
  Constant Field Values

#### ADDRESS_PARAMETER_NAME

    public static final String ADDRESS_PARAMETER_NAME

`Identity` Message parameter set to contain the Messenger Address.

See Also:
  Constant Field Values

#### MESSENGER_ADDRESS_PARAMETER_NAME

    public static final String MESSENGER_ADDRESS_PARAMETER_NAME

Message `ACTION_PARAMETER_NAME` value sent in response to receiving an `ADDRESS_PARAMETER_NAME` action Message for `delivery`.

See Also:
  Constant Field Values

#### ROUTE_TO_PARAMETER_NAME

    public static final String ROUTE_TO_PARAMETER_NAME

Message label parameter whose value is the message `route-to list`.

See Also:
  `Message.Packet_Label(int)`, Constant Field Values

#### ROUTE_FROM_PARAMETER_NAME

    public static final String ROUTE_FROM_PARAMETER_NAME

Message label parameter whose value is the message `route-from list`.

See Also:
  `Message.Packet_Label(int)`, Constant Field Values

#### ACTION_PARAMETER_NAME

    public static final String ACTION_PARAMETER_NAME

Message parameter specifying the action associated with a Message.

See Also:
  Constant Field Values

#### FORWARDING_MESSENGERS_PARAMETER_NAME

    public static final String FORWARDING_MESSENGERS_PARAMETER_NAME

The name of the `forwarding Messengers` identities parameter group.

See Also:
  Constant Field Values

#### MAX_LABEL_LENGTH_DIGITS

    public static final int MAX_LABEL_LENGTH_DIGITS

Maximum number of digits in the message label length value sequence.

The message start synchronization sequence includes the length of the message label section as a decimal integer value. The text representation of the label length value has a maximum number of digits for a reasonable value. Seven digits should be more than sufficient for the largest reasonable label length values.

See Also:
  `DEFAULT_BUFFER_INCREMENT`, Constant Field Values

#### MINIMUM_BUFFER_SIZE

    public static final int MINIMUM_BUFFER_SIZE

The minimum size of the read buffer.

The minimum read buffer size must allow for the Message start synchronization sequence:

1. `Message.START_MARKER`
2. `Message.START_MARKER_DELIMITER`
3. Up to `MAX_LABEL_LENGTH_DIGITS`
4. `Message.START_MARKER_END`

See Also:
  `DEFAULT_BUFFER_INCREMENT`

#### DEFAULT_BUFFER_INCREMENT

    public static final int DEFAULT_BUFFER_INCREMENT

The read buffer size increment.

When additional read buffer capacity is needed for storing an incoming message the buffer size is increased by a multiple of the size increment to at least the required capacity. It follows that the initital read buffer size is the size increment.

A reasonable buffer size increment will not be too small so that buffer expansion reallocation and data content copying will not need to happen too often; yet not so large that an excessive buffer size will result. It must not be smaller than the `MINIMUM_BUFFER_SIZE`. The read buffer size will be increased as needed, but never decreased unless `Shrink_Buffer()` is called.

See Also:
  Constant Field Values

#### UNDELIVERABLE_ACTION

    public static final String UNDELIVERABLE_ACTION

Bounced message due to unknown route-to address Message `ACTION_PARAMETER_NAME` value.

See Also:
  Constant Field Values

#### ORIGINAL_MESSAGE_PARAMETER_NAME

    public static final String ORIGINAL_MESSAGE_PARAMETER_NAME

Group of parameters containing the bounced message in an `UNDELIVERABLE_ACTION` Message.

See Also:
  Constant Field Values

#### EXPLANATION_PARAMETER_NAME

    public static final String EXPLANATION_PARAMETER_NAME

A parameter containing an explanation description.

See Also:
  Constant Field Values

#### EXCEPTION_PARAMETER_NAME

    public static final String EXCEPTION_PARAMETER_NAME

A parameter containing an exception description.

See Also:
  Constant Field Values

#### DEFAULT_CONNECT_TIMEOUT

    public static final int DEFAULT_CONNECT_TIMEOUT

The amount of time, in seconds, to wait for a server `connection`.

See Also:
  Constant Field Values

#### MAX_RECONNECT_ATTEMPTS

    public static final int MAX_RECONNECT_ATTEMPTS

The maximum number of repeated server reconnect tries.

See Also:
  Constant Field Values

#### DEFAULT_CLOSE_TIME

    public static final int DEFAULT_CLOSE_TIME

The amount of time, in seconds, to wait for closing a socket to complete.

See Also:
  Constant Field Values

### Constructor Detail

#### Messenger

    public Messenger(Message_Delivered_Listener employer,
             SocketChannel client_channel)
              throws IllegalArgumentException

Construct a Messenger on a client's communication channel connection.

The `address` and `identity` are intialized.

Parameters:
  `employer` - The Message_Delivered_Listener to which messages will be delivered that are not automatically forwared. If null, messages can only be `received` synchronously until an `employer` is assigned.
  `client_channel` - The SocketChannel to which messages will be sent and from which they will be received.
Throws:
  `IllegalArgumentException` - If the client is null.

#### Messenger

    public Messenger(Message_Delivered_Listener employer,
             InetSocketAddress client_address)
              throws IllegalArgumentException,
                     IOException

Construct a Messenger on a client's connection address.

The client address is used to `connect` to the client's communication channel.

The `address` and `identity` are intialized.

Parameters:
  `employer` - The Message_Delivered_Listener to which messages will be delivered that are not automatically forwared. If null, messages can only be `received` synchronously until an `employer` is assigned.
  `client_address` - An InetSocketAddress to be used in establishing a communication channel with the client.
Throws:
  `IllegalArgumentException` - If either the employer or server is null.
  `IOException` - If there was a problem connecting to the server.
See Also:
  `Messenger(Message_Delivered_Listener, SocketChannel)`

#### Messenger

    public Messenger(Message_Delivered_Listener employer,
             String host,
             int port)
              throws IllegalArgumentException,
                     IOException

Construct a Messenger to a client on a specified host and port.

The hostname and port number define the address of the client where the communication channel connection is to be made.

The `address` and `identity` are intialized.

Parameters:
  `employer` - The Message_Delivered_Listener to which messages will be delivered that are not automatically forwared. If null, messages can only be `received` synchronously until an `employer` is assigned.
  `host` - The name or IP address of the host system where the server is running.
  `port` - The port number on the server host system to use when establishing a connection.
Throws:
  `IllegalArgumentException` - If either the employer or hostname is null or the port number is invalid.
  `IOException` - If there was a problem connecting to the server.
See Also:
  `Messenger(Message_Delivered_Listener, InetSocketAddress)`

#### Messenger

    public Messenger(String host,
             int port)
              throws IllegalArgumentException,
                     IOException

Construct a Messenger to a client on a specified host and port.

The hostname and port number define the address of the client where the communication channel connection is to be made.

The `address` and `identity` are intialized.

N.B.: Messages can only be `received` synchronously until an `employer` is assigned.

Parameters:
  `host` - The name or IP address of the host system where the server is running.
  `port` - The port number on the server host system to use when establishing a connection.
Throws:
  `IllegalArgumentException` - If either the employer or hostname is null or the port number is invalid.
  `IOException` - If there was a problem connecting to the server.
See Also:
  `Messenger(Message_Delivered_Listener, String, int)`

### Method Detail

#### Address

    public String Address()

Get the address of this Messenger.

The format of the address is:

IP_ADDRESS:Port:Start_Time

where IP_ADDRESS is the `Internet Protocol address` of the host system, `Port` is the local port number used to communicate Messages, and `Start_Time` is the time when this Messgener was constructed. This address is used to uniquely identify this Messenger when Messages are `sent` and `received`.

Returns:
  The address String for this Messenger.
See Also:
  `Message.Route_To()`, `Message.Route_From()`

#### Start_Time

    public long Start_Time()

Get the time when this Messenger was constructed.

The `time` is obtained from the host system as the difference, measured in milliseconds, between the Messenger construction time and midnight, January 1, 1970 UTC.

#### Identity

    public Message Identity()

Get the Message describing the identity of this Messenger.

N.B.: A reference to, not a copy of, the identity Message is returned. This is done because the identity Message is not owned by the Messenger; it is controlled by the application.

Returns:
  A Message containing parameters the identify this Messenger. This will be null if no {#Identity(Message) identity} has been assigned.

#### Identity

    public Messenger Identity(Message identity)

Set the identity of this Messenger.

The specified Message is copied, unless it is null in which case an empty message is provided.

The identity Message may contain any parameters used by the employing application to identify this Messenger. The identity Message will be given the Name `IDENTITY_PARAMETER_NAME` and it will be guaranteed to contain an `ADDRESS_PARAMETER_NAME` with the `address` of this Messenger as its value. If the identity Message contains an `ACTION_PARAMETER_NAME` parameter it is removed.

Parameters:
  `identity` - A Message containing parameters that describe the identity of this Messenger.
Returns:
  This Messenger.

#### toString

    public String toString()

Get a description of this Messenger.

Overrides:
  `toString` in class `Object`
Returns:
  A String describing this Messenger.

#### Connect_Timeout

    public static int Connect_Timeout()

Get the amount of time, in seconds, to wait for the communication channel to connect.

Returns:
  The connection timeout, in seconds.
See Also:
  `Connect_Timeout(int)`

#### Connect_Timeout

    public static void Connect_Timeout(int timeout)

Set the amount of time, in seconds, to wait for the communication channel to connect.

Parameters:
  `timeout` - The connection timeout, in seconds. If less than one the `DEFAULT_CONNECT_TIMEOUT` will be used.
See Also:
  `Connect(SocketAddress)`

#### Client_Hostname

    public String Client_Hostname()

Get the connonical, fully qualified hostname for the remote host to which the Messenger communication channel is connected.

Returns:
  The remote hostname String, or null if the Messenger is not connected. This may, of course, be the same as the local `Host.FULL_HOSTNAME`.

#### Client_Port

    public int Client_Port()

Get the remote port number of the Message communication channel.

N.B.: The availability of a remote port number does not imply that the communication channel `is connected`.

Returns:
  The port number on the remote host system (which, of course, may be the same as the local host system) used for Message communication. This will be 0 if the Messenger is not yet connected.

#### Is_Connected

    public boolean Is_Connected()

Test if the Messenger's communication channel is connected to the client.

A Messenger is connected if the `client communication channel` is open and connected.

Returns:
  true if the client communication channel is connected; false otherwise.

#### Client_Channel

    public SocketChannel Client_Channel()

Get the client communication channel.

Returns:
  The SocketChannel used for communication with the Messenger's client.
See Also:
  `Is_Connected()`

#### Port

    public int Port()

Get the local port number used to communicate Messages.

The port number is determined by the communication channel used to construct the Messenger. All Messages `received` will be read from this port and all Messages `sent` will be written to this port.

Returns:
  The communication local port number.

#### Employer

    public Message_Delivered_Listener Employer()

Get the Messenger employer.

Messages recieved are `delivered` to the employer if they are addressed to this Messanger or have no address.

Returns:
  A Message_Delivered_Listener employer object.
See Also:
  `Message_Delivered_Listener`, `Employer(Message_Delivered_Listener)`

#### Employer

    public Messenger Employer(Message_Delivered_Listener employer)

Set the Messenger employer.

Messages recieved are `delivered` to the employer if they are addressed to this Messanger or have no address.

Parameters:
  `employer` - A Message_Delivered_Listener employer object.
Returns:
  This Messenger.
Throws:
  `IllegalArgumentException` - If the employer is null.
See Also:
  `Message_Delivered_Listener`

#### Add_Forwarding

    public Messenger Add_Forwarding(Messenger messenger)

Add a Messenger to the Message forwarding list.

When a message is asynchronously received it is `routed` based on its route-to address list. The list of forwarding Messengers provide routing possibilities in addition to delivery to the employer of this Messenger.

Parameters:
  `messenger` - A Messenger. If null nothing is done.
Returns:
  This Messenger.
See Also:
  `Remove_Forwarding(Messenger)`, `Forwarding_Messenger(String)`

#### Remove_Forwarding

    public boolean Remove_Forwarding(Messenger messenger)

Remove a Messenger from the Message forwarding list.

Parameters:
  `messenger` - A Messenger.
Returns:
  true if the Messenger was found in the list and removed; false otherwise.
See Also:
  `Add_Forwarding(Messenger)`

#### Forwarding_Messenger

    public Messenger Forwarding_Messenger(String address)

Get the Messenger associated with a forwarding address.

Parameters:
  `address` - A Messenger (@link #Address() address}. If null null is returned.
Returns:
  A Messenger, or null if the address does not match that of any Messenger in the `forward Messenger list`.
See Also:
  `Add_Forwarding(Messenger)`

#### Forwarding_Messengers

    public Message Forwarding_Messengers()

Get the identities of all Messengers in the forwarding list.

Returns:
  A `FORWARDING_MESSENGERS_PARAMETER_NAME` Message containing the identities of all the Messengers in the forwarding list. This will be null if the forwarding list is empty.

#### Messages_Sent

    public long Messages_Sent()

Get the number of Messages successfully `sent`.

Returns:
  The number of Messages successfully sent.

#### Message_Bytes_Sent

    public long Message_Bytes_Sent()

Get the number of message bytes `sent`.

Message bytes include the message transmission `label` and the message body content.

Returns:
  The total number of message packet bytes sent.

#### Messages_Sent_Dropped

    public long Messages_Sent_Dropped()

Get the number of Messages that could not be `sent`.

Returns:
  The number of Messages that could not be sent because the output was shutdown.

#### Messages_Sent_Corrupted

    public long Messages_Sent_Corrupted()

Get the number of Messages to be `sent` that had content for which a PVL representation could not be generated.

Returns:
  The number of Messages that could not be sent because the content was corrupted.

#### Messages_Received

    public long Messages_Received()

Get the number of Messages successfully `received`.

Returns:
  The number of Messages successfully received.

#### Message_Bytes_Received

    public long Message_Bytes_Received()

Get the number of message bytes `received`.

Message bytes include the message transmission `label` and the message body content.

Returns:
  The total number of message packet bytes received.

#### Messages_Received_Dropped

    public long Messages_Received_Dropped()

Get the number of Messages that were dropped becasue they could not be completely `received`.

Returns:
  The number of Messages that were dropped due to input shutdown before the message was completely received.

#### Messages_Received_Corrupted

    public long Messages_Received_Corrupted()

Get the number of Messages received that were corrupted in transmission.

Returns:
  The number of Messages that were received but their PVL content could not be correctly parsed.

#### Messages_Unforwardable

    public long Messages_Unforwardable()

Get the number of Messages that could not be `forwarded`.

Returns:
  The number of Messages that could not be forwarded due to an IOException.

#### Error_Condition

    public Exception Error_Condition()

Get the most recent error exception.

Returns:
  The Exception that most recently occured during while attempting to `send` or `receive` a message. This will be null if no error condition has occurred since the Messenger was constructed or the last `reset` of the error condition.

#### Reset_Error_Condition

    public Messenger Reset_Error_Condition()

Clear the most recent error condition.

Returns:
  This Messenger.
See Also:
  `Error_Condition()`

#### Default_Buffer_Increment

    public static int Default_Buffer_Increment(int amount)

Set the default size to use for the read buffer increment.

This value is only used when a Messenger is constructed and when a specified `read buffer increment` is to be set to the default value.

Parameters:
  `amount` - The size, in bytes, of the default read buffer increment.
Returns:
  The previous read buffer increment amount.
See Also:
  `Buffer_Increment(int)`

#### Default_Buffer_Increment

    public static int Default_Buffer_Increment()

Get the current default read buffer increment amount.

Returns:
  The current default read buffer increment amount.

#### Buffer_Increment

    public Messenger Buffer_Increment(int amount)

Set the read buffer increment amount.

The read buffer holds the message packet for a message that has been received until the message is delivered or forwarded.

While a message packet is being read from the communication channel if the read buffer is found to have insufficient space for the message packet content being read the buffer capacity is increased by to the amount of space required rounded up to the next buffer increment amount.

If a `buffer shrink` is pending it will remain pending after the new buffer increment is set.

Parameters:
  `amount` - The read buffer increment amount. This will not be allowed to be less than the `MINIMUM_BUFFER_SIZE`. If the specified amount is less than or equal to zero the `default buffer increment` is used.

#### Buffer_Increment

    public int Buffer_Increment()

Get the read buffer increment amount.

Returns:
  The read buffer increment amount.

#### Buffer_Capacity

    public int Buffer_Capacity()

Get the capacity of the read buffer.

Returns:
  The capacity of the read buffer.
See Also:
  `Shrink_Buffer()`

#### Shrink_Buffer

    public Messenger Shrink_Buffer()

Shrink the read buffer size.

When the next Message is read the size of the read buffer will be reduced to the minimum capacity to hold the Message. This capacity will be the Message label and content size rounded up to the next multiple of the `buffer size increment`. The buffer shrink will not be done again until this method is called again.

N.B.: In general, the read buffer should be allowed to expand to the maximum size for messages to be read after which point the buffer will no longer need to be reallocated (a relatively expensive operation). However, if an extraordinarily large message has been read it might be beneficial to shrink the buffer to free the excess storage.

Returns:
  This Messenger.
See Also:
  `Buffer_Capacity()`

#### Listening_for_Messages

    public boolean Listening_for_Messages()

Test if the Messenger thread is running and marked to continue `listening for messages`.

To only test if the Messenger thread is running use `Thread.isAlive()`.

Returns:
  If true the Messenger thread is running and marked to continue listening for messages. If false the Messenger thread will stop listening for messages after the current Message is handled, or the next Message is handled if the Messenger thread is waiting for an incoming message.
See Also:
  `Stop_Listening_for_Messages()`

#### Listen_for_Messages

    public Thread Listen_for_Messages()

Start the Messenger thread listening for messages.

Asynchronous message receipt can only occur when this Messenger has an `employer` to whom the messages will be delivered.

If the message listener thread is not running and the Messenger is `connected` it will be started.

Returns:
  The message listenter Thread. This will be null only if the Messenger is not connected.
Throws:
  `IllegalStateException` - If the Messenger was constructed without an employer.
See Also:
  `Listening_for_Messages()`, `Stop_Listening_for_Messages()`

#### Stop_Listening_for_Messages

    public boolean Stop_Listening_for_Messages()

Flag the Messenger thread to stop `listening for messages`.

The Messenger thread is flagged to stop listening for messages after the current Message is handled, or the next Message is handled if the Messenger thread is currently waiting for an incoming message.

N.B.: The Messenger thread, if it is running, will not stop immediately. To wait for the Messenger thread to stop:

``

        messenger.Stop_Listening_for_Messages ();
        while (messenger.isAlive ())
            {
            try {messenger.join ())
            catch (InterruptedException e) {}
            }

Returns:
  true if the Messenger has stopped listing for messages; false if the Messenger has not yet stopped.

#### Message_Listeners

    public static ThreadGroup Message_Listeners()

Get the group of all message listener threads.

When a Messenger begins to asynchronously `listen for messages` it runs a Thread which excecutes a loop that waits for a message packet to be `read` and then `routes` the packet for delivery. The message listener thread will only stop on its own if a) after handling a message that has been read, the thread has been `flagged to stop`; b) the communication input channel has been shutdown; or c) an unexpected exception occurs.

Each message listener thread is placed in a ThreadGroup named "Messengers" that is used by all Messengers. The name of each message listener thread in the group is the Messenger's `address`.

Returns:
  The ThreadGroup containing all the message listener threads in use by Messengers.

#### Send

    public void Send(Message message)
              throws IOException,
                     PVL_Exception

Send a Message over the communication channel.

The message label routing information is `updated`. Then the Message is converted to a `message packet` which is `sent` to the output channel. After successfully sending the message the count of (@link #Messages_Sent() messages sent} is incremented and the count of `message bytes sent` is updated.

If the message can not be sent because the content can not be represented by PVL syntax the count of `corrupted send messages` is incremented and the `error condition` is noted.

Parameters:
  `message` - The Message to be sent. If null or empty, nothing is sent.
Throws:
  `EOFException` - If the output communication channel was found to be shutdown before attempting to send the message.
  `IOException` - If there was a problem while writing the message to the communication channel.
  `PVL_Exception` - If the message content contains parameters that can not be represented by the Message PVL syntax.

#### Send_Packet

    protected void Send_Packet(Message message_label,
                   ByteBuffer content)
                        throws IOException

Send the message packet.

If the content is null or has nothing remaining, nothing is done.

If the output channel has been shutdown the count of `send messages dropped` is incremented, the `error condition` is set to an EOFException, and the Messenger is put in the `done` state.

If the message label is not null its routing information is `updated` and then converted to a `packet label String` which is wrapped in a ByteBuffer that is added to a message content buffers array. If the message label is null the packet content contains the entire message, including the message label, as provided by the `message packet` generator.

The content ByteBuffer is added to a message message content buffers array and the sequence of buffers is written to the output channel. This is done as a single operation, rather than writing the message label separately from the message body content, to ensure that the message will not be inadvertently interleaved with another message being written to the same ouput channel at the same time. The count of `messages sent` is incremented and the count of `message bytes sent` is updated.

If the message packet can not be transmitted the count of `send messages dropped` is incremented, the `error condition` is set to the exception that occured, and the Messenger is put in the `done` state.

N.B.: The message routing address lists are only updated if a message label is provided. Otherwise the content buffer is presumed to already contain the correct routing information.

Parameters:
  `message_label` - A Message containing the message start synchronization sequence and the routing parameters. This may be null if the content contains the entire message including the message label.
  `content` - A ByteBuffer containing the message packet content. If null or empty nothing will be done.
Throws:
  `EOFException` - If the output communication channel was found to be shutdown before attempting to send the message.
  `IOException` - If there was a problem while writing the message to the communication channel.

#### Update_Send_Routing

    protected void Update_Send_Routing(Message message)

Update the message send routing information of a Message.

If the message is not null and `the last address on its route-to list` is the same as this Messenger's `address` it is (@link Message#Pop_To() removed from the route-to list} and added to the `route-from` list.

N.B.: This method is only intended for use when sending a message. Message `delivery` and synchronous `receive` is effectively "sending" the message to the Messenger `employer`.

Parameters:
  `message` - The Message to have its routing information updated. If null, nothing is done.

#### Receive

    public Message Receive(int timeout)
                    throws IllegalStateException,
                           IOException,
                           PVL_Exception

Receive a message synchronously.

If this Messenger is currently asynchronously listening for messages an IllegalStateException will be thrown. The Messenger must first be `flagged to stop listening` and have actually stopped.

A `message packet is read` from the input channel. Its routing information is `updated` and the packet content is used to set the `message content`.

Parameters:
  `timeout` - The maximum amount of time, in seconds, to wait for message arrival. If less than or equal to zero the wait will be indefinate.
Returns:
  The Message that was received. This will not be null.
Throws:
  `IllegalStateException` - If this Messenger is currently asynchronously listening for messages.
  `IOException` - If a message could not be read. There are various possible forms of this exception:

  SocketTimeoutException
    The timeout expired.
  EOFException
    The input channel was shutdown or closed.
  Other
    Read error on the input channel.
  `PVL_Exception` - If the message content can not be parsed or is not valid.

#### Receive

    public Message Receive()
                    throws IllegalStateException,
                           IOException,
                           PVL_Exception

Receive a message synchronously.

This is the same as `receiving a message` with no timeout.

Returns:
  The Message that was received. This will not be null.
Throws:
  `IllegalStateException` - If this Messenger is currently asynchronously listening for messages.
  `IOException` - If a message could not be read.
  `PVL_Exception` - If the message content can not be parsed or is not valid.

#### Read_Packet

    protected Message Read_Packet(int timeout)
                           throws IOException,
                                  PVL_Exception

Read a Message packet from the communication channel.

A Message packet is a tentative Message: A packet Message contains only the label section of the transmitted message; the message body content remains unparsed in the read buffer. The label section must start with the message start synchronization sequence:

1. `Message.START_MARKER`
2. `Message.START_MARKER_DELIMITER`
3. Up to `MAX_LABEL_LENGTH_DIGITS`
4. `Message.START_MARKER_END`

The input `communication channel` is read one byte/character at a time until the entire message start synchnronization sequence has been recognized. Any unexpected character value will cause the scan for the message start synchronization sequence to start again from the beginning. The digits in the start synchronization sequence represent the size of the message label section that follows. This many bytes are read from the input channel and used to construct a `message`. This message label has its `route-to list` and `route-from list` set from the `ROUTE_TO_PARAMETER_NAME` Value and `ROUTE_FROM_PARAMETER_NAME` Value, respectively, if they are present. The `content amount` of the message label is obtained and this many bytes are read from the input channel. The message is invalid if the content amount can not be obtained from the message label.

Though the content section of the message will have been read, it remains unparsed in the Read_Buffer with its position set to the beginning of the content data and its limit set to the end of message data. If the message packet is to be forwarded there is no need to parse the message content section; otherwise the Receive method will replace the Message with the content section to generate the Message to be delivered.

N.B.: If the label section can not be parsed the count of `corrupted messages` will be incremented and then it will not be possible to read the content section because its size is unknown. In this case message synchronization will creep over the remaining unread message to locate the beginning of the next message.

The count of `messages received` is incremented when an entire Message has been received. The count of `message bytes received` is updated as they are read. Thus the number of bytes received includes `corrupted messages`.

N.B.: It is the responsibility of the user to call the `Done` method if an exception is thrown. Done is not called here because this method is expected to be called within a block synchronized on the Read_Buffer and the Done method should not be called within this sychnronized block since the `delivery` of the `Done Message` could result in an Employer's delivery Thread calling Done again which would result in a deadlock.

Parameters:
  `timeout` - The amount of time (seconds) to wait for the arrival of the message before a timeout exception will occur.
Returns:
  A Messsage with message label section parameters with the To and From data members having been set from these parameters.
Throws:
  `IOException` - If there was a problem reading the message.
  `PVL_Exception` - If the label section could not be parsed as valid PVL syntax.

#### Route_Packet

    protected void Route_Packet(Message message,
                    ByteBuffer content)
                         throws PVL_Exception

Route a message packet to a recipient.

The packet's `next route-to address` examined. If there is an address (the route-to list was not empty) and the address matches the `address of this Messenger` then the `next address on the packet's route-to list`, if there is one, is compared with the addresses of the `forwarding Messengers list`. If the address is for a forwarding Messenger it is used to `send the packet`.

If the address removed from the route-to list is not for this Messenger (an empty route-to list is implicitly addressed to this Messenger) or a forwarding address is found that does not match the address of the forwarding Messenger, the message is bounced back to this Messenger's client. The bounce message contains an `UNDELIVERABLE_ACTION` `action parameter`, an `EXPLANATION_PARAMETER_NAME`, `ROUTE_TO_PARAMETER_NAME` and `ROUTE_FROM_PARAMETER_NAME` parameters `set` to the address routing of the undeliverable Message, and the message that was received as an `ORIGINAL_MESSAGE_PARAMETER_NAME`. If message forwarding failed an attempt will also be made to bounce the message back to this Messenger's client; an `EXCEPTION_PARAMETER_NAME` is included in this case that provides the detail message from the exception that occurred.

If the packet is neither forwarded nor bounced the Message `contains` is `delivered` to this Messenger's `employer`.

If the content could not be parsed as valid PVL the `corrupted messages count` is incremented and the `error condition` is noted.

Parameters:
  `message` - A received Message label. If null nothing is done.
  `content` - A ByteBuffer holding the message content.
Throws:
  `PVL_Exception` - If the content could not be parsed for Message delivery.

#### Deliver

    protected void Deliver(Message message)

Deliver a Message locally.

If the Message contains an `ADDRESS_PARAMETER_NAME` `ACTION_PARAMETER_NAME` value it is changed to `MESSENGER_ADDRESS_PARAMETER_NAME` and sent as a `reply to` the source of the Message. In effect this special Message is delivered to the Messenger which simply replies so the sender can it can obtain the address routing information for this Messenger.

If the Messenger has an `employer` all non-Address Messages are delivered to it. The `address` of this Messenger is `added to the Message's route-from list` and the `route-to list` is emptied. The employer's `Message_Delivered method` is invoked with a `Message_Delivered_Event` containing the Message obtained by this Messenger. N.B.: The delivery of Message is synchronized on the employer to prevent it changing while the during delivery; do not attempt changing the employer in the thread that receives the Message delivery or a deadlock will occur.

N.B.: If the Messenger has been constructed without an employer, and one has not been assigned, then obviously no Message can be delivered.

Parameters:
  `message` - The Message to be delivered to the employer. If null, nothing is done.

#### Done

    public boolean Done()

Force the Messenger to close its client communication channel.

Input and output for the socket of the `client communication channel` is shutdown if it not already done. The channel is then closed if it was open.

N.B.: No `Done` Message notification is delivered to the `employer`.

Returns:
  true if the Messenger was not done when the method was called (this call caused the communication channel I/O to be shutdown and/or closed); false if the communication channel had already been shutdown and closed for any reason.
See Also:
  `Done(String, Exception)`

#### Done

    public void Done(String explanation,
            Exception exception)

Deliver a `Done` Message to the `employer` and close its communication channel.

N.B.: The Done Message is delivered before the request to close the communication channel occurs; the communicaiton channel may already have been closed by an external event, however.

N.B.: Only one Done Message will ever be delivered by each Messenger object.

Parameters:
  `explanation` - If non-null an `EXPLANATION_PARAMETER_NAME` is included in the Done Message with the explanation text as its value.
  `exception` - If non-null an `EXCEPTION_PARAMETER_NAME` is included in the Done Message that provides the exception detail message as its value.
See Also:
  `Done()`, `Is_Connected()`

#### Done

    public void Done(String explanation)

Force the Messenger to close its communication channel and deliver a `Done` Message.

Parameters:
  `explanation` - If non-null an `EXPLANATION_PARAMETER_NAME` is included in the Done Message with the explanation text as its value.
See Also:
  `Done(String, Exception)`

#### Connect

    public static SocketChannel Connect(SocketAddress address)
                                 throws IOException,
                                        IllegalArgumentException

Connect to a SocketAddress.

A new SocketChannel is opened and its socket set to SO_REUSEADDR mode (which allows the socket to be bound to the address port even if it is currently in a closed connection timeout state). An attempt is then made using the socket to connect to the specified address with a connection timeout of `Connect_Timeout()` seconds. If the connection fails for any reason the SocketChannel is closed and the connection attempt is repeated. After `MAX_RECONNECT_ATTEMPTS` a failure to connect will throw the last exception that cause the connection to fail.

Parameters:
  `address` - The SocketAddress to which to connect.
Returns:
  A connected SocketChannel.
Throws:
  `IllegalArgumentException` - If the address is null.
  `IOException` - If there was a problem establishing the connection.

#### Configure_Socket

    public static void Configure_Socket(Socket socket)
                                 throws IOException

Configures a Socket.

The socket options are set to:

- Performance preferences with short connection time having top priority, followed by low latency priority over bandwidth.

  These priorities are a hint that may have no effect on the specific socket implementation being used by the system.

- `SO_REUSEADDR` enabled.

  Allows a socket to be bound even though a previous connection is in a timeout state.

- `SO_KEEPALIVE` enabled.

  Provide a persistent socket connection even if there is no application communication for an extended time.

- `SO_LINGER` enabled with a linger time of `DEFAULT_CLOSE_TIME` seconds.

  When the socket is closed and unsent data is queued for transmission the close will block until the data has been trasmitted or the linger time has been reached.

N.B.: The socket must be configured before it is conneected for the socket options to be effective.

Parameters:
  `socket` - The socket to be configured.
Throws:
  `IOException`