Пример #1
0
        public void Execute()
        {
            // Get a mock compiler
            ICompiler compiler = CreateMockCompiler();

            IronPythonCompilerTask task = new IronPythonCompilerTask(compiler);
            // Create a fake engine as the logger will call into it
            Type     engineType = GenericMockFactory.CreateType("MockBuildEngine", new Type[] { typeof(Microsoft.Build.Framework.IBuildEngine) });
            BaseMock mockEngine = (BaseMock)Activator.CreateInstance(engineType);

            task.BuildEngine = (Microsoft.Build.Framework.IBuildEngine)mockEngine;

            // Set parameters
            task.SourceFiles   = new string[] { "Foo.py", "bar.py" };
            task.TargetKind    = "exe";
            task.MainFile      = "Foo.py";
            task.ResourceFiles = null;
            Microsoft.Build.Framework.ITaskItem[] resources = new Microsoft.Build.Framework.ITaskItem[1];
            resources[0]       = new Microsoft.Build.Utilities.TaskItem(@"obj\i386\form1.resources");
            task.ResourceFiles = resources;
            // Execute
            bool result = task.Execute();

            // Validation
            Assert.IsTrue(result);
            BaseMock mock = (BaseMock)compiler;

            Assert.AreEqual(PEFileKinds.ConsoleApplication, mock["TargetKind"]);
            Assert.AreEqual(task.MainFile, mock["MainFile"]);
        }
        public SdkProjectMetaData(string fullProjectPath, TargetFrameworkMoniker priorityFxVersion = TargetFrameworkMoniker.net452)
        {
            if (!string.IsNullOrEmpty(fullProjectPath))
            {
                MsBuildProject = GetProject(fullProjectPath);

                if (MsBuildProject != null)
                {
                    FxMoniker              = GetTargetFramework(MsBuildProject, priorityFxVersion);
                    FxMonikerString        = GetFxMonikerString(priorityFxVersion);
                    ProjectTaskItem        = new Microsoft.Build.Utilities.TaskItem(fullProjectPath);
                    FullProjectPath        = fullProjectPath;
                    TargetOutputFullPath   = GetTargetFullPath(MsBuildProject, FxMonikerString);
                    ProjectType            = GetProjectType(MsBuildProject);
                    IsTargetFxSupported    = IsFxSupported(FxMonikerString);
                    IsProjectDataPlane     = IsDataPlaneProject(MsBuildProject);
                    IsFxFullDesktopVersion = IsExpectedFxCategory(FxMoniker, TargetFxCategory.FullDesktop);
                    IsFxNetCore            = IsExpectedFxCategory(FxMoniker, TargetFxCategory.NetCore);
                    ProjectImports         = GetProjectImports(MsBuildProject);
                }
                else
                {
                    throw new NullReferenceException("MsBuild Project null");
                }
            }
        }
        public void InstanceItemToUtilItemIDG()
        {
            string content = @"
                    <Project xmlns='http://schemas.microsoft.com/developer/msbuild/2003' >
                        <ItemDefinitionGroup>
                            <i>
                                <m0>;x86;</m0>                                
                                <m1>%(FileName).extension</m1>
                                <m2>;%(FileName).extension;</m2>
                                <m3>v1</m3>
                                <m4>%3bx86%3b</m4> 
                            </i>
                        </ItemDefinitionGroup>
                        <ItemGroup>
                            <i Include='foo.proj'/>
                        </ItemGroup>
                    </Project>
                ";

            ProjectItemInstance item = GetOneItem(content);

            Microsoft.Build.Utilities.TaskItem taskItem = new Microsoft.Build.Utilities.TaskItem(item);

            Assert.Equal(";x86;", taskItem.GetMetadata("m0"));
            Assert.Equal("foo.extension", taskItem.GetMetadata("m1"));
            Assert.Equal(";foo.extension;", taskItem.GetMetadata("m2"));
            Assert.Equal("v1", taskItem.GetMetadata("m3"));
            Assert.Equal(";x86;", taskItem.GetMetadata("m4"));
        }
