internal ISuggestionItem GetNextItem(ITile predecessor, string prefix, int token)
        {
            ISuggestionItem item;

            if (token == 0)
            {
                item = _wordVocabularySource.CreateSuggestedWordItem(prefix);
            }
            else
            {
                item = new SuggestedSpellingSequenceItem(predecessor, this, prefix, char.ConvertFromUtf32(token));
            }

            return(item);
        }
        private SortedList <int, IReadOnlyList <ITile> > CreateFinalPredictionsList()
        {
            var predictionsList = new SortedList <int, IReadOnlyList <ITile> >();

            for (var position = 0; position < _nascents.Count; position++)
            {
                var predictions            = new List <ITile>();
                var coreCompoundPrediction = _nascents[position]._list;
                var headPrediction         = coreCompoundPrediction[0];

                var headWord = headPrediction.RawText;
                if (headWord[0] == '\0')
                {
                    if (headWord == StringTokens.StopString)
                    {
                        var tile = new TailStopItem(_source.Model.LastTile, _source);
                        predictions.Add(tile);
                    }
                    else
                    {
                        var command = (TileCommand)Enum.Parse(typeof(TileCommand), headWord.Substring(1));
                        var tile    = new CommandItem(_source.Model.LastTile, _source, command);
                        predictions.Add(tile);
                    }
                }
                else
                {
                    var item = _source.CreateSuggestedWordItem(headWord);
                    predictions.Add(item);

                    for (var corePosition = 1; corePosition < coreCompoundPrediction.Count; corePosition++)
                    {
                        var tailPrediction = coreCompoundPrediction[corePosition];
                        var tailWord       = tailPrediction.RawText;
                        Debug.Assert(tailWord.StartsWith(headWord, StringComparison.OrdinalIgnoreCase));
                        if (!headWord.StartsWith(tailWord))
                        {
                            item = new ExtendedSuggestedWordItem(_source.Model.LastTile, _source, tailWord, tailWord.Substring(headWord.Length));

                            predictions.Add(item);

                            headWord = tailWord;
                        }
                        else
                        {
                            Debug.WriteLine($"Unexpected situation of non-equal words being each others prefix: {headWord} + {tailWord}");
                        }
                    }

                    var followOn = _nascents[position]._followOn;
                    if (followOn != null)
                    {
                        var firstCreatedItem = _source.GetNextItem(item, followOn.Token);
                        var newItem          = firstCreatedItem as SuggestedWordItem;
                        predictions.Add(firstCreatedItem);

                        var firstFollowOnMaker  = _nascents[position]._followOnMaker;
                        var followOnMaker       = firstFollowOnMaker.CreateNextPredictionMaker(followOn.Token, null);
                        var isFollowOnFirstWord = followOn.IsFollowOnFirstWord;
                        var done = newItem == null;
                        while (!done && predictions.Count < _maxListItemCount)
                        {
                            var followOnPrediction = GetTopPrediction(followOnMaker, isFollowOnFirstWord);
                            if (followOnPrediction != null)
                            {
                                item = newItem;
                                var createdItem = _source.GetNextItem(item, followOnPrediction.Token);
                                newItem       = createdItem as SuggestedWordItem;
                                followOnMaker = followOnMaker.CreateNextPredictionMaker(followOnPrediction.Token, null);
                                predictions.Add(createdItem);
                                isFollowOnFirstWord = followOnPrediction.IsFollowOnFirstWord;

                                if (newItem == null)
                                {
                                    done = true;
                                }
                            }
                            else
                            {
                                done = true;
                            }
                        }

                        // item = newItem;
                    }
                }

                predictionsList.Add(headPrediction.Index, predictions);
            }

            return(predictionsList);
        }