Beispiel #1
0
        /// <summary>
        /// Approves an analysis and moves the selection to the next wordform or the
        /// next Interlinear line. An Interlinear line is one of the configurable
        /// "lines" in the Tools->Configure->Interlinear Lines dialog, not a segement.
        /// The list of lines is collected in choices[] below.
        /// WordLevel is true for word or analysis lines. The non-word lines are translation and note lines.
        /// Normally, this is invoked as a result of pressing the <Enter> key in an analysis.
        /// </summary>
        /// <param name="undoRedoText"></param>
        /// <returns>true if IP moved on, false otherwise</returns>
        internal virtual bool ApproveAndMoveNextRecursive(ICommandUndoRedoText undoRedoText)
        {
            if (!SelectedOccurrence.IsValid)
            {
                // Can happen (at least) when the text we're analyzing got deleted in another window
                SelectedOccurrence = null;
                InterlinDoc.TryHideFocusBoxAndUninstall();
                return(false);
            }
            var navigator    = new SegmentServices.StTextAnnotationNavigator(SelectedOccurrence);
            var nextWordform = navigator.GetNextWordformOrDefault(SelectedOccurrence);

            if (nextWordform == null || nextWordform.Segment != SelectedOccurrence.Segment ||
                nextWordform == SelectedOccurrence)
            {
                // We're at the end of a segment...try to go to an annotation of SelectedOccurrence.Segment
                // or possibly (See LT-12229:If the nextWordform is the same as SelectedOccurrence)
                // at the end of the text.
                UpdateRealFromSandbox(undoRedoText, true, null);                 // save work done in sandbox
                // try to select the first configured annotation (not a null note) in this segment
                if (InterlinDoc.SelectFirstTranslationOrNote())
                {                   // IP should now be on an annotation line.
                    return(true);
                }
            }
            if (nextWordform != null)
            {
                bool dealtWith = false;
                if (nextWordform.Segment != SelectedOccurrence.Segment)
                {                   // Is there another segment before the next wordform?
                    // It would have no analyses or just punctuation.
                    // It could have "real" annotations.
                    AnalysisOccurrence realAnalysis;
                    ISegment           nextSeg = InterlinDoc.GetNextSegment
                                                     (SelectedOccurrence.Segment.Owner.IndexInOwner,
                                                     SelectedOccurrence.Segment.IndexInOwner, false, out realAnalysis); // downward move
                    if (nextSeg != null && nextSeg != nextWordform.Segment)
                    {                                                                                                   // This is a segment before the one contaning the next wordform.
                        if (nextSeg.AnalysesRS.Where(an => an.HasWordform).Count() > 0)
                        {                                                                                               // Set it as the current segment and recurse
                            SelectedOccurrence = new AnalysisOccurrence(nextSeg, 0);                                    // set to first analysis
                            dealtWith          = ApproveAndMoveNextRecursive(undoRedoText);
                        }
                        else
                        {                               // only has annotations: focus on it and set the IP there.
                            InterlinDoc.SelectFirstTranslationOrNote(nextSeg);
                            return(true);               // IP should now be on an annotation line.
                        }
                    }
                }
                if (!dealtWith)
                {                   // If not dealt with continue on to the next wordform.
                    UpdateRealFromSandbox(undoRedoText, true, nextWordform);
                    // do the move.
                    InterlinDoc.SelectOccurrence(nextWordform);
                }
            }
            return(true);
        }
        /// <summary>
        /// Move to the first bundle
        /// </summary>
        /// <param name="arg"></param>
        /// <returns></returns>
        public bool OnFirstBundle(object arg)
        {
            var navigator = new SegmentServices.StTextAnnotationNavigator(SelectedOccurrence);
            IEnumerable <AnalysisOccurrence> options = navigator.GetWordformOccurrencesBackwardsIncludingStartingOccurrence();

            InterlinDoc.TriggerAnalysisSelected(options.Last(), true, true);
            return(true);
        }
		/// <summary>
		/// Approves an analysis and moves the selection to the next wordform or the
		/// next Interlinear line. An Interlinear line is one of the configurable
		/// "lines" in the Tools->Configure->Interlinear Lines dialog, not a segement.
		/// The list of lines is collected in choices[] below.
		/// WordLevel is true for word or analysis lines. The non-word lines are translation and note lines.
		/// Normally, this is invoked as a result of pressing the <Enter> key in an analysis.
		/// </summary>
		/// <param name="undoRedoText"></param>
		/// <returns>true if IP moved on, false otherwise</returns>
		internal virtual bool ApproveAndMoveNextRecursive(ICommandUndoRedoText undoRedoText)
		{
			if (!SelectedOccurrence.IsValid)
			{
				// Can happen (at least) when the text we're analyzing got deleted in another window
				SelectedOccurrence = null;
				InterlinDoc.TryHideFocusBoxAndUninstall();
				return false;
			}
			var navigator = new SegmentServices.StTextAnnotationNavigator(SelectedOccurrence);
			var nextWordform = navigator.GetNextWordformOrDefault(SelectedOccurrence);
			if (nextWordform == null || nextWordform.Segment != SelectedOccurrence.Segment ||
				nextWordform == SelectedOccurrence)
			{
				// We're at the end of a segment...try to go to an annotation of SelectedOccurrence.Segment
				// or possibly (See LT-12229:If the nextWordform is the same as SelectedOccurrence)
				// at the end of the text.
				UpdateRealFromSandbox(undoRedoText, true, null); // save work done in sandbox
				// try to select the first configured annotation (not a null note) in this segment
				if (InterlinDoc.SelectFirstTranslationOrNote())
				{   // IP should now be on an annotation line.
					return true;
				}
			}
			if (nextWordform != null)
			{
				bool dealtWith = false;
				if (nextWordform.Segment != SelectedOccurrence.Segment)
				{   // Is there another segment before the next wordform?
					// It would have no analyses or just punctuation.
					// It could have "real" annotations.
					AnalysisOccurrence realAnalysis;
					ISegment nextSeg = InterlinDoc.GetNextSegment
						(SelectedOccurrence.Segment.Owner.IndexInOwner,
						 SelectedOccurrence.Segment.IndexInOwner, false, out realAnalysis); // downward move
					if (nextSeg != null && nextSeg != nextWordform.Segment)
					{   // This is a segment before the one contaning the next wordform.
						if (nextSeg.AnalysesRS.Where(an => an.HasWordform).Count() > 0)
						{   // Set it as the current segment and recurse
							SelectedOccurrence = new AnalysisOccurrence(nextSeg, 0); // set to first analysis
							dealtWith = ApproveAndMoveNextRecursive(undoRedoText);
						}
						else
						{	// only has annotations: focus on it and set the IP there.
							InterlinDoc.SelectFirstTranslationOrNote(nextSeg);
							return true; // IP should now be on an annotation line.
						}
					}
				}
				if (!dealtWith)
				{   // If not dealt with continue on to the next wordform.
					UpdateRealFromSandbox(undoRedoText, true, nextWordform);
					// do the move.
					InterlinDoc.SelectOccurrence(nextWordform);
				}
			}
			return true;
		}
