private void MakeAnnDefn(ICmPossibilityList defns, string guid)
		{
			CmAnnotationDefn defn = new CmAnnotationDefn();
			defns.PossibilitiesOS.Append(defn);
			Cache.VwCacheDaAccessor.CacheGuidProp(defn.Hvo, (int)CmObjectFields.kflidCmObject_Guid,
				new Guid(guid));
		}
		public override void Initialize()
		{
			base.Initialize();
			m_inMemoryCache.InitializeWritingSystemEncodings();
			m_inMemoryCache.ChangeDefaultAnalWs(m_inMemoryCache.SetupWs("de"));
			m_inMemoryCache.InitializeAnnotationDefs();
			CmAnnotationDefn annDefnChkError = new CmAnnotationDefn(Cache,
				LangProject.kguidAnnCheckingError);

			CmAnnotationDefn errorType1 = new CmAnnotationDefn();
			annDefnChkError.SubPossibilitiesOS.Append(errorType1);
			errorType1.Guid = kCheckId1;
			errorType1.IsProtected = true;
			errorType1.Name.UserDefaultWritingSystem = "Dummy Check 1";
			errorType1.Description.UserDefaultWritingSystem.UnderlyingTsString =
				StringUtils.MakeTss("does nothing", Cache.DefaultUserWs);

			CmAnnotationDefn errorType2 = new CmAnnotationDefn();
			annDefnChkError.SubPossibilitiesOS.Append(errorType2);
			errorType2.Guid = kCheckId2;
			errorType2.IsProtected = true;
			errorType2.Name.UserDefaultWritingSystem = "Dummy Check 2";
			errorType2.Description.UserDefaultWritingSystem.UnderlyingTsString =
				StringUtils.MakeTss("does nothing", Cache.DefaultUserWs);
		}
		public void RecordError_NearDuplicate_DifferByCheck()
		{
			ScrChecksDataSource dataSource = new ScrChecksDataSource(Cache);
			ICmAnnotationDefn annDefnChkError = new CmAnnotationDefn(Cache,
				LangProject.kguidAnnCheckingError);
			CmAnnotationDefn errorCheck1 = new CmAnnotationDefn();
			annDefnChkError.SubPossibilitiesOS.Append(errorCheck1);
			errorCheck1.Guid = Guid.NewGuid();
			errorCheck1.Name.UserDefaultWritingSystem = "Type 1";

			CmAnnotationDefn errorCheck2 = new CmAnnotationDefn();
			annDefnChkError.SubPossibilitiesOS.Append(errorCheck2);
			errorCheck2.Guid = Guid.NewGuid();
			errorCheck2.Name.UserDefaultWritingSystem = "Type 2";

			DummyEditorialCheck check1 = new DummyEditorialCheck(errorCheck1.Guid);
			ScrCheckingToken tok = new DummyParaCheckingToken(m_scr, Cache.DefaultVernWs, 0);
			check1.m_ErrorsToReport.Add(new DummyEditorialCheck.DummyError(tok, 5, 8, "General Error"));

			m_scrInMemoryCache.AddBookToMockedScripture(tok.StartRef.Book, "My Favorite Book");

			dataSource.GetText(tok.StartRef.Book, 0);
			dataSource.RunCheck(check1);
			IScrBookAnnotations annotations = m_scr.BookAnnotationsOS[tok.StartRef.Book - 1];
			Assert.AreEqual(1, annotations.NotesOS.Count,
				"Check 1 should add 1 error annotation");
			IScrScriptureNote origErrorAnnotation = annotations.NotesOS[0];

			DummyEditorialCheck check2 = new DummyEditorialCheck(errorCheck2.Guid);
			check2.m_ErrorsToReport.Add(new DummyEditorialCheck.DummyError(tok, 5, 8, "General Error"));

			dataSource.RunCheck(check2);
			Assert.AreEqual(2, annotations.NotesOS.Count,
				"Check 2 should add another error annotation.");
			Assert.IsTrue(annotations.NotesOS.Contains(origErrorAnnotation));
		}
		/// ------------------------------------------------------------------------------------
		/// <summary>
		/// Initialize a new note.
		/// </summary>
		/// <param name="guidAnnotationType">GUID representing the type of annotation.</param>
		/// <param name="startRef">beginning reference note refers to</param>
		/// <param name="endRef">ending reference note refers to</param>
		/// <param name="beginObj">beginning object note refers to</param>
		/// <param name="endObj">ending object note refers to</param>
		/// <param name="wsSelector">The writing system selector.</param>
		/// <param name="startOffset">The starting character offset.</param>
		/// <param name="endOffset">The ending character offset.</param>
		/// <param name="bldrQuote">Para builder to use to build the Quote paragraph</param>
		/// <param name="bldrDiscussion">Para builder to use to build the Discussion
		/// paragraph</param>
		/// <param name="bldrRecommendation">Para builder to use to build the
		/// Recommendation paragraph</param>
		/// <param name="bldrResolution">Para builder to use to build the Resolution
		/// paragraph</param>
		/// ------------------------------------------------------------------------------------
		public void InitializeNote(Guid guidAnnotationType, BCVRef startRef, BCVRef endRef,
			ICmObject beginObj, ICmObject endObj, int wsSelector, int startOffset, int endOffset,
			StTxtParaBldr bldrQuote, StTxtParaBldr bldrDiscussion, StTxtParaBldr bldrRecommendation,
			StTxtParaBldr bldrResolution)
		{
			AnnotationTypeRA = new CmAnnotationDefn(Cache, guidAnnotationType);
			BeginObjectRA = beginObj;
			EndObjectRA = endObj;
			BeginRef = startRef;
			EndRef = endRef;
			WsSelector = wsSelector;
			BeginOffset = startOffset;
			EndOffset = endOffset;

			// Now, initialize all the texts
			QuoteOA = new StJournalText();
			InitializeText(bldrQuote, QuoteOA);

			DiscussionOA = new StJournalText();
			InitializeText(bldrDiscussion, DiscussionOA);

			RecommendationOA = new StJournalText();
			InitializeText(bldrRecommendation, RecommendationOA);

			ResolutionOA = new StJournalText();
			InitializeText(bldrResolution, ResolutionOA);
		}
		/// ------------------------------------------------------------------------------------
		/// <summary>
		/// Creates the scripture checks and updates the annotation definitions by checking
		/// that for each check we have a corresponding annotation definition in the database.
		/// </summary>
		/// <param name="dataSource">The data source.</param>
		/// ------------------------------------------------------------------------------------
		private static SortedList<ScrCheckKey, IScriptureCheck> InstantiateChecks(
			ScrChecksDataSource dataSource)
		{
			FdoCache cache = dataSource.Cache;

			SortedList<ScrCheckKey, IScriptureCheck> scriptureChecks =
				new SortedList<ScrCheckKey, IScriptureCheck>();

			using (new SuppressSubTasks(cache))
			{
				Dictionary<Guid, ICmAnnotationDefn> errorTypes =
					new Dictionary<Guid, ICmAnnotationDefn>();

				ICmAnnotationDefn annDefnChkError = new CmAnnotationDefn(cache,
					LangProject.kguidAnnCheckingError);

				foreach (ICmAnnotationDefn errorType in annDefnChkError.SubPossibilitiesOS)
					errorTypes[errorType.Guid] = errorType;

				foreach (Type type in s_scrCheckList)
				{
					IScriptureCheck scrCheck =
						(IScriptureCheck)Activator.CreateInstance(type, dataSource);

					if (scrCheck == null)
						continue;

					// Get the localized version of the check name
					string scrCheckName = GetCheckProperty(ScrFdoResources.ResourceManager,
						scrCheck.CheckId, "Name", scrCheck.CheckName);
					scriptureChecks.Add(new ScrCheckKey(scrCheck.RelativeOrder, scrCheckName), scrCheck);

					ICmAnnotationDefn chkType;
					if (!errorTypes.TryGetValue(scrCheck.CheckId, out chkType))
					{
						chkType = new CmAnnotationDefn();
						annDefnChkError.SubPossibilitiesOS.Append(chkType);
						chkType.Guid = scrCheck.CheckId;
						chkType.IsProtected = true;
						chkType.Name.UserDefaultWritingSystem = scrCheckName;
						chkType.Description.UserDefaultWritingSystem.UnderlyingTsString =
							StringUtils.MakeTss(scrCheck.Description, cache.DefaultUserWs);
						chkType.HelpId = scrCheck.CheckName.Replace(' ', '_');
						InheritAttributes(annDefnChkError, chkType);
					}
					else if (chkType.Name.UserDefaultWritingSystem != scrCheckName)
					{
						// Store the localized version of the check name as the current UI name.
						chkType.Name.UserDefaultWritingSystem = scrCheckName;
					}
				}
			}
			return scriptureChecks;
		}
		private void MakeAnnotationDefn(string name, Guid guid)
		{
			CmAnnotationDefn annotationDefn;
			annotationDefn = new CmAnnotationDefn();
			m_lp.AnnotationDefsOA.PossibilitiesOS.Append(annotationDefn);
			m_cacheBase.CacheGuidProp(annotationDefn.Hvo, (int)CmObjectFields.kflidCmObject_Guid,
									  guid);
			annotationDefn.Name.SetAlternative(name, s_wsHvos.En);
		}
		/// ------------------------------------------------------------------------------------
		/// <summary>
		/// Initializes annotation definitions (annotation types)
		/// </summary>
		/// ------------------------------------------------------------------------------------
		public void InitializeAnnotationDefs()
		{
			CheckDisposed();
			// Initialize the annotation definition possibility list.
			m_lp.AnnotationDefsOAHvo = m_cacheBase.NewHvo(CmPossibilityList.kClassId);

			// Add an annotation definition (i.e. type) for scripture notes
			CmAnnotationDefn annotationDefn = new CmAnnotationDefn();
			m_lp.AnnotationDefsOA.PossibilitiesOS.Append(annotationDefn);
			m_cacheBase.CacheGuidProp(annotationDefn.Hvo, (int)CmObjectFields.kflidCmObject_Guid,
				LangProject.kguidAnnNote);

			// Add a sub-annotation type (for "Consultant Note")
			m_consultantNoteDefn = new CmAnnotationDefn();
			annotationDefn.SubPossibilitiesOS.Append(m_consultantNoteDefn);
			m_cacheBase.CacheGuidProp(m_consultantNoteDefn.Hvo, (int)CmObjectFields.kflidCmObject_Guid,
				LangProject.kguidAnnConsultantNote);
			m_consultantNoteDefn.Name.SetAlternative("Consultant", s_wsHvos.En);
			m_consultantNoteDefn.UserCanCreate = true;

			// Add a sub-annotation type for "Translator Note"
			m_translatorNoteDefn = new CmAnnotationDefn();
			annotationDefn.SubPossibilitiesOS.Append(m_translatorNoteDefn);
			m_cacheBase.CacheGuidProp(m_translatorNoteDefn.Hvo, (int)CmObjectFields.kflidCmObject_Guid,
				LangProject.kguidAnnTranslatorNote);
			m_translatorNoteDefn.Name.SetAlternative("Translator", s_wsHvos.En);
			m_translatorNoteDefn.UserCanCreate = true;

			// Add an annotation definition (i.e. type) for scripture checking errors
			MakeAnnotationDefn("Errors", LangProject.kguidAnnCheckingError);
			// And the interlinear ones.
			MakeAnnotationDefn("Punctuation", new Guid(LangProject.kguidAnnPunctuationInContext));
			MakeAnnotationDefn("Wfic", new Guid(LangProject.kguidAnnWordformInContext));
		}
		/// ------------------------------------------------------------------------------------
		/// <summary>
		/// Create and Check an Annotation
		/// </summary>
		/// <param name="hvoParaStart">The hvo para start.</param>
		/// <param name="hvoParaEnd">The hvo para end.</param>
		/// <param name="startRef">The start ref.</param>
		/// <param name="endRef">The end ref.</param>
		/// <param name="startOffset">The start offset.</param>
		/// <param name="endOffset">The end offset.</param>
		/// <param name="tssQuote">The text in the quote.</param>
		/// <param name="sel">selection in main window</param>
		/// <returns></returns>
		/// ------------------------------------------------------------------------------------
		private IScrScriptureNote CreateAndCheckAnnotation(int hvoObjStart, int hvoObjEnd,
			int startRef, int endRef, int startOffset, int endOffset, string strQuote)
		{
			ILangProject lp = Cache.LangProject;
			CmAnnotationDefn transNoteAnnDefn = new CmAnnotationDefn(Cache,
				LangProject.kguidAnnTranslatorNote);

			// Get information from the selection about the location of the annotation.
			CmObject topObj = (CmObject)CmObject.CreateFromDBObject(m_inMemoryCache.Cache, hvoObjStart);
			CmObject bottomObj = (CmObject)CmObject.CreateFromDBObject(m_inMemoryCache.Cache, hvoObjEnd);
			int wsSelector = -1;
			ITsStrBldr tssBldrQuote = TsStrBldrClass.Create();
			tssBldrQuote.Replace(0, 0, strQuote, StyleUtils.ParaStyleTextProps(ScrStyleNames.Remark));

			IScrScriptureNote ann =
				m_notesEditingHelper.InsertNote(transNoteAnnDefn, startRef, endRef,
					topObj, bottomObj, wsSelector, startOffset, endOffset, tssBldrQuote.GetString());
			Assert.IsNotNull(ann);
			Assert.AreEqual(transNoteAnnDefn.Hvo, ann.AnnotationTypeRAHvo, "Wrong type of note created");
			Assert.AreEqual(hvoObjStart, ann.BeginObjectRAHvo, "Wrong paragraph annotated");
			Assert.AreEqual(hvoObjEnd, ann.EndObjectRAHvo, "Wrong paragraph annotated");
			Assert.AreEqual(startRef, ann.BeginRef, "Should have the correct start para reference");
			Assert.AreEqual(endRef, ann.EndRef, "Should have the correct end para reference");
			Assert.AreEqual(startOffset, ann.BeginOffset, "Should have the correct starting char offset");
			Assert.AreEqual(endOffset, ann.EndOffset, "Should have the correct ending char offset");
			Assert.AreEqual(lp.DefaultUserAgent.Hvo, ann.SourceRAHvo, "Wrong agent");
			VerifyInitializedText(ann.DiscussionOA, "Discussion");
			Assert.AreEqual(tssBldrQuote.Text, ((StTxtPara)ann.QuoteOA.ParagraphsOS[0]).Contents.Text);
			VerifyInitializedText(ann.RecommendationOA, "Recommendation");
			VerifyInitializedText(ann.ResolutionOA, "Resolution");
			return ann;
		}
		/// <summary>
		/// Convenient for ensuring any annotation defns we need have been created.
		/// </summary>
		protected int EnsureAnnDefn(string guid)
		{
			int result = Cache.GetIdFromGuid(guid);
			if (result == 0)
			{
				if (Cache.LangProject.AnnotationDefsOA == null)
				{
					CmPossibilityList annDefs = new CmPossibilityList();
					Cache.LangProject.AnnotationDefsOA = annDefs;
				}
				CmAnnotationDefn annotationDefn = new CmAnnotationDefn();
				Cache.LangProject.AnnotationDefsOA.PossibilitiesOS.Append(annotationDefn);
				m_inMemoryCache.CacheAccessor.CacheGuidProp(annotationDefn.Hvo, (int)CmObjectFields.kflidCmObject_Guid,
					new Guid(guid));
				return annotationDefn.Hvo;
			}
			return result;
		}