New tests.
[mono.git] / mcs / class / Microsoft.Build.Engine / Microsoft.Build.BuildEngine / ConsoleLogger.cs
index 351e427105a97bf58989c74615510617f1954a9f..02d0179fb3fdb2e8a08772a4951ad5ca7d91f70f 100644 (file)
 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 
+#if NET_2_0
+
 using System;
 using System.Runtime.InteropServices;
+using System.Collections;
+using System.Collections.Generic;
 using System.IO;
 using System.Security;
+using System.Text;
 using Microsoft.Build.Framework;
 
 namespace Microsoft.Build.BuildEngine {
@@ -42,26 +47,149 @@ namespace Microsoft.Build.BuildEngine {
                int             warningCount;
                DateTime                buildStart;
                bool            performanceSummary;
-               bool            summary;
+               bool            showSummary;
+               bool            skipProjectStartedText;
+               List<string> errors, warnings;
+               bool            projectFailed;
+               ConsoleColor errorColor, warningColor, eventColor, messageColor, highMessageColor;
+               ColorSetter colorSet;
+               ColorResetter colorReset;
+               bool no_message_color, use_colors;
+
+               List<BuildStatusEventArgs> events;
+               Dictionary<string, List<string>> errorsTable;
+               Dictionary<string, List<string>> warningsTable;
+               string current_events_string;
                
                public ConsoleLogger ()
-                       : this (LoggerVerbosity.Normal)
+                       : this (LoggerVerbosity.Normal, null, null, null)
                {
                }
 
                public ConsoleLogger (LoggerVerbosity verbosity)
+                       : this (LoggerVerbosity.Normal, null, null, null)
+               {
+               }
+               
+               public ConsoleLogger (LoggerVerbosity verbosity,
+                                     WriteHandler write,
+                                     ColorSetter colorSet,
+                                     ColorResetter colorReset)
                {
                        this.verbosity = verbosity;
                        this.indent = 0;
                        this.errorCount = 0;
                        this.warningCount = 0;
-                       this.writeHandler += new WriteHandler (WriteHandlerFunction);
+                       if (write == null)
+                               this.writeHandler += new WriteHandler (WriteHandlerFunction);
+                       else
+                               this.writeHandler += write;
                        this.performanceSummary = false;
-                       this.summary = true;
+                       this.showSummary = true;
+                       this.skipProjectStartedText = false;
+                       errors = new List<string> ();
+                       warnings = new List<string> ();
+                       this.colorSet = colorSet;
+                       this.colorReset = colorReset;
+
+                       events = new List<BuildStatusEventArgs> ();
+                       errorsTable = new Dictionary<string, List<string>> ();
+                       warningsTable = new Dictionary<string, List<string>> ();
+
+                       //defaults
+                       errorColor = ConsoleColor.DarkRed;
+                       warningColor = ConsoleColor.DarkYellow;
+                       eventColor = ConsoleColor.DarkCyan;
+                       messageColor = ConsoleColor.DarkGray;
+                       highMessageColor = ConsoleColor.White;
+
+                       // if message color is not set via the env var,
+                       // then don't use any color for it.
+                       no_message_color = true;
+
+                       use_colors = false;
+                       if (colorSet == null || colorReset == null)
+                               return;
+
+                       // color support
+                       string config = Environment.GetEnvironmentVariable ("XBUILD_COLORS");
+                       if (config == null) {
+                               use_colors = true;
+                               return;
+                       }
+
+                       if (config == "disable")
+                               return;
+
+                       use_colors = true;
+                       string [] pairs = config.Split (new char[] {','}, StringSplitOptions.RemoveEmptyEntries);
+                       foreach (string pair in pairs) {
+                               string [] parts = pair.Split (new char[] {'='}, StringSplitOptions.RemoveEmptyEntries);
+                               if (parts.Length != 2)
+                                       continue;
+
+                               if (parts [0] == "errors")
+                                       TryParseConsoleColor (parts [1], ref errorColor);
+                               else if (parts [0] == "warnings")
+                                       TryParseConsoleColor (parts [1], ref warningColor);
+                               else if (parts [0] == "events")
+                                       TryParseConsoleColor (parts [1], ref eventColor);
+                               else if (parts [0] == "messages") {
+                                       if (TryParseConsoleColor (parts [1], ref messageColor)) {
+                                               highMessageColor = GetBrightColorFor (messageColor);
+                                               no_message_color = false;
+                                       }
+                               }
+                       }
+               }
+
+               bool TryParseConsoleColor (string color_str, ref ConsoleColor color)
+               {
+                       switch (color_str.ToLower ()) {
+                       case "black": color = ConsoleColor.Black; break;
+
+                       case "blue": color = ConsoleColor.DarkBlue; break;
+                       case "green": color = ConsoleColor.DarkGreen; break;
+                       case "cyan": color = ConsoleColor.DarkCyan; break;
+                       case "red": color = ConsoleColor.DarkRed; break;
+                       case "magenta": color = ConsoleColor.DarkMagenta; break;
+                       case "yellow": color = ConsoleColor.DarkYellow; break;
+                       case "grey": color = ConsoleColor.DarkGray; break;
+
+                       case "brightgrey": color = ConsoleColor.Gray; break;
+                       case "brightblue": color = ConsoleColor.Blue; break;
+                       case "brightgreen": color = ConsoleColor.Green; break;
+                       case "brightcyan": color = ConsoleColor.Cyan; break;
+                       case "brightred": color = ConsoleColor.Red; break;
+                       case "brightmagenta": color = ConsoleColor.Magenta; break;
+                       case "brightyellow": color = ConsoleColor.Yellow; break;
+
+                       case "white":
+                       case "brightwhite": color = ConsoleColor.White; break;
+                       default: return false;
+                       }
+
+                       return true;
+               }
+
+               ConsoleColor GetBrightColorFor (ConsoleColor color)
+               {
+                       switch (color) {
+                       case ConsoleColor.DarkBlue: return ConsoleColor.Blue;
+                       case ConsoleColor.DarkGreen: return ConsoleColor.Green;
+                       case ConsoleColor.DarkCyan: return ConsoleColor.Cyan;
+                       case ConsoleColor.DarkRed: return ConsoleColor.Red;
+                       case ConsoleColor.DarkMagenta: return ConsoleColor.Magenta;
+                       case ConsoleColor.DarkYellow: return ConsoleColor.Yellow;
+                       case ConsoleColor.DarkGray: return ConsoleColor.Gray;
+                       case ConsoleColor.Gray: return ConsoleColor.White;
+
+                       default: return color;
+                       }
                }
                
-               public virtual void ApplyParameter (string parameterName,
-                                                   string parameterValue)
+               public void ApplyParameter (string parameterName,
+                                           string parameterValue)
                {
                        // FIXME: what we should do here? in msbuild it isn't
                        // changing "parameters" property
@@ -69,133 +197,297 @@ namespace Microsoft.Build.BuildEngine {
 
                public virtual void Initialize (IEventSource eventSource)
                {
-                        eventSource.BuildStarted +=  new BuildStartedEventHandler (BuildStarted);
-                        eventSource.BuildFinished += new BuildFinishedEventHandler (BuildFinished);
-                        eventSource.ProjectStarted += new ProjectStartedEventHandler (ProjectStarted);
-                        eventSource.ProjectFinished += new ProjectFinishedEventHandler (ProjectFinished);
-                        eventSource.TargetStarted += new TargetStartedEventHandler (TargetStarted);
-                        eventSource.TargetFinished += new TargetFinishedEventHandler (TargetFinished);
-                        eventSource.TaskStarted += new TaskStartedEventHandler (TaskStarted);
-                        eventSource.TaskFinished += new TaskFinishedEventHandler (TaskFinished);
-                        eventSource.MessageRaised += new BuildMessageEventHandler (MessageRaised);
-                        eventSource.WarningRaised += new BuildWarningEventHandler (WarningRaised);
-                        eventSource.ErrorRaised += new BuildErrorEventHandler (ErrorRaised);
+                        eventSource.BuildStarted +=  new BuildStartedEventHandler (BuildStartedHandler);
+                        eventSource.BuildFinished += new BuildFinishedEventHandler (BuildFinishedHandler);
+                        eventSource.ProjectStarted += new ProjectStartedEventHandler (ProjectStartedHandler);
+                        eventSource.ProjectFinished += new ProjectFinishedEventHandler (ProjectFinishedHandler);
+                        eventSource.TargetStarted += new TargetStartedEventHandler (TargetStartedHandler);
+                        eventSource.TargetFinished += new TargetFinishedEventHandler (TargetFinishedHandler);
+                        eventSource.TaskStarted += new TaskStartedEventHandler (TaskStartedHandler);
+                        eventSource.TaskFinished += new TaskFinishedEventHandler (TaskFinishedHandler);
+                        eventSource.MessageRaised += new BuildMessageEventHandler (MessageHandler);
+                        eventSource.WarningRaised += new BuildWarningEventHandler (WarningHandler);
+                        eventSource.ErrorRaised += new BuildErrorEventHandler (ErrorHandler);
                }
                
-               public void BuildStarted (object sender, BuildStartedEventArgs args)
+               public void BuildStartedHandler (object sender, BuildStartedEventArgs args)
                {
-                       WriteLine ("");
-                       WriteLine (String.Format ("Build started {0}.", args.TimeStamp));
+                       WriteLine (String.Empty);
+                       WriteLine (String.Format ("Build started {0}.", args.Timestamp));
                        WriteLine ("__________________________________________________");
-                       buildStart = args.TimeStamp;
+                       buildStart = args.Timestamp;
+
+                       PushEvent (args);
                }
                
-               public void BuildFinished (object sender, BuildFinishedEventArgs args)
+               public void BuildFinishedHandler (object sender, BuildFinishedEventArgs args)
                {
-                       if (args.Succeeded == true) {
+                       if (args.Succeeded == true && !projectFailed) {
                                WriteLine ("Build succeeded.");
                        } else {
-                               WriteLine ("Build failed.");
+                               WriteLine ("Build FAILED.");
                        }
-                       if (performanceSummary == true)
-                               ;
-                       if (summary == true){
-                               TimeSpan timeElapsed = args.TimeStamp - buildStart;
+                       if (performanceSummary == true) {
+                       }
+
+                       if (warnings.Count > 0) {
+                               WriteLine (Environment.NewLine + "Warnings:");
+                               SetColor (warningColor);
+
+                               WriteLine (String.Empty);
+                               foreach (KeyValuePair<string, List<string>> pair in warningsTable) {
+                                       if (!String.IsNullOrEmpty (pair.Key))
+                                               WriteLine (pair.Key);
+
+                                       string indent_str = String.IsNullOrEmpty (pair.Key) ? String.Empty : "\t";
+                                       foreach (string msg in pair.Value)
+                                               WriteLine (String.Format ("{0}{1}", indent_str, msg));
+
+                                       WriteLine (String.Empty);
+                               }
+
+                               ResetColor ();
+                       }
+
+                       if (errors.Count > 0) {
+                               WriteLine ("Errors:");
+                               SetColor (errorColor);
+
+                               WriteLine (String.Empty);
+                               foreach (KeyValuePair<string, List<string>> pair in errorsTable) {
+                                       if (!String.IsNullOrEmpty (pair.Key))
+                                               WriteLine (pair.Key);
+
+                                       string indent_str = String.IsNullOrEmpty (pair.Key) ? String.Empty : "\t";
+                                       foreach (string msg in pair.Value)
+                                               WriteLine (String.Format ("{0}{1}", indent_str, msg));
+
+                                       WriteLine (String.Empty);
+                               }
+                               ResetColor ();
+                       }
+
+                       if (showSummary == true){
+                               TimeSpan timeElapsed = args.Timestamp - buildStart;
                                WriteLine (String.Format ("\t {0} Warning(s)", warningCount));
                                WriteLine (String.Format ("\t {0} Error(s)", errorCount));
-                               WriteLine ("");
+                               WriteLine (String.Empty);
                                WriteLine (String.Format ("Time Elapsed {0}", timeElapsed));
                        } 
+                       PopEvent ();
                }
 
-               public void ProjectStarted (object sender, ProjectStartedEventArgs args)
+               public void ProjectStartedHandler (object sender, ProjectStartedEventArgs args)
                {
-                       WriteLine (String.Format ("Project \"{0}\" ({1} target(s)):", args.ProjectFile, args.TargetNames));
-                       WriteLine ("");
+                       SetColor (eventColor);
+                       WriteLine (String.Format ("Project \"{0}\" ({1} target(s)):", args.ProjectFile,
+                                               String.IsNullOrEmpty (args.TargetNames) ? "default" : args.TargetNames));
+                       ResetColor ();
+                       WriteLine (String.Empty);
+                       DumpProperties (args.Properties);
+                       DumpItems (args.Items);
+                       PushEvent (args);
                }
                
-               public void ProjectFinished (object sender, ProjectFinishedEventArgs args)
+               public void ProjectFinishedHandler (object sender, ProjectFinishedEventArgs args)
                {
-                       if (IsVerbosityGreaterOrEqual (LoggerVerbosity.Diagnostic)) {
-                               WriteLine (String.Format ("Done building project \"{0}\".", args.ProjectFile));
-                               WriteLine ("");
+                       if (IsVerbosityGreaterOrEqual (LoggerVerbosity.Normal)) {
+                               if (indent == 1)
+                                       indent --;
+                               SetColor (eventColor);
+                               WriteLine (String.Format ("Done building project \"{0}\".{1}", args.ProjectFile,
+                                                       args.Succeeded ? String.Empty : "-- FAILED"));
+                               ResetColor ();
+                               WriteLine (String.Empty);
                        }
+                       if (!projectFailed)
+                               // no project has failed yet, so update the flag
+                               projectFailed = !args.Succeeded;
+
+                       PopEvent ();
                }
                
-               public void TargetStarted (object sender, TargetStartedEventArgs args)
+               public void TargetStartedHandler (object sender, TargetStartedEventArgs args)
                {
-                       WriteLine (String.Format ("Target {0}:",args.TargetName));
                        indent++;
+                       SetColor (eventColor);
+                       WriteLine (String.Format ("Target {0}:",args.TargetName));
+                       ResetColor ();
+                       PushEvent (args);
                }
                
-               public void TargetFinished (object sender, TargetFinishedEventArgs args)
+               public void TargetFinishedHandler (object sender, TargetFinishedEventArgs args)
                {
+                       if (IsVerbosityGreaterOrEqual (LoggerVerbosity.Detailed) || !args.Succeeded) {
+                               SetColor (eventColor);
+                               WriteLine (String.Format ("Done building target \"{0}\" in project \"{1}\".{2}",
+                                       args.TargetName, args.ProjectFile,
+                                       args.Succeeded ? String.Empty : "-- FAILED"));
+                               ResetColor ();
+                       }
                        indent--;
-                       if (IsVerbosityGreaterOrEqual (LoggerVerbosity.Diagnostic))
-                               WriteLine (String.Format ("Done building target \"{0}\" in project \"{1}\".",
-                                       args.TargetName, args.ProjectFile));
-                       WriteLine ("");
+
+                       WriteLine (String.Empty);
+                       PopEvent ();
                }
                
-               public void TaskStarted (object sender, TaskStartedEventArgs args)
+               public void TaskStartedHandler (object sender, TaskStartedEventArgs args)
                {
-                       if (this.verbosity == LoggerVerbosity.Diagnostic)
+                       if (this.verbosity == LoggerVerbosity.Detailed) {
+                               SetColor (eventColor);
                                WriteLine (String.Format ("Task \"{0}\"",args.TaskName));
+                               ResetColor ();
+                       }
                        indent++;
+                       PushEvent (args);
                }
                
-               public void TaskFinished (object sender, TaskFinishedEventArgs args)
+               public void TaskFinishedHandler (object sender, TaskFinishedEventArgs args)
                {
                        indent--;
-                       if (this.verbosity == LoggerVerbosity.Diagnostic)
-                               WriteLine (String.Format ("Done executing task \"{0}\"",args.TaskName));
+                       if (this.verbosity == LoggerVerbosity.Detailed || !args.Succeeded) {
+                               SetColor (eventColor);
+                               if (args.Succeeded)
+                                       WriteLine (String.Format ("Done executing task \"{0}\"", args.TaskName));
+                               else
+                                       WriteLine (String.Format ("Task \"{0}\" execution -- FAILED", args.TaskName));
+                               ResetColor ();
+                       }
+                       PopEvent ();
                }
                
-               public void MessageRaised (object sender, BuildMessageEventArgs args)
+               public void MessageHandler (object sender, BuildMessageEventArgs args)
                {
                        if (IsMessageOk (args)) {
-                               WriteLine (args.Message);
+                               if (no_message_color) {
+                                       WriteLine (args.Message);
+                               } else {
+                                       SetColor (args.Importance == MessageImportance.High ? highMessageColor : messageColor);
+                                       WriteLine (args.Message);
+                                       ResetColor ();
+                               }
                        }
                }
                
-               public void WarningRaised (object sender, BuildWarningEventArgs args)
+               public void WarningHandler (object sender, BuildWarningEventArgs args)
                {
-                       if (IsVerbosityGreaterOrEqual (LoggerVerbosity.Normal)) 
-                               WriteLineWithoutIndent (FormatWarningEvent (args));
+                       string msg = FormatWarningEvent (args);
+                       if (IsVerbosityGreaterOrEqual (LoggerVerbosity.Normal)) {
+                               SetColor (warningColor);
+                               WriteLineWithoutIndent (msg);
+                               ResetColor ();
+                       }
+                       warnings.Add (msg);
+
+                       List<string> list = null;
+                       if (!warningsTable.TryGetValue (EventsAsString, out list))
+                               warningsTable [EventsAsString] = list = new List<string> ();
+                       list.Add (msg);
+
                        warningCount++;
                }
                
-               public void ErrorRaised (object sender, BuildErrorEventArgs args)
+               public void ErrorHandler (object sender, BuildErrorEventArgs args)
                {
-                       if (IsVerbosityGreaterOrEqual (LoggerVerbosity.Minimal)) 
-                               WriteLineWithoutIndent (FormatErrorEvent (args));
+                       string msg = FormatErrorEvent (args);
+                       if (IsVerbosityGreaterOrEqual (LoggerVerbosity.Minimal)) {
+                               SetColor (errorColor);
+                               WriteLineWithoutIndent (msg);
+                               ResetColor ();
+                       }
+                       errors.Add (msg);
+
+                       List<string> list = null;
+                       if (!errorsTable.TryGetValue (EventsAsString, out list))
+                               errorsTable [EventsAsString] = list = new List<string> ();
+                       list.Add (msg);
                        errorCount++;
                }
                
+               [MonoTODO]
+               public void CustomEventHandler (object sender, CustomBuildEventArgs args)
+               {
+               }
+
                private void WriteLine (string message)
                {
-                       for (int i = 0; i < indent; i++)
-                               Console.Write ('\t');
-                       writeHandler (message);
+                       if (indent > 0) {
+                               StringBuilder sb = new StringBuilder ();
+                               for (int i = 0; i < indent; i++)
+                                       sb.Append ('\t');
+                               sb.Append (message);
+
+                               writeHandler (sb.ToString ());
+                       } else {
+                               writeHandler (message);
+                       }
                }
-               
-               private void WriteLineWithoutIndent (string message)
+
+               void PushEvent (BuildStatusEventArgs args)
                {
-                       writeHandler (message);
+                       events.Add (args);
+                       current_events_string = null;
+               }
+
+               void PopEvent ()
+               {
+                       events.RemoveAt (events.Count - 1);
+                       current_events_string = null;
+               }
+
+               string EventsToString ()
+               {
+                       StringBuilder sb = new StringBuilder ();
+
+                       string last_imported_target_file = String.Empty;
+                       for (int i = 0; i < events.Count; i ++) {
+                               BuildStatusEventArgs args = events [i];
+                               ProjectStartedEventArgs pargs = args as ProjectStartedEventArgs;
+                               if (pargs != null) {
+                                       sb.AppendFormat ("{0} ({1}) ->\n", pargs.ProjectFile,
+                                                       String.IsNullOrEmpty (pargs.TargetNames) ?
+                                                               "default targets" :
+                                                               pargs.TargetNames);
+                                       last_imported_target_file = String.Empty;
+                                       continue;
+                               }
+
+                               TargetStartedEventArgs targs = args as TargetStartedEventArgs;
+                               if (targs != null) {
+                                       if (targs.TargetFile != targs.ProjectFile && targs.TargetFile != last_imported_target_file)
+                                               // target from an imported file,
+                                               // and it hasn't been mentioned as yet
+                                               sb.AppendFormat ("{0} ", targs.TargetFile);
+
+                                       last_imported_target_file = targs.TargetFile;
+                                       sb.AppendFormat ("({0} target) ->\n", targs.TargetName);
+                               }
+                       }
+
+                       return sb.ToString ();
                }
                
-               private void WriteLineWithSender (object sender, string message)
+               private void WriteLineWithoutIndent (string message)
                {
-                       if ((string) sender == "MSBuild")
-                               WriteLine (message);
-                       else
-                               WriteLine ((string) sender + ": " + message);
+                       writeHandler (message);
                }
                
                private void WriteHandlerFunction (string message)
                {
                        Console.WriteLine (message);
                }
+
+               void SetColor (ConsoleColor color)
+               {
+                       if (use_colors)
+                               colorSet (color);
+               }
+
+               void ResetColor ()
+               {
+                       if (use_colors)
+                               colorReset ();
+               }
                
                private void ParseParameters ()
                {
@@ -206,7 +498,7 @@ namespace Microsoft.Build.BuildEngine {
                                        this.performanceSummary = true;
                                        break;
                                case "NoSummary":
-                                       this.summary = false;
+                                       this.showSummary = false;
                                        break;
                                default:
                                        throw new ArgumentException ("Invalid parameter.");
@@ -217,25 +509,47 @@ namespace Microsoft.Build.BuildEngine {
                public virtual void Shutdown ()
                {
                }
+
+               static bool InEmacs = Environment.GetEnvironmentVariable ("EMACS") == "t";
                
                private string FormatErrorEvent (BuildErrorEventArgs args)
                {
-                       // FIXME: show more complicated args
-                       if (args.LineNumber != 0 && args.ColumnNumber != 0) {
-                               return String.Format ("{0}({1},{2}): {3} error {4}: {5}", args.File, args.LineNumber, args.ColumnNumber,
-                                       args.Subcategory, args.Code, args.Message);
+                       // For some reason we get an 1-char empty string as Subcategory somtimes.
+                       string subprefix = args.Subcategory == null || args.Subcategory == "" || args.Subcategory == " " ? "" : " ";
+                       string subcat = subprefix == "" ? "" : args.Subcategory;
+                               
+                       if (args.LineNumber != 0){
+                               if (args.ColumnNumber != 0 && !InEmacs) 
+                                       return String.Format ("{0}({1},{2}): {3}{4}error {5}: {6}",
+                                                             args.File, args.LineNumber, args.ColumnNumber,
+                                                             subprefix, subcat, args.Code, args.Message);
+
+                               return String.Format ("{0}({1}): {2}{3}error {4}: {5}",
+                                                     args.File, args.LineNumber,
+                                                     subprefix, subcat, args.Code, args.Message);
                        } else {
-                               return String.Format ("{0}: {1} error {2}: {3}", args.File, args.Subcategory, args.Code,
+                               return String.Format ("{0}: {1}{2}error {3}: {4}", args.File, subprefix, subcat, args.Code,
                                        args.Message);
                        }
                }
 
                private string FormatWarningEvent (BuildWarningEventArgs args)
                {
+                       // For some reason we get an 1-char empty string as Subcategory somtimes.
+                       string subprefix = args.Subcategory == null || args.Subcategory == "" || args.Subcategory == " " ? "" : " ";
+                       string subcat = subprefix == "" ? "" : args.Subcategory;
+
                        // FIXME: show more complicated args
-                       if (args.LineNumber != 0 && args.ColumnNumber != 0) {
-                               return String.Format ("{0}({1},{2}): {3} warning {4}: {5}", args.File, args.LineNumber, args.ColumnNumber,
-                                       args.Subcategory, args.Code, args.Message);
+                       if (args.LineNumber != 0){
+
+                               if (args.ColumnNumber != 0 && !InEmacs) {
+                                       return String.Format ("{0}({1},{2}): {3}{4}warning {5}: {6}",
+                                                             args.File, args.LineNumber, args.ColumnNumber,
+                                                             subprefix, subcat, args.Code, args.Message);
+                               }
+                               return String.Format ("{0}({1}): {2}{3}warning {4}: {5}",
+                                                     args.File, args.LineNumber,
+                                                     subprefix, subcat, args.Code, args.Message);
                        } else {
                                return String.Format ("{0}: {1} warning {2}: {3}", args.File, args.Subcategory, args.Code,
                                        args.Message);
@@ -270,6 +584,59 @@ namespace Microsoft.Build.BuildEngine {
                                        return false;
                 }
 
+               void DumpProperties (IEnumerable properties)
+               {
+                       if (!IsVerbosityGreaterOrEqual (LoggerVerbosity.Diagnostic))
+                               return;
+
+                       SetColor (eventColor);
+                       WriteLine ("\n");
+                       WriteLine ("Initial Properties:");
+                       ResetColor ();
+
+                       if (properties == null)
+                               return;
+
+                       var dict = new SortedDictionary<string, string> ();
+                       foreach (DictionaryEntry de in properties)
+                               dict [(string)de.Key] = (string)de.Value;
+
+                       foreach (KeyValuePair<string, string> pair in dict)
+                               WriteLine (String.Format ("{0} = {1}", pair.Key, pair.Value));
+                       WriteLine ("\n");
+               }
+
+               void DumpItems (IEnumerable items)
+               {
+                       if (!IsVerbosityGreaterOrEqual (LoggerVerbosity.Diagnostic) || items == null)
+                               return;
+
+                       SetColor (eventColor);
+                       WriteLine ("\n");
+                       WriteLine ("Initial Items:");
+                       ResetColor ();
+                       if (items == null)
+                               return;
+
+                       var items_table = new SortedDictionary<string, List<ITaskItem>> ();
+                       foreach (DictionaryEntry de in items) {
+                               string key = (string)de.Key;
+                               if (!items_table.ContainsKey (key))
+                                       items_table [key] = new List<ITaskItem> ();
+
+                               items_table [key].Add ((ITaskItem) de.Value);
+                       }
+
+                       foreach (string name in items_table.Keys) {
+                               WriteLine (name);
+                               indent ++;
+                               foreach (ITaskItem item in items_table [name])
+                                       WriteLine (item.ItemSpec);
+                               indent--;
+                       }
+                       WriteLine ("\n");
+               }
+
                public string Parameters {
                        get {
                                return parameters;
@@ -283,22 +650,34 @@ namespace Microsoft.Build.BuildEngine {
                        }
                }
 
-               public LoggerVerbosity Verbosity {
+               string EventsAsString {
                        get {
-                               return verbosity;
-                       }
-                       set {
-                               verbosity = value;
+                               if (current_events_string == null)
+                                       current_events_string = EventsToString ();
+                               return current_events_string;
                        }
                }
+               
+               public bool ShowSummary {
+                       get { return showSummary; }
+                       set { showSummary = value; }
+               }
+               
+               public bool SkipProjectStartedText {
+                       get { return skipProjectStartedText; }
+                       set { skipProjectStartedText = value; }
+               }
+
+               public LoggerVerbosity Verbosity {
+                       get { return verbosity; }
+                       set { verbosity = value; }
+               }
 
                protected WriteHandler WriteHandler {
-                       get {
-                               return writeHandler;
-                       }
-                       set {
-                               writeHandler = value;
-                       }
+                       get { return writeHandler; }
+                       set { writeHandler = value; }
                }
        }
 }
+
+#endif