Beispiel #4
0
        public void AdvanceThroughWordformInThePara_Using_GetNextWordformOrDefault()
        {
            //start before end of sentence
            var navigator    = new SegmentServices.StTextAnnotationNavigator(m_expectedOccurrences[2]);
            var nextWordform = navigator.GetNextWordformOrDefault(null);

            Assert.AreEqual(m_expectedOccurrences[3], nextWordform);

            navigator    = new SegmentServices.StTextAnnotationNavigator(m_expectedOccurrences[3]);
            nextWordform = navigator.GetNextWordformOrDefault(null);
            Assert.AreEqual(m_expectedOccurrences[5], nextWordform);

            navigator    = new SegmentServices.StTextAnnotationNavigator(m_expectedOccurrences[6]);
            nextWordform = navigator.GetNextWordformOrDefault(null);
            Assert.AreEqual(m_expectedOccurrences[8], nextWordform);

            //position the navigator at the last occurrence of the stText.
            navigator = new SegmentServices.StTextAnnotationNavigator(m_expectedOccurrences[18]);
            //if there are no occurrences beyond this position in the stText then null should be returned
            nextWordform = navigator.GetNextWordformOrDefault(null);
            Assert.AreEqual(null, nextWordform);

            // JohnT: this is to test that it returns an arbitrary default passed in, if there are
            // no more. This dummy analysis occurrence is probably not in a valid state, so don't
            // use it for other things or be too surprised if improved validation detects a problem.
            var expected = new AnalysisOccurrence(m_para0.SegmentsOS[0], 18);

            nextWordform = navigator.GetNextWordformOrDefault(expected);
            Assert.AreEqual(expected, nextWordform);

            navigator = new SegmentServices.StTextAnnotationNavigator(m_expectedOccurrences[18]);
            //if there are no occurrences beyond this position in the stText then null should be returned
            nextWordform = navigator.GetNextWordformOrDefault(null);
            Assert.AreEqual(null, nextWordform);

            //========================================================================
            navigator    = new SegmentServices.StTextAnnotationNavigator(m_expectedOccurrences[2]);
            nextWordform = navigator.GetNextWordformOrStartingWordform();
            Assert.AreEqual(m_expectedOccurrences[3], nextWordform);

            navigator    = new SegmentServices.StTextAnnotationNavigator(m_expectedOccurrences[3]);
            nextWordform = navigator.GetNextWordformOrStartingWordform();
            Assert.AreEqual(m_expectedOccurrences[5], nextWordform);

            navigator    = new SegmentServices.StTextAnnotationNavigator(m_expectedOccurrences[6]);
            nextWordform = navigator.GetNextWordformOrStartingWordform();
            Assert.AreEqual(m_expectedOccurrences[8], nextWordform);

            //position the navigator at the last occurrence of the stText.
            navigator = new SegmentServices.StTextAnnotationNavigator(m_expectedOccurrences[18]);
            //if there are no occurrences beyond this position in the stText then null should be returned
            nextWordform = navigator.GetNextWordformOrStartingWordform();
            Assert.AreEqual(m_expectedOccurrences[18], nextWordform);
        }
