예제 #1
0
        /// <summary>
        /// Processes the "include" list and the "exclude" list for an item element, and returns
        /// the resultant virtual group of items. Ignores any condition on the item.
        /// </summary>
        /// <param name="baseDirectory">Where relative paths should be evaluated from</param>
        /// <param name="originalItem">The "mother" item that's being expanded</param>
        /// <param name="expander">Expander to evaluated items and properties</param>
        /// <param name="expandMetadata">Whether metadata expressions should be expanded, or left as literals</param>
        internal static BuildItemGroup ExpandItemIntoItems
        (
            string baseDirectory,
            BuildItem originalItem,
            Expander expander,
            bool expandMetadata
        )
        {
            ErrorUtilities.VerifyThrow(originalItem != null, "Can't add a null item to project.");
            ErrorUtilities.VerifyThrow(expander != null, "expander can't be null.");

            // Take the entire string specified in the "Include" attribute, and split
            // it up by semi-colons.  Then loop over the individual pieces.
            // Expand only with properties first, so that expressions like Include="@(foo)" will transfer the metadata of the "foo" items as well, not just their item specs.
            List <string>  itemIncludePieces = (new Expander(expander, ExpanderOptions.ExpandProperties).ExpandAllIntoStringListLeaveEscaped(originalItem.Include, originalItem.IncludeAttribute));
            BuildItemGroup itemsToInclude    = new BuildItemGroup();

            for (int i = 0; i < itemIncludePieces.Count; i++)
            {
                BuildItemGroup itemizedGroup = expander.ExpandSingleItemListExpressionIntoItemsLeaveEscaped(itemIncludePieces[i], originalItem.IncludeAttribute);
                if (itemizedGroup == null)
                {
                    // The expression did not represent a single @(...) item list reference.
                    if (expandMetadata)
                    {
                        // We're inside a target: metadata expressions like %(foo) are legal, so expand them now
                        itemIncludePieces[i] = expander.ExpandMetadataLeaveEscaped(itemIncludePieces[i]);
                    }
                    // Now it's a string constant, possibly with wildcards.
                    // Take each individual path or file expression, and expand any
                    // wildcards.  Then loop through each file returned.
                    if (itemIncludePieces[i].Length > 0)
                    {
                        string[] includeFileList = EngineFileUtilities.GetFileListEscaped(baseDirectory, itemIncludePieces[i]);
                        for (int j = 0; j < includeFileList.Length; j++)
                        {
                            BuildItem newItem = itemsToInclude.AddNewItem(originalItem.Name, originalItem.Include);
                            newItem.SetEvaluatedItemSpecEscaped(itemIncludePieces[i]); // comes from XML include --- "arbitrarily escaped"
                            newItem.SetFinalItemSpecEscaped(includeFileList[j]);       // comes from file system matcher -- "canonically escaped"
                        }
                    }
                }
                else
                {
                    itemsToInclude.ImportItems(itemizedGroup);
                }
            }

            List <BuildItem> matchingItems = FindItemsMatchingSpecification(itemsToInclude, originalItem.Exclude, originalItem.ExcludeAttribute, expander, baseDirectory);

            if (matchingItems != null)
            {
                foreach (BuildItem item in matchingItems)
                {
                    itemsToInclude.RemoveItem(item);
                }
            }

            return(itemsToInclude);
        }
예제 #2
0
        /// <summary>
        /// Generate a hashtable of items by type with a bunch of sample items, so that we can exercise
        /// ItemExpander.ItemizeItemVector.
        /// </summary>
        /// <returns></returns>
        /// <owner>RGoel</owner>
        private Hashtable GenerateTestItems()
        {
            Hashtable itemGroupsByType = new Hashtable(StringComparer.OrdinalIgnoreCase);

            // Set up our item group programmatically.
            BuildItemGroup itemGroup = new BuildItemGroup();
            itemGroupsByType["Compile"] = itemGroup;
            BuildItem a = itemGroup.AddNewItem("Compile", "a.cs");
            a.SetMetadata("WarningLevel", "4");
            BuildItem b = itemGroup.AddNewItem("Compile", "b.cs");
            b.SetMetadata("WarningLevel", "3");

            BuildItemGroup itemGroup2 = new BuildItemGroup();
            itemGroupsByType["Resource"] = itemGroup2;
            BuildItem c = itemGroup2.AddNewItem("Resource", "c.resx");

            return itemGroupsByType;
        }
예제 #3
0
        public void SecondaryItemNotShadowedByPrimaryItem()
        {
            BuildItemGroup group1 = new BuildItemGroup();
            group1.AddNewItem("i1", "a1");
            Hashtable table1 = new Hashtable(StringComparer.OrdinalIgnoreCase);
            table1.Add("i1", group1);
            Lookup lookup = LookupHelpers.CreateLookup(table1);

            lookup.EnterScope();

            // Should return item from the secondary table.
            Assertion.AssertEquals("a1", lookup.GetItems("i1")[0].FinalItemSpec);
        }
        /// <summary>
        /// Attempts to extract the items in the given item vector expression. Item vectors embedded in strings,
        /// and item vectors with separator specifications are considered invalid, because it is not clear
        /// if those item vectors are meant to be lists or strings -- if the latter, the ExpandEmbeddedItemVectors()
        /// method should be used instead.
        /// </summary>
        /// <param name="itemVectorExpression"></param>
        /// <param name="parentNode"></param>
        /// <param name="readOnlyLookup"></param>
        /// <param name="itemVectorMatch"></param>
        /// <returns>a virtual BuildItemGroup containing the items resulting from the expression, or null if the expression was invalid.</returns>
        /// <owner>SumedhK;RGoel</owner>
        internal static BuildItemGroup ItemizeItemVector
        (
            string itemVectorExpression,
            XmlNode parentNode,
            ReadOnlyLookup readOnlyLookup,
            out Match itemVectorMatch
        )
        {
            itemVectorMatch = null;
            BuildItemGroup items = null;

            itemVectorMatch = GetItemVectorMatches(itemVectorExpression);

            if (itemVectorMatch?.Success == true)
            {
                // The method above reports a match if there are any
                // valid @(itemlist) references in the given expression.
                // If the passed-in expression contains exactly one item list reference,
                // with nothing else concatenated to the beginning or end, then proceed
                // with itemizing it, otherwise error.
                ProjectErrorUtilities.VerifyThrowInvalidProject(itemVectorMatch.Value == itemVectorExpression,
                                                                parentNode, "EmbeddedItemVectorCannotBeItemized", itemVectorExpression);

                ItemExpander itemExpander = new ItemExpander(parentNode, readOnlyLookup);

                // If the reference contains a separator, we need to flatten the list into a scalar and then create
                // an item group with a single item. This is necessary for VSWhidbey 525917 - basically we need this
                // to be able to convert item lists with user specified separators into properties.
                if (itemVectorMatch.Groups["SEPARATOR_SPECIFICATION"].Length > 0)
                {
                    string expandedItemVector = itemExpander.ExpandItemVector(itemVectorMatch);

                    string itemType = itemVectorMatch.Groups["TYPE"].Value;
                    items = new BuildItemGroup();

                    if (expandedItemVector.Length > 0)
                    {
                        items.AddNewItem(itemType, expandedItemVector);
                    }
                }
                else
                {
                    items = itemExpander.ItemizeItemVector(itemVectorMatch);
                }

                ErrorUtilities.VerifyThrow(items != null, "ItemizeItemVector shouldn't give us null.");
            }

            return(items);
        }
