public void LT7974_Phrase_MakeAndBreak()
		{
			// 1. Make Phrases
			IList<int[]> secondaryPathsToJoinWords = new List<int[]>();
			IList<int[]> secondaryPathsToBreakPhrases = new List<int[]>();
			//Thist test proved to be incapable of being Undone, since further tests relied on state this test affected
			//the following two variables duplicate member variables to isolate changes to this test.
			XmlDocument donTouchIt = new XmlDocument();
			IText noLoToque = LoadTestText(
				Path.Combine("FDO",
				 Path.Combine("FDOTests",
				  Path.Combine("TestData", "ParagraphParserTestTexts.xml"))),
					1, donTouchIt);

			ParagraphBuilder pb = new ParagraphBuilder(donTouchIt, noLoToque, (int)Text1ParaIndex.PhraseWordforms);
			ParagraphAnnotatorForParagraphBuilder tapb = new ParagraphAnnotatorForParagraphBuilder(pb);
			// go ahead and parse the text generating real wordforms to be more like a real user situation (LT-7974)
			// and reset the concordance to simulate the situation where the user hasn't loaded ConcordanceWords yet.
			ParagraphParser.ParseText(noLoToque.ContentsOA);
			pb.ResyncExpectedAnnotationIds();

			// first do a basic phrase (without secondary phrases (guesses)), which should not delete "xxxpus" or "xxxyalola"
			// since they occur later in the text.
			// [xxxpus xxxyalola] xxxnihimbilira. xxxpus xxxyalola xxxhesyla xxxnihimbilira. xxxpus xxxyalola xxxnihimbilira
			IWfiWordform wf1 = pb.ActualParagraph.SegmentsOS[0].AnalysesRS[0].Wordform;
			IWfiWordform wf2 = pb.ActualParagraph.SegmentsOS[0].AnalysesRS[1].Wordform;
			tapb.MergeAdjacentAnnotations(0, 0, secondaryPathsToJoinWords, secondaryPathsToBreakPhrases);
			// after the merge, make sure the wordforms for xxxpus and xxxyalola are still valid
			Assert.IsTrue(wf1.IsValidObject, "expected xxxpus to still be valid");
			Assert.IsTrue(wf2.IsValidObject, "expected xxxyalola to still be valid");
			tapb.ValidateAnnotations(true);

			// now break the phrase and make sure we delete this wordform, b/c it is not occurring elsewhere
			pb.ResyncExpectedAnnotationIds();
			// \xxxpus\ \xxxyalola\ xxxnihimbilira. xxxpus xxxyalola xxxhesyla xxxnihimbilira. xxxpus xxxyalola xxxnihimbilira
			IWfiWordform wf3 = pb.ActualParagraph.SegmentsOS[0].AnalysesRS[0].Wordform;
			secondaryPathsToJoinWords.Clear();
			secondaryPathsToBreakPhrases.Clear();
			tapb.BreakPhrase(0, 0, secondaryPathsToBreakPhrases, secondaryPathsToJoinWords, null);
			Assert.IsFalse(wf3.IsValidObject, "expected 'xxxpus xxxyalola' to be deleted.");
			tapb.ValidateAnnotations(true);

			// rejoin the first phrase, parse the text, and break the first phrase
			// [xxxpus xxxyalola] xxxnihimbilira. {xxxpus xxxyalola} xxxhesyla xxxnihimbilira. {xxxpus xxxyalola} xxxnihimbilira
			secondaryPathsToJoinWords.Add(new int[2] { 1, 0 }); // {xxxpus xxxyalola} xxxhesyla
			secondaryPathsToJoinWords.Add(new int[2] { 2, 0 }); // {xxxpus xxxyalola} xxxnihimbilira
			tapb.MergeAdjacentAnnotations(0, 0, secondaryPathsToJoinWords, secondaryPathsToBreakPhrases);
			wf1 = pb.ActualParagraph.SegmentsOS[0].AnalysesRS[0].Wordform;
			tapb.ReparseParagraph();
			// just break the new phrase (and the leave existing guesses)
			// \xxxpus\ \xxxyalola\ xxxnihimbilira. {xxxpus xxxyalola} xxxhesyla xxxnihimbilira. {xxxpus xxxyalola} xxxnihimbilira
			secondaryPathsToJoinWords.Clear();
			tapb.BreakPhrase(0, 0, secondaryPathsToBreakPhrases, secondaryPathsToJoinWords, null);
			Assert.IsTrue(wf1.IsValidObject, "expected 'xxxpus xxxyalola' to still be valid");
			tapb.ValidateAnnotations(true);
			// xxxpus xxxyalola xxxnihimbilira. \xxxpus\ \xxxyalola\ xxxhesyla xxxnihimbilira. {xxxpus xxxyalola} xxxnihimbilira
			tapb.BreakPhrase(1, 0, secondaryPathsToBreakPhrases, secondaryPathsToJoinWords, null);
			Assert.IsTrue(wf1.IsValidObject, "expected 'xxxpus xxxyalola' to still be valid");
			tapb.ValidateAnnotations(true);
			// xxxpus xxxyalola xxxnihimbilira. xxxpus xxxyalola xxxhesyla xxxnihimbilira. \xxxpus\ \xxxyalola\ xxxnihimbilira
			tapb.BreakPhrase(2, 0, secondaryPathsToBreakPhrases, secondaryPathsToJoinWords, null);
			Assert.IsFalse(wf1.IsValidObject, "expected 'xxxpus xxxyalola' to be deleted");
			tapb.ValidateAnnotations(true);

			// now do two joins, the second resulting in deletion of a wordform.
			// xxxpus xxxyalola xxxnihimbilira. xxxpus [xxxyalola xxxhesyla] xxxnihimbilira. xxxpus xxxyalola xxxnihimbilira
			// xxxpus xxxyalola xxxnihimbilira. xxxpus [xxxyalola xxxhesyla xxxnihimbilira]. xxxpus xxxyalola xxxnihimbilira
			ParagraphParser.ParseText(noLoToque.ContentsOA);
			pb.ResyncExpectedAnnotationIds();
			tapb.MergeAdjacentAnnotations(1, 1, secondaryPathsToJoinWords, secondaryPathsToBreakPhrases);
			IWfiWordform wf4 = pb.ActualParagraph.SegmentsOS[1].AnalysesRS[1].Wordform;
			tapb.MergeAdjacentAnnotations(1, 1, secondaryPathsToJoinWords, secondaryPathsToBreakPhrases);
			// this merge should have deleted 'xxxyalola xxxhesyla'
			Assert.IsFalse(wf4.IsValidObject, "expected 'xxxyalola xxxhesyla' to be deleted.");
			tapb.ValidateAnnotations(true);
		}
		public void LT7974_Phrase_MakeAndBreak()
		{
			CheckDisposed();
			// 1. Make Phrases
			IList<int[]> secondaryPathsToJoinWords = new List<int[]>();
			IList<int[]> secondaryPathsToBreakPhrases = new List<int[]>();

			ParagraphBuilder pb = new ParagraphBuilder(m_textsDefn, m_text1, (int)Text1ParaIndex.PhraseWordforms);
			ParagraphAnnotatorForParagraphBuilder tapb = new ParagraphAnnotatorForParagraphBuilder(pb);
			// go ahead and parse the text generating real wordforms to be more like a real user situation (LT-7974)
			// and reset the concordance to simulate the situation where the user hasn't loaded ConcordanceWords yet.
			(Cache.LangProject.WordformInventoryOA as WordformInventory).ResetConcordanceWordformsAndOccurrences();
			bool fDidParse;
			(m_text1.ContentsOA as StText).LastParsedTimestamp = 0;
			ParagraphParser.ParseText(m_text1.ContentsOA, new NullProgressState(), out fDidParse);
			pb.ResyncExpectedAnnotationIds();

			// first do a basic phrase (without secondary phrases (guesses)), which should not delete "xxxpus" or "xxxyalola"
			// since they occur later in the text.
			// [xxxpus xxxyalola] xxxnihimbilira. xxxpus xxxyalola xxxhesyla xxxnihimbilira. xxxpus xxxyalola xxxnihimbilira
			int hvoCba1_0 = tapb.GetSegmentForm(1, 0);	// second xxxpus
			int hvoCba1_1 = tapb.GetSegmentForm(1, 1);	// second xxxyalola
			ICmBaseAnnotation cba1_0 = new CmBaseAnnotation(Cache, hvoCba1_0);
			ICmBaseAnnotation cba1_1 = new CmBaseAnnotation(Cache, hvoCba1_1);
			IWfiWordform wf1 = cba1_0.InstanceOfRA as WfiWordform;
			IWfiWordform wf2 = cba1_0.InstanceOfRA as WfiWordform;
			tapb.MergeAdjacentAnnotations(0, 0, secondaryPathsToJoinWords, secondaryPathsToBreakPhrases);
			// after the merge, make sure the wordforms for xxxpus and xxxyalola are still valid
			Assert.IsTrue(wf1.IsValidObject(), "expected xxxpus to still be valid");
			Assert.IsTrue(wf2.IsValidObject(), "expected xxxyalola to still be valid");
			tapb.ValidateAnnotations(true);

			// now break the phrase and make sure we delete this wordform, b/c it is not occurring elsewhere
			(Cache.LangProject.WordformInventoryOA as WordformInventory).ResetConcordanceWordformsAndOccurrences();
			pb.ResyncExpectedAnnotationIds();
			// \xxxpus\ \xxxyalola\ xxxnihimbilira. xxxpus xxxyalola xxxhesyla xxxnihimbilira. xxxpus xxxyalola xxxnihimbilira
			int hvoCba0_0 = tapb.GetSegmentForm(0, 0);	// xxxpus xxxyalola
			ICmBaseAnnotation cba0_0 = new CmBaseAnnotation(Cache, hvoCba0_0);
			IWfiWordform wf3 = cba0_0.InstanceOfRA as WfiWordform;
			secondaryPathsToJoinWords.Clear();
			secondaryPathsToBreakPhrases.Clear();
			tapb.BreakPhrase(0, 0, secondaryPathsToBreakPhrases, secondaryPathsToJoinWords, null);
			Assert.IsFalse(wf3.IsValidObject(), "expected 'xxxpus xxxyalola' to be deleted.");
			tapb.ValidateAnnotations(true);

			// rejoin the first phrase, parse the text, and break the first phrase
			// [xxxpus xxxyalola] xxxnihimbilira. {xxxpus xxxyalola} xxxhesyla xxxnihimbilira. {xxxpus xxxyalola} xxxnihimbilira
			secondaryPathsToJoinWords.Add(new int[2] { 1, 0 }); // {xxxpus xxxyalola} xxxhesyla
			secondaryPathsToJoinWords.Add(new int[2] { 2, 0 }); // {xxxpus xxxyalola} xxxnihimbilira
			tapb.MergeAdjacentAnnotations(0, 0, secondaryPathsToJoinWords, secondaryPathsToBreakPhrases);
			hvoCba0_0 = tapb.GetSegmentForm(0, 0);	// xxxpus xxxyalola
			cba0_0 = new CmBaseAnnotation(Cache, hvoCba0_0);
			wf1 = cba0_0.InstanceOfRA as WfiWordform;
			tapb.ReparseParagraph();
			// just break the new phrase (and the leave existing guesses)
			// \xxxpus\ \xxxyalola\ xxxnihimbilira. {xxxpus xxxyalola} xxxhesyla xxxnihimbilira. {xxxpus xxxyalola} xxxnihimbilira
			(Cache.LangProject.WordformInventoryOA as WordformInventory).ResetConcordanceWordformsAndOccurrences();
			secondaryPathsToJoinWords.Clear();
			tapb.BreakPhrase(0, 0, secondaryPathsToBreakPhrases, secondaryPathsToJoinWords, null);
			Assert.IsTrue(wf1.IsValidObject(), "expected 'xxxpus xxxyalola' to still be valid");
			tapb.ValidateAnnotations(true);
			// xxxpus xxxyalola xxxnihimbilira. \xxxpus\ \xxxyalola\ xxxhesyla xxxnihimbilira. {xxxpus xxxyalola} xxxnihimbilira
			tapb.BreakPhrase(1, 0, secondaryPathsToBreakPhrases, secondaryPathsToJoinWords, null);
			Assert.IsTrue(wf1.IsValidObject(), "expected 'xxxpus xxxyalola' to still be valid");
			tapb.ValidateAnnotations(true);
			// xxxpus xxxyalola xxxnihimbilira. xxxpus xxxyalola xxxhesyla xxxnihimbilira. \xxxpus\ \xxxyalola\ xxxnihimbilira
			tapb.BreakPhrase(2, 0, secondaryPathsToBreakPhrases, secondaryPathsToJoinWords, null);
			Assert.IsFalse(wf1.IsValidObject(), "expected 'xxxpus xxxyalola' to be deleted");
			tapb.ValidateAnnotations(true);

			// now do two joins, the second resulting in deletion of a wordform.
			// xxxpus xxxyalola xxxnihimbilira. xxxpus [xxxyalola xxxhesyla] xxxnihimbilira. xxxpus xxxyalola xxxnihimbilira
			// xxxpus xxxyalola xxxnihimbilira. xxxpus [xxxyalola xxxhesyla xxxnihimbilira]. xxxpus xxxyalola xxxnihimbilira
			(Cache.LangProject.WordformInventoryOA as WordformInventory).ResetConcordanceWordformsAndOccurrences();
			(m_text1.ContentsOA as StText).LastParsedTimestamp = 0;
			ParagraphParser.ParseText(m_text1.ContentsOA, new NullProgressState(), out fDidParse);
			pb.ResyncExpectedAnnotationIds();
			tapb.MergeAdjacentAnnotations(1, 1, secondaryPathsToJoinWords, secondaryPathsToBreakPhrases);
			hvoCba1_1 = tapb.GetSegmentForm(1, 1);	// xxxyalola xxxhesyla
			cba1_1 = new CmBaseAnnotation(Cache, hvoCba1_1);
			IWfiWordform wf4 = cba1_1.InstanceOfRA as WfiWordform;
			tapb.MergeAdjacentAnnotations(1, 1, secondaryPathsToJoinWords, secondaryPathsToBreakPhrases);
			// this merge should have deleted 'xxxyalola xxxhesyla'
			Assert.IsFalse(wf4.IsValidObject(), "expected 'xxxyalola xxxhesyla' to be deleted.");
			tapb.ValidateAnnotations(true);
		}