Пример #4
0
        public SdkProjectMetaData(string fullProjectPath, TargetFrameworkMoniker priorityFxVersion = TargetFrameworkMoniker.net452)
        {
            if (!string.IsNullOrEmpty(fullProjectPath))
            {
                try
                {
                    if (ProjectCollection.GlobalProjectCollection.GetLoadedProjects(fullProjectPath).Count != 0)
                    {
                        MsBuildProject = ProjectCollection.GlobalProjectCollection.GetLoadedProjects(fullProjectPath).FirstOrDefault <Project>();
                    }
                    else
                    {
                        MsBuildProject = new Project(fullProjectPath);
                    }
                }
                catch (Exception) { }

                if (MsBuildProject != null)
                {
                    FxMoniker              = GetTargetFramework(MsBuildProject, priorityFxVersion);
                    FxMonikerString        = GetFxMonikerString(priorityFxVersion);
                    ProjectTaskItem        = new Microsoft.Build.Utilities.TaskItem(fullProjectPath);
                    FullProjectPath        = fullProjectPath;
                    TargetOutputFullPath   = GetTargetFullPath(MsBuildProject, FxMonikerString);
                    ProjectType            = GetProjectType(MsBuildProject);
                    IsTargetFxSupported    = IsFxSupported(FxMonikerString);
                    IsProjectDataPlane     = IsDataPlaneProject(MsBuildProject);
                    IsFxFullDesktopVersion = IsExpectedFxCategory(FxMoniker, TargetFxCategory.FullDesktop);
                    IsFxNetCore            = IsExpectedFxCategory(FxMoniker, TargetFxCategory.NetCore);
                    ProjectImports         = GetProjectImports(MsBuildProject);
                }
            }
        }