예제 #5
0
        private void SetupMembers()
        {
            pg1 = new BuildPropertyGroup();
            pg1.SetProperty("foo", "bar");
            pg1.SetProperty("abc", "true");
            pg1.SetProperty("Unit", "inches");

            pg2 = new BuildPropertyGroup();
            pg2.SetProperty("foo", "bar");
            pg2.SetProperty("abc", "true");

            pg3 = new BuildPropertyGroup();

            // These Choose objects are only suitable for
            // holding a place in the GroupingCollection.
            choose1 = new Choose();
            choose2 = new Choose();
            choose3 = new Choose();

            ig1 = new BuildItemGroup();
            ig1.AddNewItem("x", "x1");
            ig1.AddNewItem("x", "x2");
            ig1.AddNewItem("y", "y1");
            ig1.AddNewItem("y", "y2");
            ig1.AddNewItem("y", "y3");
            ig1.AddNewItem("y", "y4");

            ig2 = new BuildItemGroup();
            ig2.AddNewItem("jacksonfive", "germaine");
            ig2.AddNewItem("jacksonfive", "tito");
            ig2.AddNewItem("jacksonfive", "michael");
            ig2.AddNewItem("jacksonfive", "latoya");
            ig2.AddNewItem("jacksonfive", "janet");

            ig3 = new BuildItemGroup();
        }
예제 #6
0
		public void TestAddNewItem1 ()
		{
			string name = "name";
			string include = "a;b;c";
			
			BuildItemGroup big = new BuildItemGroup ();
			BuildItem bi = big.AddNewItem (name, include);

			Assert.AreEqual (String.Empty, bi.Condition, "A1");
			Assert.AreEqual (String.Empty, bi.Exclude, "A2");
			Assert.AreEqual (include, bi.FinalItemSpec, "A3");
			Assert.AreEqual (include, bi.Include, "A4");
			Assert.IsFalse (bi.IsImported, "A5");
			Assert.AreEqual (name, bi.Name, "A6");
			Assert.AreEqual (1, big.Count, "A7");
		}
예제 #7
0
        public void InitiallyNoItemsInBucketOfTypesInItemNames()
        {
            // This bucket is for items of type "i"
            string[] itemNames = new string[] { "i" };

            // There are items of type "i" and "j" available in the project, though
            BuildItemGroup group1 = new BuildItemGroup();
            BuildItemGroup group2 = new BuildItemGroup();
            group1.AddNewItem("i", "i1");
            group2.AddNewItem("j", "j1");
            Hashtable items = new Hashtable(StringComparer.OrdinalIgnoreCase);
            items.Add("i", group1);
            items.Add("j", group2);
            Lookup lookup = LookupHelpers.CreateLookup(items);

            ItemBucket bucket = new ItemBucket(itemNames, new Dictionary<string, string>(), lookup, 0);

            // No items of type i
            Assertion.AssertEquals(0, bucket.Lookup.GetItems("i1").Count);
            // Items of type j, however, are visible
            Assertion.AssertEquals(1, bucket.Lookup.GetItems("j").Count);
        }
예제 #8
0
 internal static void AddItemToGroup(MSBuild.BuildItemGroup group, ProjectItem item)
 {
     if (group == null)
     {
         throw new ArgumentNullException("group");
     }
     if (item == null)
     {
         throw new ArgumentNullException("item");
     }
     if (item.IsAddedToProject)
     {
         throw new ArgumentException("item is already added to project", "item");
     }
     MSBuild.BuildItem newItem = group.AddNewItem(item.ItemType.ToString(), item.Include, item.TreatIncludeAsLiteral);
     foreach (string name in item.MetadataNames)
     {
         newItem.SetMetadata(name, item.GetMetadata(name));
     }
     item.BuildItem = newItem;
     Debug.Assert(item.IsAddedToProject);
 }
예제 #9
0
		public void TestAddNewItem5 ()
		{
			BuildItemGroup big = new BuildItemGroup ();

			big.AddNewItem ("I1", "Value");

			BuildItem bi = big.AddNewItem ("I2", "@(I1)");

			Assert.AreEqual ("@(I1)", bi.FinalItemSpec, "A1");
			Assert.AreEqual ("@(I1)", bi.Include, "A2");
			Assert.AreEqual (2, big.Count, "A3");
		}
예제 #10
0
        public void IsImportedInMemoryBuildItemGroup()
        {
            BuildItemGroup group = new BuildItemGroup();
            group.AddNewItem("n", "i");

            Assertion.AssertEquals(false, group.IsImported);
        }
예제 #11
0
        /// <summary>
        /// Render feature list
        /// </summary>
        private void RenderFeatureList(List<Feature> features, string[][] templateFields, List<KeyValuePair<FeatureRendererAttribute, IFeatureRenderer>> renderers, BuildItemGroup fileItemGroup, BuildItemGroup mobileItemGroup, Dictionary<String, StringCollection> parameters)
        {
            // Scan the class repo and start processing
            foreach (Feature f in features)
            {
                System.Diagnostics.Trace.WriteLine(String.Format("Rendering C# for '{0}'...", f.Name), "debug");

                // Is there a renderer for this feature
                KeyValuePair<FeatureRendererAttribute, IFeatureRenderer> fr = renderers.Find(o => o.Key.Feature == f.GetType());

                // Was a renderer found?
                if (fr.Key == null)
                    System.Diagnostics.Trace.WriteLine(String.Format("can't find renderer for {0}", f.GetType().Name), "warn");
                else
                {
                    string file = String.Empty;
                    try // To write the file
                    {
                        // Start the rendering
                        file = fr.Value.CreateFile(f, hostContext.Output);

                        // Is the renderer for a file
                        if (fr.Key.IsFile)
                        {

                            TextWriter tw = File.CreateText(file);
                            try // Render the file
                            {

                                string Header = Template.Default; // Set the header to the default

                                // Populate template fields
                                foreach (String[] st in templateFields)
                                    Header = Header.Replace(st[0], st[1]);

                                // Write header
                                tw.Write(Header);

                                // Render the template out
                                fr.Value.Render(parameters["rimbapi-target-ns"][0], parameters["rimbapi-api-ns"][0], f, tw);
                            }
                            finally
                            {
                                tw.Close();
                            }

                            // Add to the files in the project
                            string projName = file.Replace(hostContext.Output, "");
                            if (projName.StartsWith(Path.DirectorySeparatorChar.ToString()))
                                projName = projName.Substring(1);
                            if (Array.Find<BuildItem>(fileItemGroup.ToArray(), itm => itm.Include.Equals(projName)) == null)
                            {
                                fileItemGroup.AddNewItem("Compile", projName);
                                mobileItemGroup.AddNewItem("Compile", projName);
                            }
                            else
                                Trace.WriteLine(String.Format("Class '{0}' is defined more than once, second include is ignored", projName), "warn");

                        }
                    }
                    catch (NotSupportedException)
                    {
                        if (!String.IsNullOrEmpty(file)) File.Delete(file);
                    }
                    catch (Exception e)
                    {
                        if (!String.IsNullOrEmpty(file)) File.Delete(file);
                        System.Diagnostics.Trace.WriteLine(e.Message, "error");
                    }
                }
            }
        }
예제 #12
0
		public void TestToArray1 ()
		{
			BuildItemGroup big = new BuildItemGroup ();

			BuildItem[] items = big.ToArray ();

			Assert.AreEqual (0, items.Length, "A1");

			big.AddNewItem ("a", "b");
			big.AddNewItem ("c", "d");

			items = big.ToArray ();

			Assert.AreEqual ("a", items [0].Name, "A2");
			Assert.AreEqual ("c", items [1].Name, "A3");
		}
예제 #13
0
		public void TestRemoveItemAt1 ()
		{
			BuildItemGroup big = new BuildItemGroup ();

			big.AddNewItem ("a", "b");
			big.AddNewItem ("b", "c");
			big.AddNewItem ("c", "d");

			big.RemoveItemAt (1);

			BuildItem[] items = big.ToArray ();
			Assert.AreEqual (2, big.Count, "A1");
			Assert.AreEqual ("a", items [0].Name, "A2");
			Assert.AreEqual ("c", items [1].Name, "A3");
		}
예제 #14
0
 protected void AddFileToProject(BuildItemGroup items, string fullPath, string itemType)
 {
     items.AddNewItem(itemType, fullPath);
 }
