///
/// \addtogroup stk_util_runtime_message_detail
/// @{
///
/// @brief Runtime messages are warning and errors which may occur in parallel that need to be
/// reported to the anaylst which may need to be collected to a root processor and written with
/// greater emphasis than regular output.
///
/// Parallel system architectures greatly complicate the reporting of warning and fatal error
/// messages.  To simplify this, messages are categorized by their generation mechanism.  Some
/// messages are generated symmetrically, meaning that all processors contain the exact same
/// information and the root processor may simply write it's message to the log file and the
/// remaining may simple ignore it.  Some messages are generated in an ad hoc manner, meaning that
/// some processors may generate them at any time, and the output can simply be collected to the root
/// processor at a later time and reported.  And some are generated by several processors with
/// related information and deferred until they should be aggregated to the root processor written
/// as an assembled condensed message.
/// 
/// The message is displayed prominently by the report_handler() via the report() function.  Each
/// application registers a report_handler with the set_report_handler() function.  The report()
/// accepts two arguments, the message string and a message type.  The message types MSG_WARNING,
/// MSG_ERROR, MSG_INFORMATION and MSG_EXCEPTION are currently defined as well as two type flags,
/// MSG_SYMMETRIC and MSG_DEFERRED.  These flags indicate the category of the message.  Generally,
/// symmetric messages are written to the output log by the root processor and to the per-processor
/// log by the remaining processors, see \ref stk_util_runtime_message_symmetric.  Ad hoc message are
/// collected at a parallel safe time and written to the output log by the root processor, see \ref
/// stk_util_runtime_message_adhoc.  And, deferred message are written immediately to per-processors log and
/// aggregated to the root processors at a parallel safe time, see \ref stk_util_runtime_message_deferred.
///
/// The messages are counted by the underlying message reporting functions and are limited by
/// message code and content and message occurance type.
///
/// \anchor stk_util_runtime_message_howto_throttle
/// \section stk_util_runtime_message_counts Message Throttling and Counting
///
/// The messages of each type are counted.  Once the display count for a particular message has been
/// exceeded, that message will no longer be displayed.  However, it continues to be counted.
/// Deferred messages are counted once for each aggregated message.
///
/// By constructing a static MessageCode object, you can throttle the display of messages.  These
/// must be static objects for the counting to function properly. See \ref MessageCode::MessageCode
/// MessageCode for details.  When constructed, a max display count and a display group may be
/// provided.  The count limits the number of times that the message is displayed.  Once this count
/// has been exceeded, the message is no longer displayed.  The group may be MSG_APPLICATION or
/// MSG_TIME_STEP.  The display count for each group may be reset so allow messages to be display
/// for each time step, for instance, even if exceeded by the previous time step.
///
/// The functions get_message_count(), get_warning_count() and get_doomed_count() return the current
/// accumulated counts.  The root processor has the official count.  Other processors counts may be
/// different.
///
/// The maximum number of messages to be displayed during the execution of an application can be set
/// using the set_max_message_count(), set_max_warning_count() and set_max_doomed_count() functions.
///
/// It may be important to count message during various points in the programs execution.  So, to
/// reset the counts back to zero, use the reset_message_count(), reset_warning_count() and
/// reset_doomed_count() functions.
///
/// For example:
///
/// \code
///
///     if (symmetric_handler_doomed_condition) { // limited to 5 fatal error messages
///         static MessageCode message_code(5);
///         RuntimeDoomedSymmetric(message_code) << "My useful message about " << some_data;
///     }
///
///     if (symmetric_runtime_warning_condition) { // Limited to 5 warning messages on each time step
///         static MessageCode message_code(5, stk_classic::MSG_TIME_STEP);
///	    RuntimeWarningSymmetric(message_code) << "My useful message about " << some_data;
///     }
///
/// \endcode
///
/// \anchor stk_util_runtime_message_howto_symmetric
/// \section stk_util_runtime_message_symmetric Symmetric Messages
///
/// Since these messages are generated symmetrically across all processors, only the root processor
/// needs to send the output to the log.  A message generated exclusively on the roor processor
/// could also be written symmetrically as this just relieves the other processors from ignoring the
/// message.  These message often occur during input deck parsing and initialization.  These
/// messages are counted and throttled on all processors, but have the same throttle count on all
/// processors.  The functions report_message(), report_symmetric_warning() and
/// report_symmetric_doomed() send a message string and message type to the report() function.
///
/// The sentry classes RuntimeWarningSymmetric and RuntimeDoomedSymmetric may be used to simplify
/// the coding of the messages.
///
/// For example:
///
/// \code
///
///     if (symmetric_runtime_warning_condition) // Unlimited warning output
///	    RuntimeWarningSymmetric() << "My useful message about " << some_data;
///
///     if (symmetric_runtime_doomed_condition) // Unlimited doomed output
///	    RuntimeDoomedSymmetric() << "My useful message about " << some_data;
///
///     if (root_processor_runtime_warning_condition) // Unlimited warning output
///	    RuntimeWarningSymmetric() << "My useful message about " << some_data;
///
///     if (symmetric_handler_doomed_condition) { // limited to 5 fatal error messages
///         static MessageCode message_code(5);
///         RuntimeDoomedSymmetric(message_code) << "My useful message about " << some_data;
///     }
///
///     if (symmetric_runtime_warning_condition) { // Limited to 5 warning messages on each time step
///         static MessageCode message_code(5, stk_classic::MSG_TIME_STEP);
///	    RuntimeWarningSymmetric(message_code) << "My useful message about " << some_data;
///     }
///
/// \endcode
///
/// \anchor stk_util_runtime_message_howto_adhoc
/// \section stk_util_runtime_message_adhoc Ad hoc Messages
///
/// Deprecated.  Use deferred warnings and dooms.
///
/// This is the old style message collection technique.  Since the messages are not generated in a
/// parallel safe environment, they are buffered into a seperate output stream that is aggregated
/// and written when the main output stream is flushed at a parallel safe time.  These message are
/// counted and throttles on each processor and therefore throttled on a per-processor basis.
///
/// The sentry classes RuntimeWarningAdHoc and RuntimeDoomedAdHoc may be used to simplify the coding
/// of the messages.
///
/// For example (deprecated):
///
/// \code
///
///     if (runtime_warning_condition) // Unlimited warning output
///	    RuntimeWarning() << "My useful message about " << some_data;
///
///     if (runtime_doomed_condition) // Unlimited doomed output
///	    RuntimeDoomed() << "My useful message about " << some_data;
///
///     if (root_processor_runtime_warning_condition) // Unlimited warning output
///	    RuntimeWarning() << "My useful message about " << some_data;
///
///     if (handler_doomed_condition) { // limited to 5 fatal error messages on this processor
///         static MessageCode message_code(5);
///         RuntimeDoomed(message_code) << "My useful message about " << some_data;
///     }
///
///     if (runtime_warning_condition) { // Limited to 5 warning messages on each time step on this processor
///         static MessageCode message_code(5, stk_classic::MSG_TIME_STEP);
///	    RuntimeWarning(message_code) << "My useful message about " << some_data;
///     }
///
/// \endcode
///
/// \anchor stk_util_runtime_message_howto_deferred
/// \section stk_util_runtime_message_deferred Deferred Messages
///
/// This is the new style of message collection.  These messages are also not generated in a
/// parallel safe environment but are buffered to the deferred message queue.  When the main output
/// stream is flushed at a parallel safe time, the messages are collected to the root processor and
/// aggregated by message id and message content.  All messages which are aggregated are counted as
/// singly and reported in the aggregated form.
///
/// For deferred messages, the message is keyed by the message code and the non-aggregate message
/// content.  This allows additional aggregation possibilities.
///
/// The sentry classes RuntimeWarningDeferred and RuntimeDoomedDeferred may be used to simplify the
/// coding of the messages.
///
/// For example:
///
/// \code
///
///     if (handler_doomed_condition) { // limited to 5 fatal error messages
///         static MessageCode message_code(5);
///         RuntimeDoomedDeferred(message_code) << "My useful message about " << some_data;
///     }
///
///     if (runtime_warning_condition) { // Limited to 5 warning messages on each time step
///         static MessageCode message_code(5, stk_classic::MSG_TIME_STEP);
///	    RuntimeWarningDeferred(message_code) << "My useful message about " << some_data;
///     }
///
///     if (handler_doomed_condition) { // limited to 5 fatal error messages
///         static MessageCode message_code(5);
///         RuntimeDoomedDeferred x(message_code);
///         x << "My useful message about " << some_data;
///         x.aggregate << "my proc info";
///     }
///
///     if (runtime_warning_condition) { // Limited to 5 warning messages on each time step
///         static MessageCode message_code(5, stk_classic::MSG_TIME_STEP);
///	    RuntimeWarningDeferred x(message_code);
///         x << "My useful message about " << some_data;
///         x.aggregate << "my proc info";
///     }
///
/// \endcode
///
///
/// \section stk_util_runtime_message_assembly Message Assembly
///
/// Messages are generally assembled into a string output stream and this string is reported via the
/// report() mechanism.  You may select to use a variety of interfaces to accomplish this.
///
/// The lowest level functions are the report_warning(), report_symmetric_warning() and
/// report_deferred_warning() functions.  These functions are counted by message code and write the
/// message based on the category, ad hoc, symmetric or deferred.
///
/// There are three convenience classes that make the assembly easier for a developer to identify
/// and simpler to code.  The RuntimeWarning, RuntimeWarningSymmetric and RuntimeWarningDeferred
/// sentry classes are constructed with an optional message code, accept additional data via the
/// put-to (<<) operator and report the message upon destruction.  All of these classes present the
/// output string stream as the public member variable 'message'.  And, the RuntimeWarningDeferred
/// class presents the 'aggregate' public member variable to be written to with aggregation text.
///
/// \anchor stk_util_runtime_message_howto_assembly
/// For example:
///
/// \code
///
///     if (runtime_doomed_condition) // Unlimited fatal error output
///	    RuntimeDoomedSymmetric() << "My useful message about " << some_data << " and will die soon";
///
///     if (runtime_doomed_condition) { // Unlimited fatal error output
///	    RuntimeDoomedSymmetric x;
///         x << "My useful message about " << some_data << " and will die soon";
///         for (int i = 0; i < 10; ++i)
///           x << " " << i;
///     }
///
///     if (runtime_doomed_condition) { // Unlimited fatal error output
///	    RuntimeDoomedSymmetric x;
///         x.message << "My useful message about " << some_data << " and will die soon";
///         for (int i = 0; i < 10; ++i)
///           x.message << " " << i;
///     }
///
///     if (runtime_doomed_condition) { // Unlimited fatal error output
///	    std::ostringstream s;
///         x << "My useful message about " << some_data << " and will die soon";
///         stk_classic::report_symmetic_warning(s.str());
///     }
///
/// \endcode
///
/// \section stk_util_runtime_message_reporting Message Reporting
///
/// The report functions send the assembled message string and message type to the registered
/// report_handler() function.  The report handler function has the signature:
///
/// \code
///     report_handler(const char *message, int type)
/// \endcode
///
/// and is set with set_report_handler().
///
/// If you want special decorations around your messages during execution, you can change the
/// reporter.
///
/// @}
///