Пример #5
0
        /// <summary>
        /// Parses the crazy string passed into AssertItemsMatch and returns a list of ITaskItems.
        /// </summary>
        /// <param name="expectedItemsString"></param>
        /// <returns></returns>
        /// <owner>RGoel</owner>
        static private List <ITaskItem> ParseExpectedItemsString(string expectedItemsString)
        {
            List <ITaskItem> expectedItems = new List <ITaskItem>();

            // First, parse this massive string that we've been given, and create an ITaskItem[] out of it,
            // so we can more easily compare it against the actual items.
            string[] expectedItemsStringSplit = expectedItemsString.Split(new char[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries);
            foreach (string singleExpectedItemString in expectedItemsStringSplit)
            {
                string singleExpectedItemStringTrimmed = singleExpectedItemString.Trim();
                if (singleExpectedItemStringTrimmed.Length > 0)
                {
                    int indexOfColon = singleExpectedItemStringTrimmed.IndexOf(": ");
                    if (indexOfColon == -1)
                    {
                        expectedItems.Add(new Microsoft.Build.Utilities.TaskItem(singleExpectedItemStringTrimmed));
                    }
                    else
                    {
                        // We found a colon, which means there's metadata in there.

                        // The item spec is the part before the colon.
                        string itemSpec = singleExpectedItemStringTrimmed.Substring(0, indexOfColon).Trim();

                        // The metadata is the part after the colon.
                        string itemMetadataString = singleExpectedItemStringTrimmed.Substring(indexOfColon + 1);

                        ITaskItem expectedItem = new Microsoft.Build.Utilities.TaskItem(itemSpec);

                        string[] itemMetadataPieces = itemMetadataString.Split(new char[] { ';' }, StringSplitOptions.RemoveEmptyEntries);
                        foreach (string itemMetadataPiece in itemMetadataPieces)
                        {
                            string itemMetadataPieceTrimmed = itemMetadataPiece.Trim();
                            if (itemMetadataPieceTrimmed.Length > 0)
                            {
                                int indexOfEquals = itemMetadataPieceTrimmed.IndexOf('=');
                                Assertion.Assert(String.Format("Could not find <equals> in item metadata definition '{0}'", itemMetadataPieceTrimmed), indexOfEquals != -1);

                                string itemMetadataName  = itemMetadataPieceTrimmed.Substring(0, indexOfEquals).Trim();
                                string itemMetadataValue = itemMetadataPieceTrimmed.Substring(indexOfEquals + 1).Trim();

                                expectedItem.SetMetadata(itemMetadataName, itemMetadataValue);
                            }
                        }

                        expectedItems.Add(expectedItem);
                    }
                }
            }

            return(expectedItems);
        }
Пример #6
0
 public void TestTaskItemSpecEcho()
 {
     PerformTestPackageTest(
         "EchoTaskItemSpec",
         (task, ignored) =>
     {
         var input = new TaskItem[] { new TaskItem(TEST_VALUE) };
         task.GetType().GetRuntimeProperty("Value").SetMethod.Invoke(task, new Object[] { input });
         Assert.IsTrue(task.Execute());
         var outputProperty = task.GetType().GetRuntimeProperty("Result");
         Assert.IsTrue(ArrayEqualityComparer <ITaskItem> .ArrayEquality(input, (ITaskItem[])outputProperty.GetMethod.Invoke(task, null), (t1, t2) => String.Equals(t1.ItemSpec, t2.ItemSpec)));
     });
 }
Пример #7
0
        static private bool IsBuiltInItemMetadataName(string metadataName)
        {
            if (builtInMetadataNames == null)
            {
                builtInMetadataNames = new Hashtable();

                Microsoft.Build.Utilities.TaskItem dummyTaskItem = new Microsoft.Build.Utilities.TaskItem();
                foreach (string builtInMetadataName in dummyTaskItem.MetadataNames)
                {
                    builtInMetadataNames[builtInMetadataName] = String.Empty;
                }
            }

            return builtInMetadataNames.Contains(metadataName);
        }
Пример #8
0
        static private bool IsBuiltInItemMetadataName(string metadataName)
        {
            if (builtInMetadataNames == null)
            {
                builtInMetadataNames = new Hashtable();

                Microsoft.Build.Utilities.TaskItem dummyTaskItem = new Microsoft.Build.Utilities.TaskItem();
                foreach (string builtInMetadataName in dummyTaskItem.MetadataNames)
                {
                    builtInMetadataNames[builtInMetadataName] = String.Empty;
                }
            }

            return(builtInMetadataNames.Contains(metadataName));
        }
Пример #9
0
        public override bool Execute()
        {
            var processes = new Task [DynamicLibrary.Length];

            ReidentifiedDynamicLibrary = new ITaskItem [DynamicLibrary.Length];

            for (var i = 0; i < DynamicLibrary.Length; i++)
            {
                var input = DynamicLibrary [i];
                var src   = Path.GetFullPath(input.ItemSpec);
                // Make sure we use the correct path separator, these are relative paths, so it doesn't look
                // like MSBuild does the conversion automatically.
                var target          = input.GetMetadata("ReidentifiedPath").Replace('\\', Path.DirectorySeparatorChar);
                var temporaryTarget = target + ".tmp";

                // install_name_tool modifies the file in-place, so copy it first to a temporary file first.
                Directory.CreateDirectory(Path.GetDirectoryName(temporaryTarget));
                File.Copy(src, temporaryTarget, true);

                var arguments = new List <string> ();

                arguments.Add("install_name_tool");
                arguments.Add("-id");
                arguments.Add(input.GetMetadata("DynamicLibraryId"));
                arguments.Add(temporaryTarget);

                processes [i] = ExecuteAsync("xcrun", arguments, sdkDevPath: SdkDevPath).ContinueWith((v) => {
                    if (v.IsFaulted)
                    {
                        throw v.Exception;
                    }
                    if (v.Status == TaskStatus.RanToCompletion)
                    {
                        File.Delete(target);
                        File.Move(temporaryTarget, target);
                    }
                });

                ReidentifiedDynamicLibrary [i] = new Microsoft.Build.Utilities.TaskItem(target);
            }

            Task.WaitAll(processes);

            return(!Log.HasLoggedErrors);
        }
Пример #10
0
        public void TestTaskItemWithMetaDataEcho()
        {
            PerformTestPackageTest(
                "EchoTaskItemWithMetaData",
                (task, ignored) =>
            {
                const String MD1 = "MD1";
                const String MD2 = "MD2";

                var input = new TaskItem[] { new TaskItem(TEST_VALUE, new Dictionary <String, String>()
                    {
                        { "MetaData1", MD1 }, { "MetaData2", MD2 }
                    }) };
                task.GetType().GetRuntimeProperty("Value").SetMethod.Invoke(task, new Object[] { input });
                Assert.IsTrue(task.Execute());
                var outputProperty = task.GetType().GetRuntimeProperty("Result");
                Assert.IsTrue(ArrayEqualityComparer <ITaskItem> .ArrayEquality(input, (ITaskItem[])outputProperty.GetMethod.Invoke(task, null), TaskItemEquality));
            });
        }
Пример #11
0
        public static void TestTaskItem()
        {
            var publishAdditionalInformation = new Dictionary <string, string>();

            publishAdditionalInformation.Add("BranchName", "master");
            var publishAdditionalInformationTaskItem = new Microsoft.Build.Utilities.TaskItem("PublishAdditionalInformation", publishAdditionalInformation);

            publishAdditionalInformationTaskItem.SetMetadata("ispackageupdated", "true");
            var metadata = new Dictionary <string, string>();

            foreach (DictionaryEntry m in publishAdditionalInformationTaskItem.CloneCustomMetadata())
            {
                metadata.Add(m.Key.ToString(), m.Value?.ToString());
            }
            var bn = FromTaskItem <string>(publishAdditionalInformationTaskItem, "BranchName");
            var dt = publishAdditionalInformationTaskItem.CloneCustomMetadata();

            foreach (DictionaryEntry entry in dt)
            {
                Console.WriteLine(entry.Key);
            }
        }
Пример #12
0
        public void InstanceItemToUtilItemIDG()
        {
            string content = @"
                    <Project xmlns='http://schemas.microsoft.com/developer/msbuild/2003' >
                        <ItemDefinitionGroup>
                            <i>
                                <m0>;x86;</m0>                                
                                <m1>%(FileName).extension</m1>
                                <m2>;%(FileName).extension;</m2>
                                <m3>v1</m3>
                                <m4>%3bx86%3b</m4> 
                            </i>
                        </ItemDefinitionGroup>
                        <ItemGroup>
                            <i Include='foo.proj'/>
                        </ItemGroup>
                    </Project>
                ";

            ProjectItemInstance item = GetOneItem(content);

            Microsoft.Build.Utilities.TaskItem taskItem = new Microsoft.Build.Utilities.TaskItem(item);

            Assert.Equal(";x86;", taskItem.GetMetadata("m0"));
            Assert.Equal("foo.extension", taskItem.GetMetadata("m1"));
            Assert.Equal(";foo.extension;", taskItem.GetMetadata("m2"));
            Assert.Equal("v1", taskItem.GetMetadata("m3"));
            Assert.Equal(";x86;", taskItem.GetMetadata("m4"));
        }
Пример #13
0
        public void ITaskItem2Operations()
        {
            Project project = new Project();
            ProjectInstance projectInstance = project.CreateProjectInstance();

            ProjectItemInstance item = projectInstance.AddItem("EscapedItem", "esca%20ped%3bitem");
            item.SetMetadata("m", "m1");
            item.SetMetadata("m;", "m%3b1");
            ITaskItem2 taskItem = (ITaskItem2)item;

            Assert.Equal(taskItem.EvaluatedIncludeEscaped, "esca%20ped%3bitem");
            Assert.Equal(taskItem.ItemSpec, "esca ped;item");

            Assert.Equal(taskItem.GetMetadata("m;"), "m;1");
            Assert.Equal(taskItem.GetMetadataValueEscaped("m;"), "m%3b1");
            Assert.Equal(taskItem.GetMetadataValueEscaped("m"), "m1");

            Assert.Equal(taskItem.EvaluatedIncludeEscaped, "esca%20ped%3bitem");
            Assert.Equal(taskItem.ItemSpec, "esca ped;item");

            ITaskItem2 taskItem2 = new Microsoft.Build.Utilities.TaskItem(taskItem);

            taskItem2.SetMetadataValueLiteral("m;", "m;2");

            Assert.Equal(taskItem2.GetMetadataValueEscaped("m;"), "m%3b2");
            Assert.Equal(taskItem2.GetMetadata("m;"), "m;2");

            IDictionary<string, string> taskItem2Metadata = (IDictionary<string, string>)taskItem2.CloneCustomMetadata();
            Assert.Equal(3, taskItem2Metadata.Count);

            foreach (KeyValuePair<string, string> pair in taskItem2Metadata)
            {
                if (pair.Key.Equals("m"))
                {
                    Assert.Equal("m1", pair.Value);
                }

                if (pair.Key.Equals("m;"))
                {
                    Assert.Equal("m;2", pair.Value);
                }

                if (pair.Key.Equals("OriginalItemSpec"))
                {
                    Assert.Equal("esca ped;item", pair.Value);
                }
            }

            IDictionary<string, string> taskItem2MetadataEscaped = (IDictionary<string, string>)taskItem2.CloneCustomMetadataEscaped();
            Assert.Equal(3, taskItem2MetadataEscaped.Count);

            foreach (KeyValuePair<string, string> pair in taskItem2MetadataEscaped)
            {
                if (pair.Key.Equals("m"))
                {
                    Assert.Equal("m1", pair.Value);
                }

                if (pair.Key.Equals("m;"))
                {
                    Assert.Equal("m%3b2", pair.Value);
                }

                if (pair.Key.Equals("OriginalItemSpec"))
                {
                    Assert.Equal("esca%20ped%3bitem", pair.Value);
                }
            }
        }
Пример #14
0
        /// <summary>
        /// Prepares HelixWorkItem given xUnit project information.
        /// </summary>
        /// <returns>An ITaskItem instance representing the prepared HelixWorkItem.</returns>
        private async Task <ITaskItem> PrepareWorkItem(ITaskItem xunitProject)
        {
            // Forces this task to run asynchronously
            await Task.Yield();

            if (!xunitProject.GetRequiredMetadata(Log, "PublishDirectory", out string publishDirectory))
            {
                return(null);
            }
            if (!xunitProject.GetRequiredMetadata(Log, "TargetPath", out string targetPath))
            {
                return(null);
            }
            if (!xunitProject.GetRequiredMetadata(Log, "RuntimeTargetFramework", out string runtimeTargetFramework))
            {
                return(null);
            }

            xunitProject.TryGetMetadata("Arguments", out string arguments);

            string assemblyName       = Path.GetFileName(targetPath);
            string driver             = runtimeTargetFramework.Contains("core") ? $"{PathToDotnet} exec " : "";
            string runnerName         = runtimeTargetFramework.Contains("core") ? "xunit.console.dll" : "xunit.console.exe";
            string correlationPayload = IsPosixShell ? "$HELIX_CORRELATION_PAYLOAD" : "%HELIX_CORRELATION_PAYLOAD%";
            string xUnitRunner        = $"{correlationPayload}/xunit-runner/tools/{runtimeTargetFramework}/{runnerName}";

            if (runtimeTargetFramework.Contains("core"))
            {
                // If we don't know what version we are, or it isn't 1.x or 2.x, add --roll-forward
                if (string.IsNullOrEmpty(DotNetCliVersion) ||
                    !(DotNetCliVersion.StartsWith("1.") ||
                      DotNetCliVersion.StartsWith("2.")))
                {
                    Log.LogMessage("Adding dotnet cli roll-forward policy.");
                    driver += "--roll-forward Major ";
                }

                var assemblyBaseName = assemblyName;
                if (assemblyBaseName.EndsWith(".dll"))
                {
                    assemblyBaseName = assemblyBaseName.Substring(0, assemblyBaseName.Length - 4);
                }

                Log.LogMessage($"Adding runtimeconfig and depsfile parameters for assembly {assemblyBaseName}.");
                driver += $"--runtimeconfig {assemblyBaseName}.runtimeconfig.json --depsfile {assemblyBaseName}.deps.json ";
            }

            string command = $"{driver}{xUnitRunner} {assemblyName}{(XUnitArguments != null ? " " + XUnitArguments : "")} -xml testResults.xml {arguments}";

            Log.LogMessage($"Creating work item with properties Identity: {assemblyName}, PayloadDirectory: {publishDirectory}, Command: {command}");

            TimeSpan timeout = TimeSpan.FromMinutes(5);

            if (!string.IsNullOrEmpty(XUnitWorkItemTimeout))
            {
                if (!TimeSpan.TryParse(XUnitWorkItemTimeout, out timeout))
                {
                    Log.LogWarning($"Invalid value \"{XUnitWorkItemTimeout}\" provided for XUnitWorkItemTimeout; falling back to default value of \"00:05:00\" (5 minutes)");
                }
            }

            var result = new Microsoft.Build.Utilities.TaskItem(assemblyName, new Dictionary <string, string>()
            {
                { "Identity", assemblyName },
                { "PayloadDirectory", publishDirectory },
                { "Command", command },
                { "Timeout", timeout.ToString() },
            });

            xunitProject.CopyMetadataTo(result);
            return(result);
        }
        public void ITaskItem2Operations()
        {
            Project         project         = new Project();
            ProjectInstance projectInstance = project.CreateProjectInstance();

            ProjectItemInstance item = projectInstance.AddItem("EscapedItem", "esca%20ped%3bitem");

            item.SetMetadata("m", "m1");
            item.SetMetadata("m;", "m%3b1");
            ITaskItem2 taskItem = (ITaskItem2)item;

            Assert.Equal(taskItem.EvaluatedIncludeEscaped, "esca%20ped%3bitem");
            Assert.Equal(taskItem.ItemSpec, "esca ped;item");

            Assert.Equal(taskItem.GetMetadata("m;"), "m;1");
            Assert.Equal(taskItem.GetMetadataValueEscaped("m;"), "m%3b1");
            Assert.Equal(taskItem.GetMetadataValueEscaped("m"), "m1");

            Assert.Equal(taskItem.EvaluatedIncludeEscaped, "esca%20ped%3bitem");
            Assert.Equal(taskItem.ItemSpec, "esca ped;item");

            ITaskItem2 taskItem2 = new Microsoft.Build.Utilities.TaskItem(taskItem);

            taskItem2.SetMetadataValueLiteral("m;", "m;2");

            Assert.Equal(taskItem2.GetMetadataValueEscaped("m;"), "m%3b2");
            Assert.Equal(taskItem2.GetMetadata("m;"), "m;2");

            IDictionary <string, string> taskItem2Metadata = (IDictionary <string, string>)taskItem2.CloneCustomMetadata();

            Assert.Equal(3, taskItem2Metadata.Count);

            foreach (KeyValuePair <string, string> pair in taskItem2Metadata)
            {
                if (pair.Key.Equals("m"))
                {
                    Assert.Equal("m1", pair.Value);
                }

                if (pair.Key.Equals("m;"))
                {
                    Assert.Equal("m;2", pair.Value);
                }

                if (pair.Key.Equals("OriginalItemSpec"))
                {
                    Assert.Equal("esca ped;item", pair.Value);
                }
            }

            IDictionary <string, string> taskItem2MetadataEscaped = (IDictionary <string, string>)taskItem2.CloneCustomMetadataEscaped();

            Assert.Equal(3, taskItem2MetadataEscaped.Count);

            foreach (KeyValuePair <string, string> pair in taskItem2MetadataEscaped)
            {
                if (pair.Key.Equals("m"))
                {
                    Assert.Equal("m1", pair.Value);
                }

                if (pair.Key.Equals("m;"))
                {
                    Assert.Equal("m%3b2", pair.Value);
                }

                if (pair.Key.Equals("OriginalItemSpec"))
                {
                    Assert.Equal("esca%20ped%3bitem", pair.Value);
                }
            }
        }
        public void Execute()
        {
            // Get a mock compiler
            ICompiler compiler = CreateMockCompiler();

            IronPythonCompilerTask task = new IronPythonCompilerTask(compiler);
            // Create a fake engine as the logger will call into it
            Type engineType = GenericMockFactory.CreateType("MockBuildEngine", new Type[] { typeof(Microsoft.Build.Framework.IBuildEngine) });
            BaseMock mockEngine = (BaseMock)Activator.CreateInstance(engineType);
            task.BuildEngine = (Microsoft.Build.Framework.IBuildEngine)mockEngine;

            // Set parameters
            task.SourceFiles = new string[] { "Foo.py", "bar.py" };
            task.TargetKind = "exe";
            task.MainFile = "Foo.py";
            task.ResourceFiles = null;
            Microsoft.Build.Framework.ITaskItem[] resources = new Microsoft.Build.Framework.ITaskItem[1];
            resources[0] = new Microsoft.Build.Utilities.TaskItem(@"obj\i386\form1.resources");
            task.ResourceFiles = resources;
            // Execute
            bool result = task.Execute();

            // Validation
            Assert.IsTrue(result);
            BaseMock mock = (BaseMock)compiler;
            Assert.AreEqual(PEFileKinds.ConsoleApplication, mock["TargetKind"]);
            Assert.AreEqual(task.MainFile, mock["MainFile"]);
        }
Пример #17
0
        /// <summary>
        /// Parses the crazy string passed into AssertItemsMatch and returns a list of ITaskItems.
        /// </summary>
        /// <param name="expectedItemsString"></param>
        /// <returns></returns>
        /// <owner>RGoel</owner>
        static private List<ITaskItem> ParseExpectedItemsString(string expectedItemsString)
        {
            List<ITaskItem> expectedItems = new List<ITaskItem>();

            // First, parse this massive string that we've been given, and create an ITaskItem[] out of it,
            // so we can more easily compare it against the actual items.
            string[] expectedItemsStringSplit = expectedItemsString.Split(new char[] {'\r', '\n'}, StringSplitOptions.RemoveEmptyEntries);
            foreach (string singleExpectedItemString in expectedItemsStringSplit)
            {
                string singleExpectedItemStringTrimmed = singleExpectedItemString.Trim();
                if (singleExpectedItemStringTrimmed.Length > 0)
                {
                    int indexOfColon = singleExpectedItemStringTrimmed.IndexOf(": ");
                    if (indexOfColon == -1)
                    {
                        expectedItems.Add(new Microsoft.Build.Utilities.TaskItem(singleExpectedItemStringTrimmed));
                    }
                    else
                    {
                        // We found a colon, which means there's metadata in there.

                        // The item spec is the part before the colon.
                        string itemSpec = singleExpectedItemStringTrimmed.Substring(0, indexOfColon).Trim();

                        // The metadata is the part after the colon.
                        string itemMetadataString = singleExpectedItemStringTrimmed.Substring(indexOfColon + 1);

                        ITaskItem expectedItem = new Microsoft.Build.Utilities.TaskItem(itemSpec);

                        string[] itemMetadataPieces = itemMetadataString.Split(new char[]{';'}, StringSplitOptions.RemoveEmptyEntries);
                        foreach (string itemMetadataPiece in itemMetadataPieces)
                        {
                            string itemMetadataPieceTrimmed = itemMetadataPiece.Trim();
                            if (itemMetadataPieceTrimmed.Length > 0)
                            {
                                int indexOfEquals = itemMetadataPieceTrimmed.IndexOf('=');
                                Assertion.Assert(String.Format("Could not find <equals> in item metadata definition '{0}'", itemMetadataPieceTrimmed), indexOfEquals != -1);

                                string itemMetadataName = itemMetadataPieceTrimmed.Substring(0, indexOfEquals).Trim();
                                string itemMetadataValue = itemMetadataPieceTrimmed.Substring(indexOfEquals + 1).Trim();

                                expectedItem.SetMetadata(itemMetadataName, itemMetadataValue);
                            }
                        }

                        expectedItems.Add(expectedItem);
                    }
                }
            }

            return expectedItems;
        }