예제 #15
0
        /// <summary>
        /// Creates a set of complicated item metadata and properties, and items to exercise
        /// the Expander class.  The data here contains escaped characters, metadata that
        /// references properties, properties that reference items, and other complex scenarios.
        /// </summary>
        /// <param name="pg"></param>
        /// <param name="primaryItemsByName"></param>
        /// <param name="secondaryItemsByName"></param>
        /// <param name="itemMetadata"></param>
        /// <owner>RGoel</owner>
        private void CreateComplexPropertiesItemsMetadata
            (
            out ReadOnlyLookup readOnlyLookup,
            out Dictionary<string, string> itemMetadata
            )
        {
            itemMetadata = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
            itemMetadata["Culture"] = "abc%253bdef;$(Gee_Aych_Ayee)";
            itemMetadata["Language"] = "english";

            BuildPropertyGroup pg = new BuildPropertyGroup();
            pg.SetProperty("Gee_Aych_Ayee", "ghi");
            pg.SetProperty("OutputPath", @"\jk ; l\mno%253bpqr\stu");
            pg.SetProperty("TargetPath", "@(IntermediateAssembly->'%(RelativeDir)')");

            BuildItemGroup intermediateAssemblyItemGroup = new BuildItemGroup();
            BuildItem i1 = intermediateAssemblyItemGroup.AddNewItem("IntermediateAssembly", @"subdir1\engine.dll");
            i1.SetMetadata("aaa", "111");
            BuildItem i2 = intermediateAssemblyItemGroup.AddNewItem("IntermediateAssembly", @"subdir2\tasks.dll");
            i2.SetMetadata("bbb", "222");

            BuildItemGroup contentItemGroup = new BuildItemGroup();
            BuildItem i3 = contentItemGroup.AddNewItem("Content", "splash.bmp");
            i3.SetMetadata("ccc", "333");

            BuildItemGroup resourceItemGroup = new BuildItemGroup();
            BuildItem i4 = resourceItemGroup.AddNewItem("Resource", "string$(p).resx");
            i4.SetMetadata("ddd", "444");
            BuildItem i5 = resourceItemGroup.AddNewItem("Resource", "dialogs%253b.resx");
            i5.SetMetadata("eee", "555");

            BuildItemGroup contentItemGroup2 = new BuildItemGroup();
            BuildItem i6 = contentItemGroup2.AddNewItem("Content", "about.bmp");
            i6.SetMetadata("fff", "666");

            Hashtable secondaryItemsByName = new Hashtable(StringComparer.OrdinalIgnoreCase);
            secondaryItemsByName["Resource"] = resourceItemGroup;
            secondaryItemsByName["Content"] = contentItemGroup2;

            Lookup lookup = LookupHelpers.CreateLookup(pg, secondaryItemsByName);

            // Add primary items
            lookup.EnterScope();
            lookup.PopulateWithItems("IntermediateAssembly", intermediateAssemblyItemGroup);
            lookup.PopulateWithItems("Content", contentItemGroup);

            readOnlyLookup = new ReadOnlyLookup(lookup);
        }
예제 #16
0
        public void ExampleTest()
        {
            ////    Part 1 of Example test - working with BuildItemGroup where
            ////        you have an XML project
            project.LoadXml(ProjectContentWithOneBuildItemGroupThreeBuildItems);
            BuildItemGroup groupOne = GetBuildItemGroupFromProject(project, false);

            Assertion.AssertEquals("'A'=='B'", groupOne.Condition);
            Assertion.AssertEquals(3, groupOne.Count);
            Assertion.AssertEquals(false, groupOne.IsImported);

            BuildItem itemOne = GetSpecificBuildItemFromBuildItemGroup(groupOne, "n2");
            Assertion.AssertEquals("'a2' == 'b2'", itemOne.Condition);
            groupOne.RemoveItem(itemOne);
            Assertion.AssertEquals(2, groupOne.Count);

            BuildItem itemOther = groupOne.AddNewItem("n4", "i4");
            Assertion.AssertEquals(3, groupOne.Count);

            ////    Part 2 of Example test - working with BuildItemGroup where
            ////        you have an in-memory buildItemGroup
            BuildItemGroup groupTwo = new BuildItemGroup();
            groupTwo.AddNewItem("name", "include");
            Assertion.AssertEquals(1, groupTwo.Count);

            ////    Part 3 of Example test - working with BuildItemGroup where
            ////        you have an XML project that contains an Imported Project
            Project p = GetProjectThatImportsAnotherProject(null, null);
            BuildItemGroup groupThree = GetBuildItemGroupFromProject(p, true);

            Assertion.AssertEquals(true, groupThree.IsImported);

            BuildItem itemThree = GetSpecificBuildItemFromBuildItemGroup(groupThree, "n3Imported");
            Assertion.AssertEquals("n3Importedvalue1", itemThree.GetMetadata("n3ImportedMeta1"));
        }
예제 #17
0
        public void RemoveItemAtFirstItem()
        {
            BuildItemGroup group = new BuildItemGroup();
            group.AddNewItem("n1", "i1");
            group.AddNewItem("n2", "i2");
            group.AddNewItem("n3", "i3");

            group.RemoveItemAt(0);

            Assertion.AssertEquals(2, group.Count);

            Dictionary<string, string> items = GetDictionaryOfBuildItemsInBuildItemsGroup(group);
            Assertion.AssertEquals("i2", items["n2"]);
            Assertion.AssertEquals("i3", items["n3"]);
        }
예제 #18
0
        public void RemoveItemAllOfSeveral()
        {
            BuildItemGroup group = new BuildItemGroup();
            BuildItem[] item = new BuildItem[3];
            item[0] = group.AddNewItem("n1", "i1");
            item[1] = group.AddNewItem("n2", "i2");
            item[2] = group.AddNewItem("n3", "i3");

            group.RemoveItem(item[0]);
            group.RemoveItem(item[1]);
            group.RemoveItem(item[2]);

            Assertion.AssertEquals(0, group.Count);
        }
예제 #19
0
        public void AddNewItemNameToNullMemoryGroup()
        {
            BuildItemGroup group = new BuildItemGroup();
            group.AddNewItem(null, "i");

            Assertion.AssertEquals(1, group.Count);
        }
예제 #20
0
		public void TestClear1 ()
		{
			BuildItemGroup big = new BuildItemGroup ();
			big.AddNewItem ("a", "a");
			big.AddNewItem ("b", "a");

			Assert.AreEqual (2, big.Count, "A1");
			
			big.Clear ();

			Assert.AreEqual (0, big.Count, "A2");
		}
예제 #21
0
		public void TestClone2 ()
		{
			BuildItemGroup big = new BuildItemGroup ();
			big.AddNewItem ("a", "a");
			big.AddNewItem ("b", "a");

			BuildItemGroup big2 = big.Clone (true);
			BuildItem[] items = big2.ToArray ();

			Assert.AreEqual (2, big2.Count, "A1");

			Assert.AreEqual (String.Empty, items [0].Condition, "A2");
			Assert.AreEqual (String.Empty, items [0].Exclude, "A3");
			Assert.AreEqual ("a", items [0].FinalItemSpec, "A4");
			Assert.AreEqual ("a", items [0].Include, "A5");
			Assert.IsFalse (items [0].IsImported, "A6");
			Assert.AreEqual ("a", items [0].Name, "A7");
			
			Assert.AreEqual (String.Empty, items [1].Condition, "A8");
			Assert.AreEqual (String.Empty, items [1].Exclude, "A9");
			Assert.AreEqual ("a", items [1].FinalItemSpec, "A10");
			Assert.AreEqual ("a", items [1].Include, "A11");
			Assert.IsFalse (items [1].IsImported, "A12");
			Assert.AreEqual ("b", items [1].Name, "A13");
		}
예제 #22
0
파일: Program.cs 프로젝트: pingvinen/worm
 private static void AddFileToProject(BuildItemGroup itemGroup, CodeFile cf)
 {
     string include = cf.Filename.Replace("/", "\\");
     itemGroup.AddNewItem("Compile", include);
 }
