////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
            ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
            ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

            private void ParseDependencyLine(string line)
            {
                if (string.IsNullOrWhiteSpace(line))
                {
                    return;
                }

                //
                // Remove a trailing '\' character used to signify the list continues on the next line.
                //

                if (line.EndsWith(@"\"))
                {
                    line = line.Substring(0, line.Length - 1);
                }

                line.Trim();

                //
                // Now iterate through the line which can contain zero or more dependencies.
                // Although they are seperated by spaces we can't use Split() here since filenames
                // can also contain spaces that are escaped using backslash.  For some reason only
                // spaces are escaped.  Even literal backslash chars don't need escaping.
                //

                while ((line.Length > 0) && (!string.IsNullOrWhiteSpace(line)))
                {
                    int end = FindEndOfFilename(line);

                    string filename = line.Substring(0, end);

                    if (!string.IsNullOrWhiteSpace(filename))
                    {
                        //
                        // Files with spaces in look like this:
                        //  C:\Program\ Files\ (x86)\ARM\Mali\ Developer\ Tools\OpenGL\ ES\ 1.1\ Emulator\ v1.0\include/GLES2/gl2ext.h \
                        //

                        filename = PathUtils.UnescapePath(filename);

                        filename = PathUtils.ConvertPathCygwinToWindows(filename);

                        if (!m_dependencies.ContainsKey(filename))
                        {
                            m_dependencies.Add(filename, new TaskItem(filename));
                        }
                    }

                    if (end == line.Length)
                    {
                        break;
                    }

                    line = line.Substring(end + 1).Trim();
                }
            }
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

        public static string ConvertJavaOutputToVS(string line)
        {
            //
            // Parse and reformat Java error and warning output into a Visual Studio 'jump to line' style.
            //

            StringBuilder vsOutputBuilder = new StringBuilder(line);

            string [] patterns = new string []
            {
                // Android\com\google\android\vending\licensing\LicenseChecker.java:257: warning: [deprecation] toGMTString() in Date has been deprecated
                "^(?<sourcefile>.?.?[^:]*.*?):(?<row>[0-9]*): (?<message>.*$)",
            };

            foreach (string pattern in patterns)
            {
                Regex regExMatcher = new Regex(pattern, RegexOptions.Compiled);

                Match regExMatch = regExMatcher.Match(line);

                if (regExMatch.Success)
                {
                    string sourcefile = regExMatch.Result("${sourcefile}");

                    string row = regExMatch.Result("${row}");

                    string column = regExMatch.Result("${column}");

                    string message = regExMatch.Result("${message}");

                    vsOutputBuilder.Clear();

                    if (!string.IsNullOrWhiteSpace(sourcefile) && !sourcefile.Equals("${sourcefile}"))
                    {
                        vsOutputBuilder.Append(PathUtils.ConvertPathCygwinToWindows(sourcefile));
                    }

                    if (!string.IsNullOrWhiteSpace(row) && !row.Equals("${row}"))
                    {
                        if (string.IsNullOrWhiteSpace(column) && !column.Equals("${column}"))
                        {
                            vsOutputBuilder.AppendFormat("({0},{1})", row, column);
                        }
                        else
                        {
                            vsOutputBuilder.AppendFormat("({0})", row);
                        }
                    }

                    vsOutputBuilder.Append(": ");

                    if (!string.IsNullOrWhiteSpace(message))
                    {
                        vsOutputBuilder.Append(message);
                    }

                    break;
                }
            }

            vsOutputBuilder.Replace("error: ", "error : ");

            vsOutputBuilder.Replace("warning: ", "warning : ");

            return(vsOutputBuilder.ToString());
        }
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

        public static string ConvertGccOutputToVS(string line)
        {
            //
            // Parse and reformat GCC error and warning output into a Visual Studio 'jump to line' style.
            //

            StringBuilder vsOutputBuilder = new StringBuilder(line);

            string [] patterns = new string []
            {
                // "src/foo.c:25: error: new.h: No such file or directory"
                // "src/foo.c:13:15: error: undefined reference to 'native_library_a_dummy()'"
                "^(?<sourcefile>.?.?[^:]*.*?):(?<row>[0-9]*):?(?<column>[0-9]*)?: (?<message>.*$)",

                // "debug/foo.obj:src/foo.c:38: first defined here"
                "^(?<objectfile>.?.?[^:]*.*?):(?<sourcefile>.?.?[^:]*.*?):?(?<row>[0-9]*)?: (?<message>.*$)",

                // debug/libFoobar.a(foo.obj):src/foo.c:function AnExampleFunction::nativeMethodDefs: error: undefined reference to 'nativeCallback(_JNIEnv*, _jobject*, _jstring*)'
                "^(?<objectfile>.?.?[^:]*.*?):(?<sourcefile>.?.?[^:]*.*?):function (?<function>[^ ]*)(?<message>.*$)",
            };

            foreach (string pattern in patterns)
            {
                Regex regExMatcher = new Regex(pattern, RegexOptions.Compiled);

                Match regExMatch = regExMatcher.Match(line);

                if (regExMatch.Success)
                {
                    string sourcefile = regExMatch.Result("${sourcefile}");

                    string objectfile = regExMatch.Result("${objectfile}");

                    string row = regExMatch.Result("${row}");

                    string column = regExMatch.Result("${column}");

                    string function = regExMatch.Result("${function}");

                    string message = regExMatch.Result("${message}");

                    vsOutputBuilder.Clear();

                    if (!string.IsNullOrWhiteSpace(sourcefile) && !sourcefile.Equals("${sourcefile}"))
                    {
                        vsOutputBuilder.Append(PathUtils.ConvertPathCygwinToWindows(sourcefile));
                    }

                    if (!string.IsNullOrWhiteSpace(row) && !row.Equals("${row}"))
                    {
                        if (string.IsNullOrWhiteSpace(column) && !column.Equals("${column}"))
                        {
                            vsOutputBuilder.AppendFormat("({0},{1})", row, column);
                        }
                        else
                        {
                            vsOutputBuilder.AppendFormat("({0})", row);
                        }
                    }

                    vsOutputBuilder.Append(": ");

                    if (!string.IsNullOrWhiteSpace(message))
                    {
                        vsOutputBuilder.Append(message);
                    }

#if false
                    if (!string.IsNullOrWhiteSpace(function))
                    {
                        vsOutputBuilder.AppendFormat(" ({0})", function.Trim(new char [] { ':' }));
                    }
#endif

                    break;
                }
            }

            vsOutputBuilder.Replace("error: ", "error : ");

            vsOutputBuilder.Replace("warning: ", "warning : ");

            return(vsOutputBuilder.ToString());
        }