public void ProjectPropertyGroupElementModify()
        {
            var pair    = GetNewInMemoryProject("temp.prj");
            var xmlPair = new ProjectXmlPair(pair);
            var propGrp = xmlPair.AddNewLabeledChaildWithVerify <ProjectPropertyGroupElement>(ObjectType.View, "grp", (p, l) => p.AddPropertyGroup());

            Assert.Empty(propGrp.View.Properties);
            Assert.Empty(propGrp.View.PropertiesReversed);

            propGrp.Add2NewChildrenWithVerify <ProjectPropertyElement>("prop", (pg, n) => pg.AddProperty(n, $"value{n}"), (p, n) => p.Name == n, out var prop1, out var prop2);
            Assert.Equal(2, propGrp.View.Properties.Count);
            Assert.Equal(2, propGrp.View.PropertiesReversed.Count);
            // set prop will add them if they dont exist
            propGrp.Add2NewChildrenWithVerify <ProjectPropertyElement>("setnewprop", (pg, n) => pg.SetProperty(n, $"value{n}"), (p, n) => p.Name == n, out var setNewProp1, out var setNewProp2);
            Assert.Equal(4, propGrp.View.Properties.Count);
            Assert.Equal(4, propGrp.View.PropertiesReversed.Count);
            // Add Prop will add them even if they do already exist.
            propGrp.Add2NewChildrenWithVerify <ProjectPropertyElement>("prop" /*same name*/, (pg, n) => pg.AddProperty(n, $"value2{n}"), (p, n) => p.Value == $"value2{n}", out var prop1_2, out var prop2_2);
            Assert.Equal(6, propGrp.View.Properties.Count);
            Assert.Equal(6, propGrp.View.PropertiesReversed.Count);
            prop1_2.VerifyNotSame(prop1);
            prop2_2.VerifyNotSame(prop2);
            // set prop will override them if they do.
            propGrp.Add2NewChildrenWithVerify <ProjectPropertyElement>("setnewprop" /*same name*/, (pg, n) => pg.SetProperty(n, $"value2{n}"), (p, n) => p.Value == $"value2{n}", out var setNewProp1_2, out var setNewProp2_2);
            Assert.Equal(6, propGrp.View.Properties.Count);
            Assert.Equal(6, propGrp.View.PropertiesReversed.Count);
            setNewProp1_2.VerifySame(setNewProp1);
            setNewProp2_2.VerifySame(setNewProp2);
        }
        public void ProjectPropertyElementModify()
        {
            var pair    = GetNewInMemoryProject("temp.prj");
            var xmlPair = new ProjectXmlPair(pair);
            var propGrp = xmlPair.AddNewLabeledChaildWithVerify <ProjectPropertyGroupElement>(ObjectType.View, "grp", (p, l) => p.AddPropertyGroup());
            var prop    = propGrp.AddNewChaildWithVerify <ProjectPropertyElement>(ObjectType.View, "prop", (pg, n) => pg.AddProperty(n, $"value{n}"), (p, n) => p.Name == n);

            prop.VerifySetter("newValue", (p) => p.Value, (p, v) => p.Value = v);
            prop.VerifySetter("newName", (p) => p.Name, (p, v) => p.Name    = v);
            xmlPair.Verify(); // after rename
        }
        public void ProjectItemGroupElementModify()
        {
            var pair    = GetNewInMemoryProject("temp.prj");
            var xmlPair = new ProjectXmlPair(pair);
            var itemGrp = xmlPair.AddNewLabeledChaildWithVerify <ProjectItemGroupElement>(ObjectType.View, "igrp", (p, s) => p.AddItemGroup());

            Assert.Empty(itemGrp.View.Items);
            itemGrp.Add2NewChildrenWithVerify <ProjectItemElement>("file.cpp", (ig, inc) => ig.AddItem("cpp", inc), (i, inc) => i.Include == inc, out var item1, out var item2);
            Assert.Equal(2, itemGrp.View.Items.Count);

            List <KeyValuePair <string, string> > itemMetadata = new List <KeyValuePair <string, string> >()
            {
                new KeyValuePair <string, string>("igm1", "v1"),
                new KeyValuePair <string, string>("igm2", "v2"),
            };

            itemGrp.Add2NewChildrenWithVerify <ProjectItemElement>("file.cs", (ig, inc) => ig.AddItem("cs", inc, itemMetadata), (i, inc) => i.Include == inc, out var itemWithMetadata1, out var itemWithMetadata2);
            Assert.Equal(4, itemGrp.View.Items.Count);
            ViewValidation.VerifyMetadata(itemMetadata, (k) => itemWithMetadata1.View.Metadata.Where((md) => md.Name == k).FirstOrDefault().Value);
            ViewValidation.VerifyMetadata(itemMetadata, (k) => itemWithMetadata2.View.Metadata.Where((md) => md.Name == k).FirstOrDefault().Value);
        }
        private void CopyFromInternal(ProjectRootElement sourceProject)
        {
            // quite a few complexity in the ExternalProjectProvider implementation is because of
            // ProjectElement.CopyFrom and ProjectElementContainer.DeepCopyFrom....

            bool externalSource = sourceProject != null;

            var projectPair = GetNewInMemoryProject("CopyFrom", TestCollectionGroup.BigProjectFile);
            var xmlPair     = new ProjectXmlPair(projectPair);

            Assert.True(xmlPair.View.HasUnsavedChanges);
            xmlPair.View.Save();
            Assert.False(xmlPair.View.HasUnsavedChanges);

            sourceProject = sourceProject ?? xmlPair.View;

            var existingItemGroupList = sourceProject.AllChildren.OfType <ProjectItemGroupElement>().Where(((ig) => ig.Label == "Group1")).ToList();

            Assert.Single(existingItemGroupList);
            var existingItemGroup = existingItemGroupList[0];

            Assert.NotNull(existingItemGroup);
            var realExistingItemGroup = ViewValidation.GetRealObject(existingItemGroup);

            var ourGroup1 = xmlPair.QuerySingleChildrenWithValidation <ProjectItemGroupElement>((ig) => ig.Label == "Group1");

            var newCopyFrom = xmlPair.AddNewLabeledChaildWithVerify <ProjectItemGroupElement>(ObjectType.View, "newGrop", (p, l) => p.AddItemGroup());

            newCopyFrom.View.CopyFrom(existingItemGroup);
            xmlPair.QueryChildrenWithValidation <ProjectItemGroupElement>((ig) => ig.Label == "Group1", 2);
            newCopyFrom.View.Label = "CopyFrom";
            newCopyFrom.VerifySame(xmlPair.QuerySingleChildrenWithValidation <ProjectItemGroupElement>((ig) => ig.Label == "CopyFrom"));
            ourGroup1.VerifySame(xmlPair.QuerySingleChildrenWithValidation <ProjectItemGroupElement>((ig) => ig.Label == "Group1"));
            // children are not copied.
            Assert.Empty(newCopyFrom.View.Items);
            // but attributes are (even non standard)
            //Assert.Equal("2", ProjectElementLink.GetAttributeValue(existingItemGroup, "FunnyAttribute", true));
            //Assert.Equal("2", ProjectElementLink.GetAttributeValue(newCopyFrom.View, "FunnyAttribute", true));
            newCopyFrom.VerifyNotSame(ourGroup1);


            Assert.True(xmlPair.View.HasUnsavedChanges);
            Assert.False(externalSource && sourceProject.HasUnsavedChanges);

            var newDeepCopy = xmlPair.AddNewLabeledChaildWithVerify <ProjectItemGroupElement>(ObjectType.View, "newGrop", (p, l) => p.AddItemGroup());

            newDeepCopy.View.DeepCopyFrom(existingItemGroup);

            xmlPair.QueryChildrenWithValidation <ProjectItemGroupElement>((ig) => ig.Label == "Group1", 2);
            // slightly cheting but we know that the large groups should be the same, even though there are not the same object
            // note do that before changing the label.
            Assert.NotSame(realExistingItemGroup, newDeepCopy.Real);
            // TODO XmlLocation is (correctly) different for the items, need to find a way to bypass it.
            var context = new ValidationContext();

            context.ValidateLocation = delegate(ElementLocation a, ElementLocation e) { return; };

            ViewValidation.Verify(newDeepCopy.View, realExistingItemGroup, context);
            newDeepCopy.View.Label = "DeepCopyFrom";
            newDeepCopy.VerifySame(xmlPair.QuerySingleChildrenWithValidation <ProjectItemGroupElement>((ig) => ig.Label == "DeepCopyFrom"));
            ourGroup1.VerifySame(xmlPair.QuerySingleChildrenWithValidation <ProjectItemGroupElement>((ig) => ig.Label == "Group1"));
            newDeepCopy.VerifyNotSame(ourGroup1);

            Assert.False(externalSource && sourceProject.HasUnsavedChanges);
        }