public void DataMigration7000001_and_Delint_Tests()
        {
            var dtos = new HashSet <DomainObjectDTO>();
            // 1. Add barebones LP.
            // LP will have one extra property to make sure it isnt; affected.
            // LP will also have a couple 'dangling' references for when 'Delint' is tested.
            // LP will also have an empty Name element that ought to be removed.
            var xml =
                string.Format("<rt class=\"LangProject\" guid=\"9719A466-2240-4DEA-9722-9FE0746A30A6\">{0}" +
                              "<CmObject></CmObject>{0}" +
                              "<LangProject>{0}" +
                              "<Name>{0}" +
                              "</Name>{0}" +
                              "<FakeBoolProperty val=\"True\" />{0}" +
                              "<FakeProperty>bogus content</FakeProperty>{0}" +
                              "<EthnologueCode>{0}" +
                              "<Uni>ZPI</Uni>{0}" +
                              "</EthnologueCode>{0}" +
                              "<WordformInventory>{0}" +
                              "<objsur guid=\"6C84F84A-5B99-4CF5-A7D5-A308DDC604E0\" t=\"o\"/>{0}" +
                              "</WordformInventory>{0}" +
                              "<AnalysisStatus>{0}" +
                              "<objsur guid=\"44AF225F-964C-4F7B-BE51-1AE05995D38C\" t=\"o\" />{0}" +
                              "</AnalysisStatus>{0}" +
                              "<CurVernWss>{0}" +
                              "<objsur guid=\"D75F7FB5-BABD-4D60-B57F-E188BEF264B7\" t=\"r\"/>{0}" +
                              "</CurVernWss>{0}" +
                              "</LangProject>{0}" +
                              "</rt>", Environment.NewLine);
            var lpDto = new DomainObjectDTO("9719A466-2240-4DEA-9722-9FE0746A30A6",
                                            "LangProject",
                                            xml);

            dtos.Add(lpDto);

            xml = string.Format(
                "<rt class=\"WordformInventory\" guid=\"6C84F84A-5B99-4CF5-A7D5-A308DDC604E0\" ownerguid=\"9719A466-2240-4DEA-9722-9FE0746A30A6\" owningflid=\"6001013\" owningord=\"1\">{0}" +
                "<CmObject></CmObject>{0}" +
                "<WordformInventory>{0}" +
                "<Wordforms>{0}" +
                "<objsur guid=\"88304983-CDB2-460B-B3D5-5F95C66F27FF\" t=\"o\" />{0}" +
                "<objsur guid=\"59821DAB-AB03-470E-B430-5696A0503A08\" t=\"o\" />{0}" +
                "</Wordforms>{0}" +
                "</WordformInventory>{0}" +
                "</rt>", Environment.NewLine);
            var wfiDto = new DomainObjectDTO("6C84F84A-5B99-4CF5-A7D5-A308DDC604E0",
                                             "WordformInventory",
                                             xml);

            dtos.Add(wfiDto);

            // 3. Add two wordforms
            // First wordform.
            xml = string.Format(
                "<rt class=\"WfiWordform\" guid=\"88304983-CDB2-460B-B3D5-5F95C66F27FF\" ownerguid=\"6C84F84A-5B99-4CF5-A7D5-A308DDC604E0\" owningflid=\"5063001\" owningord=\"1\">{0}" +
                "<CmObject></CmObject>{0}" +
                "<WfiWordform>{0}" +
                "<Checksum val=\"1722980789\"/>{0}" +
                "<Form>{0}" +
                "<AUni ws=\"eZPI\">aerekondixyonada</AUni>{0}" +
                "</Form>{0}" +
                "<SpellingStatus val=\"1\"/>{0}" +
                "</WfiWordform>{0}" +
                "</rt>", Environment.NewLine);
            var wf1Dto = new DomainObjectDTO("88304983-CDB2-460B-B3D5-5F95C66F27FF",
                                             "WfiWordform",
                                             xml);

            dtos.Add(wf1Dto);

            // Second wordform.
            xml = string.Format(
                "<rt class=\"WfiWordform\" guid=\"59821DAB-AB03-470E-B430-5696A0503A08\" ownerguid=\"6C84F84A-5B99-4CF5-A7D5-A308DDC604E0\" owningflid=\"5063001\" owningord=\"2\">{0}" +
                "<CmObject></CmObject>{0}" +
                "<WfiWordform>{0}" +
                "<Checksum val=\"-1933028922\"/>{0}" +
                "<Form>{0}" +
                "<AUni ws=\"eZPI\">aeropwerto</AUni>{0}" +
                "</Form>{0}" +
                "<SpellingStatus val=\"1\"/>{0}" +
                "</WfiWordform>{0}" +
                "</rt>", Environment.NewLine);
            var wf2Dto = new DomainObjectDTO("59821DAB-AB03-470E-B430-5696A0503A08",
                                             "WfiWordform",
                                             xml);

            dtos.Add(wf2Dto);

            // Add zombie, which is where an object's owner does not exist.
            xml = @"<rt class=""LexSense"" guid=""3462BE3E-4817-4BBE-B2B9-30828B48E2C7"" ownerguid=""0875E978-79C5-4F87-95FE-A4235C0711C1"" owningflid=""5002011"" owningord=""1"" />";
            var zombie = new DomainObjectDTO("3462BE3E-4817-4BBE-B2B9-30828B48E2C7",
                                             "LexSense",
                                             xml);

            dtos.Add(zombie);
            // Add another zombie,
            // which is where an object's owner *does* exist,
            // but it doesn't know it owns the zombie.
            xml = @"<rt class=""Text"" guid=""c1ecaa72-e382-11de-8a39-0800200c9a66"" ownerguid=""9719A466-2240-4DEA-9722-9FE0746A30A6"" owningflid=""6001006"" owningord=""1"" />";
            var zombie2 = new DomainObjectDTO("c1ecaa72-e382-11de-8a39-0800200c9a66",
                                              "Text",
                                              xml);

            dtos.Add(zombie2);

            // Set up mock MDC.
            var mockMDC = new MockMDCForDataMigration();

            mockMDC.AddClass(1, "CmObject", null, new List <string> {
                "LangProject", "Text", "WfiWordform", "LexSense"
            });
            mockMDC.AddClass(2, "LangProject", "CmObject", new List <string>());
            mockMDC.AddClass(3, "Text", "CmObject", new List <string>());
            mockMDC.AddClass(4, "WfiWordform", "CmObject", new List <string>());
            mockMDC.AddClass(5, "LexSense", "CmObject", new List <string>());
            IDomainObjectDTORepository dtoRepos = new DomainObjectDtoRepository(7000000, dtos, mockMDC, null, TestDirectoryFinder.LcmDirectories);

            m_dataMigrationManager.PerformMigration(dtoRepos, 7000001, new DummyProgressDlg());

            // Make sure version number is correct.
            Assert.AreEqual(7000001, dtoRepos.CurrentModelVersion, "Wrong updated version.");
            // Make sure <rt class=\"LangProject\" ...> has no WFI property.
            var lpElement        = XElement.Parse(lpDto.Xml);
            var lpInnerLpElement = lpElement.Element("LangProject");

            Assert.IsNotNull(lpInnerLpElement, "Oops. The 'LangProject' node was also eaten :-(.");

            Assert.IsNull(lpInnerLpElement.Element("WordformInventory"), "Still has WFI in the LangProj element.");

            // Sanity checks.
            Assert.IsNotNull(lpInnerLpElement.Element("EthnologueCode"), "Oops. The 'EthnologueCode' was also eaten :-(.");

            // Make sure there is no WordformInventory <rt> element
            DataMigrationTestServices.CheckDtoRemoved(dtoRepos, wfiDto);

            // Make sure the two wordforms have no owning-related attrs.
            var wfRtElements = new List <XElement> {
                XElement.Parse(wf1Dto.Xml), XElement.Parse(wf2Dto.Xml)
            };

            foreach (var wfElement in wfRtElements)
            {
                Assert.IsNull(wfElement.Attribute("ownerguid"), "Still has 'ownerguid'attr.");
                Assert.IsNull(wfElement.Attribute("owningflid"), "Still has 'owningflid'attr.");
                Assert.IsNull(wfElement.Attribute("owningord"), "Still has 'owningord'attr.");
                // Sanity checks.
                Assert.IsNotNull(wfElement.Descendants("WfiWordform").FirstOrDefault(), "Oops. The 'WfiWordform' element was also eaten :-(.");
                Assert.IsNotNull(wfElement.Descendants("Checksum").FirstOrDefault(), "Oops. The 'Checksum' element was also eaten :-(.");
            }

            // [NB: Other unit tests need not check Delint, as once is good enough. :-)]
            // Make sure Delint worked.
            // Make sure dangling owned object was removed.
            var analStatusElement = lpElement.Descendants("AnalysisStatus").FirstOrDefault();

            Assert.IsNull(analStatusElement, "Now empty element was not removed.");
            // Make sure dangling regular reference was removed.
            var curVernWssElement = lpElement.Descendants("CurVernWss").FirstOrDefault();

            Assert.IsNull(curVernWssElement, "Now empty element was not removed.");
            // Make sure zombie was removed.
            DataMigrationTestServices.CheckDtoRemoved(dtoRepos, zombie);
            // Make sure zombie2 was removed.
            DataMigrationTestServices.CheckDtoRemoved(dtoRepos, zombie2);
            // Make sure Delint handled emtpy properties correctly.
            Assert.IsNull(lpInnerLpElement.Element("Name"), "Empty 'Name' property not removed.");
            Assert.IsNotNull(lpInnerLpElement.Element("FakeBoolProperty"), "Oops. 'FakeBoolProperty' removed.");
            Assert.IsNull(lpInnerLpElement.Element("FakeProperty"), "'FakeProperty' survived.");
        }
        public void DataMigration7000011Test()
        {
            var dtos = new HashSet <DomainObjectDTO>();
            var sb   = new StringBuilder();

            // 1. Add barebones Notebook.
            sb.Append("<rt class=\"RnResearchNbk\" guid=\"2E237D40-853C-49D5-AAC6-EFF01121AC25\">");
            sb.Append("<RnResearchNbk>");
            sb.Append("<RecTypes><objsur t=\"o\" guid=\"513B370D-8EFC-4C94-8192-7707677A6F98\" /></RecTypes>");
            sb.Append("<Records>");
            sb.Append("<objsur t=\"o\" guid=\"C84B721B-3617-43DE-A436-9E0538837A66\" />");
            sb.Append("</Records>");
            sb.Append("</RnResearchNbk>");
            sb.Append("</rt>");
            var nbkDto = new DomainObjectDTO("2E237D40-853C-49D5-AAC6-EFF01121AC25", "RnResearchNbk", sb.ToString());

            dtos.Add(nbkDto);

            sb = new StringBuilder();
            // 2. Add barebones RecTypes List
            sb.Append("<rt class=\"CmPossibilityList\" guid=\"513B370D-8EFC-4C94-8192-7707677A6F98\" ownerguid=\"2E237D40-853C-49D5-AAC6-EFF01121AC25\">");
            sb.Append("<CmPossibilityList>");
            sb.Append("<Possibilities>");
            sb.Append("<objsur t=\"o\" guid=\"27C32299-3B41-4FAD-A85C-F47657BCF95A\" />");
            sb.Append("<objsur t=\"o\" guid=\"5E3D9C56-404C-44C5-B3CB-99BF390E322E\" />");
            sb.Append("</Possibilities>");
            sb.Append("</CmPossibilityList>");
            sb.Append("</rt>");
            var recTypesDto = new DomainObjectDTO("513B370D-8EFC-4C94-8192-7707677A6F98", "CmPossibilityList", sb.ToString());

            dtos.Add(recTypesDto);

            sb = new StringBuilder();
            // 3. Add barebones Conversation
            sb.Append("<rt class=\"CmPossibility\" guid=\"27C32299-3B41-4FAD-A85C-F47657BCF95A\" ownerguid=\"513B370D-8EFC-4C94-8192-7707677A6F98\">");
            sb.Append("<CmPossibility>");
            sb.Append("<Abbreviation><AUni ws=\"en\">Con</AUni></Abbreviation>");
            sb.Append("</CmPossibility>");
            sb.Append("</rt>");
            var conDto = new DomainObjectDTO("27C32299-3B41-4FAD-A85C-F47657BCF95A", "CmPossibility", sb.ToString());

            dtos.Add(conDto);

            sb = new StringBuilder();
            // 4. Add barebones Observation
            sb.Append("<rt class=\"CmPossibility\" guid=\"5E3D9C56-404C-44C5-B3CB-99BF390E322E\" ownerguid=\"513B370D-8EFC-4C94-8192-7707677A6F98\">");
            sb.Append("<CmPossibility>");
            sb.Append("<Abbreviation><AUni ws=\"en\">Obs</AUni></Abbreviation>");
            sb.Append("<SubPossibilities>");
            sb.Append("<objsur t=\"o\" guid=\"9827CBE0-31F3-434E-80F7-5D5354C110B0\" />");
            sb.Append("</SubPossibilities>");
            sb.Append("</CmPossibility>");
            sb.Append("</rt>");
            var obsDto = new DomainObjectDTO("5E3D9C56-404C-44C5-B3CB-99BF390E322E", "CmPossibility", sb.ToString());

            dtos.Add(obsDto);

            sb = new StringBuilder();
            // 5. Add barebones Performance
            sb.Append("<rt class=\"CmPossibility\" guid=\"9827CBE0-31F3-434E-80F7-5D5354C110B0\" ownerguid=\"5E3D9C56-404C-44C5-B3CB-99BF390E322E\">");
            sb.Append("<CmPossibility>");
            sb.Append("<Abbreviation><AUni ws=\"en\">Per</AUni></Abbreviation>");
            sb.Append("</CmPossibility>");
            sb.Append("</rt>");
            var perDto = new DomainObjectDTO("9827CBE0-31F3-434E-80F7-5D5354C110B0", "CmPossibility", sb.ToString());

            dtos.Add(perDto);

            sb = new StringBuilder();
            // 6. Add barebones RnGenericRec
            sb.Append("<rt class=\"RnGenericRec\" guid=\"c84b721b-3617-43de-a436-9e0538837a66\" ownerguid=\"2E237D40-853C-49D5-AAC6-EFF01121AC25\">");
            sb.Append("<RnGenericRec>");
            sb.Append("<Type><objsur guid=\"27c32299-3b41-4fad-a85c-f47657bcf95a\" t=\"r\" /></Type>");
            sb.Append("</RnGenericRec>");
            sb.Append("</rt>");
            var recDto = new DomainObjectDTO("c84b721b-3617-43de-a436-9e0538837a66", "RnGenericRec", sb.ToString());

            dtos.Add(recDto);

            // Set up mock MDC.
            var mockMDC = new MockMDCForDataMigration();

            mockMDC.AddClass(1, "CmObject", null, new List <string> {
                "RnResearchNbk", "CmPossibilityList", "CmPossibility", "RnGenericRec"
            });
            mockMDC.AddClass(2, "RnResearchNbk", "CmObject", new List <string>());
            mockMDC.AddClass(3, "CmPossibilityList", "CmObject", new List <string>());
            mockMDC.AddClass(4, "CmPossibility", "CmObject", new List <string>());
            mockMDC.AddClass(5, "RnGenericRec", "CmObject", new List <string>());
            IDomainObjectDTORepository dtoRepos = new DomainObjectDtoRepository(7000010, dtos, mockMDC, null,
                                                                                TestDirectoryFinder.LcmDirectories);

            m_dataMigrationManager.PerformMigration(dtoRepos, 7000011, new DummyProgressDlg());

            XElement nbkElem = XElement.Parse(nbkDto.Xml);

            Assert.AreEqual("D9D55B12-EA5E-11DE-95EF-0013722F8DEC",
                            (string)nbkElem.XPathSelectElement("RnResearchNbk/RecTypes/objsur").Attribute("guid"));

            DataMigrationTestServices.CheckDtoRemoved(dtoRepos, recTypesDto);
            recTypesDto = dtoRepos.GetDTO("D9D55B12-EA5E-11DE-95EF-0013722F8DEC");
            XElement        recTypesElem = XElement.Parse(recTypesDto.Xml);
            List <XElement> objSurElems  = recTypesElem.XPathSelectElements("CmPossibilityList/Possibilities/objsur").ToList();

            Assert.AreEqual(2, objSurElems.Count);
            Assert.AreEqual("B7B37B86-EA5E-11DE-80E9-0013722F8DEC", (string)objSurElems[0].Attribute("guid"));
            Assert.AreEqual("B7EA5156-EA5E-11DE-9F9C-0013722F8DEC", (string)objSurElems[1].Attribute("guid"));

            DataMigrationTestServices.CheckDtoRemoved(dtoRepos, conDto);
            conDto = dtoRepos.GetDTO("B7B37B86-EA5E-11DE-80E9-0013722F8DEC");
            XElement conElem = XElement.Parse(conDto.Xml);

            Assert.AreEqual("Con", (string)conElem.XPathSelectElement("CmPossibility/Abbreviation/AUni[@ws='en']"));
            Assert.AreEqual("D9D55B12-EA5E-11DE-95EF-0013722F8DEC", (string)conElem.Attribute("ownerguid"));

            DataMigrationTestServices.CheckDtoRemoved(dtoRepos, obsDto);
            obsDto = dtoRepos.GetDTO("B7EA5156-EA5E-11DE-9F9C-0013722F8DEC");
            XElement obsElem = XElement.Parse(obsDto.Xml);

            Assert.AreEqual("Obs", (string)obsElem.XPathSelectElement("CmPossibility/Abbreviation/AUni[@ws='en']"));
            Assert.AreEqual("B7F63D0E-EA5E-11DE-9F02-0013722F8DEC",
                            (string)obsElem.XPathSelectElement("CmPossibility/SubPossibilities/objsur").Attribute("guid"));
            Assert.AreEqual("D9D55B12-EA5E-11DE-95EF-0013722F8DEC", (string)obsElem.Attribute("ownerguid"));

            DataMigrationTestServices.CheckDtoRemoved(dtoRepos, perDto);
            perDto = dtoRepos.GetDTO("B7F63D0E-EA5E-11DE-9F02-0013722F8DEC");
            XElement perElem = XElement.Parse(perDto.Xml);

            Assert.AreEqual("Per", (string)perElem.XPathSelectElement("CmPossibility/Abbreviation/AUni[@ws='en']"));
            Assert.AreEqual("B7EA5156-EA5E-11DE-9F9C-0013722F8DEC", (string)perElem.Attribute("ownerguid"));

            XElement recElem = XElement.Parse(recDto.Xml);

            Assert.AreEqual("B7B37B86-EA5E-11DE-80E9-0013722F8DEC", (string)recElem.XPathSelectElement("RnGenericRec/Type/objsur").Attribute("guid"));
        }