public void SetMappingNaturalClass()
		{
			SelectionHelper sel = SelectionHelper.Create(m_view);

			Set<int> natClasses = new Set<int>();
			foreach (IPhNaturalClass nc in m_cache.LangProject.PhonologicalDataOA.NaturalClassesOS)
			{
				if (nc.ClassID == PhNCFeatures.kclsidPhNCFeatures)
					natClasses.Add(nc.Hvo);
			}
			int ncHvo = m_insertionControl.DisplayChooser(MEStrings.ksRuleNCOpt, MEStrings.ksRuleNCChooserLink,
				"naturalClassedit", "RuleNaturalClassFlatList", natClasses);
			m_view.Select();
			if (ncHvo != 0)
			{
				int index = -1;
				using (new UndoRedoTaskHelper(m_cache, MEStrings.ksAffixRuleUndoSetNC, MEStrings.ksAffixRuleRedoSetNC))
				{
					int curHvo = CurrentHvo;
					switch (m_cache.GetClassOfObject(curHvo))
					{
						case MoCopyFromInput.kclsidMoCopyFromInput:
							IMoCopyFromInput copy = new MoCopyFromInput(m_cache, curHvo);
							IMoModifyFromInput newModify = new MoModifyFromInput();
							Rule.OutputOS.InsertAt(newModify, copy.IndexInOwner);
							newModify.ModificationRAHvo = ncHvo;
							newModify.ContentRAHvo = copy.ContentRAHvo;
							index = newModify.IndexInOwner;
							newModify.NotifyNew();

							copy.DeleteUnderlyingObject();
							break;

						case MoModifyFromInput.kclsidMoModifyFromInput:
							IMoModifyFromInput modify = new MoModifyFromInput(m_cache, curHvo);
							modify.ModificationRAHvo = ncHvo;
							index = modify.IndexInOwner;
							break;
					}
				}

				ReconstructView((int)MoAffixProcess.MoAffixProcessTags.kflidOutput, index, true);
			}
		}
		public void SetMappingFeatures()
		{
			SelectionHelper sel = SelectionHelper.Create(m_view);
			bool reconstruct = false;
			int index = -1;
			using (new UndoRedoTaskHelper(m_cache, MEStrings.ksAffixRuleUndoSetMappingFeatures, MEStrings.ksAffixRuleRedoSetMappingFeatures))
			{
				using (PhonologicalFeatureChooserDlg featChooser = new PhonologicalFeatureChooserDlg())
				{
					int hvo = CurrentHvo;
					switch (m_cache.GetClassOfObject(hvo))
					{
						case MoCopyFromInput.kclsidMoCopyFromInput:
							featChooser.SetDlgInfo(m_cache, m_mediator);
							if (featChooser.ShowDialog() == DialogResult.OK)
							{
								// create a new natural class behind the scenes
								PhNCFeatures featNC = new PhNCFeatures();
								m_cache.LangProject.PhonologicalDataOA.NaturalClassesOS.Append(featNC);
								featNC.Name.UserDefaultWritingSystem = string.Format(MEStrings.ksRuleNCFeatsName,
									Rule.Form.BestVernacularAnalysisAlternative.Text);
								featNC.FeaturesOA = new FsFeatStruc();
								featChooser.FS = featNC.FeaturesOA;
								featChooser.UpdateFeatureStructure();
								featNC.FeaturesOA.NotifyNew();
								featNC.NotifyNew();

								IMoCopyFromInput copy = new MoCopyFromInput(m_cache, hvo);
								IMoModifyFromInput newModify = new MoModifyFromInput();
								Rule.OutputOS.InsertAt(newModify, copy.IndexInOwner);
								newModify.ModificationRAHvo = featNC.Hvo;
								newModify.ContentRAHvo = copy.ContentRAHvo;
								index = newModify.IndexInOwner;
								newModify.NotifyNew();

								copy.DeleteUnderlyingObject();

								reconstruct = true;
							}
							break;

						case MoModifyFromInput.kclsidMoModifyFromInput:
							IMoModifyFromInput modify = new MoModifyFromInput(m_cache, hvo);
							featChooser.SetDlgInfo(m_cache, m_mediator, modify.ModificationRA.FeaturesOA);
							if (featChooser.ShowDialog() == DialogResult.OK)
							{
								if (modify.ModificationRA.FeaturesOA.FeatureSpecsOC.Count == 0)
								{
									IMoCopyFromInput newCopy = new MoCopyFromInput();
									Rule.OutputOS.InsertAt(newCopy, modify.IndexInOwner);
									newCopy.ContentRAHvo = modify.ContentRAHvo;
									index = newCopy.IndexInOwner;
									newCopy.NotifyNew();

									modify.DeleteUnderlyingObject();
								}
								else
								{
									index = modify.IndexInOwner;
								}
								reconstruct = true;
							}
							break;
					}
				}
			}

			m_view.Select();
			if (reconstruct)
				ReconstructView((int)MoAffixProcess.MoAffixProcessTags.kflidOutput, index, true);
		}