예제 #23
0
		public void TestGetEnumerator ()
		{
			BuildItemGroup big = new BuildItemGroup ();
			big.AddNewItem ("a", "c");
			big.AddNewItem ("b", "d");

			IEnumerator e = big.GetEnumerator ();
			e.MoveNext ();
			Assert.AreEqual ("a", ((BuildItem) e.Current).Name, "A1");
			Assert.AreEqual ("c", ((BuildItem) e.Current).FinalItemSpec, "A2");
			e.MoveNext ();
			Assert.AreEqual ("b", ((BuildItem) e.Current).Name, "A3");
			Assert.AreEqual ("d", ((BuildItem) e.Current).FinalItemSpec, "A4");
			
			Assert.IsFalse (e.MoveNext ());
		}
예제 #24
0
        public void ValidUnqualifiedMetadataReference()
        {
            List<string> parameters = new List<string>();
            parameters.Add("@(File)");
            parameters.Add("%(Culture)");

            Hashtable itemsByType = new Hashtable(StringComparer.OrdinalIgnoreCase);

            BuildItemGroup items = new BuildItemGroup();
            itemsByType["FILE"] = items;

            BuildItem a = items.AddNewItem("File", "a.foo");
            BuildItem b = items.AddNewItem("File", "b.foo");
            a.SetMetadata("Culture", "fr-fr");
            b.SetMetadata("Culture", "en-en");

            BuildPropertyGroup properties = new BuildPropertyGroup();

            ArrayList buckets = BatchingEngine.PrepareBatchingBuckets(new XmlDocument().CreateElement("Foo"), parameters, CreateLookup(itemsByType, properties));
            Assertion.AssertEquals(2, buckets.Count);
        }
예제 #25
0
		public void TestRemoveItemAt3 ()
		{
			BuildItemGroup big = new BuildItemGroup ();

			big.AddNewItem ("a", "b");
			big.AddNewItem ("b", "c");
			big.AddNewItem ("c", "d");

			big.RemoveItemAt (3);
		}
예제 #26
0
        public void Regress_Mutation_DuplicateBatchingBucketsAreFoldedTogether()
        {
            List<string> parameters = new List<string>();
            parameters.Add("%(File.Culture)");

            Hashtable itemsByType = new Hashtable(StringComparer.OrdinalIgnoreCase);
            
            BuildItemGroup items = new BuildItemGroup();
            items.AddNewItem("File", "a.foo");
            items.AddNewItem("File", "b.foo"); // Need at least two items for this test case to ensure multiple buckets might be possible
            itemsByType["FILE"] = items;

            BuildPropertyGroup properties = new BuildPropertyGroup();

            ArrayList buckets = BatchingEngine.PrepareBatchingBuckets(new XmlDocument().CreateElement("Foo"), parameters, CreateLookup(itemsByType, properties));

            // If duplicate buckes have been folded correctly, then there will be exactly one bucket here
            // containing both a.foo and b.foo.
            Assertion.AssertEquals(1, buckets.Count);
        }
예제 #27
0
		public void TestIndexer1 ()
		{
			BuildItemGroup big = new BuildItemGroup ();
			big.AddNewItem ("a", "b");
			big.AddNewItem ("c", "d");

			Assert.AreEqual ("a", big [0].Name, "A1");
			Assert.AreEqual ("c", big [1].Name, "A2");
		}
예제 #28
0
        /// <summary>
        /// Processes the "include" list and the "exclude" list for an item element, and returns
        /// the resultant virtual group of items. Ignores any condition on the item.
        /// </summary>
        /// <param name="baseDirectory">Where relative paths should be evaluated from</param>
        /// <param name="originalItem">The "mother" item that's being expanded</param>
        /// <param name="expander">Expander to evaluated items and properties</param>
        /// <param name="expandMetadata">Whether metadata expressions should be expanded, or left as literals</param>
        internal static BuildItemGroup ExpandItemIntoItems
        (
            string baseDirectory,
            BuildItem originalItem,
            Expander expander,
            bool expandMetadata
        )
        {
            ErrorUtilities.VerifyThrow(originalItem != null, "Can't add a null item to project.");
            ErrorUtilities.VerifyThrow(expander != null, "expander can't be null.");

            // Take the entire string specified in the "Include" attribute, and split
            // it up by semi-colons.  Then loop over the individual pieces.
            // Expand only with properties first, so that expressions like Include="@(foo)" will transfer the metadata of the "foo" items as well, not just their item specs.
            List<string> itemIncludePieces = (new Expander(expander, ExpanderOptions.ExpandProperties).ExpandAllIntoStringListLeaveEscaped(originalItem.Include, originalItem.IncludeAttribute));
            BuildItemGroup itemsToInclude = new BuildItemGroup();
            for (int i = 0; i < itemIncludePieces.Count; i++)
            {
                BuildItemGroup itemizedGroup = expander.ExpandSingleItemListExpressionIntoItemsLeaveEscaped(itemIncludePieces[i], originalItem.IncludeAttribute);
                if (itemizedGroup == null)
                {
                    // The expression did not represent a single @(...) item list reference. 
                    if (expandMetadata)
                    {
                        // We're inside a target: metadata expressions like %(foo) are legal, so expand them now
                        itemIncludePieces[i] = expander.ExpandMetadataLeaveEscaped(itemIncludePieces[i]);
                    }
                    // Now it's a string constant, possibly with wildcards.
                    // Take each individual path or file expression, and expand any
                    // wildcards.  Then loop through each file returned.
                    if (itemIncludePieces[i].Length > 0)
                    {
                        string[] includeFileList = EngineFileUtilities.GetFileListEscaped(baseDirectory, itemIncludePieces[i]);
                        for (int j = 0; j < includeFileList.Length; j++)
                        {
                            BuildItem newItem = itemsToInclude.AddNewItem(originalItem.Name, originalItem.Include);
                            newItem.SetEvaluatedItemSpecEscaped(itemIncludePieces[i]);   // comes from XML include --- "arbitrarily escaped"
                            newItem.SetFinalItemSpecEscaped(includeFileList[j]);  // comes from file system matcher -- "canonically escaped"
                        }
                    }
                }
                else
                {
                    itemsToInclude.ImportItems(itemizedGroup);
                }
            }

            List<BuildItem> matchingItems = FindItemsMatchingSpecification(itemsToInclude, originalItem.Exclude, originalItem.ExcludeAttribute, expander, baseDirectory);

            if (matchingItems != null)
            {
                foreach (BuildItem item in matchingItems)
                {
                    itemsToInclude.RemoveItem(item);
                }
            }
            
            return itemsToInclude;
        }
예제 #29
0
        internal static Expander GetExpander()
        {
            BuildPropertyGroup propertyGroup = new BuildPropertyGroup();
            propertyGroup.SetProperty("Property1", "Value1");
            propertyGroup.SetProperty("Property2", "Value2");
            propertyGroup.SetProperty("Property3", "Value3");
            propertyGroup.SetProperty("Property4", "Value4");
            propertyGroup.SetProperty("Property5", "Value5");

            BuildItemGroup itemGroup1 = new BuildItemGroup();
            itemGroup1.AddNewItem("FirstItem", "FirstValue1");
            itemGroup1.AddNewItem("FirstItem", "FirstValue2");
            itemGroup1.AddNewItem("FirstItem", "FirstValue3");

            BuildItemGroup itemGroup2 = new BuildItemGroup();
            itemGroup2.AddNewItem("SecondItem", "SecondValue1");
            itemGroup2.AddNewItem("SecondItem", "SecondValue2");
            itemGroup2.AddNewItem("SecondItem", "SecondValue3");

            BuildItemGroup itemGroup3 = new BuildItemGroup();
            itemGroup3.AddNewItem("ThirdItem", "ThirdValue1");

            Hashtable itemsByName = new Hashtable(StringComparer.OrdinalIgnoreCase);
            itemsByName["FirstItem"] = itemGroup1;
            itemsByName["SecondItem"] = itemGroup2;
            itemsByName["ThirdItem"] = itemGroup3;

            return new Expander(new ReadOnlyLookup(itemsByName, propertyGroup));
        }
        public void InputItemThatCorrelatesWithMultipleTransformOutputItems()
        {
            string inputs = "@(Items)";
            string outputs = "@(Items->'%(Filename).dll');@(Items->'%(Filename).xml')";

            FileWriteInfo[] filesToAnalyze = new FileWriteInfo[] 
                                             { 
                                                 new FileWriteInfo("a.cs", yesterday),
                                                 new FileWriteInfo("a.dll", today),
                                                 new FileWriteInfo("a.xml", today),
                                                 new FileWriteInfo("b.cs", yesterday),
                                                 new FileWriteInfo("b.dll", twoDaysAgo),
                                                 new FileWriteInfo("b.xml", today),
                                                 new FileWriteInfo("c.cs", yesterday),
                                                 new FileWriteInfo("c.dll", today),
                                                 new FileWriteInfo("c.xml", today)
                                             };

            BuildItemGroup items = new BuildItemGroup();
            items.AddNewItem("Items", "a.cs");
            items.AddNewItem("Items", "b.cs");
            items.AddNewItem("Items", "c.cs");
            
            Hashtable itemsByName = new Hashtable(StringComparer.OrdinalIgnoreCase);
            itemsByName.Add("Items", items);

            DependencyAnalysisResult result = PerformDependencyAnalysisTestHelper(filesToAnalyze, itemsByName, inputs, outputs);

            Assertion.AssertEquals("Should only build partially.", DependencyAnalysisResult.IncrementalBuild, result);
        }
