private static void UpgradeToWordGloss(Word word, ref IAnalysis analysis)
		{
			FdoCache cache = analysis.Cache;
			var tsStrFactory = cache.ServiceLocator.GetInstance<ITsStrFactory>();
			var wsFact = cache.WritingSystemFactory;
			if (s_importOptions.AnalysesLevel == ImportAnalysesLevel.WordGloss)
			{
				// test for adding multiple glosses in the same language. If so, create separate analyses with separate glosses.
				bool fHasMultipleGlossesInSameLanguage = false;
				var dictMapLangToGloss = new Dictionary<string, string>();
				foreach (var wordGlossItem in word.Items.Select(i => i).Where(i => i.type == "gls"))
				{
					string gloss;
					if (!dictMapLangToGloss.TryGetValue(wordGlossItem.lang, out gloss))
					{
						dictMapLangToGloss.Add(wordGlossItem.lang, wordGlossItem.Value);
						continue;
					}
					if (wordGlossItem.Value == gloss) continue;
					fHasMultipleGlossesInSameLanguage = true;
					break;
				}

				AnalysisTree analysisTree = null;
				foreach (var wordGlossItem in word.Items.Select(i => i).Where(i => i.type == "gls"))
				{
					if (wordGlossItem == null) continue;
					if (wordGlossItem.analysisStatusSpecified &&
						wordGlossItem.analysisStatus != analysisStatusTypes.humanApproved) continue;
					// first make sure that an existing gloss does not already exist. (i.e. don't add duplicate glosses)
					int wsNewGloss = GetWsEngine(wsFact, wordGlossItem.lang).Handle;
					ITsString newGlossTss = tsStrFactory.MakeString(wordGlossItem.Value,
																	wsNewGloss);
					var wfiWord = analysis.Wordform;
					bool hasGlosses = wfiWord.AnalysesOC.Any(wfia => wfia.MeaningsOC.Any());
					IWfiGloss matchingGloss = null;
					if (hasGlosses)
					{
						foreach (var wfa in wfiWord.AnalysesOC)
						{
							matchingGloss = wfa.MeaningsOC.FirstOrDefault(wfg => wfg.Form.get_String(wsNewGloss).Equals(newGlossTss));
							if (matchingGloss != null)
								break;
						}
					}

					if (matchingGloss != null)
						analysis = matchingGloss;
					else
					{
						// TODO: merge with analysis having same morpheme breakdown (or at least the same stem)

						if (analysisTree == null || dictMapLangToGloss.Count == 1 || fHasMultipleGlossesInSameLanguage)
						{
							// create a new WfiAnalysis to store a new gloss
							analysisTree = WordAnalysisOrGlossServices.CreateNewAnalysisTreeGloss(wfiWord);
						}
						// else, reuse the same analysisTree for setting a gloss alternative

						analysisTree.Gloss.Form.set_String(wsNewGloss, wordGlossItem.Value);
						// Make sure this analysis is marked as user-approved (green check mark)
						cache.LangProject.DefaultUserAgent.SetEvaluation(analysisTree.WfiAnalysis, Opinions.approves);
						// Create a morpheme form that matches the wordform.
						var morphemeBundle = cache.ServiceLocator.GetInstance<IWfiMorphBundleFactory>().Create();
						var wordItem = word.Items.Select(i => i).First(i => i.type == "txt");
						int wsWord = GetWsEngine(wsFact, wordItem.lang).Handle;
						analysisTree.WfiAnalysis.MorphBundlesOS.Add(morphemeBundle);
						morphemeBundle.Form.set_String(wsWord, wordItem.Value);

						analysis = analysisTree.Gloss;
					}
				}
			}
		}
		internal void ImportWordsFrag(Word[] words, ImportAnalysesLevel analysesLevel)
		{
			s_importOptions = new ImportInterlinearOptions {AnalysesLevel = analysesLevel};
			var tsStrFactory = m_cache.ServiceLocator.GetInstance<ITsStrFactory>();
			NonUndoableUnitOfWorkHelper.Do(m_cache.ActionHandlerAccessor, () =>
			{
				foreach (var word in words)
				{
					CreateWordAnalysisStack(m_cache, word, tsStrFactory);
				}
			});
		}
		/// <summary>
		/// add any alternative forms (in alternative writing systems) to the wordform.
		/// Overwrite any existing alternative form in a given alternative writing system.
		/// </summary>
		/// <param name="analysis"></param>
		/// <param name="word"></param>
		/// <param name="wsMainVernWs"></param>
		/// <param name="strFactory"></param>
		private static void AddAlternativeWssToWordform(IAnalysis analysis, Word word, ILgWritingSystem wsMainVernWs, ITsStrFactory strFactory)
		{
			ILgWritingSystemFactory wsFact = analysis.Cache.WritingSystemFactory;
			var wf = analysis.Wordform;
			foreach (var wordItem in word.Items)
			{
				ITsString wffAlt = null;
				switch (wordItem.type)
				{
					case "txt":
						var wsAlt = GetWsEngine(wsFact, wordItem.lang);
						if (wsAlt.Handle == wsMainVernWs.Handle)
							continue;
						wffAlt = strFactory.MakeString(wordItem.Value, wsAlt.Handle);
						if (wffAlt.Length > 0)
							wf.Form.set_String(wsAlt.Handle, wffAlt);
						break;
				}
			}
		}
		private static IAnalysis CreateWordAnalysisStack(FdoCache cache, Word word, ITsStrFactory strFactory)
		{
			if (word.Items == null || word.Items.Length <= 0) return null;
			IAnalysis analysis = null;
			var wsFact = cache.WritingSystemFactory;
			ILgWritingSystem wsMainVernWs = null;
			foreach (var wordItem in word.Items)
			{
				ITsString wordForm = null;
				switch (wordItem.type)
				{
					case "txt":
						wsMainVernWs = GetWsEngine(wsFact, wordItem.lang);
						wordForm = strFactory.MakeString(wordItem.Value, wsMainVernWs.Handle);
						analysis = WfiWordformServices.FindOrCreateWordform(cache, wordForm);
						break;
					case "punct":
						wordForm = strFactory.MakeString(wordItem.Value,
														 GetWsEngine(wsFact, wordItem.lang).Handle);
						analysis = WfiWordformServices.FindOrCreatePunctuationform(cache, wordForm);
						break;
				}
				if (wordForm != null)
					break;
			}

			// now add any alternative word forms. (overwrite any existing)
			if (analysis != null && analysis.HasWordform)
			{
				AddAlternativeWssToWordform(analysis, word, wsMainVernWs, strFactory);
			}

			if (analysis != null)
			{
				UpgradeToWordGloss(word, ref analysis);
			}
			else
			{
				Debug.Assert(analysis != null, "What else could this do?");
			}
			//Add any morphemes to the thing
			if (word.morphemes != null && word.morphemes.morphs.Length > 0)
			{
				//var bundle = newSegment.Cache.ServiceLocator.GetInstance<IWfiMorphBundleFactory>().Create();
				//analysis.Analysis.MorphBundlesOS.Add(bundle);
				//foreach (var morpheme in word.morphemes)
				//{
				//    //create a morpheme
				//    foreach(item item in morpheme.items)
				//    {
				//        //fill in morpheme's stuff
				//    }
				//}
			}
			return analysis;
		}
		private static void AddWordToSegment(ISegment newSegment, Word word, ITsStrFactory strFactory)
		{
			//use the items under the word to determine what kind of thing to add to the segment
			var cache = newSegment.Cache;
			IAnalysis analysis = CreateWordAnalysisStack(cache, word, strFactory);

			// Add to segment
			if (analysis != null)
			{
				newSegment.AnalysesRS.Add(analysis);
			}
		}
		private static void MergeWordToSegment(ISegment newSegment, Word word, ITsStrFactory tsStrFactory)
		{
			if(!String.IsNullOrEmpty(word.guid))
			{
				ICmObject repoObj;
				newSegment.Cache.ServiceLocator.ObjectRepository.TryGetObject(new Guid(word.guid), out repoObj);
				IAnalysis modelWord = repoObj as IAnalysis;
				if(modelWord != null)
				{
					UpgradeToWordGloss(word, ref modelWord);
					newSegment.AnalysesRS.Add(modelWord);
				}
				else
				{
					AddWordToSegment(newSegment, word, tsStrFactory);
				}
			}
			else
			{
				AddWordToSegment(newSegment, word, tsStrFactory);
			}
		}
		/// <summary>
		/// This method will update the phraseText ref item with the contents of the item entries under the word
		/// </summary>
		/// <param name="wsFactory"></param>
		/// <param name="tsStrFactory"></param>
		/// <param name="phraseText"></param>
		/// <param name="word"></param>
		/// <param name="lastWasWord"></param>
		/// <param name="space"></param>
		private static void UpdatePhraseTextForWordItems(ILgWritingSystemFactory wsFactory, ITsStrFactory tsStrFactory, ref ITsString phraseText, Word word, ref bool lastWasWord, char space)
		{
			bool isWord = false;
			foreach (var item in word.Items)
			{
				switch (item.type)
				{
					case "txt": //intentional fallthrough
						isWord = true;
						goto case "punct";
					case "punct":
						ITsString wordString = tsStrFactory.MakeString(item.Value,
							GetWsEngine(wsFactory, item.lang).Handle);
						if (phraseText == null)
						{
							phraseText = wordString;
						}
						else
						{
							var phraseBldr = phraseText.GetBldr();
							if (lastWasWord && isWord) //two words next to each other deserve a space between
							{
								phraseBldr.ReplaceTsString(phraseText.Length, phraseText.Length,
								   tsStrFactory.MakeString("" + space, GetWsEngine(wsFactory, item.lang).Handle));
							}
							else if (!isWord) //handle punctuation
							{
								wordString = GetSpaceAdjustedPunctString(wsFactory, tsStrFactory,
									item, wordString, space, lastWasWord);
							}
							phraseBldr.ReplaceTsString(phraseBldr.Length, phraseBldr.Length, wordString);
							phraseText = phraseBldr.GetString();
						}
						lastWasWord = isWord;
						return; // only handle the baseline "txt" or "punct" once per "word" bundle, especially don't want extra writing system content in the baseline.
				}
			}
		}