Beispiel #5
0
        public void AdvanceThroughAnalysisOccurrences_StartingAtEndOfPara()
        {
            var navigator = new SegmentServices.StTextAnnotationNavigator(m_expectedOccurrences[6]);
            int i         = 6;

            foreach (var occurrence in navigator.GetAnalysisOccurrencesAdvancingIncludingStartingOccurrence())
            {
                Assert.AreEqual(m_expectedOccurrences[i], occurrence);
                i++;
            }
            //ensure the all paragraphs in the stText were processed.
            Assert.AreEqual(m_expectedOccurrences.Count, i);
        }
Beispiel #6
0
        public void AdvanceThroughEachAnalysisOccurrenceInTheStText()
        {
            var navigator = new SegmentServices.StTextAnnotationNavigator(m_stText);
            int i         = 0;

            foreach (var occurrence in navigator.GetAnalysisOccurrencesAdvancingInStText())
            {
                Assert.AreEqual(m_expectedOccurrences[i], occurrence);
                i++;
            }
            //ensure the all paragraphs in the stText were processed.
            Assert.AreEqual(m_expectedOccurrences.Count, i);
        }
Beispiel #7
0
        public void BackwardsThroughEachAnalysisOccurrenceInTheStText()
        {
            var navigator = new SegmentServices.StTextAnnotationNavigator(m_stText);
            int i         = m_expectedOccurrences.Count - 1;

            foreach (var occurrence in navigator.GetAnalysisOccurrencesBackwardsInStText())
            {
                Assert.AreEqual(m_expectedOccurrences[i], occurrence);
                i--;
            }
            //ensure all paragraphs in stText were processed and not just the last one.
            Assert.AreEqual(-1, i);
        }
        // Caller must create UOW
        private void ApplyAnalysisToInstancesOfWordform(IAnalysis newAnalysis, IWfiWordform oldWordform, IWfiWordform newWordform)
        {
            var navigator = new SegmentServices.StTextAnnotationNavigator(SelectedOccurrence);

            foreach (var occ in navigator.GetAnalysisOccurrencesAdvancingInStText().ToList())
            {
                // We certainly want to update any occurrence that exactly matches the wordform of the analysis we are confirming.
                // If oldWordform is different, we are confirming a different case form from what occurred in the text,
                // and we only confirm these if SelectedOccurrence and occ are both sentence-initial.
                // We want to do that only for sentence-initial occurrences.
                if (occ.Analysis == newWordform || (occ.Analysis == oldWordform && occ.Index == 0 && SelectedOccurrence.Index == 0))
                {
                    occ.Segment.AnalysesRS[occ.Index] = newAnalysis;
                }
            }
        }
        // It would be nice to have more of this logic in the StTextAnnotationNavigator, but the definition of FullyAnalyzed
        // is dependent on what lines we are displaying.
        private AnalysisOccurrence GetNextOccurrenceToAnalyze(bool fForward, bool skipFullyAnalyzedWords)
        {
            var navigator = new SegmentServices.StTextAnnotationNavigator(SelectedOccurrence);
            var options   = fForward
                                                          ? navigator.GetWordformOccurrencesAdvancingIncludingStartingOccurrence()
                                                          : navigator.GetWordformOccurrencesBackwardsIncludingStartingOccurrence();

            if (options.First() == SelectedOccurrence)
            {
                options = options.Skip(1);
            }
            if (skipFullyAnalyzedWords)
            {
                options = options.Where(analysis => !IsFullyAnalyzed(analysis));
            }
            return(options.DefaultIfEmpty(SelectedOccurrence).FirstOrDefault());
        }