예제 #31
0
        public void InvalidUnqualifiedMetadataReference()
        {
            List<string> parameters = new List<string>();
            parameters.Add("@(File)");
            parameters.Add("%(Culture)");

            Hashtable itemsByType = new Hashtable(StringComparer.OrdinalIgnoreCase);

            BuildItemGroup items = new BuildItemGroup();
            itemsByType["FILE"] = items;

            BuildItem a = items.AddNewItem("File", "a.foo");
            BuildItem b = items.AddNewItem("File", "b.foo");
            a.SetMetadata("Culture", "fr-fr");

            BuildPropertyGroup properties = new BuildPropertyGroup();

            // This is expected to throw because not all items contain a value for metadata "Culture".
            // Only a.foo has a Culture metadata.  b.foo does not.
            ArrayList buckets = BatchingEngine.PrepareBatchingBuckets(new XmlDocument().CreateElement("Foo"), parameters, CreateLookup(itemsByType, properties));
        }
예제 #32
0
        /// <summary>
        /// Creates an instance of a MockTask, and returns the objects necessary to exercise
        /// taskEngine.InitializeTask
        /// </summary>
        /// <param name="taskNode"></param>
        /// <param name="taskEngine"></param>
        /// <param name="mockTask"></param>
        /// <param name="itemBucket"></param>
        /// <owner>RGoel</owner>
        private void InstantiateMockTaskHelper
            (
            XmlElement taskNode,
            out TaskEngine taskEngine,
            out MockTask mockTask,
            out ItemBucket itemBucket,
            out EngineProxy engineProxy,
            string condition
            )
        {
            LoadedType taskClass = new LoadedType(typeof(MockTask), new AssemblyLoadInfo(typeof(MockTask).Assembly.FullName, null));
            Engine engine = new Engine(@"c:\");
            Project project = new Project(engine);
            EngineCallback engineCallback = new EngineCallback(engine);
            TaskExecutionModule taskExecutionModule = new TaskExecutionModule(engineCallback, 
                                        TaskExecutionModule.TaskExecutionModuleMode.SingleProcMode, false);
            ProjectBuildState buildContext = new ProjectBuildState(null, null, new BuildEventContext(0, 1, 1, 1));
            int nodeProxyID = engineCallback.CreateTaskContext(project, null, buildContext, taskNode, EngineCallback.inProcNode, new BuildEventContext(BuildEventContext.InvalidNodeId, BuildEventContext.InvalidTargetId, BuildEventContext.InvalidProjectContextId, BuildEventContext.InvalidTaskId));
            taskEngine = new TaskEngine
                                (
                                    taskNode,
                                    null, /* host object */
                                    "In Memory",
                                    project.FullFileName,
                                    engine.LoggingServices,
                                    nodeProxyID,
                                    taskExecutionModule, 
                                    new BuildEventContext(0, 1, 1, 1)
                                );
            taskEngine.TaskClass = taskClass;
            engineProxy = new EngineProxy(taskExecutionModule, nodeProxyID, project.FullFileName, project.FullFileName, engine.LoggingServices, null);
            mockTask = new MockTask(new EngineProxy(taskExecutionModule, nodeProxyID, project.FullFileName, project.FullFileName, engine.LoggingServices, null));

            // The code below creates an item table that is equivalent to the following MSBuild syntax:
            //
            //      <ItemGroup>
            //          <ItemListContainingOneItem Include="a.cs">
            //              <Culture>fr-fr</Culture>
            //          </ItemListContainingOneItem>
            //
            //          <ItemListContainingTwoItems Include="b.cs">
            //              <HintPath>c:\foo</HintPath>
            //          </ItemListContainingTwoItems>
            //          <ItemListContainingTwoItems Include="c.cs">
            //              <HintPath>c:\bar</HintPath>
            //          </ItemListContainingTwoItems>
            //      </ItemGroup>
            //
            Hashtable itemsByName = new Hashtable(StringComparer.OrdinalIgnoreCase);

            BuildItemGroup itemListContainingOneItem = new BuildItemGroup();
            BuildItem a = itemListContainingOneItem.AddNewItem("ItemListContainingOneItem", "a.cs");
            a.SetMetadata("Culture", "fr-fr");
            itemsByName["ItemListContainingOneItem"] = itemListContainingOneItem;

            BuildItemGroup itemListContainingTwoItems = new BuildItemGroup();
            BuildItem b = itemListContainingTwoItems.AddNewItem("ItemListContainingTwoItems", "b.cs");
            b.SetMetadata("HintPath", "c:\\foo");
            BuildItem c = itemListContainingTwoItems.AddNewItem("ItemListContainingTwoItems", "c.cs");
            c.SetMetadata("HintPath", "c:\\bar");
            itemsByName["ItemListContainingTwoItems"] = itemListContainingTwoItems;

            itemBucket = new ItemBucket(new string[0], new Dictionary<string, string>(), LookupHelpers.CreateLookup(itemsByName), 0);
        }
예제 #33
0
        public void GetBuckets()
        {
            List<string> parameters = new List<string>();
            parameters.Add("@(File);$(unittests)");
            parameters.Add("$(obj)\\%(Filename).ext");
            parameters.Add("@(File->'%(extension)')");  // attributes in transforms don't affect batching

            Hashtable itemsByType = new Hashtable(StringComparer.OrdinalIgnoreCase);

            BuildItemGroup items = new BuildItemGroup();
            items.AddNewItem("File", "a.foo");
            items.AddNewItem("File", "b.foo");
            items.AddNewItem("File", "c.foo");
            items.AddNewItem("File", "d.foo");
            items.AddNewItem("File", "e.foo");
            itemsByType["FILE"] = items;

            items = new BuildItemGroup();
            items.AddNewItem("Doc", "a.doc");
            items.AddNewItem("Doc", "b.doc");
            items.AddNewItem("Doc", "c.doc");
            items.AddNewItem("Doc", "d.doc");
            items.AddNewItem("Doc", "e.doc");
            itemsByType["DOC"] = items;

            BuildPropertyGroup properties = new BuildPropertyGroup();
            properties.SetProperty("UnitTests", "unittests.foo");
            properties.SetProperty("OBJ", "obj");

            ArrayList buckets = BatchingEngine.PrepareBatchingBuckets(new XmlDocument().CreateElement("Foo"), parameters, CreateLookup(itemsByType, properties));

            Assertion.AssertEquals(5, buckets.Count);

            foreach (ItemBucket bucket in buckets)
            {
                // non-batching data -- same for all buckets
                XmlAttribute tempXmlAttribute = (new XmlDocument()).CreateAttribute("attrib");
                tempXmlAttribute.Value = "'$(Obj)'=='obj'";

                Assertion.Assert(BuildEngine.Utilities.EvaluateCondition(tempXmlAttribute.Value,
                    tempXmlAttribute, bucket.Expander, null, ParserOptions.AllowAll, null, null));
                Assertion.AssertEquals("a.doc;b.doc;c.doc;d.doc;e.doc", ExpandItemsIntoString(bucket, "@(doc)"));
                Assertion.AssertEquals("unittests.foo", ExpandMetadataAndProperties(bucket, "$(bogus)$(UNITTESTS)"));
            }

            Assertion.AssertEquals("a.foo", ExpandItemsIntoString((ItemBucket)buckets[0], "@(File)"));
            Assertion.AssertEquals(".foo", ExpandItemsIntoString((ItemBucket)buckets[0], "@(File->'%(Extension)')"));
            Assertion.AssertEquals("obj\\a.ext", ExpandMetadataAndProperties((ItemBucket)buckets[0], "$(obj)\\%(Filename).ext"));

            // we weren't batching on this attribute, so it has no value
            Assertion.AssertEquals(String.Empty, ExpandMetadataAndProperties((ItemBucket)buckets[0], "%(Extension)"));

            items = ((ItemBucket)buckets[0]).Expander.ExpandSingleItemListExpressionIntoItemsLeaveEscaped("@(file)", null);
            Assertion.AssertNotNull(items);
            Assertion.AssertEquals(1, items.Count);

            int invalidProjectFileExceptions = 0;
            try
            {
                // This should throw because we don't allow item lists to be concatenated
                // with other strings.
                items = ((ItemBucket)buckets[0]).Expander.ExpandSingleItemListExpressionIntoItemsLeaveEscaped("@(file);$(unitests)", null);
            }
            catch (InvalidProjectFileException)
            {
                invalidProjectFileExceptions++;
            }

            // We do allow separators in item vectors, this results in an item group with a single flattened item
            items = ((ItemBucket)buckets[0]).Expander.ExpandSingleItemListExpressionIntoItemsLeaveEscaped("@(file, ',')", null);
            Assertion.AssertNotNull(items);
            Assertion.AssertEquals(1, items.Count);
            Assertion.AssertEquals("a.foo", items[0].FinalItemSpec);

            Assertion.AssertEquals(1, invalidProjectFileExceptions);
        }
예제 #34
0
        public override void Execute()
        {
            if (!(hostContext.Data["EnabledRenderers"] as StringCollection).Contains(this.Identifier))
            {
                return;
            }

            // Get parameters
            Dictionary <String, StringCollection> parameters = hostContext.Data["CommandParameters"] as Dictionary <String, StringCollection>;

            System.Diagnostics.Trace.WriteLine("\r\nStarting RIMBA Renderer", "information");
            StringCollection genFormatters = new StringCollection();
            bool             makeWP7Proj   = false;

            if (hostContext.Mode == Pipeline.OperationModeType.Quirks)
            {
                System.Diagnostics.Trace.WriteLine("--- WARNING ---\r\n Host context is operating in Quirks mode, GPMR cannot guarantee output will be accurate\r\n--- WARNING ---");
            }

            #region Validate all parameters
            // Validate parameters
            if (!parameters.ContainsKey("rimbapi-api-ns"))
            {
                parameters.Add("rimbapi-api-ns", new StringCollection());
                parameters["rimbapi-api-ns"].Add("MARC.Everest");
            }
            if (!parameters.ContainsKey("rimbapi-target-ns"))
            {
                parameters.Add("rimbapi-target-ns", new StringCollection());
                parameters["rimbapi-target-ns"].Add("output");
            }
            if (parameters.ContainsKey("rimbapi-root-class"))
            {
                RootClass = parameters["rimbapi-root-class"][0];
            }
            if (parameters.ContainsKey("rimbapi-gen-vocab"))
            {
                GenerateVocab = Convert.ToBoolean(parameters["rimbapi-gen-vocab"][0]);
            }
            if (parameters.ContainsKey("rimbapi-gen-rim"))
            {
                GenerateRim = Convert.ToBoolean(parameters["rimbapi-gen-rim"][0]);
            }
            if (parameters.ContainsKey("rimbapi-profileid"))
            {
                InteractionRenderer.profileId = parameters["rimbapi-profileid"][0];
            }
            if (parameters.ContainsKey("rimbapi-oid-profileid"))
            {
                InteractionRenderer.profileIdOid = parameters["rimbapi-oid-profileid"][0];
            }
            if (parameters.ContainsKey("rimbapi-oid-interactionid"))
            {
                InteractionRenderer.interactionIdOid = parameters["rimbapi-oid-interactionid"][0];
            }
            if (parameters.ContainsKey("rimbapi-oid-triggerevent"))
            {
                InteractionRenderer.triggerEventOid = parameters["rimbapi-oid-triggerevent"][0];
            }
            if (parameters.ContainsKey("rimbapi-gen-its"))
            {
                genFormatters = parameters["rimbapi-gen-its"];
            }
            if (parameters.ContainsKey("rimbapi-phone"))
            {
                makeWP7Proj = bool.Parse(parameters["rimbapi-phone"][0]);
            }

            #endregion

            // Initialize Heuristics
            MohawkCollege.EHR.gpmr.Pipeline.Renderer.RimbaCS.HeuristicEngine.Datatypes.Initialize(parameters["rimbapi-api-ns"][0]);
            MohawkCollege.EHR.gpmr.Pipeline.Renderer.RimbaCS.HeuristicEngine.Interfaces.Initialize(parameters["rimbapi-api-ns"][0]);

            // Get our repository ready
            ClassRepository classRep = hostContext.Data["SourceCR"] as ClassRepository;

            string ProjectFileName = "output.csproj"; // Set the output file name
            if (parameters.ContainsKey("rimbapi-target-ns"))
            {
                ProjectFileName = parameters["rimbapi-target-ns"][0];
            }
            if (parameters.ContainsKey("rimbapi-partials"))
            {
                RenderPartials = Boolean.Parse(parameters["rimbapi-partials"][0]);
            }
            if (parameters.ContainsKey("rimbapi-realm-pref"))
            {
                prefRealm = parameters["rimbapi-realm-pref"][0];
            }
            if (parameters.ContainsKey("rimbapi-max-literals"))
            {
                MaxLiterals = Int32.Parse(parameters["rimbapi-max-literals"][0]);
            }
            if (parameters.ContainsKey("rimbapi-suppress-doc"))
            {
                SuppressDoc = Boolean.Parse(parameters["rimbapi-suppress-doc"][0]);
            }
            // Setup the template parameters
            string[][] templateFields = new string[][]
            {
                new string[] { "$license$", parameters.ContainsKey("rimbapi-license") ? Licenses.ResourceManager.GetString(parameters["rimbapi-license"][0].ToUpper()) : "" },
                new string[] { "$org$", parameters.ContainsKey("rimbapi-org") ? parameters["rimbapi-org"][0] : "" },
                new string[] { "$date$", DateTime.Now.ToString("yyyy-MM-dd") },
                new string[] { "$clrversion$", Environment.Version.ToString() },
                new string[] { "$time$", DateTime.Now.ToString("HH:mm:ss") },
                new string[] { "$author$", SystemInformation.UserName },
                new string[] { "$year$", DateTime.Now.Year.ToString() },
                new string[] { "$version$", Assembly.GetEntryAssembly().GetName().Version.ToString() },
                new string[] { "$guid$", Guid.NewGuid().ToString() },
                new string[] { "$name$", ProjectFileName },
                new string[] { "$mrversion$", InteractionRenderer.profileId ?? "" }
            };

            // Now we want to scan our assembly for FeatureRenderers
            List <KeyValuePair <FeatureRendererAttribute, IFeatureRenderer> > renderers = new List <KeyValuePair <FeatureRendererAttribute, IFeatureRenderer> >();
            foreach (Type t in this.GetType().Assembly.GetTypes())
            {
                if (t.GetInterface("MohawkCollege.EHR.gpmr.Pipeline.Renderer.RimbaCS.Interfaces.IFeatureRenderer") != null &&
                    t.GetCustomAttributes(typeof(FeatureRendererAttribute), true).Length > 0)
                {
                    foreach (FeatureRendererAttribute feature in (t.GetCustomAttributes(typeof(FeatureRendererAttribute), true)))
                    {
                        // Only one feature renderer per feature, so if the dictionary throws an exception
                        // on the add it is ok
                        renderers.Add(new KeyValuePair <FeatureRendererAttribute, IFeatureRenderer>(feature, (IFeatureRenderer)t.Assembly.CreateInstance(t.FullName)));
                    }
                }
            }

            #region Setup the project
            // Create engine reference
            Microsoft.Build.BuildEngine.Engine engine = new Microsoft.Build.BuildEngine.Engine(
                Path.Combine(Path.Combine(Path.Combine(System.Environment.SystemDirectory, "..\\Microsoft.NET"), "Framework"), "v3.5")),
                                               phoneEngine = new Microsoft.Build.BuildEngine.Engine(
                Path.Combine(Path.Combine(Path.Combine(System.Environment.SystemDirectory, "..\\Microsoft.NET"), "Framework"), "v4.0.30319"));

            // Create MSPROJ
            Microsoft.Build.BuildEngine.Project project   = new Microsoft.Build.BuildEngine.Project(engine),
                                                phoneProj = new Project(phoneEngine, "4.0");


            phoneProj.DefaultTargets = project.DefaultTargets = "Build";


            // Setup project attributes
            Microsoft.Build.BuildEngine.BuildPropertyGroup pg = project.AddNewPropertyGroup(false);

            Microsoft.Build.BuildEngine.BuildProperty property = pg.AddNewProperty("Configuration", "Release");

            property.Condition = "'$(Configuration)' == ''";
            property           = pg.AddNewProperty("Platform", "AnyCPU");
            property.Condition = "'$(Platform)' == ''";
            pg.AddNewProperty("ProductVersion", "10.0.20506");
            pg.AddNewProperty("SchemaVersion", "2.0");
            pg.AddNewProperty("ProjectGuid", Guid.NewGuid().ToString());
            pg.AddNewProperty("OutputType", "Library");
            pg.AddNewProperty("AppDesignerFolder", "Properties");
            pg.AddNewProperty("RootNamespace", parameters["rimbapi-target-ns"][0]);
            pg.AddNewProperty("AssemblyName", parameters["rimbapi-target-ns"][0]);

            // Release AnyCPU
            pg           = project.AddNewPropertyGroup(false);
            pg.Condition = "'$(Configuration)|$(Platform)' == 'Release|AnyCPU'";
            pg.AddNewProperty("DebugType", "pdbonly");
            pg.AddNewProperty("Optimize", "true");
            pg.AddNewProperty("OutputPath", "bin\\release");
            pg.AddNewProperty("DefineConstants", "TRACE");
            pg.AddNewProperty("ErrorReport", "prompt");
            pg.AddNewProperty("WarningLevel", "4");
            pg.AddNewProperty("DocumentationFile", "bin\\release\\" + parameters["rimbapi-target-ns"][0] + ".xml");

            // Create Dir Structure
            Directory.CreateDirectory(Path.Combine(hostContext.Output, "bin"));
            Directory.CreateDirectory(Path.Combine(hostContext.Output, "lib"));
            Directory.CreateDirectory(Path.Combine(hostContext.Output, "Properties"));
            Directory.CreateDirectory(Path.Combine(hostContext.Output, "Vocabulary"));
            Directory.CreateDirectory(Path.Combine(hostContext.Output, "Interaction"));

            // Add reference structure
            Microsoft.Build.BuildEngine.BuildItemGroup refItemGroup = project.AddNewItemGroup();

            // Add References
            File.Copy(Path.Combine(System.Windows.Forms.Application.StartupPath, "MARC.Everest.dll"), Path.Combine(Path.Combine(hostContext.Output, "lib"), "MARC.Everest.dll"), true);

            if (makeWP7Proj)
            {
                File.Copy(Path.Combine(Path.Combine(System.Windows.Forms.Application.StartupPath, "lib"), "MARC.Everest.Phone.dll"), Path.Combine(Path.Combine(hostContext.Output, "lib"), "MARC.Everest.Phone.dll"), true);
            }

            File.Copy(Path.Combine(System.Windows.Forms.Application.StartupPath, "MARC.Everest.xml"), Path.Combine(Path.Combine(hostContext.Output, "lib"), "MARC.Everest.xml"), true);
            refItemGroup.AddNewItem("Reference", "System");
            refItemGroup.AddNewItem("Reference", "System.Drawing");
            refItemGroup.AddNewItem("Reference", "System.Xml");
            Microsoft.Build.BuildEngine.BuildItem buildItem = refItemGroup.AddNewItem("Reference", @"MARC.Everest");
            buildItem.SetMetadata("SpecificVersion", "false");
            buildItem.SetMetadata("HintPath", "lib\\MARC.Everest.dll");

            project.AddNewImport("$(MSBuildBinPath)\\Microsoft.CSharp.targets", null);

            Microsoft.Build.BuildEngine.BuildItemGroup fileItemGroup      = project.AddNewItemGroup(),
                                                       phoneFileItemGroup = phoneProj.AddNewItemGroup();

            #region Assembly Info
            try
            {
                TextWriter tw = File.CreateText(Path.Combine(Path.Combine(hostContext.Output, "Properties"), "AssemblyInfo.cs"));
                try
                {
                    string Header = Template.AssemblyInfo; // Set the header to the default

                    // Populate template fields
                    foreach (String[] st in templateFields)
                    {
                        Header = Header.Replace(st[0], st[1]);
                    }

                    // Write header
                    tw.Write(Header);
                }
                finally
                {
                    tw.Close();
                }
                fileItemGroup.AddNewItem("Compile", Path.Combine("Properties", "AssemblyInfo.cs"));
                phoneFileItemGroup.AddNewItem("Compile", Path.Combine("Properties", "AssemblyInfo.cs"));
            }
            catch (Exception)
            {
                System.Diagnostics.Trace.WriteLine("Couldn't generate the AssemblyInfo.cs file for this project", "warn");
            }
            #endregion
            #endregion

            #region Code Create
            // Convert class rep to list
            List <Feature> features = new List <Feature>();
            foreach (KeyValuePair <String, Feature> kv in classRep)
            {
                features.Add(kv.Value);
            }
            // Sort so classes are processed first
            features.Sort(delegate(Feature a, Feature b)
            {
                if ((a is SubSystem) && !(b is SubSystem))
                {
                    return(-1);
                }
                else if ((b is SubSystem) && !(a is SubSystem))
                {
                    return(1);
                }
                else
                {
                    return(a.GetType().Name.CompareTo(b.GetType().Name));
                }
            });

            RenderFeatureList(features, templateFields, renderers, fileItemGroup, phoneFileItemGroup, parameters);

            // Any added features?
            // HACK: This should be fixed soon, but meh... I'll get around to it
            List <Feature> addlFeatures = new List <Feature>();
            foreach (KeyValuePair <String, Feature> kv in classRep)
            {
                if (!features.Contains(kv.Value))
                {
                    addlFeatures.Add(kv.Value);
                }
            }
            RenderFeatureList(addlFeatures, templateFields, renderers, fileItemGroup, phoneFileItemGroup, parameters);

            // Save the project
            project.Save(Path.Combine(hostContext.Output, ProjectFileName) + ".csproj");
            #endregion

            // Compile?
            #region Compile this project

            // Does the user want to compile?
            if (parameters.ContainsKey("rimbapi-compile") && Convert.ToBoolean(parameters["rimbapi-compile"][0]))
            {
                string logPath = Path.Combine(Path.GetTempPath(), Path.GetTempFileName()); // Create log
                Microsoft.Build.BuildEngine.FileLogger logger = new Microsoft.Build.BuildEngine.FileLogger();
                logger.Parameters = "logfile=" + logPath;
                engine.RegisterLogger(logger);

                System.Diagnostics.Trace.Write(String.Format("Compiling project (Build log {0})...", logPath), "information");

                // Compile
                if (engine.BuildProject(project))
                {
                    System.Diagnostics.Trace.WriteLine("Success!", "information");
                }
                else
                {
                    System.Diagnostics.Trace.WriteLine("Fail", "information");
                    throw new InvalidOperationException("Failed compilation, operation cannot continue");
                }
                engine.UnregisterAllLoggers();
            }
            #endregion

            #region Windows Phone

            if (makeWP7Proj)
            {
                // Setup project attributes
                pg                 = phoneProj.AddNewPropertyGroup(false);
                property           = pg.AddNewProperty("Configuration", "Release");
                property.Condition = "'$(Configuration)' == ''";
                property           = pg.AddNewProperty("Platform", "AnyCPU");
                property.Condition = "'$(Platform)' == ''";
                pg.AddNewProperty("ProductVersion", "10.0.20506");
                pg.AddNewProperty("SchemaVersion", "2.0");
                pg.AddNewProperty("ProjectGuid", Guid.NewGuid().ToString());
                pg.AddNewProperty("OutputType", "Library");
                pg.AddNewProperty("AppDesignerFolder", "Properties");
                pg.AddNewProperty("RootNamespace", parameters["rimbapi-target-ns"][0]);
                pg.AddNewProperty("AssemblyName", parameters["rimbapi-target-ns"][0] + ".Phone");
                pg.AddNewProperty("ProjectTypeGuids", "{C089C8C0-30E0-4E22-80C0-CE093F111A43};{fae04ec0-301f-11d3-bf4b-00c04f79efbc}");
                pg.AddNewProperty("TargetFrameworkVersion", "v4.0");
                pg.AddNewProperty("SilverlightVersion", "$(TargetFrameworkVersion)");
                pg.AddNewProperty("TargetFrameworkProfile", "WindowsPhone71");
                pg.AddNewProperty("TargetFrameworkIdentifier", "Silverlight");
                pg.AddNewProperty("SilverlightApplication", "false");
                pg.AddNewProperty("ValidateXaml", "true");
                pg.AddNewProperty("ThrowErrorsInValidation", "true");

                // Release AnyCPU
                pg           = phoneProj.AddNewPropertyGroup(false);
                pg.Condition = "'$(Configuration)|$(Platform)' == 'Release|AnyCPU'";
                pg.AddNewProperty("DebugType", "pdbonly");
                pg.AddNewProperty("Optimize", "true");
                pg.AddNewProperty("OutputPath", "bin\\release");
                pg.AddNewProperty("DefineConstants", "TRACE;SILVERLIGHT;WINDOWS_PHONE");
                pg.AddNewProperty("ErrorReport", "prompt");
                pg.AddNewProperty("NoStdLib", "true");
                pg.AddNewProperty("NoConfig", "true");
                pg.AddNewProperty("WarningLevel", "4");
                pg.AddNewProperty("DocumentationFile", "bin\\release\\" + parameters["rimbapi-target-ns"][0] + ".Phone.xml");

                // Add reference structure
                refItemGroup = phoneProj.AddNewItemGroup();
                refItemGroup.AddNewItem("Reference", "System");
                refItemGroup.AddNewItem("Reference", "System.Xml");

                BuildItem evReference = refItemGroup.AddNewItem("Reference", @"MARC.Everest.Phone");
                evReference.SetMetadata("SpecificVersion", "false");
                evReference.SetMetadata("HintPath", "lib\\MARC.Everest.Phone.dll");

                // Add WP7 Imports
                phoneProj.AddNewImport(@"$(MSBuildExtensionsPath)\Microsoft\Silverlight for Phone\$(TargetFrameworkVersion)\Microsoft.Silverlight.$(TargetFrameworkProfile).Overrides.targets", null);
                phoneProj.AddNewImport(@"$(MSBuildExtensionsPath)\Microsoft\Silverlight for Phone\$(TargetFrameworkVersion)\Microsoft.Silverlight.CSharp.targets", null);

                // HACK: Add tools version
                string fileName = Path.Combine(hostContext.Output, ProjectFileName) + ".Phone.csproj";
                phoneProj.Save(fileName);
                XmlDocument doc = new XmlDocument();
                doc.Load(fileName);
                doc.DocumentElement.Attributes.Append(doc.CreateAttribute("ToolsVersion"));
                doc.DocumentElement.Attributes["ToolsVersion"].Value = "4.0";
                doc.Save(fileName);

                if (parameters.ContainsKey("rimbapi-compile") && Convert.ToBoolean(parameters["rimbapi-compile"][0]))
                {
                    System.Diagnostics.Trace.Write(String.Format("Compiling phone project..."), "information");

                    // Compile
                    if (phoneEngine.BuildProjectFile(fileName))
                    {
                        System.Diagnostics.Trace.WriteLine("Success!", "information");
                    }
                    else
                    {
                        System.Diagnostics.Trace.WriteLine("Fail", "information");
                        throw new InvalidOperationException("Failed compilation, operation cannot continue");
                    }
                }
            }

            #endregion

            #region Generate Formatter Assemblies

            // Generate the formatter assemblies
            if (genFormatters.Count > 0 && parameters.ContainsKey("rimbapi-compile") && Convert.ToBoolean(parameters["rimbapi-compile"][0]))
            {
                AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(CurrentDomain_AssemblyResolve);
                Trace.WriteLine("Generating ITS Formatter Types:", "information");

                // Load the assembly
                Assembly genAsm = Assembly.LoadFile(Path.Combine(Path.Combine(Path.Combine(hostContext.Output, "bin"), "release"), ProjectFileName + ".dll"));
                foreach (string s in genFormatters)
                {
                    GenerateFormatterAssembly(s, genAsm, InteractionRenderer.profileId ?? "formatter");
                }

                // Assembly resolve
                AppDomain.CurrentDomain.AssemblyResolve -= new ResolveEventHandler(CurrentDomain_AssemblyResolve);
            }
            else if (genFormatters.Count > 0)
            {
                Trace.WriteLine("Can't use --rimbapi-gen-its when --rimbapi-compile is not true, skipping ITS generation", "warn");
            }
            #endregion

            // Does the user only want asm?
            #region dllonly
            if (parameters.ContainsKey("rimbapi-dllonly") && parameters.ContainsKey("rimbapi-compile") && Convert.ToBoolean(parameters["rimbapi-dllonly"][0]))
            {
                try
                {
                    // Move the assemblies up to root
                    foreach (string file in Directory.GetFiles(Path.Combine(Path.Combine(hostContext.Output, "bin"), "release")))
                    {
                        if (File.Exists(Path.Combine(hostContext.Output, Path.GetFileName(file))))
                        {
                            File.Delete(Path.Combine(hostContext.Output, Path.GetFileName(file)));
                        }
                        File.Move(file, Path.Combine(hostContext.Output, Path.GetFileName(file)));
                    }

                    // Clean all in the projects and remove all directories
                    List <String> directories = new List <string>(new string[] {
                        Path.Combine(Path.Combine(hostContext.Output, "bin"), "release"),
                        Path.Combine(hostContext.Output, "bin"),
                        Path.Combine(hostContext.Output, "lib"),
                        Path.Combine(hostContext.Output, "Vocabulary"),
                        Path.Combine(hostContext.Output, "Interaction"),
                        Path.Combine(hostContext.Output, "obj")
                    });

                    // Gather files and clean
                    foreach (Microsoft.Build.BuildEngine.BuildItem fi in fileItemGroup)
                    {
                        // Add directory on the "to be deleted"
                        string dirName = Path.GetDirectoryName(Path.Combine(hostContext.Output, fi.Include));
                        if (!directories.Contains(dirName))
                        {
                            directories.Add(dirName);
                        }

                        Trace.WriteLine(String.Format("Deleting {0}...", fi.Include), "debug");
                        File.Delete(Path.Combine(hostContext.Output, fi.Include));
                    }
                    // Clean dirs
                    foreach (string s in directories)
                    {
                        Directory.Delete(s, true);
                    }
                    File.Delete(project.FullFileName);
                }
                catch (Exception)
                {
                    System.Diagnostics.Trace.WriteLine("Could not clean working files!", "warn");
                }
            }
            #endregion
        }