+ //
+ // Default message recorder, it uses two types of message groups.
+ // Common messages: messages reported in all sessions.
+ // Merged messages: union of all messages in all sessions.
+ //
+ public struct MessageRecorder : IMessageRecorder
+ {
+ ArrayList session_messages;
+ //
+ // A collection of exactly same messages reported in all sessions
+ //
+ ArrayList common_messages;
+
+ //
+ // A collection of unique messages reported in all sessions
+ //
+ ArrayList merged_messages;
+
+ public void EndSession ()
+ {
+ if (session_messages == null)
+ return;
+
+ //
+ // Handles the first session
+ //
+ if (common_messages == null) {
+ common_messages = new ArrayList (session_messages);
+ merged_messages = session_messages;
+ session_messages = null;
+ return;
+ }
+
+ //
+ // Store common messages if any
+ //
+ for (int i = 0; i < common_messages.Count; ++i) {
+ AbstractMessage cmsg = (AbstractMessage) common_messages [i];
+ bool common_msg_found = false;
+ foreach (AbstractMessage msg in session_messages) {
+ if (cmsg.Equals (msg)) {
+ common_msg_found = true;
+ break;
+ }
+ }
+
+ if (!common_msg_found)
+ common_messages.RemoveAt (i);
+ }
+
+ //
+ // Merge session and previous messages
+ //
+ for (int i = 0; i < session_messages.Count; ++i) {
+ AbstractMessage msg = (AbstractMessage) session_messages [i];
+ bool msg_found = false;
+ for (int ii = 0; ii < merged_messages.Count; ++ii) {
+ if (msg.Equals (merged_messages [ii])) {
+ msg_found = true;
+ break;
+ }
+ }
+
+ if (!msg_found)
+ merged_messages.Add (msg);
+ }
+ }
+
+ public void AddMessage (AbstractMessage msg)
+ {
+ if (session_messages == null)
+ session_messages = new ArrayList ();
+
+ session_messages.Add (msg);
+ }
+
+ public bool IsEmpty {
+ get {
+ return merged_messages == null && common_messages == null;
+ }
+ }
+
+ //
+ // Prints collected messages, common messages have a priority
+ //
+ public bool PrintMessages ()
+ {
+ ArrayList messages_to_print = merged_messages;
+ if (common_messages != null && common_messages.Count > 0) {
+ messages_to_print = common_messages;
+ }
+
+ if (messages_to_print == null)
+ return false;
+
+ foreach (AbstractMessage msg in messages_to_print)
+ msg.Print ();
+
+ return true;
+ }
+ }
+
+ public abstract class AbstractMessage
+ {
+ readonly string[] extra_info;
+ protected readonly int code;
+ protected readonly Location location;
+ readonly string message;
+
+ protected AbstractMessage (int code, Location loc, string msg, ArrayList extraInfo)
+ {
+ this.code = code;
+ if (code < 0)
+ this.code = 8000 - code;
+
+ this.location = loc;
+ this.message = msg;
+ if (extraInfo.Count != 0) {
+ this.extra_info = (string[])extraInfo.ToArray (typeof (string));
+ }
+ }
+
+ protected AbstractMessage (AbstractMessage aMsg)
+ {
+ this.code = aMsg.code;
+ this.location = aMsg.location;
+ this.message = aMsg.message;
+ this.extra_info = aMsg.extra_info;
+ }