/// <summary>
        /// Creates a study item using the phrase and nativeLanguageText.  If the phrase.Language
        /// is the same as the native language, then this will be a study item related to studying
        /// the meaning of the phrase, all in the native language.  If these two languages are 
        /// different, then it will procure a translation study item.
        /// This prepares the view model so that all that is necessary for the caller is to call
        /// viewmodel.Show(...);
        /// </summary>
        public void Procure(PhraseEdit phrase, 
                        string nativeLanguageText, 
                        AsyncCallback<StudyItemViewModelBase> callback)
        {
            //FOR NOW, THIS WILL JUST CREATE ONE TYPE OF STUDY ITEM VIEW MODEL: STUDY QUESTION ANSWER VIEWMODEL.
              //IT WILL SHOW THE QUESTION AND HIDE THE ANSWER FOR VARIOUS AMOUNTS OF TIME, DEPENDING ON QUESTION
              //LENGTH, AND OTHER FACTORS.
              //IN THE FUTURE, THIS WILL BE EXTENSIBILITY POINT WHERE WE CAN SELECT DIFFERENT VARIETIES OF Q AND A
              //TRANSLATION VIEW MODELS BASED ON HOW SUCCESSFUL THEY ARE.  WE CAN ALSO HAVE DIFFERENT CONFIGURATIONS
              //OF VARIETIES BE SELECTED HERE.

              //ViewModels.StudyTimedQuestionAnswerViewModel viewModel = new ViewModels.StudyTimedQuestionAnswerViewModel();

              var languageText = phrase.Language.Text;

              //IF THE TARGET LANGUAGE IS DIFFERENT FROM THE PHRASE LANGUAGE, THEN WE CREATE A TRANSLATION Q & A.
              //IF THE TWO LANGUAGES ARE THE SAME, THEN WE CREATE A STUDY NATIVE LANGUAGE PHRASE Q & A.

              bool phraseIsInForeignLanguage = (languageText != nativeLanguageText);
              if (phraseIsInForeignLanguage)
              {
            //DO A TRANSLATION Q & A
            //WE NEED TO FIND A TRANSLATION FOR THIS FOREIGN LANGUAGE PHRASE.
            PhraseEdit translatedPhrase = null;

            GetTranslatedPhrase(phrase, nativeLanguageText, (s, r) =>
              {
            if (r.Error != null)
            {
              callback(this, new ResultArgs<StudyItemViewModelBase>(r.Error));
              return;
            }

            translatedPhrase = r.Object;

            try
            {
              //RIGHT NOW, WE HAVE A MANUAL AND A TIMED QA.
              var timedQA = new ViewModels.StudyPhraseTimedQuestionAnswerViewModel();
              var manualQA = new ViewModels.StudyPhraseManualQuestionAnswerViewModel();

              //PICK A RANDOM VIEW MODEL, EITHER TIMED OR MANUAL
              StudyItemViewModelBase dummy = null;
              var qaViewModel = RandomPicker.Ton.PickOne<StudyItemViewModelBase>(timedQA, manualQA, out dummy);

              //ASSIGN QUESTION/ANSWER RANDOMLY FROM PHRASE AND TRANSLATED PHRASE
              PhraseEdit answer = null;
              var question = RandomPicker.Ton.PickOne(phrase, translatedPhrase, out answer);

              //INITIALIZE VIEWMODEL WITH Q & A
              if (qaViewModel is ViewModels.StudyPhraseTimedQuestionAnswerViewModel)
                ((ViewModels.StudyPhraseTimedQuestionAnswerViewModel)qaViewModel).Initialize(question, answer, (e1) =>
                  {
                    //error callback
                    if (e1 != null)
                      callback(this, new ResultArgs<StudyItemViewModelBase>(e1));

                    //success callback
                    callback(this, new ResultArgs<StudyItemViewModelBase>(qaViewModel));
                  });
              else
                ((ViewModels.StudyPhraseManualQuestionAnswerViewModel)qaViewModel).Initialize(question, answer, (e2) =>
                  {
                    //error callback
                    if (e2 != null)
                      callback(this, new ResultArgs<StudyItemViewModelBase>(e2));

                    //success callback
                    callback(this, new ResultArgs<StudyItemViewModelBase>(qaViewModel));
                  });

              ////INITIATE THE CALLBACK TO LET IT KNOW WE HAVE OUR VIEWMODEL!  WHEW THAT'S A LOT OF ASYNC.
              //callback(this, new ResultArgs<StudyItemViewModelBase>(qaViewModel));
            }
            catch (Exception ex)
            {
              callback(this, new ResultArgs<StudyItemViewModelBase>(ex));
            }
              });

              }
              else
              {
            //DO A NATIVE LANGUAGE Q & A
            throw new NotImplementedException();
              }
        }
        /// <summary>
        /// Creates a study item using the phrase and nativeLanguageText.  If the phrase.Language
        /// is the same as the native language, then this will be a study item related to studying
        /// the meaning of the phrase, all in the native language.  If these two languages are
        /// different, then it will procure a translation study item.
        /// This prepares the view model so that all that is necessary for the caller is to call
        /// viewmodel.Show(...);
        /// </summary>
        public async Task <StudyItemViewModelBase> ProcureAsync(PhraseEdit phrase,
                                                                string nativeLanguageText)
        //public async Task<ResultArgs<StudyItemViewModelBase>> ProcureAsync(PhraseEdit phrase,
        {
            //FOR NOW, THIS WILL JUST CREATE ONE TYPE OF STUDY ITEM VIEW MODEL: STUDY QUESTION ANSWER VIEWMODEL.
            //IT WILL SHOW THE QUESTION AND HIDE THE ANSWER FOR VARIOUS AMOUNTS OF TIME, DEPENDING ON QUESTION
            //LENGTH, AND OTHER FACTORS.
            //IN THE FUTURE, THIS WILL BE EXTENSIBILITY POINT WHERE WE CAN SELECT DIFFERENT VARIETIES OF Q AND A
            //TRANSLATION VIEW MODELS BASED ON HOW SUCCESSFUL THEY ARE.  WE CAN ALSO HAVE DIFFERENT CONFIGURATIONS
            //OF VARIETIES BE SELECTED HERE.

            //ViewModels.StudyTimedQuestionAnswerViewModel viewModel = new ViewModels.StudyTimedQuestionAnswerViewModel();

            var languageText = phrase.Language.Text;

            //IF THE TARGET LANGUAGE IS DIFFERENT FROM THE PHRASE LANGUAGE, THEN WE CREATE A TRANSLATION Q & A.
            //IF THE TWO LANGUAGES ARE THE SAME, THEN WE CREATE A STUDY NATIVE LANGUAGE PHRASE Q & A.

            bool phraseIsInForeignLanguage = (languageText != nativeLanguageText);

            if (phraseIsInForeignLanguage)
            {
                //DO A TRANSLATION Q & A
                //WE NEED TO FIND A TRANSLATION FOR THIS FOREIGN LANGUAGE PHRASE.
                PhraseEdit translatedPhrase = null;
                #region Thinking (try..)
                var targetId = Guid.NewGuid();
                History.Events.ThinkingAboutTargetEvent.Publish(targetId);
                try
                {
                    #endregion
                    var result = await GetTranslatedPhrase(phrase, nativeLanguageText);

                    translatedPhrase = result.Object;
                    #region (...finally) Thinked
                }
                finally
                {
                    History.Events.ThinkedAboutTargetEvent.Publish(targetId);
                }
                #endregion

                //RIGHT NOW, WE HAVE A MANUAL AND A TIMED QA.
                var timedQA  = new ViewModels.StudyPhraseTimedQuestionAnswerViewModel();
                var manualQA = new ViewModels.StudyPhraseTimedQuestionAnswerViewModel();
                //hack: I'm just setting these both to timed, because that is what I've corrected
                //for the async stuff and I want to make sure that it works.
                //var manualQA = new ViewModels.StudyPhraseManualQuestionAnswerViewModel();

                //PICK A RANDOM VIEW MODEL, EITHER TIMED OR MANUAL
                StudyItemViewModelBase dummy = null;
                var qaViewModel = RandomPicker.Ton.PickOne <StudyItemViewModelBase>(timedQA, manualQA, out dummy);

                //ASSIGN QUESTION/ANSWER RANDOMLY FROM PHRASE AND TRANSLATED PHRASE
                PhraseEdit answer   = null;
                var        question = RandomPicker.Ton.PickOne(phrase, translatedPhrase, out answer);

                //INITIALIZE VIEWMODEL WITH Q & A
                if (qaViewModel is ViewModels.StudyPhraseTimedQuestionAnswerViewModel)
                {
                    ((ViewModels.StudyPhraseTimedQuestionAnswerViewModel)qaViewModel).Initialize(question, answer);//, (e1) =>
                }
                else
                {
                    ((ViewModels.StudyPhraseTimedQuestionAnswerViewModel)qaViewModel).Initialize(question, answer);
                }
                //((ViewModels.StudyPhraseManualQuestionAnswerViewModel)qaViewModel).Initialize(question, answer);

                return(qaViewModel);
                //var resultQAViewModel = new ResultArgs<StudyItemViewModelBase>(qaViewModel);
                //return await StudyHelper.WrapInTask<ResultArgs<StudyItemViewModelBase>>(resultQAViewModel);
            }
            else
            {
                //DO A NATIVE LANGUAGE Q & A
                throw new NotImplementedException();
            }
        }
    /// <summary>
    /// Creates a study item using the phrase and nativeLanguageText.  If the phrase.Language
    /// is the same as the native language, then this will be a study item related to studying
    /// the meaning of the phrase, all in the native language.  If these two languages are 
    /// different, then it will procure a translation study item.
    /// This prepares the view model so that all that is necessary for the caller is to call
    /// viewmodel.Show(...);
    /// </summary>
    public async Task<StudyItemViewModelBase> ProcureAsync(PhraseEdit phrase,
      string nativeLanguageText)
    //public async Task<ResultArgs<StudyItemViewModelBase>> ProcureAsync(PhraseEdit phrase, 
    {
      //FOR NOW, THIS WILL JUST CREATE ONE TYPE OF STUDY ITEM VIEW MODEL: STUDY QUESTION ANSWER VIEWMODEL.
      //IT WILL SHOW THE QUESTION AND HIDE THE ANSWER FOR VARIOUS AMOUNTS OF TIME, DEPENDING ON QUESTION
      //LENGTH, AND OTHER FACTORS.
      //IN THE FUTURE, THIS WILL BE EXTENSIBILITY POINT WHERE WE CAN SELECT DIFFERENT VARIETIES OF Q AND A 
      //TRANSLATION VIEW MODELS BASED ON HOW SUCCESSFUL THEY ARE.  WE CAN ALSO HAVE DIFFERENT CONFIGURATIONS
      //OF VARIETIES BE SELECTED HERE.

      //ViewModels.StudyTimedQuestionAnswerViewModel viewModel = new ViewModels.StudyTimedQuestionAnswerViewModel();

      var languageText = phrase.Language.Text;

      //IF THE TARGET LANGUAGE IS DIFFERENT FROM THE PHRASE LANGUAGE, THEN WE CREATE A TRANSLATION Q & A.
      //IF THE TWO LANGUAGES ARE THE SAME, THEN WE CREATE A STUDY NATIVE LANGUAGE PHRASE Q & A.
        
      bool phraseIsInForeignLanguage = (languageText != nativeLanguageText);
      if (phraseIsInForeignLanguage)
      {
        //DO A TRANSLATION Q & A
        //WE NEED TO FIND A TRANSLATION FOR THIS FOREIGN LANGUAGE PHRASE.
        PhraseEdit translatedPhrase = null;
        #region Thinking (try..)
        var targetId = Guid.NewGuid();
        History.Events.ThinkingAboutTargetEvent.Publish(targetId);
        try
        {
        #endregion
          var result = await GetTranslatedPhrase(phrase, nativeLanguageText);
          translatedPhrase = result.Object;
        #region (...finally) Thinked
        }
        finally
        {
          History.Events.ThinkedAboutTargetEvent.Publish(targetId);
        }
        #endregion

        //RIGHT NOW, WE HAVE A MANUAL AND A TIMED QA.
        var timedQA = new ViewModels.StudyPhraseTimedQuestionAnswerViewModel();
        var manualQA = new ViewModels.StudyPhraseTimedQuestionAnswerViewModel();
        //hack: I'm just setting these both to timed, because that is what I've corrected
        //for the async stuff and I want to make sure that it works.
        //var manualQA = new ViewModels.StudyPhraseManualQuestionAnswerViewModel();

        //PICK A RANDOM VIEW MODEL, EITHER TIMED OR MANUAL
        StudyItemViewModelBase dummy = null;
        var qaViewModel = RandomPicker.Ton.PickOne<StudyItemViewModelBase>(timedQA, manualQA, out dummy);

        //ASSIGN QUESTION/ANSWER RANDOMLY FROM PHRASE AND TRANSLATED PHRASE
        PhraseEdit answer = null;
        var question = RandomPicker.Ton.PickOne(phrase, translatedPhrase, out answer);

        //INITIALIZE VIEWMODEL WITH Q & A
        if (qaViewModel is ViewModels.StudyPhraseTimedQuestionAnswerViewModel)
          ((ViewModels.StudyPhraseTimedQuestionAnswerViewModel)qaViewModel).Initialize(question, answer);//, (e1) =>
        else
          ((ViewModels.StudyPhraseTimedQuestionAnswerViewModel)qaViewModel).Initialize(question, answer);
          //((ViewModels.StudyPhraseManualQuestionAnswerViewModel)qaViewModel).Initialize(question, answer);

        return qaViewModel;
        //var resultQAViewModel = new ResultArgs<StudyItemViewModelBase>(qaViewModel);
        //return await StudyHelper.WrapInTask<ResultArgs<StudyItemViewModelBase>>(resultQAViewModel);
      }
      else
      {
        //DO A NATIVE LANGUAGE Q & A
        throw new NotImplementedException();
      }
    }