/// <summary>
        /// KeyUp Event
        /// </summary>
        /// <param name="e">KeyEventArgs</param>
        protected override void OnPreviewKeyUp(KeyEventArgs e)
        {
            base.OnPreviewKeyUp(e);
            SetWordAtPointer();
            SetLastWord();
            KeyColourRun();

            if ((_isAssistPredictOn == false) && (e.Key == Key.Space))  //need to know key is space so call in KeyUp
            {
                //save variable names, we for now will just add if last word has $ at the front
                if (_haveVariable)
                {
                    if (!_variableNames.Contains(_lastWord))
                    {
                        _variableNames.Add(_lastWord);
                    }

                    _predictKeyWord = "$";
                }
                else
                {
                    _predictKeyWord = _lastWord;//see what word we need to predict
                }

                var trigger = PredictTriggers.Where(s => s.Key == _predictKeyWord);
                if (trigger.Any())
                {
                    FilterAssistBoxItemsPredict((e.Key == Key.Space));
                    return;
                }
            }
            if ((_isAssistKeyWordOn == false) && ((_isAssistPredictOn == false) || _haveVariable) && !string.IsNullOrEmpty(_lastWord) && (e.Key != Key.Space))
            {
                IEnumerable <string> match;
                if (_haveVariable)
                {
                    match = _variableNames.Where(s => s.ToUpper().StartsWith(_lastWord.ToUpper()));
                }
                else
                {
                    match = KeyWordSource.Where(s => s.ToUpper().StartsWith(_lastWord.ToUpper()));
                }

                if (match.Any())
                {
                    FilterAssistBoxItemsKeyWord((e.Key == Key.Space));
                    return;
                }
            }

            if (_isAssistKeyWordOn)
            {
                FilterAssistBoxItemsKeyWord((e.Key == Key.Space));
            }
            else if (_isAssistPredictOn)
            {
                FilterAssistBoxItemsPredict((e.Key == Key.Space));
            }
        }
 /// <summary>
 /// Set the colour of the keyword, assume only one word per run when a key word
 /// </summary>
 /// <param name="run">Run</param>
 protected void SetKeyWordColour(Run run)
 {
     if (KeyWordSource.Contains(run.Text.Trim().ToUpper()))
     {
         if (run.Foreground != Brushes.Blue)
         {
             run.Foreground = Brushes.Blue;
             run.FontWeight = FontWeights.Bold;
         }
     }
     else
     {
         if (run.Foreground != Brushes.Black)
         {
             run.Foreground = Brushes.Black;
             run.FontWeight = FontWeights.Normal;
         }
     }
 }
        /// <summary>
        ///  Controller for the KeyWord list control
        /// </summary>
        /// <param name="haveSpace">bool</param>
        private void FilterAssistBoxItemsKeyWord(bool haveSpace)
        {
#if DEBUG
            //Debug.Print("LastWord in  FilterAssistBoxItemsKeyWord= {0}", _lastWord);
#endif
            //if a empty last word then kill box
            if ((string.IsNullOrEmpty(_lastWord)) || haveSpace || (_wordAtPointer.Length > _lastWord.Length)) //middle of an existing word
            {
                _assistListBox.Visibility = Visibility.Collapsed;
                _isAssistKeyWordOn        = false;
                return;
            }

            IEnumerable <string> displayItems;
            if (_haveVariable)
            {
                displayItems = _variableNames.Where(s => s.ToUpper().StartsWith(_lastWord.ToUpper()) && (s.ToUpper() != _lastWord.ToUpper()) && (s.ToUpper() != _wordAtPointer)).OrderBy(s => s);
            }
            else
            {
                displayItems = KeyWordSource.Where(s => s.ToUpper().StartsWith(_lastWord) && (s.ToUpper() != _lastWord) && (s.ToUpper() != _wordAtPointer)).OrderBy(s => s);
            }
            List <string> sortedItems = displayItems.ToList();
            sortedItems.Sort();
            _assistListBox.ItemsSource   = sortedItems;
            _assistListBox.SelectedIndex = 0;

            if (displayItems.Count() == 0)
            {
                _assistListBox.Visibility = Visibility.Collapsed;
                _isAssistKeyWordOn        = false;
            }
            else if (_assistListBox.Visibility != Visibility.Visible)
            {
                _isAssistKeyWordOn = true;
                _isAssistPredictOn = false;   //override predict if on
                ResetAssistListBoxLocation(); //set list box position
                _assistListBox.Visibility = Visibility.Visible;
            }
        }
        /// <summary>
        /// Colour the run if keyword, also splits the run if a key word, so keyword is within a single run
        /// </summary>
        private void KeyColourRun()
        {
            int symCount = GetOffsetFromStartDoc(CaretPosition);
            Run run      = CaretPosition.Parent as Run;

            if (!KeyColour) //no colour required
            {
                if ((run != null) && (run.Foreground != Brushes.Black))
                {
                    run.Foreground = Brushes.Black;
                    run.FontWeight = FontWeights.Normal;
                }
                return; //keyword colour turned off, so exit
            }

            string run1Text = string.Empty;
            string run2Text = string.Empty;
            string run3Text = string.Empty;

            if (run != null)
            {
                string text = run.Text;

                //check if run text is single keyword and if so see if it needs highlight, no need to go through the splitting of runs
                //if (KeyWordSource.Contains(text.Trim().ToUpper()))
                //{
                //    SetKeyWordColour(run);
                //    return;
                //}
                //more than one word so split if we can
                if (KeyWordSource.Contains(_wordAtPointer))
                {
                    TextPointer startLine  = run.ContentStart;
                    int         startIdx   = startLine.GetOffsetToPosition(_startWord);
                    int         wordLength = _wordAtPointer.Length;
                    int         endIdx     = startIdx + wordLength;

                    if (startIdx > 0)
                    {
                        startIdx   -= 1;                                          //pick up the character before the word to see if a " "
                        wordLength += 1;                                          //ditto
                        string newRuntext = text.Substring(startIdx, wordLength); //pick up the character before the word to see if a " "
                        if (!char.IsSeparator(newRuntext[0]))
                        {
                            return;
                        }
                    }


                    if (startIdx == 0)
                    {
                        run1Text = text.Substring(startIdx, wordLength);;
                        if (text.Length > wordLength)
                        {
                            run2Text = text.Substring(endIdx);
                        }
                    }
                    else
                    {
                        run1Text = text.Substring(0, startIdx);
                        run2Text = text.Substring(startIdx, wordLength);
                        if (text.Length > endIdx)
                        {
                            run3Text = text.Substring(endIdx);
                        }
                    }

                    Run run1 = new Run(run1Text);
                    Run run2 = new Run(run2Text);
                    SetKeyWordColour(run1);
                    CaretPosition.Paragraph.Inlines.InsertBefore(run as Inline, run1);

                    if (!string.IsNullOrEmpty(run2Text))
                    {
                        SetKeyWordColour(run2);
                        CaretPosition.Paragraph.Inlines.InsertBefore(run as Inline, run2);
                    }
                    if (!string.IsNullOrEmpty(run3Text))
                    {
                        Run run3 = new Run(run3Text);
                        SetKeyWordColour(run3);
                        CaretPosition.Paragraph.Inlines.InsertBefore(run as Inline, run3);
                    }
                    CaretPosition.Paragraph.Inlines.Remove(run);
                }
                else
                {
                    SetKeyWordColour(run);
                }
            }
            if (string.IsNullOrEmpty(run2Text))
            {
                CaretPosition = GetPointerFromStartDocOffset(symCount);
            }
        }