Beispiel #10
0
        public void AdvanceThroughEachWordformInTheStText()
        {
            var navigator = new SegmentServices.StTextAnnotationNavigator(m_stText);
            int i         = 0;

            foreach (var occurrence in navigator.GetWordformsAdvancingInStText())
            {
                if (i == 4 || i == 7 || i == 13)
                {
                    i++;
                }
                Assert.AreEqual(m_expectedOccurrences[i], occurrence);
                i++;
            }
            //ensure all occurrences of both paragraphs were processed.
            Assert.AreEqual(m_expectedOccurrences.Count - 1, i);
        }
		public void AdvanceThroughWordformInThePara_Using_GetNextWordformOrDefault()
		{
			//start before end of sentence
			var navigator = new SegmentServices.StTextAnnotationNavigator(m_expectedOccurrences[2]);
			var nextWordform = navigator.GetNextWordformOrDefault(null);
			Assert.AreEqual(m_expectedOccurrences[3], nextWordform);

			navigator = new SegmentServices.StTextAnnotationNavigator(m_expectedOccurrences[3]);
			nextWordform = navigator.GetNextWordformOrDefault(null);
			Assert.AreEqual(m_expectedOccurrences[5], nextWordform);

			navigator = new SegmentServices.StTextAnnotationNavigator(m_expectedOccurrences[6]);
			nextWordform = navigator.GetNextWordformOrDefault(null);
			Assert.AreEqual(m_expectedOccurrences[8], nextWordform);

			//position the navigator at the last occurrence of the stText.
			navigator = new SegmentServices.StTextAnnotationNavigator(m_expectedOccurrences[18]);
			//if there are no occurrences beyond this position in the stText then null should be returned
			nextWordform = navigator.GetNextWordformOrDefault(null);
			Assert.AreEqual(null, nextWordform);

			// JohnT: this is to test that it returns an arbitrary default passed in, if there are
			// no more. This dummy analysis occurrence is probably not in a valid state, so don't
			// use it for other things or be too surprised if improved validation detects a problem.
			var expected = new AnalysisOccurrence(m_para0.SegmentsOS[0], 18);
			nextWordform = navigator.GetNextWordformOrDefault(expected);
			Assert.AreEqual(expected, nextWordform);

			navigator = new SegmentServices.StTextAnnotationNavigator(m_expectedOccurrences[18]);
			//if there are no occurrences beyond this position in the stText then null should be returned
			nextWordform = navigator.GetNextWordformOrDefault(null);
			Assert.AreEqual(null, nextWordform);

			//========================================================================
			navigator = new SegmentServices.StTextAnnotationNavigator(m_expectedOccurrences[2]);
			nextWordform = navigator.GetNextWordformOrStartingWordform();
			Assert.AreEqual(m_expectedOccurrences[3], nextWordform);

			navigator = new SegmentServices.StTextAnnotationNavigator(m_expectedOccurrences[3]);
			nextWordform = navigator.GetNextWordformOrStartingWordform();
			Assert.AreEqual(m_expectedOccurrences[5], nextWordform);

			navigator = new SegmentServices.StTextAnnotationNavigator(m_expectedOccurrences[6]);
			nextWordform = navigator.GetNextWordformOrStartingWordform();
			Assert.AreEqual(m_expectedOccurrences[8], nextWordform);

			//position the navigator at the last occurrence of the stText.
			navigator = new SegmentServices.StTextAnnotationNavigator(m_expectedOccurrences[18]);
			//if there are no occurrences beyond this position in the stText then null should be returned
			nextWordform = navigator.GetNextWordformOrStartingWordform();
			Assert.AreEqual(m_expectedOccurrences[18], nextWordform);
		}
		/// <summary>
		/// Move to the first bundle
		/// </summary>
		/// <param name="arg"></param>
		/// <returns></returns>
		public bool OnFirstBundle(object arg)
		{
			var navigator = new SegmentServices.StTextAnnotationNavigator(SelectedOccurrence);
			IEnumerable<AnalysisOccurrence> options = navigator.GetWordformOccurrencesBackwardsIncludingStartingOccurrence();
			InterlinDoc.TriggerAnalysisSelected(options.Last(), true, true);
			return true;
		}
		public void AdvanceThroughAnalysisOccurrences_StartingAtEndOfPara()
		{
			var navigator = new SegmentServices.StTextAnnotationNavigator(m_expectedOccurrences[6]);
			int i = 6;
			foreach (var occurrence in navigator.GetAnalysisOccurrencesAdvancingIncludingStartingOccurrence())
			{
				Assert.AreEqual(m_expectedOccurrences[i], occurrence);
				i++;
			}
			//ensure the all paragraphs in the stText were processed.
			Assert.AreEqual(m_expectedOccurrences.Count, i);
		}
		public void AdvanceThroughEachAnalysisOccurrenceInTheStText()
		{
			var navigator = new SegmentServices.StTextAnnotationNavigator(m_stText);
			int i = 0;

			foreach (var occurrence in navigator.GetAnalysisOccurrencesAdvancingInStText())
			{
				Assert.AreEqual(m_expectedOccurrences[i], occurrence);
				i++;
			}
			//ensure the all paragraphs in the stText were processed.
			Assert.AreEqual(m_expectedOccurrences.Count, i);
		}
		public void AdvanceThroughEachWordformInTheStText()
		{
			var navigator = new SegmentServices.StTextAnnotationNavigator(m_stText);
			int i = 0;

			foreach (var occurrence in navigator.GetWordformsAdvancingInStText())
			{
				if (i == 4 || i == 7 || i == 13)
					i++;
				Assert.AreEqual(m_expectedOccurrences[i], occurrence);
				i++;
			}
			//ensure all occurrences of both paragraphs were processed.
			Assert.AreEqual(m_expectedOccurrences.Count - 1, i);
		}
		// Caller must create UOW
		private void ApplyAnalysisToInstancesOfWordform(IAnalysis newAnalysis, IWfiWordform oldWordform, IWfiWordform newWordform)
		{
			var navigator = new SegmentServices.StTextAnnotationNavigator(SelectedOccurrence);
			foreach (var occ in navigator.GetAnalysisOccurrencesAdvancingInStText().ToList())
			{
				// We certainly want to update any occurrence that exactly matches the wordform of the analysis we are confirming.
				// If oldWordform is different, we are confirming a different case form from what occurred in the text,
				// and we only confirm these if SelectedOccurrence and occ are both sentence-initial.
				// We want to do that only for sentence-initial occurrences.
				if (occ.Analysis == newWordform || (occ.Analysis == oldWordform && occ.Index == 0 && SelectedOccurrence.Index == 0))
					occ.Segment.AnalysesRS[occ.Index] = newAnalysis;
			}
		}
		public void BackwardsThroughEachWordformOccurrenceInTheStText()
		{
			var navigator = new SegmentServices.StTextAnnotationNavigator(m_stText);
			int i = m_expectedOccurrences.Count - 2;

			foreach (var occurrence in navigator.GetWordformOccurrencesBackwardsInStText())
			{
				if (i == 4 || i == 7 || i == 13)
					i--;
				Assert.AreEqual(m_expectedOccurrences[i], occurrence);
				i--;
			}
			//ensure all paragraphs in stText were processed and not just the last one.
			Assert.AreEqual(-1, i);
		}
		/// <summary>
		/// Approve all the suggested analyses in this text. See LT-4312.
		/// </summary>
		/// <param name="cmd">The command object from the selection event.</param>
		public void ApproveAllSuggestedAnalyses(Command cmd)
		{   // Go through the entire text looking for suggested analyses that can be approved.
			// remember where the focus box or ip is
			// might be on an analysis, labels or translation text
			var helper = SelectionHelper.Create(RootBox.Site); // only helps restore translation and note line selections
			AnalysisOccurrence focusedWf = SelectedOccurrence; // need to restore focus box if selected

			// find the very first analysis
			ISegment firstRealSeg = null;
			IAnalysis firstRealOcc = null;
			int occInd = 0;
			foreach (IStPara p in RootStText.ParagraphsOS)
			{
				var para = (IStTxtPara) p;
				foreach (ISegment seg in para.SegmentsOS)
				{
					firstRealSeg = seg;
					occInd = 0;
					foreach(IAnalysis an in seg.AnalysesRS)
					{
						if (an.HasWordform && an.IsValidObject)
						{
							firstRealOcc = an;
							break;
						}
						occInd++;
					}
					if (firstRealOcc != null) break;
				}
				if (firstRealOcc != null) break;
			}
			// Set it as the current segment and recurse
			if (firstRealOcc == null)
				return; // punctuation only or nothing to analyze
			AnalysisOccurrence ao = null;
			if (focusedWf != null && focusedWf.Analysis == firstRealOcc)
				ao = new AnalysisOccurrence(focusedWf.Segment, focusedWf.Index);
			else
				ao = new AnalysisOccurrence(firstRealSeg, occInd);
			TriggerAnalysisSelected(ao, true, true, false);
			var navigator = new SegmentServices.StTextAnnotationNavigator(ao);

			// This needs to be outside the block for the UOW, since what we are suppressing
			// happens at the completion of the UOW.
			SuppressResettingGuesses(
				() =>
				{
					// Needs to include GetRealAnalysis, since it might create a new one.
					UndoableUnitOfWorkHelper.Do(cmd.UndoText, cmd.RedoText, Cache.ActionHandlerAccessor,
					() =>
					{
						var nav = new SegmentServices.StTextAnnotationNavigator(SelectedOccurrence);
						AnalysisOccurrence lastOccurrence;
						var analyses = navigator.GetAnalysisOccurrencesAdvancingInStText().ToList();
						foreach (var occ in analyses)
						{   // This could be punctuation or any kind of analysis.
							IAnalysis occAn = occ.Analysis; // averts “Access to the modified closure” warning in resharper
							if (occAn is IWfiAnalysis || occAn is IWfiWordform)
							{   // this is an analysis or a wordform
								int hvo = m_vc.GetGuess(occAn);
								if (occAn.Hvo != hvo)
								{   // this is a guess, so approve it
									// 1) A second occurence of a word that has had a lexicon entry or sense created for it.
									// 2) A parser result - not sure which gets picked if multiple.
									// #2 May take a while to "percolate" through to become a "guess".
									var guess = Cache.ServiceLocator.ObjectRepository.GetObject(hvo);
									if (guess != null && guess is IAnalysis)
										occ.Segment.AnalysesRS[occ.Index] = (IAnalysis) guess;
									else
									{
										occ.Segment.AnalysesRS[occ.Index] = occAn.Wordform.AnalysesOC.FirstOrDefault();
									}
								}
							/*	else if (occAn.HasWordform && occAn.Wordform.ParserCount > 0)
								{   // this doesn't seem to be needed (and may not be correct) - always caught above
									bool isHumanNoOpinion = occAn.Wordform.HumanNoOpinionParses.Cast<IWfiWordform>().Any(wf => wf.Hvo == occAn.Hvo);
									if (isHumanNoOpinion)
									{
										occ.Segment.AnalysesRS[occ.Index] = occAn.Wordform.AnalysesOC.FirstOrDefault();
									}
								} */
							}
						}
					});
				}
			);
			// MoveFocusBoxIntoPlace();
			if (focusedWf != null)
				SelectOccurrence(focusedWf);
			else if (helper != null)
				helper.SetSelection(true, true);
			Update();
		}
		// It would be nice to have more of this logic in the StTextAnnotationNavigator, but the definition of FullyAnalyzed
		// is dependent on what lines we are displaying.
		private AnalysisOccurrence GetNextOccurrenceToAnalyze(bool fForward, bool skipFullyAnalyzedWords)
		{
			var navigator = new SegmentServices.StTextAnnotationNavigator(SelectedOccurrence);
			var options = fForward
							  ? navigator.GetWordformOccurrencesAdvancingIncludingStartingOccurrence()
							  : navigator.GetWordformOccurrencesBackwardsIncludingStartingOccurrence();
			if (options.First() == SelectedOccurrence)
				options = options.Skip(1);
			if (skipFullyAnalyzedWords)
				options = options.Where(analysis => !IsFullyAnalyzed(analysis));
			return options.DefaultIfEmpty(SelectedOccurrence).FirstOrDefault();
		}