private ContentPresenter GetAndAddElementFor(ItemTuple tuple)
        {
            ContentPresenter cp = null;
            bool isNew = false;

            switch (tuple.ItemType)
            {
                case ItemType.Item:
                    if (_recycledItems.Count > 0)
                    {
                        cp = _recycledItems.Pop();
                    }
                    else
                    {
                        isNew = true;
                        cp = new ContentPresenter();
                        cp.ContentTemplate = ItemTemplate;

                        GestureService.GetGestureListener(cp).Tap += OnItemTap;
                    }
                    break;
                case ItemType.GroupHeader:
                    if (_recycledGroupHeaders.Count > 0)
                    {
                        cp = _recycledGroupHeaders.Pop();
                    }
                    else
                    {
                        isNew = true;
                        cp = new ContentPresenter();
                        cp.ContentTemplate = GroupHeaderTemplate;

                        GestureService.GetGestureListener(cp).Tap += GroupHeaderTap;
                    }
                    break;
                case ItemType.GroupFooter:
                    if (_recycledGroupFooters.Count > 0)
                    {
                        cp = _recycledGroupFooters.Pop();
                    }
                    else
                    {
                        isNew = true;
                        cp = new ContentPresenter();
                        cp.ContentTemplate = GroupFooterTemplate;
                    }
                    break;
                case ItemType.ListHeader:
                    if (_recycledListHeader != null)
                    {
                        cp = _recycledListHeader;
                        _recycledListHeader = null;
                    }
                    else
                    {
                        isNew = true;
                        cp = new ContentPresenter();
                        cp.ContentTemplate = ListHeaderTemplate;
                    }
                    break;
                case ItemType.ListFooter:
                    if (_recycledListFooter != null)
                    {
                        cp = _recycledListFooter;
                        _recycledListFooter = null;
                    }
                    else
                    {
                        isNew = true;
                        cp = new ContentPresenter();
                        cp.ContentTemplate = ListFooterTemplate;
                    }
                    break;
                default:
                    break;
            }

            if (isNew)
            {
                cp.CacheMode = new BitmapCache();
                _itemsPanel.Children.Add(cp);
                cp.SizeChanged += new SizeChangedEventHandler(OnItemSizeChanged);
            }

            if (cp != null)
            {
                if (cp.Width != _availableSize.Width)
                {
                    cp.Width = _availableSize.Width;
                }
                cp.Content = tuple.Item;
                cp.Visibility = Visibility.Visible;
            }

            EventHandler<LinkUnlinkEventArgs> handler = Link;
            if (handler != null)
            {
                handler(this, new LinkUnlinkEventArgs(cp));
            }
            
            tuple.ContentPresenter = cp;
            cp.Measure(_availableSize);            
            ++_resolvedCount;
            return cp;
        }
        private void OnAdd(int startingIndex, ItemType itemType, object group, IList newItems)
        {
            int resolvedLastIndex = _resolvedFirstIndex + _resolvedCount - 1;

            // Perform the Add operation

            ItemTuple[] newData = new ItemTuple[newItems.Count];
            for (int index = 0; index < newItems.Count; ++index)
            {
                newData[index] = new ItemTuple() { ItemType = itemType, Group = group, Item = newItems[index] };
            }

            if (startingIndex <= _resolvedFirstIndex || startingIndex > resolvedLastIndex)
            {
                // If the operation is completely outside the bounds of the resolved items, then it can just happen.
                
                if (startingIndex <= _resolvedFirstIndex)
                {
                    if (_resolvedCount > 0)
                    {
                        _resolvedFirstIndex += newItems.Count;
                    }
                    else
                    {
                        _resolvedFirstIndex = 0;
                    }
                }
            }
            else if (startingIndex < _screenFirstIndex)
            {
                int removeCount = startingIndex - _resolvedFirstIndex + 1;

                while (removeCount-- > 0)
                {
                    RecycleFirst();
                }

                _resolvedFirstIndex += newItems.Count;
            }
            else
            {
                int removeCount = _resolvedCount - startingIndex + _resolvedFirstIndex;

                while (removeCount-- > 0)
                {
                    RecycleLast();
                }
            }

            // Perform the Add operation
            _flattenedItems.InsertRange(startingIndex, newData);
        }
        private void RemoveAndAddToRecycleBin(ItemTuple tuple)
        {
            ContentPresenter cp = tuple.ContentPresenter;

            switch (tuple.ItemType)
            {
                case ItemType.Item:
                    _recycledItems.Push(cp);
                    break;
                case ItemType.GroupHeader:
                    _recycledGroupHeaders.Push(cp);
                    break;
                case ItemType.GroupFooter:
                    _recycledGroupFooters.Push(cp);
                    break;
                case ItemType.ListHeader:
                    Debug.Assert(_recycledListHeader == null);
                    _recycledListHeader = cp;
                    break;
                case ItemType.ListFooter:
                    Debug.Assert(_recycledListFooter == null);
                    _recycledListFooter = cp;
                    break;
            }

            EventHandler<LinkUnlinkEventArgs> handler = Unlink;
            if (handler != null)
            {
                handler(this, new LinkUnlinkEventArgs(cp));
            }
            tuple.ContentPresenter = null;
            cp.Content = null;
            cp.SetExtraData(-1, 0);

            --_resolvedCount;
        }