protected IEnumerator decelerate()
    {
        if (_isDraggingPastExtents)
        {
            yield return(_manager.StartCoroutine(springBackToBounds(2f)));
        }
        else if (_velocities.Count > 0)          // bail out if we have no velocities!
        {
            // get the average velocity by summing all the velocities and dividing by count
            float total = 0;
            foreach (var v in _velocities)
            {
                total += v;
            }

            var avgVelocity = total / _velocities.Count;
            var elasticDecelerationModifier = 0.7f;

            while (!_isDragging)
            {
                var deltaMovement = avgVelocity * Time.deltaTime;
                var newOffset     = _scrollPosition;

                if (layoutType == UIAbstractContainer.UILayoutType.Horizontal)
                {
                    newOffset += deltaMovement;
                }
                else
                {
                    newOffset -= deltaMovement;
                }

                var absVelocity = Mathf.Abs(avgVelocity);

                // if paging is enabled once we slow down we will snap to a page
                if (pagingEnabled && absVelocity < 2500)
                {
                    // if we are past the extents let the handler below do the scrolling
                    if (!_isDraggingPastExtents)
                    {
                        scrollToNearestPage();
                    }
                    break;
                }

                // make sure we have some velocity and we are within our bounds
                if (absVelocity < 25)
                {
                    break;
                }

                // use x for horizontal and y for vertical
                float lowerBounds;
                if (layoutType == UIAbstractContainer.UILayoutType.Horizontal)
                {
                    lowerBounds = _minEdgeInset.x;
                }
                else
                {
                    lowerBounds = _minEdgeInset.y;
                }

                if (newOffset < 0 && newOffset > lowerBounds)
                {
                    _scrollPosition = newOffset;
                    layoutChildren();
                    avgVelocity *= SCROLL_DECELERATION_MODIFIER;

                    yield return(null);
                }
                else
                {
                    _isDraggingPastExtents = true;

                    _scrollPosition = newOffset;
                    layoutChildren();
                    avgVelocity *= elasticDecelerationModifier;

                    // we up the elasticDecelerationModifier each iteration
                    elasticDecelerationModifier -= 0.1f;

                    if (elasticDecelerationModifier <= 0)
                    {
                        break;
                    }

                    yield return(null);
                }
            }

            if (_isDraggingPastExtents)
            {
                yield return(_manager.StartCoroutine(springBackToBounds(0.9f)));
            }
        }
    }