private Section CreateSection(string sRef, string heading, int startRef, int endRef, int cOverviewQuestions, int cDetailQuestions)
		{
			Section s = new Section();
			s.ScriptureReference = sRef;
			s.Heading = heading;
			s.StartRef = startRef;
			s.EndRef = endRef;
			s.Categories = new Category[2];
			s.Categories[0] = new Category();
			s.Categories[0].Type = "Overview";
			s.Categories[0].Questions = new Question[cOverviewQuestions];
			for (int i = 0; i < cOverviewQuestions; i++)
				s.Categories[0].Questions[i] = new Question();

			s.Categories[1] = new Category();
			s.Categories[1].Type = "Details";
			s.Categories[1].Questions = new Question[cDetailQuestions];
			for (int i = 0; i < cDetailQuestions; i++)
				s.Categories[1].Questions[i] = new Question();
			return s;
		}
		public void EnumeratePhrases_UnnamedCategory()
		{
			QuestionSections qs = new QuestionSections();
			qs.Items = new Section[1];
			int iS= 0;
			Section s = new Section();
			qs.Items[iS] = s;

			s.ScriptureReference = "ROM 1.1-17";
			s.Heading = "Romans 1:1-17 Introduction to the book.";
			s.StartRef = 45001001;
			s.EndRef = 45001017;
			s.Categories = new Category[1];
			s.Categories[0] = new Category();
			s.Categories[0].Questions = new Question[1];
			Question q = s.Categories[0].Questions[0] = new Question();
			q.Text = "Who wrote this book?";
			q.Answers = new[] { "Paul." };

			QuestionProvider qp = new QuestionProvider(qs, null);

			Assert.AreEqual(1, qp.SectionHeads.Count);
			Assert.AreEqual("Romans 1:1-17 Introduction to the book.", qp.SectionHeads["ROM 1.1-17"]);
			Assert.AreEqual(1, qp.AvailableBookIds.Length);
			Assert.AreEqual(45, qp.AvailableBookIds[0]);
			List<TranslatablePhrase> phrases = qp.ToList();
			Assert.AreEqual(1, phrases.Count);

			TranslatablePhrase phrase = phrases[0];
			Assert.AreEqual("Who wrote this book?", phrase.PhraseInUse);
			Assert.AreEqual(0, phrase.Category);
			Assert.AreEqual("ROM 1.1-17", phrase.Reference);
			Assert.AreEqual(45001001, phrase.StartRef);
			Assert.AreEqual(45001017, phrase.EndRef);
			Assert.AreEqual(1, phrase.SequenceNumber);
			Assert.IsNotNull(phrase.QuestionInfo);
			Assert.AreEqual(1, phrase.QuestionInfo.Answers.Count());
			Assert.IsNull(phrase.QuestionInfo.Notes);
			Assert.AreEqual("Paul.", phrase.QuestionInfo.Answers.First());
		}
		public static QuestionSections Generate(IEnumerable<string> sourceLines, Dictionary<string, string[]> alternatives)
		{
			m_canonicalBookNumbers = new HashSet<int>();

			// Initialize the ID textbox.
			Category currCat = null;
			string currRef = null;
			int startRef = 0, endRef = 0;
			Section currSection = null;
			bool currSectionRefSet = false;
			Question currQuestion = null;
			List<Section> sections = new List<Section>();
			List<Question> currentQuestions = new List<Question>();
			int cAnswers = 0, cComments = 0, cCategories = 0;
			int kSectHeadMarkerLen = s_kSectionHead.Length;
			int kRefMarkerLen = s_kRefMarker.Length;
			int kQMarkerLen = s_kQuestionMarker.Length;
			int kAMarkerLen = s_kAnswerMarker.Length;
			int kCommentMarkerLen = s_kCommentMarker.Length;
			Debug.Assert(s_kDetailsMarker.Length == s_kOverviewMarker.Length);
			int kCategoryMarkerLen = s_kDetailsMarker.Length;
			Regex regexVerseNum = new Regex(@"\((?<startVerse>\d+)(-(?<endVerse>\d+))?\)$", RegexOptions.Compiled);
			foreach (string sLine in SourceFields(sourceLines))
			{
				if (sLine.StartsWith(s_kQuestionMarker))
				{
					if (currQuestion != null && cAnswers == 0 && cComments == 0)
					{
						// Question continued in a subsequent field. Just append the text to the existing question.
						currQuestion.Text += " " + sLine.Substring(kQMarkerLen).Trim();
					}
					else
					{
						currQuestion = new Question();
						currentQuestions.Add(currQuestion);
						currQuestion.Text = sLine.Substring(kQMarkerLen).Trim();
						if (currRef != currSection.ScriptureReference)
						{
							currQuestion.ScriptureReference = currRef;
							currQuestion.StartRef = startRef;
							currQuestion.EndRef = endRef;
						}
						cAnswers = 0;
						cComments = 0;
					}
				}
				else if (sLine.StartsWith(s_kAnswerMarker))
				{
					string currAnswer = sLine.Substring(kAMarkerLen).Trim();
					if (!currCat.IsOverview)
					{
						Match match = regexVerseNum.Match(currAnswer);
						if (match.Success)
						{
							int startVerse = Int32.Parse(match.Result("${startVerse}"));
							string sEndVerse = match.Result("${endVerse}");
							int endVerse = string.IsNullOrEmpty(sEndVerse) ? startVerse : Int32.Parse(sEndVerse);
							BCVRef bcvStart, bcvEnd;
							if (currQuestion.StartRef > 0)
							{
								bcvStart = new BCVRef(currQuestion.StartRef);
								bcvEnd = new BCVRef(currQuestion.EndRef);
								if (startVerse < bcvStart.Verse)
									bcvStart.Verse = startVerse;
								if (endVerse > bcvEnd.Verse)
									bcvEnd.Verse = endVerse;
							}
							else
							{
								bcvStart = new BCVRef(currSection.StartRef);
								bcvEnd = new BCVRef(currSection.EndRef);
								bcvStart.Verse = startVerse;
								bcvEnd.Verse = endVerse;
							}
							currQuestion.StartRef = bcvStart.BBCCCVVV;
							currQuestion.EndRef = bcvEnd.BBCCCVVV;
							currQuestion.ScriptureReference = BCVRef.MakeReferenceString(
								currSection.ScriptureReference.Substring(0, 3), bcvStart, bcvEnd, ".", "-");
						}
					}
					string[] source = currQuestion.Answers;
					currQuestion.Answers = new string[cAnswers + 1];
					if (source != null)
						Array.Copy(source, currQuestion.Answers, cAnswers);

					currQuestion.Answers[cAnswers++] = currAnswer;
				}
				else if (sLine.StartsWith(s_kCommentMarker))
				{
					if (currQuestion != null)
					{
						string[] source = currQuestion.Notes;
						currQuestion.Notes = new string[cComments + 1];
						if (source != null)
							Array.Copy(source, currQuestion.Notes, cComments);

						currQuestion.Notes[cComments++] = sLine.Substring(kCommentMarkerLen).Trim();
					}
				}
				else
				{
					if (sLine.StartsWith(s_kRefMarker))
					{
						currRef = sLine.Substring(kRefMarkerLen).Trim();
						Parse(currRef, out startRef, out endRef);
						if (!currSectionRefSet)
						{
							currSection.ScriptureReference = currRef;
							currSection.StartRef = startRef;
							currSection.EndRef = endRef;
							currSectionRefSet = true;
						}
					}
					else if (sLine.StartsWith(s_kSectionHead))
					{
						if (currentQuestions.Count > 0)
						{
							currCat.Questions = currentQuestions.ToArray();
							currentQuestions.Clear();
						}
						currSection = new Section();
						sections.Add(currSection);
						cCategories = 1;
						currSection.Categories = new Category[cCategories];
						currSection.Categories[0] = currCat = new Category();
						currSection.Heading = sLine.Substring(kSectHeadMarkerLen).Trim();
						currSectionRefSet = false;
					}
					else
					{
						bool isOverviewMarker = sLine.StartsWith(s_kOverviewMarker);
						if (isOverviewMarker || sLine.StartsWith(s_kDetailsMarker))
						{
							if (currentQuestions.Count > 0)
							{
								currCat.Questions = currentQuestions.ToArray();
								currentQuestions.Clear();
							}
							if (currCat.Type != null || currCat.Questions != null)
							{
								currCat = new Category();
								Category[] source = currSection.Categories;
								currSection.Categories = new Category[cCategories + 1];
								if (source != null)
									Array.Copy(source, currSection.Categories, cCategories);

								currSection.Categories[cCategories++] = currCat;
							}
							currCat.Type = sLine.Substring(kCategoryMarkerLen).Trim();
							currCat.IsOverview = isOverviewMarker;
						}
					}

					if (currQuestion != null)
					{
						currQuestion = null;
						cAnswers = 0;
						cComments = 0;
					}
				}
			}
			if (currCat != null && currentQuestions.Count > 0)
				currCat.Questions = currentQuestions.ToArray();

			QuestionSections questionSections = new QuestionSections();
			questionSections.Items = sections.ToArray();
			GenerateAlternateForms(questionSections, alternatives);
			return questionSections;
		}