public void GetPhrasesSortedByDefault()
		{
			AddMockedKeyTerm("God", 1, 4);
			AddMockedKeyTerm("Paul", 1, 2, 5);
			AddMockedKeyTerm("have", 1, 2, 3, 4, 5, 6);
			AddMockedKeyTerm("say", 1, 2, 5);

			PhraseTranslationHelper pth = new PhraseTranslationHelper(new[] {
				new TranslatablePhrase(new TestQ("What would God have me to say with respect to Paul?", "A", 1, 1), 1, 0),       // what would (1)     | me to (3)       | with respect to (3)
				new TranslatablePhrase(new TestQ("What is Paul asking me to say with respect to that dog?", "B", 2, 2), 1, 0),   // what is (3)        | asking (1)      | me to (3)           | with respect to (3) | that dog (4)
				new TranslatablePhrase(new TestQ("that dog", "C", 3, 3), 1, 0),                                                  // that dog (4)
				new TranslatablePhrase(new TestQ("Is it okay for Paul me to talk with respect to God today?", "D", 4, 4), 1, 0), // is it okay for (1) | me to (3)       | talk (1)            | with respect to (3) | today (1)
				new TranslatablePhrase(new TestQ("that dog wishes this Paul and what is say radish", "E", 5, 5), 1, 0),          // that dog (4)       | wishes this (1) | and (1)             | what is (3)         | radish (1)
				new TranslatablePhrase(new TestQ("What is that dog?", "F", 6, 6), 1, 0)},                                        // what is (3)        | that dog (4)
				m_dummyKtList, m_keyTermRules, new List<Substitution>());

			Assert.AreEqual(6, pth.Phrases.Count(), "Wrong number of phrases in helper");

			Assert.AreEqual("C", pth[0].Reference);
			Assert.AreEqual("F", pth[1].Reference);
			Assert.AreEqual("A", pth[2].Reference);
			Assert.AreEqual("B", pth[3].Reference);
			Assert.AreEqual("E", pth[4].Reference);
			Assert.AreEqual("D", pth[5].Reference);
		}
		public void GetPhrasesSortedByOriginalPhrase()
		{
			PhraseTranslationHelper pth = new PhraseTranslationHelper(new[] {
				new TranslatablePhrase(new TestQ("What would God have me to say with respect to Paul?", "A", 1, 1), 1, 0),
				new TranslatablePhrase(new TestQ("What is Paul asking me to say with respect to that dog?", "B", 2, 2), 1, 0),
				new TranslatablePhrase(new TestQ("that dog", "C", 3, 3), 1, 0),
				new TranslatablePhrase(new TestQ("Is it okay for Paul me to talk with respect to God today?", "D", 4, 4), 1, 0),
				new TranslatablePhrase(new TestQ("that dog wishes this Paul and what is say radish", "E", 5, 5), 1, 0),
				new TranslatablePhrase(new TestQ("What is that dog?", "F", 6, 6), 1, 0)},
				m_dummyKtList, m_keyTermRules, new List<Substitution>());

			pth.Sort(PhraseTranslationHelper.SortBy.EnglishPhrase, true);

			Assert.AreEqual("D", pth[0].Reference);
			Assert.AreEqual("C", pth[1].Reference);
			Assert.AreEqual("E", pth[2].Reference);
			Assert.AreEqual("B", pth[3].Reference);
			Assert.AreEqual("F", pth[4].Reference);
			Assert.AreEqual("A", pth[5].Reference);

			pth.Sort(PhraseTranslationHelper.SortBy.EnglishPhrase, false);

			Assert.AreEqual("A", pth[0].Reference);
			Assert.AreEqual("F", pth[1].Reference);
			Assert.AreEqual("B", pth[2].Reference);
			Assert.AreEqual("E", pth[3].Reference);
			Assert.AreEqual("C", pth[4].Reference);
			Assert.AreEqual("D", pth[5].Reference);
		}
		public void SetTranslation_UseStatsAndConfidenceToDeterminePartTranslations()
		{
			AddMockedKeyTerm("ask");
			AddMockedKeyTerm("give");
			AddMockedKeyTerm("want");
			AddMockedKeyTerm("whatever");
			AddMockedKeyTerm("thing");

			TranslatablePhrase phrase1 = new TranslatablePhrase("ABC ask DEF");
			TranslatablePhrase phrase2 = new TranslatablePhrase("ABC give XYZ");
			TranslatablePhrase phrase3 = new TranslatablePhrase("XYZ want ABC whatever EFG");
			TranslatablePhrase phrase4 = new TranslatablePhrase("EFG thing ABC");

			PhraseTranslationHelper pth = new PhraseTranslationHelper(new[] { phrase1, phrase2,
				phrase3, phrase4 }, m_dummyKtList, m_keyTermRules, new List<Substitution>());
			ReflectionHelper.SetField(pth, "m_justGettingStarted", false);

			Assert.AreEqual(2, phrase1.TranslatableParts.Count());
			Assert.AreEqual(3, phrase1.GetParts().Count());
			Assert.AreEqual(2, phrase2.TranslatableParts.Count());
			Assert.AreEqual(3, phrase2.GetParts().Count());
			Assert.AreEqual(3, phrase3.TranslatableParts.Count());
			Assert.AreEqual(5, phrase3.GetParts().Count());
			Assert.AreEqual(2, phrase4.TranslatableParts.Count());
			Assert.AreEqual(3, phrase4.GetParts().Count());

			phrase1.Translation = "def ASK abc";
			phrase2.Translation = "abc xyz GIVE";
			phrase3.Translation = "WANT xyz abc WHATEVER efg";

			Assert.AreEqual("efg THING abc", phrase4.Translation);
		}
		public void GetParts_KeyTermsList_ComplexPhraseSubstitutions()
		{
			AddMockedKeyTerm("John"); // The apostle
			AddMockedKeyTerm("John"); // The Baptist
			AddMockedKeyTerm("Paul");
			AddMockedKeyTerm("Mary");
			AddMockedKeyTerm("altar");
			AddMockedKeyTerm("forgive");
			AddMockedKeyTerm("bless");
			AddMockedKeyTerm("God");
			AddMockedKeyTerm("Jesus");
			AddMockedKeyTerm("sin");

			List<Substitution> ignored = new List<Substitution>();
			ignored.Add(new Substitution("what do you think it means", "what means", false, true));
			ignored.Add(new Substitution(@"\ban\b", "a", true, false));
			ignored.Add(new Substitution(@"did (\S+) do", @"did $1", true, true));
			ignored.Add(new Substitution(@"ed\b", null, true, true));

			PhraseTranslationHelper pth = new PhraseTranslationHelper(new[] {
				new TranslatablePhrase("What did John do?"),
				new TranslatablePhrase("What did Paul do?"),
				new TranslatablePhrase("Who was Mary?"),
				new TranslatablePhrase("Who walked on a wall?"),
				new TranslatablePhrase("Who walked on an altar?"),
				new TranslatablePhrase("What do you think it means to forgive?"),
				new TranslatablePhrase("what do you think it means to bless someone?"),
				new TranslatablePhrase("Did Mary do the right thing?")},
				m_dummyKtList, m_keyTermRules, ignored);

			Assert.AreEqual(8, pth.Phrases.Count(), "Wrong number of phrases in helper");

			VerifyTranslatablePhrase(pth, "What did John do?", "what did", 2);
			VerifyTranslatablePhrase(pth, "What did Paul do?", "what did", 2);
			VerifyTranslatablePhrase(pth, "Who was Mary?", "who was", 1);
			VerifyTranslatablePhrase(pth, "Who walked on a wall?", "who walk on a", 2, "wall", 1);
			VerifyTranslatablePhrase(pth, "Who walked on an altar?", "who walk on a", 2);
			VerifyTranslatablePhrase(pth, "What do you think it means to forgive?", "what do you think it means to", 1);
			VerifyTranslatablePhrase(pth, "what do you think it means to bless someone?", "what means to", 1, "someone", 1);
			VerifyTranslatablePhrase(pth, "Did Mary do the right thing?", "did", 1, "do the right thing", 1);
		}
		public void GetParts_KeyTermsList_Apostrophes()
		{
			AddMockedKeyTerm("(God described as the) Most High");
			AddMockedKeyTerm("(God of) hosts");
			AddMockedKeyTerm("God");
			AddMockedKeyTerm("heavenly creature, symbol of God's majesty and associated with his presence");
			AddMockedKeyTerm("(one's own) burial-place");
			AddMockedKeyTerm("to make straight (one's way)");
			AddMockedKeyTerm("love for one's fellow believer");

			PhraseTranslationHelper pth = new PhraseTranslationHelper(new[] {
				new TranslatablePhrase("If one gives one's word and doesn't keep it, is it sin?"),
				new TranslatablePhrase("Is there one way to heaven?"),
				new TranslatablePhrase("Is the Bible God's Word?"),
				new TranslatablePhrase("Who is God's one and only Son?"),
				new TranslatablePhrase("Can the God of hosts also be called the Most High God?"),
				new TranslatablePhrase("Should one be buried in one's own burial-place?"),
				new TranslatablePhrase("Do wise people make straight paths for themselves?"),
				new TranslatablePhrase("How can you tell if one has love for one's fellow believer?"),
				new TranslatablePhrase("Is the earth God's?")},
				m_dummyKtList, m_keyTermRules, new List<Substitution>());

			Assert.AreEqual(9, pth.Phrases.Count(), "Wrong number of phrases in helper");

			VerifyTranslatablePhrase(pth, "If one gives one's word and doesn't keep it, is it sin?", "if one gives one's word and doesn't keep it is it sin", 1);
			VerifyTranslatablePhrase(pth, "Is there one way to heaven?", "is there one way to heaven", 1);
			VerifyTranslatablePhrase(pth, "Is the Bible God's Word?", "is the bible", 1, "word", 1);
			VerifyTranslatablePhrase(pth, "Who is God's one and only Son?", "who is", 1, "one and only son", 1);
			VerifyTranslatablePhrase(pth, "Can the God of hosts also be called the Most High God?", "can the", 1, "also be called the", 1);
			VerifyTranslatablePhrase(pth, "Should one be buried in one's own burial-place?", "should one be buried in", 1);
			VerifyTranslatablePhrase(pth, "Do wise people make straight paths for themselves?", "do wise people", 1, "paths for themselves", 1);
			VerifyTranslatablePhrase(pth, "How can you tell if one has love for one's fellow believer?", "how can you tell if one has", 1);
			VerifyTranslatablePhrase(pth, "Is the earth God's?", "is the earth", 1);
		}
		public void GetPhrasesFilteredTextually_PartialMatchWithoutRenderings()
		{
			AddMockedKeyTerm("God", 1, 4);
			AddMockedKeyTerm("Paul", 1, 2, 5);
			AddMockedKeyTerm("have", 1, 2, 3, 4, 5, 6);
			AddMockedKeyTerm("say", null, 1, 2, 5);

			PhraseTranslationHelper pth = new PhraseTranslationHelper(new[] {
				new TranslatablePhrase(new TestQ("This would God have me to say with respect to Paul?", "A", 1, 1), 1, 0),       // what would (1)     | me to (3)       | with respect to (3)
				new TranslatablePhrase(new TestQ("What is Paul asking me to say with respect to that dog?", "B", 2, 2), 1, 0),   // what is (3)        | asking (1)      | me to (3)           | with respect to (3) | that dog (4)
				new TranslatablePhrase(new TestQ("that dog", "C", 3, 3), 1, 0),                                                  // that dog (4)
				new TranslatablePhrase(new TestQ("Is it okay for Paul me to talk with respect to God today?", "D", 4, 4), 1, 0), // is it okay for (1) | me to (3)       | talk (1)            | with respect to (3) | today (1)
				new TranslatablePhrase(new TestQ("that dog wishes this Paul and what is say radish", "E", 5, 5), 1, 0),          // that dog (4)       | wishes this (1) | and (1)             | what is (3)         | radish (1)
				new TranslatablePhrase(new TestQ("What is that dog?", "F", 6, 6), 1, 0)},                                        // what is (3)        | that dog (4)
				m_dummyKtList, m_keyTermRules, new List<Substitution>());

			Assert.AreEqual(6, pth.Phrases.Count(), "Wrong number of phrases in helper");

			pth.Filter("is", false, PhraseTranslationHelper.KeyTermFilterType.WithoutRenderings, null, false);
			Assert.AreEqual(3, pth.Phrases.Count(), "Wrong number of phrases in helper");
			pth.Sort(PhraseTranslationHelper.SortBy.Reference, true);

			Assert.AreEqual("A", pth[0].Reference);
			Assert.AreEqual("B", pth[1].Reference);
			Assert.AreEqual("E", pth[2].Reference);
		}
		public void GetPhrasesFilteredByKeyTerms_WithRenderings_IncludeExcluded()
		{
			AddMockedKeyTerm("God", (string)null);
			AddMockedKeyTerm("Paul");
			AddMockedKeyTerm("have", (string)null);
			AddMockedKeyTerm("say");

			PhraseTranslationHelper pth = new PhraseTranslationHelper(new[] {
				new TranslatablePhrase(new TestQ("What would God have me to say with respect to Paul?", "A", 1, 1), 1, 0) { IsExcluded = true },       // God & have don't have renderings
				new TranslatablePhrase(new TestQ("What is Paul asking me to say with respect to that dog?", "B", 2, 2), 1, 0) { IsExcluded = true },
				new TranslatablePhrase(new TestQ("that dog", "C", 3, 3), 1, 0),
				new TranslatablePhrase(new TestQ("Is it okay for Paul me to talk with respect to God today?", "D", 4, 4), 1, 0), // God doesn't have a rendering
				new TranslatablePhrase(new TestQ("that dog wishes this Paul and what is say radish", "E", 5, 5), 1, 0) { IsExcluded = true },
				new TranslatablePhrase(new TestQ("What is that dog?", "F", 6, 6), 1, 0)},
				m_dummyKtList, m_keyTermRules, new List<Substitution>());

			Assert.AreEqual(6, pth.Phrases.Count(), "Wrong number of phrases in helper");

			pth.Filter(null, false, PhraseTranslationHelper.KeyTermFilterType.WithRenderings, null, false);
			pth.Sort(PhraseTranslationHelper.SortBy.Reference, true);
			Assert.AreEqual(2, pth.Phrases.Count(), "Wrong number of phrases in helper");

			Assert.AreEqual("C", pth[0].Reference);
			Assert.AreEqual("F", pth[1].Reference);

			pth.Filter(null, false, PhraseTranslationHelper.KeyTermFilterType.WithRenderings, null, true);
			Assert.AreEqual(5, pth.Phrases.Count(), "Wrong number of phrases in helper");

			Assert.AreEqual("A", pth[0].Reference); // Even though there is an unrendered term, this phrase gets included because we don't actually parse excluded phrases to look for key term matches.
			Assert.AreEqual("B", pth[1].Reference);
			Assert.AreEqual("C", pth[2].Reference);
			Assert.AreEqual("E", pth[3].Reference);
			Assert.AreEqual("F", pth[4].Reference);
		}
		public void ChangeTranslation_FallbackToSmallerCommonSubstring_StartingInLargerSubstring()
		{
			AddMockedKeyTerm("the squirrel", "ardilla");
			AddMockedKeyTerm("donkey", "asno");
			AddMockedKeyTerm("Balaam", "Balaam");

			TranslatablePhrase phrase1 = new TranslatablePhrase("When did the donkey and the squirrel fight?");
			TranslatablePhrase phrase2 = new TranslatablePhrase("Where are Balaam and the squirrel?");
			TranslatablePhrase phrase3 = new TranslatablePhrase("What did the donkey and Balaam do?");
			TranslatablePhrase phrase4 = new TranslatablePhrase("and?");

			PhraseTranslationHelper pth = new PhraseTranslationHelper(new[] { phrase1, phrase2, phrase3, phrase4 }, m_dummyKtList, m_keyTermRules, new List<Substitution>());
			ReflectionHelper.SetField(pth, "m_justGettingStarted", false);

			Assert.AreEqual(3, phrase1.TranslatableParts.Count());
			Assert.AreEqual(2, phrase2.TranslatableParts.Count());
			Assert.AreEqual(3, phrase3.TranslatableParts.Count());
			Assert.AreEqual(1, phrase4.TranslatableParts.Count());

			phrase1.Translation = "\u00BFCua\u0301ndo pelearon el asno y la ardilla?";
			phrase2.Translation = "\u00BFDo\u0301nde esta\u0301n Balaam y la ardilla?";
			phrase3.Translation = "\u00BFQue\u0301 hicieron el asno y Balaam?";
			Assert.AreEqual("\u00BFy?", phrase4.Translation);

			Assert.IsTrue(phrase1.HasUserTranslation);
			Assert.IsTrue(phrase2.HasUserTranslation);
			Assert.IsTrue(phrase3.HasUserTranslation);
			Assert.IsFalse(phrase4.HasUserTranslation);
		}
		public void ChangeTranslation_PreventUpdatedTranslationFromChangingGoodPartTranslation()
		{
			AddMockedKeyTerm("donkey", "asno");
			AddMockedKeyTerm("Balaam", "Balaam");

			TranslatablePhrase phrase1 = new TranslatablePhrase("When?");
			TranslatablePhrase phrase2 = new TranslatablePhrase("When Balaam eats donkey.");
			TranslatablePhrase phrase3 = new TranslatablePhrase("What donkey eats?");
			TranslatablePhrase phrase4 = new TranslatablePhrase("What Balaam eats?");
			TranslatablePhrase phrase5 = new TranslatablePhrase("Donkey eats?");

			PhraseTranslationHelper pth = new PhraseTranslationHelper(new[] { phrase1, phrase2, phrase3, phrase4, phrase5 }, m_dummyKtList, m_keyTermRules, new List<Substitution>());
			ReflectionHelper.SetField(pth, "m_justGettingStarted", false);

			Assert.AreEqual(1, phrase1.TranslatableParts.Count());
			Assert.AreEqual(2, phrase2.TranslatableParts.Count());
			Assert.AreEqual(2, phrase3.TranslatableParts.Count());
			Assert.AreEqual(2, phrase4.TranslatableParts.Count());
			Assert.AreEqual(1, phrase5.TranslatableParts.Count());

			phrase1.Translation = "\u00BFCua\u0301ndo?";
			phrase2.Translation = "\u00BFCua\u0301ndo come Balaam al asno.";
			phrase3.Translation = "\u00BFQue\u0301 come el asno?";
			phrase4.Translation = "\u00BFQue\u0301 ingiere Balaam?";
			Assert.AreEqual("\u00BFasno come?", phrase5.Translation);

			Assert.IsTrue(phrase1.HasUserTranslation);
			Assert.IsTrue(phrase2.HasUserTranslation);
			Assert.IsTrue(phrase3.HasUserTranslation);
			Assert.IsTrue(phrase4.HasUserTranslation);
			Assert.IsFalse(phrase5.HasUserTranslation);
		}
		public void ChangeTranslation_PreventPartTranslationFromBeingSetToPunctuation()
		{
			AddMockedKeyTerm("Isaiah", "Isai\u0301as");
			AddMockedKeyTerm("Paul", "Pablo");
			AddMockedKeyTerm("Silas", "Silas");

			TranslatablePhrase phrase1 = new TranslatablePhrase("What did Paul and Silas do in jail?");
			TranslatablePhrase phrase2 = new TranslatablePhrase("Were Isaiah and Paul prophets?");
			TranslatablePhrase phrase3 = new TranslatablePhrase("Did Paul and Silas run away?");
			TranslatablePhrase phrase4 = new TranslatablePhrase("And what did Paul do next?");

			PhraseTranslationHelper pth = new PhraseTranslationHelper(new[] { phrase1, phrase2,
				phrase3, phrase4 }, m_dummyKtList, m_keyTermRules, new List<Substitution>());
			ReflectionHelper.SetField(pth, "m_justGettingStarted", false);

			Assert.AreEqual(3, phrase1.TranslatableParts.Count());
			Assert.AreEqual(3, phrase2.TranslatableParts.Count());
			Assert.AreEqual(3, phrase3.TranslatableParts.Count());
			Assert.AreEqual(3, phrase4.TranslatableParts.Count());

			phrase1.Translation = "\u00BFQue\u0301 hicieron Pablo y Silas en la carcel?";
			phrase2.Translation = "\u00BFEran profetas Pablo e Isai\u0301as?";
			phrase3.Translation = "\u00BFSe corrieron Pablo y Silas?";
			Assert.AreEqual("\u00BFy Pablo?", phrase4.Translation);
		}
		public void ChangeTranslation_PreventTrashingPartTranslationsWhenReCalculating()
		{
			AddMockedKeyTerm("Mary", "Mari\u0301a");
			AddMockedKeyTerm("Jesus");

			TranslatablePhrase phrase1 = new TranslatablePhrase("When?");
			TranslatablePhrase phrase2 = new TranslatablePhrase("Where did Mary find Jesus?");
			TranslatablePhrase phrase3 = new TranslatablePhrase("Where did Jesus find a rock?");
			TranslatablePhrase phrase4 = new TranslatablePhrase("Where did Mary eat?");
			TranslatablePhrase phrase5 = new TranslatablePhrase("When Mary went to the tomb, where did Jesus meet her?");

			PhraseTranslationHelper pth = new PhraseTranslationHelper(new[] { phrase1, phrase2,
				phrase3, phrase4, phrase5 }, m_dummyKtList, m_keyTermRules, new List<Substitution>());
			ReflectionHelper.SetField(pth, "m_justGettingStarted", false);

			Assert.AreEqual(1, phrase1.TranslatableParts.Count());
			Assert.AreEqual(2, phrase2.TranslatableParts.Count());
			Assert.AreEqual(2, phrase3.TranslatableParts.Count());
			Assert.AreEqual(2, phrase4.TranslatableParts.Count());
			Assert.AreEqual(4, phrase5.TranslatableParts.Count());

			phrase1.Translation = "\u00BFCua\u0301ndo?";
			phrase2.Translation = "\u00BFDo\u0301nde encontro\u0301 Mari\u0301a a JESUS?";
			phrase3.Translation = "\u00BFDo\u0301nde encontro\u0301 JESUS una piedra?";
			phrase4.Translation = "\u00BFDo\u0301nde comio\u0301 Mari\u0301a?";
			Assert.AreEqual("\u00BFCua\u0301ndo Mari\u0301a Do\u0301nde JESUS?", phrase5.Translation);

			Assert.IsTrue(phrase1.HasUserTranslation);
			Assert.IsTrue(phrase2.HasUserTranslation);
			Assert.IsTrue(phrase3.HasUserTranslation);
			Assert.IsFalse(phrase5.HasUserTranslation);
		}
		public void SetTranslation_DoNotTreatNormalLeadingPuncAsOpeningQuestionMark()
		{
			AddMockedKeyTerm("Isaiah", "Isai\u0301as");
			AddMockedKeyTerm("Paul", "Pablo");
			AddMockedKeyTerm("Silas", "Silas");

			TranslatablePhrase phrase1 = new TranslatablePhrase("What did Paul and Silas do in jail?");
			TranslatablePhrase phrase2 = new TranslatablePhrase("Were Isaiah and Paul prophets?");

			PhraseTranslationHelper pth = new PhraseTranslationHelper(new[] { phrase1, phrase2 },
				m_dummyKtList, m_keyTermRules, new List<Substitution>());
			ReflectionHelper.SetField(pth, "m_justGettingStarted", false);

			Assert.AreEqual(3, phrase1.TranslatableParts.Count());
			Assert.AreEqual(3, phrase2.TranslatableParts.Count());

			phrase1.Translation = "*\u00BFQue\u0301 hicieron Pablo y Silas en la carcel?";
			Assert.AreEqual("Isai\u0301as Pablo?", phrase2.Translation);
		}
		public void SetTranslation_UseStatisticalBestPartTranslationsRatherThanCommonPartialWord()
		{
			AddMockedKeyTerm("Isaac", "Isaac");
			AddMockedKeyTerm("Paul", "Pablo");

			TranslatablePhrase phraseBreakerA = new TranslatablePhrase("Now what?");
			TranslatablePhrase phraseBreakerB = new TranslatablePhrase("What did Isaac say?");
			TranslatablePhrase phraseBreakerC = new TranslatablePhrase("What could Isaac say?");
			TranslatablePhrase phrase1 = new TranslatablePhrase("So now what did those two brothers do?");
			TranslatablePhrase phrase2 = new TranslatablePhrase("So what could they do about the problem?");
			TranslatablePhrase phrase3 = new TranslatablePhrase("So what did he do?");
			TranslatablePhrase phrase4 = new TranslatablePhrase("So now what was Isaac complaining about?");
			TranslatablePhrase phrase5 = new TranslatablePhrase("So what did the Apostle Paul say about that?");
			TranslatablePhrase phrase6 = new TranslatablePhrase("Why did they treat the Apostle Paul so?");

			PhraseTranslationHelper pth = new PhraseTranslationHelper(new[] { phraseBreakerA, phraseBreakerB, phraseBreakerC,
				phrase1, phrase2, phrase3, phrase4, phrase5, phrase6 }, m_dummyKtList, m_keyTermRules, new List<Substitution>());
			ReflectionHelper.SetField(pth, "m_justGettingStarted", false);

			Assert.AreEqual(3, phrase1.TranslatableParts.Count());
			Assert.AreEqual(3, phrase1.GetParts().Count());
			Assert.AreEqual(3, phrase2.TranslatableParts.Count());
			Assert.AreEqual(3, phrase2.GetParts().Count());
			Assert.AreEqual(3, phrase3.TranslatableParts.Count());
			Assert.AreEqual(3, phrase3.GetParts().Count());
			Assert.AreEqual(4, phrase4.TranslatableParts.Count());
			Assert.AreEqual(5, phrase4.GetParts().Count());
			Assert.AreEqual(4, phrase5.TranslatableParts.Count());
			Assert.AreEqual(5, phrase5.GetParts().Count());
			Assert.AreEqual(2, phrase6.TranslatableParts.Count());
			Assert.AreEqual(3, phrase6.GetParts().Count());

			phrase1.Translation = "Entonces AB Zuxelopitmyfor CD EF GH";
			phrase2.Translation = "Entonces Vuxelopitmyfor IJ KL MN OP QR";
			phrase3.Translation = "Entonces Wuxelopitmyfor ST";
			phrase5.Translation = "Entonces Xuxelopitmyfor dijo Pablo UV WX YZ";
			phrase6.Translation = "BG LP Yuxelopitmyfor DW MR Pablo";

			Assert.AreEqual("Entonces Isaac", phrase4.Translation);
		}
		public void SetTranslation_UseStatisticalBestPartTranslations()
		{
			AddMockedKeyTerm("Isaac", "Isaac");
			AddMockedKeyTerm("Paul", "Pablo");

			TranslatablePhrase phraseBreakerA = new TranslatablePhrase("Now what?");
			TranslatablePhrase phraseBreakerB = new TranslatablePhrase("What did Isaac say?");
			TranslatablePhrase phrase1 = new TranslatablePhrase("So now what did those two brothers do?");
			TranslatablePhrase phrase2 = new TranslatablePhrase("So what did they do about the problem?");
			TranslatablePhrase phrase3 = new TranslatablePhrase("So what did he do?");
			TranslatablePhrase phrase4 = new TranslatablePhrase("So now what was Isaac complaining about?");
			TranslatablePhrase phrase5 = new TranslatablePhrase("So what did the Apostle Paul say about that?");

			PhraseTranslationHelper pth = new PhraseTranslationHelper(new[] { phraseBreakerA, phraseBreakerB,
				phrase1, phrase2, phrase3, phrase4, phrase5 }, m_dummyKtList, m_keyTermRules, new List<Substitution>());
			ReflectionHelper.SetField(pth, "m_justGettingStarted", false);

			Assert.AreEqual(3, phrase1.TranslatableParts.Count());
			Assert.AreEqual(3, phrase1.GetParts().Count());
			Assert.AreEqual(3, phrase2.TranslatableParts.Count());
			Assert.AreEqual(3, phrase2.GetParts().Count());
			Assert.AreEqual(3, phrase3.TranslatableParts.Count());
			Assert.AreEqual(3, phrase3.GetParts().Count());
			Assert.AreEqual(4, phrase4.TranslatableParts.Count());
			Assert.AreEqual(5, phrase4.GetParts().Count());
			Assert.AreEqual(4, phrase5.TranslatableParts.Count());
			Assert.AreEqual(5, phrase5.GetParts().Count());

			phrase1.Translation = "\u00BFEntonces ahora que\u0301 hicieron esos dos hermanos?";
			phrase2.Translation = "\u00BFEntonces que\u0301 hicieron acerca del problema?";
			phrase3.Translation = "\u00BFEntonces que\u0301 hizo?";
			phrase5.Translation = "\u00BFEntonces que\u0301 dijo Pablo acerca de eso?";

			Assert.AreEqual("\u00BFEntonces Isaac?", phrase4.Translation);
		}
		/// ------------------------------------------------------------------------------------
		/// <summary>
		/// Verifies the translatable phrase.
		/// </summary>
		/// <param name="pth">The PhraseTranslationHelper.</param>
		/// <param name="phrase">The phrase.</param>
		/// <param name="parts">Parts information, with alternating sub-phrases and their
		/// occurrence counts (across all phrases in the test).</param>
		/// ------------------------------------------------------------------------------------
		private static void VerifyTranslatablePhrase(PhraseTranslationHelper pth, string phrase,
			params object[] parts)
		{
			TranslatablePhrase phr = pth.UnfilteredPhrases.FirstOrDefault(x => x.OriginalPhrase == phrase.Normalize(NormalizationForm.FormD));
			Assert.IsNotNull(phr);
			Assert.AreEqual(parts.Length / 2, phr.TranslatableParts.Count(), "Phrase \"" + phrase +
				"\" was split into the wrong number of parts.");
			int i = 0;
			foreach (Part part in phr.TranslatableParts)
			{
				Assert.AreEqual(parts[i++], part.Text, "Unexpected part");
				Assert.AreEqual(GetWordCount(part.Text), part.Words.Count(),
					"Unexpected word count for part \"" + part.Text + "\"");
				Assert.AreEqual(parts[i++], part.OwningPhrases.Count(),
					"Unexpected number of owning phrases for part \"" + part.Text + "\"");
			}
		}
		public void GetPhrasesSortedByTranslation()
		{
			TranslatablePhrase tp1 = new TranslatablePhrase(new TestQ("What would God have me to say with respect to Paul?", "A", 1, 1), 1, 0);
			TranslatablePhrase tp2 = new TranslatablePhrase(new TestQ("What is Paul asking me to say with respect to that dog?", "B", 2, 2), 1, 0);
			TranslatablePhrase tp3 = new TranslatablePhrase(new TestQ("that dog", "C", 3, 3), 1, 0);
			TranslatablePhrase tp4 = new TranslatablePhrase(new TestQ("Is it okay for Paul me to talk with respect to God today?", "D", 4, 4), 1, 0);
			TranslatablePhrase tp5 = new TranslatablePhrase(new TestQ("that dog wishes this Paul and what is say radish", "E", 5, 5), 1, 0);
			TranslatablePhrase tp6 = new TranslatablePhrase(new TestQ("What is that dog?", "F", 6, 6), 1, 0);

			PhraseTranslationHelper pth = new PhraseTranslationHelper(new[] { tp1, tp2, tp3, tp4, tp5, tp6 }, m_dummyKtList, m_keyTermRules, new List<Substitution>());

			tp1.Translation = "Z";
			tp2.Translation = "B";
			tp3.Translation = "alligator";
			tp4.Translation = "D";
			tp5.Translation = "e";
			tp6.Translation = "E";

			pth.Sort(PhraseTranslationHelper.SortBy.Translation, true);

			Assert.AreEqual(tp3, pth[0]);
			Assert.AreEqual(tp2, pth[1]);
			Assert.AreEqual(tp4, pth[2]);
			Assert.AreEqual(tp5, pth[3]);
			Assert.AreEqual(tp6, pth[4]);
			Assert.AreEqual(tp1, pth[5]);

			pth.Sort(PhraseTranslationHelper.SortBy.Translation, false);

			Assert.AreEqual(tp1, pth[0]);
			Assert.AreEqual(tp6, pth[1]);
			Assert.AreEqual(tp5, pth[2]);
			Assert.AreEqual(tp4, pth[3]);
			Assert.AreEqual(tp2, pth[4]);
			Assert.AreEqual(tp3, pth[5]);
		}
		public void GetPhrasesFilteredTextually_PreventBogusRegExCrash()
		{
			AddMockedKeyTerm("God", 1, 4);
			AddMockedKeyTerm("Paul", 1, 2, 5);
			AddMockedKeyTerm("have", 1, 2, 3, 4, 5, 6);
			AddMockedKeyTerm("say", 1, 2, 5);

			PhraseTranslationHelper pth = new PhraseTranslationHelper(new[] {
				new TranslatablePhrase(new TestQ("This would God have me [to] say with respect to Paul?", "A", 1, 1), 1, 0),
				new TranslatablePhrase(new TestQ("What is that dog?", "B", 6, 6), 1, 0)},
				m_dummyKtList, m_keyTermRules, new List<Substitution>());

			Assert.AreEqual(2, pth.Phrases.Count(), "Wrong number of phrases in helper");

			pth.Filter("[", false, PhraseTranslationHelper.KeyTermFilterType.All, null, false);
			Assert.AreEqual(1, pth.Phrases.Count(), "Wrong number of phrases in helper");
			Assert.AreEqual("A", pth[0].Reference);
		}
		public void ConstrainByRef_GodMatchesAnywhere()
		{
			AddMockedKeyTerm("God");
			AddMockedKeyTerm("Paul", 1, 3, 5);
			AddMockedKeyTerm("have", 99);
			AddMockedKeyTerm("say", 2, 5);

			PhraseTranslationHelper pth = new PhraseTranslationHelper(new[] {
				new TranslatablePhrase(new TestQ("What would God have me to say with respect to Paul?", "A-D", 1, 4), 0, 0),
				new TranslatablePhrase(new TestQ("What is Paul asking me to say with respect to that dog?", "B", 2, 2), 1, 0),
				new TranslatablePhrase(new TestQ("that dog", "C", 3, 3), 1, 0),
				new TranslatablePhrase(new TestQ("Is it okay for Paul to talk with respect to God today?", "B-D", 2, 4), 0, 0),
				new TranslatablePhrase(new TestQ("that dog wishes this Paul what is say radish", "E", 5, 5), 1, 0),
				new TranslatablePhrase(new TestQ("What is that dog?", "E-F", 5, 6), 0, 0)}, m_dummyKtList, m_keyTermRules, new List<Substitution>());

			Assert.AreEqual(6, pth.Phrases.Count(), "Wrong number of phrases in helper");
			VerifyTranslatablePhrase(pth, "What would God have me to say with respect to Paul?", "what would", 1, "have me to", 1, "with respect to", 3);
			VerifyTranslatablePhrase(pth, "What is Paul asking me to say with respect to that dog?", "what is", 3, "paul asking me to", 1, "with respect to", 3, "that dog", 4);
			VerifyTranslatablePhrase(pth, "that dog", "that dog", 4);
			VerifyTranslatablePhrase(pth, "Is it okay for Paul to talk with respect to God today?", "is it okay for", 1, "to talk", 1, "with respect to", 3, "today", 1);
			VerifyTranslatablePhrase(pth, "that dog wishes this Paul what is say radish", "that dog", 4, "wishes this", 1, "what is", 3, "radish", 1);
			VerifyTranslatablePhrase(pth, "What is that dog?", "what is", 3, "that dog", 4);
		}
		public void GetPhrasesFilteredOnlyByRef_IncludeExcluded()
		{
			AddMockedKeyTerm("God", 1, 4);
			AddMockedKeyTerm("Paul", 1, 2, 5);
			AddMockedKeyTerm("have", 1, 2, 3, 4, 5, 6);
			AddMockedKeyTerm("say", 1, 2, 5);

			TranslatablePhrase tp1 = new TranslatablePhrase(new TestQ("What would God have me to say with respect to Paul?", "A", 1, 1), 1, 0);       // what would (1)     | me to (3)       | with respect to (3)
			TranslatablePhrase tp2 = new TranslatablePhrase(new TestQ("What is Paul asking me to say with respect to that dog?", "B", 2, 2), 1, 0);   // what is (3)        | asking (1)      | me to (3)           | with respect to (3) | that dog (4)
			TranslatablePhrase tp3 = new TranslatablePhrase(new TestQ("that dog", "C", 3, 3), 1, 0);                                                  // that dog (4)
			TranslatablePhrase tp4 = new TranslatablePhrase(new TestQ("Is it okay for Paul me to talk with respect to God today?", "D", 4, 4), 1, 0); // is it okay for (1) | me to (3)       | talk (1)            | with respect to (3) | today (1)
			TranslatablePhrase tp5 = new TranslatablePhrase(new TestQ("that dog wishes this Paul and what is say radish", "E", 5, 5), 1, 0);          // that dog (4)       | wishes this (1) | and (1)             | what is (3)         | radish (1)
			TranslatablePhrase tp6 = new TranslatablePhrase(new TestQ("What is that dog?", "F", 6, 6), 1, 0);                                         // what is (3)        | that dog (4)
			tp4.IsExcluded = true;
			tp5.IsExcluded = true;

			PhraseTranslationHelper pth = new PhraseTranslationHelper(new[] { tp1, tp2, tp3, tp4, tp5, tp6 },
				m_dummyKtList, m_keyTermRules, new List<Substitution>());

			Assert.AreEqual(6, pth.Phrases.Count(), "Wrong number of phrases in helper");

			pth.Filter(null, false, PhraseTranslationHelper.KeyTermFilterType.All,
				((start, end, sref) => start >= 2 && end <= 5 && sref != "C"), false);
			pth.Sort(PhraseTranslationHelper.SortBy.Reference, true);
			Assert.AreEqual(1, pth.Phrases.Count(), "Wrong number of phrases in filtered list");
			Assert.AreEqual(tp2, pth[0]);

			pth.Filter(null, false, PhraseTranslationHelper.KeyTermFilterType.All,
				((start, end, sref) => start >= 2 && end <= 5 && sref != "C"), true);
			Assert.AreEqual(3, pth.Phrases.Count(), "Wrong number of phrases in filtered list");
			Assert.AreEqual(tp2, pth[0]);
			Assert.AreEqual(tp4, pth[1]);
			Assert.AreEqual(tp5, pth[2]);
		}
		public void ConstrainByRef_ComplexKeyTerms()
		{
			AddMockedKeyTerm("high priest", 1);
			AddMockedKeyTerm("high", 1, 2);
			AddMockedKeyTerm("radish", 1, 2);
			AddMockedKeyTerm("(to have) eaten or drunk", 2, 3);
			AddMockedKeyTerm("high or drunk sailor", 2, 4);

			PhraseTranslationHelper pth = new PhraseTranslationHelper(new[] {
				new TranslatablePhrase(new TestQ("Was the high priest on his high horse?", "A", 1, 1), 1, 0),
				new TranslatablePhrase(new TestQ("Who was the high priest?", "B", 2, 2), 1, 0),
				new TranslatablePhrase(new TestQ("I have eaten the horse.", "A", 1, 1), 1, 0),
				new TranslatablePhrase(new TestQ("How high is this?", "C", 3, 3), 1, 0),
				new TranslatablePhrase(new TestQ("That drunk sailor has eaten a radish", "C-D", 3, 4), 0, 0),
				new TranslatablePhrase(new TestQ("That high sailor was to have drunk some radish juice", "A-B", 1, 2), 0, 0)}, m_dummyKtList, m_keyTermRules, new List<Substitution>());

			Assert.AreEqual(6, pth.Phrases.Count(), "Wrong number of phrases in helper");
			VerifyTranslatablePhrase(pth, "Was the high priest on his high horse?", "was the", 2, "on his", 1, "horse", 1);
			VerifyTranslatablePhrase(pth, "Who was the high priest?", "who", 1, "was the", 2, "priest", 1);
			VerifyTranslatablePhrase(pth, "I have eaten the horse.", "i have eaten the horse", 1);
			VerifyTranslatablePhrase(pth, "How high is this?", "how high is this", 1);
			VerifyTranslatablePhrase(pth, "That drunk sailor has eaten a radish", "that", 2, "has", 1, "a radish", 1);
			VerifyTranslatablePhrase(pth, "That high sailor was to have drunk some radish juice", "that", 2, "was", 1, "some", 1, "juice", 1);
		}
		public void GetPhrasesFilteredByKeyTerms_WithoutRenderings()
		{
			AddMockedKeyTerm("God", (string)null);
			AddMockedKeyTerm("Paul");
			AddMockedKeyTerm("have", (string)null);
			AddMockedKeyTerm("say");

			PhraseTranslationHelper pth = new PhraseTranslationHelper(new[] {
				new TranslatablePhrase(new TestQ("What would God have me to say with respect to Paul?", "A", 1, 1), 1, 0),       // God & have don't have renderings
				new TranslatablePhrase(new TestQ("What is Paul asking me to say with respect to that dog?", "B", 2, 2), 1, 0),
				new TranslatablePhrase(new TestQ("that dog", "C", 3, 3), 1, 0),
				new TranslatablePhrase(new TestQ("Is it okay for Paul me to talk with respect to God today?", "D", 4, 4), 1, 0), // God doesn't have a rendering
				new TranslatablePhrase(new TestQ("that dog wishes this Paul and what is say radish", "E", 5, 5), 1, 0),
				new TranslatablePhrase(new TestQ("What is that dog?", "F", 6, 6), 1, 0)},
				m_dummyKtList, m_keyTermRules, new List<Substitution>());

			Assert.AreEqual(6, pth.Phrases.Count(), "Wrong number of phrases in helper");

			pth.Filter(null, false, PhraseTranslationHelper.KeyTermFilterType.WithoutRenderings, null, false);
			pth.Sort(PhraseTranslationHelper.SortBy.Reference, true);
			Assert.AreEqual(2, pth.Phrases.Count(), "Wrong number of phrases in helper");

			Assert.AreEqual("A", pth[0].Reference);
			Assert.AreEqual("D", pth[1].Reference);
		}
		public void SelectCorrectTermRendering_SomePartsTranslated_BasedOnFollowingWordRule()
		{
			AddMockedKeyTerm("Stephen", "Esteban");
			AddMockedKeyTerm("Mary", "Mari\u0301a");
			AddMockedKeyTerm("look", "mirar", new[] { "pareci\u0301a", "buscaba", "busca", "busco" });

			TranslatablePhrase phrase1 = new TranslatablePhrase("What did Stephen look like to the priests and elders and other people present?");
			TranslatablePhrase phrase2 = new TranslatablePhrase("What did Stephen do?");
			TranslatablePhrase phrase3 = new TranslatablePhrase("What did Mary look for?");

			PhraseTranslationHelper pth = new PhraseTranslationHelper(new[] {
				phrase1, phrase2, phrase3 }, m_dummyKtList, m_keyTermRules, new List<Substitution>());
			ReflectionHelper.SetField(pth, "m_justGettingStarted", false);

			Assert.AreEqual(2, phrase1.TranslatableParts.Count());
			Assert.AreEqual(2, phrase2.TranslatableParts.Count());
			Assert.AreEqual(2, phrase3.TranslatableParts.Count());

			phrase1.Translation = "\u00BFCo\u0301mo pareci\u0301a Esteban a los sacerdotes y ancianos y a los dema\u0301s?";
			phrase2.Translation = "\u00BFCo\u0301mo hizo Esteban?";

			Assert.IsFalse(phrase3.HasUserTranslation);
			Assert.AreEqual("\u00BFCo\u0301mo Mari\u0301a mirar?", phrase3.Translation);

			pth.TermRenderingSelectionRules = new List<RenderingSelectionRule>(new[] {
				new RenderingSelectionRule(@"{0} like\b", @"\bparec"),
				new RenderingSelectionRule(@"{0} for\b", @"\bbusc")});

			Assert.AreEqual("\u00BFCo\u0301mo Mari\u0301a buscaba?", phrase3.Translation);
		}
		public void GetParts_EmptyKeyTermsList_NoPhraseSubstitutions()
		{
			PhraseTranslationHelper pth = new PhraseTranslationHelper(new [] {
				new TranslatablePhrase(" What do  you think?"),
				new TranslatablePhrase("What  do you think it means to forgive?"),
				new TranslatablePhrase(string.Empty),
				new TranslatablePhrase("-OR-"),
				new TranslatablePhrase("How could I have forgotten the question mark"),
				new TranslatablePhrase("What do you think  it means to bless someone? "),
				new TranslatablePhrase("What is this? ")}, m_dummyKtList, m_keyTermRules, new List<Substitution>());

			Assert.AreEqual(6, pth.Phrases.Count(), "Wrong number of phrases in helper");

			VerifyTranslatablePhrase(pth, " What do  you think?", "what do you think", 3);
			VerifyTranslatablePhrase(pth, "What  do you think it means to forgive?", "what do you think", 3, "it means to forgive", 1);
			VerifyTranslatablePhrase(pth, "-OR-", "-or-", 1);
			VerifyTranslatablePhrase(pth, "How could I have forgotten the question mark", "how could i have forgotten the question mark", 1);
			VerifyTranslatablePhrase(pth, "What do you think  it means to bless someone? ", "what do you think", 3, "it means to bless someone", 1);
			VerifyTranslatablePhrase(pth, "What is this? ", "what is this", 1);
		}
		public void SelectCorrectTermRendering_FillInTemplate_BasedOnSuffixRule()
		{
			AddMockedKeyTerm("magician", "mago", new[] { "brujo" });
			AddMockedKeyTerm("servant", "criado", new[] { "siervo" });
			AddMockedKeyTerm("heal", "sanar", new[] { "curada", "sanada", "sanara\u0301", "sanas", "curan", "cura", "sana", "sanado" });

			TranslatablePhrase phrase1 = new TranslatablePhrase("Was the servant healed?");
			TranslatablePhrase phrase2 = new TranslatablePhrase("Was the magician healed?");

			PhraseTranslationHelper pth = new PhraseTranslationHelper(new[] {
				phrase1, phrase2 }, m_dummyKtList, m_keyTermRules, new List<Substitution>());
			ReflectionHelper.SetField(pth, "m_justGettingStarted", false);

			Assert.AreEqual(1, phrase1.TranslatableParts.Count());
			Assert.AreEqual(1, phrase2.TranslatableParts.Count());

			phrase1.Translation = "\u00BFFue sanado el siervo?";

			Assert.IsFalse(phrase2.HasUserTranslation);
			Assert.AreEqual("\u00BFFue sanar el mago?", phrase2.Translation);

			pth.TermRenderingSelectionRules = new List<RenderingSelectionRule>(new[] {
				new RenderingSelectionRule(@"{0}\w*ed\b", @"o$")});

			Assert.AreEqual("\u00BFFue sanado el mago?", phrase2.Translation);
		}
		public void GetParts_EmptyKeyTermsList_PhraseSubstitutions()
		{
			List<Substitution> ignored = new List<Substitution>();
			ignored.Add(new Substitution("What do you think it means", "What means", false, false));
			ignored.Add(new Substitution("tHe", null, false, false));
			ignored.Add(new Substitution("do", string.Empty, false, false));

			PhraseTranslationHelper pth = new PhraseTranslationHelper(new[] {
				new TranslatablePhrase("What do you think it means?"),
				new TranslatablePhrase("What do you think it means to forgive?"),
				new TranslatablePhrase(string.Empty),
				new TranslatablePhrase("-OR-"),
				new TranslatablePhrase("How could I have forgotten the question mark"),
				new TranslatablePhrase("What do you think it means to bless someone? "),
				new TranslatablePhrase("What means of support do disciples have?")},
				m_dummyKtList, m_keyTermRules, ignored);

			Assert.AreEqual(6, pth.Phrases.Count(), "Wrong number of phrases in helper");

			VerifyTranslatablePhrase(pth, "What do you think it means?", "what means", 4);
			VerifyTranslatablePhrase(pth, "What do you think it means to forgive?", "what means", 4, "to forgive", 1);
			VerifyTranslatablePhrase(pth, "-OR-", "-or-", 1);
			VerifyTranslatablePhrase(pth, "How could I have forgotten the question mark", "how could i have forgotten question mark", 1);
			VerifyTranslatablePhrase(pth, "What do you think it means to bless someone? ", "what means", 4, "to bless someone", 1);
			VerifyTranslatablePhrase(pth, "What means of support do disciples have?", "what means", 4, "of support disciples have", 1);
		}
		public void SelectCorrectTermRendering_FillInTemplate_BasedOnSuffixRule_PreferDefault()
		{
			AddMockedKeyTerm("magician", "mago", new[] { "brujo" });
			AddMockedKeyTerm("servant", "criado", new[] { "siervo" });
			AddMockedKeyTerm("heal", "sanara\u0301", new[] { "curada", "sanada", "sanar", "curara\u0301", "sanas", "curan", "cura", "sana", "sanado" });

			TranslatablePhrase phrase1 = new TranslatablePhrase("Will the servant be healed?");
			TranslatablePhrase phrase2 = new TranslatablePhrase("Will the magician be healed?");

			PhraseTranslationHelper pth = new PhraseTranslationHelper(new[] {
				phrase1, phrase2 }, m_dummyKtList, m_keyTermRules, new List<Substitution>());
			ReflectionHelper.SetField(pth, "m_justGettingStarted", false);

			Assert.AreEqual(2, phrase1.TranslatableParts.Count());
			Assert.AreEqual(2, phrase2.TranslatableParts.Count());

			phrase1.Translation = "\u00BFSe curara\u0301 el siervo?";

			Assert.IsFalse(phrase2.HasUserTranslation);
			Assert.AreEqual("\u00BFSe sanara\u0301 el mago?", phrase2.Translation);

			pth.TermRenderingSelectionRules = new List<RenderingSelectionRule>(new[] {
				new RenderingSelectionRule(@"Will .* {0}\w*\b", "ra\u0301$")});

			Dictionary<Word, List<KeyTermMatch>> keyTermsTable =
				(Dictionary<Word, List<KeyTermMatch>>)ReflectionHelper.GetField(pth, "m_keyTermsTable");

			keyTermsTable["heal"].First().BestRendering = "curara\u0301";

			Assert.AreEqual("\u00BFSe curara\u0301 el mago?", phrase2.Translation);
		}
		public void GetParts_KeyTermsList_SimplePhraseSubstitutions()
		{
			AddMockedKeyTerm("John"); // The apostle
			AddMockedKeyTerm("John"); // The Baptist
			AddMockedKeyTerm("Paul");
			AddMockedKeyTerm("Mary");
			AddMockedKeyTerm("temple");
			AddMockedKeyTerm("forgive");
			AddMockedKeyTerm("bless");
			AddMockedKeyTerm("God");
			AddMockedKeyTerm("Jesus");
			AddMockedKeyTerm("sin");

			List<Substitution> ignored = new List<Substitution>();
			ignored.Add(new Substitution("What do you think it means", "What means", false, false));
			ignored.Add(new Substitution("the", null, false, false));
			ignored.Add(new Substitution("do", string.Empty, false, false));

			PhraseTranslationHelper pth = new PhraseTranslationHelper(new[] {
				new TranslatablePhrase("Who was John?"),
				new TranslatablePhrase("Who was Paul?"),
				new TranslatablePhrase("Who was Mary?"),
				new TranslatablePhrase("Who went to the well?"),
				new TranslatablePhrase("Who went to the temple?"),
				new TranslatablePhrase("What do you think it means to forgive?"),
				new TranslatablePhrase("What do you think it means to bless someone?"),
				new TranslatablePhrase("What do you think God wants you to do?"),
				new TranslatablePhrase("Why do you think God created man?"),
				new TranslatablePhrase("Why do you think God  sent Jesus to the earth?"),
				new TranslatablePhrase("Who went to the well with Jesus?"),
				new TranslatablePhrase("Do you think God could forgive someone who sins?"),
				new TranslatablePhrase("What do you think it means to serve two masters?")},
				m_dummyKtList, m_keyTermRules, ignored);

			Assert.AreEqual(13, pth.Phrases.Count(), "Wrong number of phrases in helper");

			VerifyTranslatablePhrase(pth, "Who was John?", "who was", 3);
			VerifyTranslatablePhrase(pth, "Who was Paul?", "who was", 3);
			VerifyTranslatablePhrase(pth, "Who was Mary?", "who was", 3);
			VerifyTranslatablePhrase(pth, "Who went to the well?", "who went to well", 2);
			VerifyTranslatablePhrase(pth, "Who went to the temple?", "who went to", 1);
			VerifyTranslatablePhrase(pth, "What do you think it means to forgive?", "what means to", 3);
			VerifyTranslatablePhrase(pth, "What do you think it means to bless someone?", "what means to", 3, "someone", 1);
			VerifyTranslatablePhrase(pth, "What do you think God wants you to do?", "what", 1, "you think", 2, "wants you to", 1);
			VerifyTranslatablePhrase(pth, "Why do you think God created man?", "why you think", 2, "created man", 1);
			VerifyTranslatablePhrase(pth, "Why do you think God  sent Jesus to the earth?", "why you think", 2, "sent", 1, "to earth", 1);
			VerifyTranslatablePhrase(pth, "Who went to the well with Jesus?", "who went to well", 2, "with", 1);
			VerifyTranslatablePhrase(pth, "Do you think God could forgive someone who sins?", "you think", 2, "could", 1, "someone who", 1);
			VerifyTranslatablePhrase(pth, "What do you think it means to serve two masters?", "what means to", 3, "serve two masters", 1);
		}
		public void SelectCorrectTermRendering_RuleDisabled()
		{
			AddMockedKeyTerm("Jesus", "Cristo", new[] { "Jesucristo", "Jesus", "Cristo Jesus" });

			TranslatablePhrase phrase1 = new TranslatablePhrase("Who was the man Jesus healed?");

			PhraseTranslationHelper pth = new PhraseTranslationHelper(new[] {
				phrase1 }, m_dummyKtList, m_keyTermRules, new List<Substitution>());
			ReflectionHelper.SetField(pth, "m_justGettingStarted", false);

			Assert.AreEqual(2, phrase1.TranslatableParts.Count());

			Assert.IsFalse(phrase1.HasUserTranslation);
			Assert.AreEqual("Cristo", phrase1.Translation);

			pth.TermRenderingSelectionRules = new List<RenderingSelectionRule>(new[] { new RenderingSelectionRule(@"\bman {0}", @"ucristo\b") });
			pth.TermRenderingSelectionRules[0].Disabled = true;

			Assert.AreEqual("Cristo", phrase1.Translation);
		}
		public void GetParts_MultiWordKeyTermsList()
		{
			AddMockedKeyTerm("to forgive (flamboyantly)");
			AddMockedKeyTerm("to forgive always and forever");
			AddMockedKeyTerm("high priest");
			AddMockedKeyTerm("God");
			AddMockedKeyTerm("sentence that is seven words long");
			AddMockedKeyTerm("sentence");
			AddMockedKeyTerm("seven");

			PhraseTranslationHelper pth = new PhraseTranslationHelper(new[] {
				new TranslatablePhrase("What do you think it means to forgive?"),
				new TranslatablePhrase("Bla bla bla to forgive always?"),
				new TranslatablePhrase("Please forgive!"),
				new TranslatablePhrase("Who do you think God wants you to forgive and why?"),
				new TranslatablePhrase("Can you say a sentence that is seven words long?"),
				new TranslatablePhrase("high priest"),
				new TranslatablePhrase("If the high priest wants you to forgive God, can he ask you using a sentence that is seven words long or not?"),
				new TranslatablePhrase("Is this sentence that is seven dwarves?")},
				m_dummyKtList, m_keyTermRules, new List<Substitution>());

			Assert.AreEqual(8, pth.Phrases.Count(), "Wrong number of phrases in helper");

			VerifyTranslatablePhrase(pth, "What do you think it means to forgive?", "what do you think it means", 1);
			VerifyTranslatablePhrase(pth, "Bla bla bla to forgive always?", "bla bla bla", 1, "always", 1);
			VerifyTranslatablePhrase(pth, "Please forgive!", "please", 1);
			VerifyTranslatablePhrase(pth, "Who do you think God wants you to forgive and why?", "who do you think", 1, "wants you", 2, "and why", 1);
			VerifyTranslatablePhrase(pth, "Can you say a sentence that is seven words long?", "can you say a", 1);
			VerifyTranslatablePhrase(pth, "high priest");
			VerifyTranslatablePhrase(pth, "If the high priest wants you to forgive God, can he ask you using a sentence that is seven words long or not?",
				"if the", 1, "wants you", 2, "can he ask you using a", 1, "or not", 1);
			VerifyTranslatablePhrase(pth, "Is this sentence that is seven dwarves?", "is this", 1, "that is", 1, "dwarves", 1);
		}
		public void SetTranslation_PreventTranslationFromBeingUsedForMultipleParts()
		{
			AddMockedKeyTerm("Jacob", "Jacob");
			AddMockedKeyTerm("John", "Juan");
			AddMockedKeyTerm("Jesus", "Jesu\u0301s");
			AddMockedKeyTerm("Mary", "Mari\u0301a");
			AddMockedKeyTerm("Moses", "Moise\u0301s");

			TranslatablePhrase phrase1 = new TranslatablePhrase("So what did Jacob do?");
			TranslatablePhrase phrase2 = new TranslatablePhrase("So what did Jesus do?");
			TranslatablePhrase phrase3 = new TranslatablePhrase("What did Jacob do?");
			TranslatablePhrase phrase4 = new TranslatablePhrase("What did Moses ask?");
			TranslatablePhrase phrase5 = new TranslatablePhrase("So what did John ask?");
			TranslatablePhrase phrase6 = new TranslatablePhrase("So what did Mary want?");
			TranslatablePhrase phrase7 = new TranslatablePhrase("What did Moses do?");
			TranslatablePhrase phrase8 = new TranslatablePhrase("Did Moses ask, \"What did Jacob do?\"");

			PhraseTranslationHelper pth = new PhraseTranslationHelper(new[] { phrase1, phrase2, phrase3,
				phrase4, phrase5, phrase6, phrase7, phrase8 }, m_dummyKtList, m_keyTermRules, new List<Substitution>());
			ReflectionHelper.SetField(pth, "m_justGettingStarted", false);

			Assert.AreEqual(2, phrase1.TranslatableParts.Count());
			Assert.AreEqual(3, phrase1.GetParts().Count());
			Assert.AreEqual(2, phrase2.TranslatableParts.Count());
			Assert.AreEqual(3, phrase2.GetParts().Count());
			Assert.AreEqual(2, phrase3.TranslatableParts.Count());
			Assert.AreEqual(3, phrase3.GetParts().Count());
			Assert.AreEqual(2, phrase4.TranslatableParts.Count());
			Assert.AreEqual(3, phrase4.GetParts().Count());
			Assert.AreEqual(2, phrase5.TranslatableParts.Count());
			Assert.AreEqual(3, phrase5.GetParts().Count());
			Assert.AreEqual(2, phrase6.TranslatableParts.Count());
			Assert.AreEqual(3, phrase6.GetParts().Count());
			Assert.AreEqual(2, phrase7.TranslatableParts.Count());
			Assert.AreEqual(3, phrase7.GetParts().Count());
			Assert.AreEqual(4, phrase8.TranslatableParts.Count());
			Assert.AreEqual(6, phrase8.GetParts().Count());

			phrase1.Translation = "\u00BFEntonces que\u0301 hizo Jacob?";
			phrase2.Translation = "\u00BFEntonces que\u0301 hizo Jesu\u0301s?";
			phrase3.Translation = "\u00BFQue\u0301 hizo Jacob?";
			phrase4.Translation = "\u00BFQue\u0301 pregunto\u0301 Moise\u0301s?";
			phrase5.Translation = "\u00BFEntonces que\u0301 pregunto\u0301 Juan?";

			Assert.AreEqual("\u00BFEntonces que\u0301 Mari\u0301a?", phrase6.Translation);
			Assert.AreEqual("\u00BFQue\u0301 hizo Moise\u0301s?", phrase7.Translation);
			Assert.AreEqual("Moise\u0301s pregunto\u0301 Que\u0301 Jacob hizo", phrase8.Translation);
		}