public void InterstitialGapItemCoverage()
        {
            var model   = new ApplicationModel();
            var gapItem = new InterstitialGapItem(null, model, model.Source, 0, 1);

            Assert.AreEqual(":", gapItem.Content);
        }
        private void UpdateSuggestionsView(int _lowerBound, int _upperLimit, bool isComplete)
        {
            var maxItemCount    = Math.Min(Count, Model.DisplayRows - 1);
            var suggestionLists = CreateSuggestionLists(_lowerBound, _upperLimit, maxItemCount);

            var suggestions             = new List <IReadOnlyList <ITile> >();
            var suggestionInterstitials = new List <ITile>();

            var previousIndex = -1;

            foreach (var pair in suggestionLists)
            {
                var index = pair.Key;

                if (AreAdjacentIndices(previousIndex + 1, index))
                {
                    // Item contiguous with previous one, so allow it to dictate its interstitial.
                    EmitPriorInterstitial(index);
                }
                else
                {
                    if (previousIndex != -1)
                    {
                        // Not the first item, so items that are displayed adjacent to one another, but are not actually contiguous.
                        EmitInterstitial(previousIndex + 1, index);
                    }
                    else if (_lowerBound < index)
                    {
                        // First item, but within the bounds of the items being displayed, so need interstitial to start of bounds.
                        EmitInterstitial(_lowerBound, index);
                    }
                    else
                    {
                        Debug.Assert(index <= _lowerBound);

                        // First item of bounded area, so emit interstitial from start to this item.
                        var interstitialItem = new InterstitialGapItem(Model.LastTile, Model, this, 0, Math.Max(_lowerBound, maxItemCount));
                        suggestionInterstitials.Add(interstitialItem);
                    }
                }

                suggestions.Add(pair.Value);

                previousIndex = index;
            }

            if (AreAdjacentIndices(previousIndex + 1, Count))
            {
                // Last item in source, so allow it to dictate the final interstitial.
                EmitPriorInterstitial(Count);
            }
            else if (previousIndex + 1 < _upperLimit)
            {
                // Last item of bounded items, but not necessary last in source.
                EmitInterstitial(previousIndex + 1, _upperLimit);
            }
            else
            {
                Debug.Assert(_upperLimit < Count);

                // Last item was last of bounded items, but not of source, so emit interstitial to end.
                EmitInterstitial(Math.Min(previousIndex + 1, Count - maxItemCount), Count);
            }

            Model.UpdateSuggestions(this, _lowerBound, _upperLimit, isComplete, suggestions, suggestionInterstitials);

            void EmitPriorInterstitial(int index)
            {
                var interstitialItem = CreatePriorInterstitial(index);
                var actualItem       = interstitialItem ?? new InterstitialNonItem(Model);

                suggestionInterstitials.Add(actualItem);
            }

            void EmitInterstitial(int min, int lim)
            {
                var effectiveMin = min;
                var effectiveLim = lim;

                if (min != 0 && CreatePriorInterstitial(min) != null)
                {
                    // If we're top is going to replace custom interstitial, extend top by one item.
                    effectiveMin--;
                }

                if (lim != Count && CreatePriorInterstitial(lim) != null)
                {
                    // If we're at the bottom and going to replace custom interstitial, extend bottom by one item.
                    effectiveLim++;
                }

                var underrun    = Math.Max(0, maxItemCount - (effectiveLim - effectiveMin));
                var adjustedMin = Math.Max(0, effectiveMin - underrun / 2);
                var adjustedLim = Math.Max(adjustedMin + maxItemCount, effectiveLim);

                var overrun = adjustedLim - Count;

                if (0 < overrun)
                {
                    adjustedMin -= overrun;
                    adjustedLim -= overrun;
                }

                var interstitial = new InterstitialGapItem(Model.LastTile, Model, this, adjustedMin, adjustedLim);

                suggestionInterstitials.Add(interstitial);
            }
        }