function concludeRefresh()

in src/Clients/Web/winjs/js/winjs.js [28426:29353]


                function concludeRefresh() {
                    beginRefreshCount = 0;
                    refreshHistory = new Array(100);
                    refreshHistoryPos = -1;

                    indexUpdateDeferred = true;

                    keyFetchIDs = {};

                    var i,
                        j,
                        slot,
                        slotPrev,
                        slotNext,
                        slotBefore,
                        slotAfter,
                        slotRefresh,
                        slotExisting,
                        slotFirstInSequence,
                        sequenceCountOld,
                        sequencesOld = [],
                        sequenceOld,
                        sequenceOldPrev,
                        sequenceOldBestMatch,
                        sequenceCountNew,
                        sequencesNew = [],
                        sequenceNew,
                        index,
                        offset;

                    // Assign a sequence number to each refresh slot
                    sequenceCountNew = 0;
                    for (slotRefresh = refreshStart; slotRefresh; slotRefresh = slotRefresh.next) {
                        slotRefresh.sequenceNumber = sequenceCountNew;

                        if (slotRefresh.firstInSequence) {
                            slotFirstInSequence = slotRefresh;
                        }

                        if (slotRefresh.lastInSequence) {
                            sequencesNew[sequenceCountNew] = {
                                first: slotFirstInSequence,
                                last: slotRefresh,
                                matchingItems: 0
                            };
                            sequenceCountNew++;
                        }
                    }

                    // Remove unnecessary information from main slot list, and update the items
                    lastSlotReleased = null;
                    releasedSlots = 0;
                    for (slot = slotsStart.next; slot !== slotsEnd;) {
                        slotRefresh = refreshKeyMap[slot.key];
                        slotNext = slot.next;

                        if (slot !== slotListEnd) {
                            if (!slotLive(slot)) {
                                // Some more items might have been released since the refresh started.  Strip them away from the
                                // main slot list, as they'll just get in the way from now on.  Since we're discarding these, but
                                // don't know if they're actually going away, split the sequence as our starting assumption must be
                                // that the items on either side are in separate sequences.
                                deleteUnnecessarySlot(slot);
                            } else if (slot.key && !slotRefresh) {
                                // Remove items that have been deleted (or moved far away) and send removed notifications
                                deleteSlot(slot, false);
                            } else if (refreshCount === 0 || (slot.indexRequested && slot.index >= refreshCount)) {
                                // Remove items that can't exist in the list and send mirage removed notifications
                                deleteSlot(slot, true);
                            } else if (slot.item || slot.keyRequested) {
                                // Store the new item; this value will be compared with that stored in slot.item later
                                slot.itemNew = slotRefresh.item;
                            } else {
                                // Clear keys and items that have never been observed by client
                                if (slot.key) {
                                    if (!slot.keyRequested) {
                                        delete keyMap[slot.key];
                                        delete slot.key;
                                    }
                                    slot.itemNew = null;
                                }
                            }
                        }

                        slot = slotNext;
                    }

                    // Placeholders generated by itemsAtIndex should not move.  Match these to items now if possible, or merge them
                    // with existing items if necessary.
                    for (slot = slotsStart.next; slot !== slotListEnd;) {
                        slotNext = slot.next;

                        if (slot.indexRequested) {
                            slotRefresh = refreshIndexMap[slot.index];
                            if (slotRefresh) {
                                matchSlotForRefresh(slotFromSlotRefresh(slotRefresh), slot, slotRefresh);
                            }
                        }

                        slot = slotNext;
                    }

                    // Match old sequences to new sequences
                    var bestMatch,
                        bestMatchCount,
                        previousBestMatch = 0,
                        newSequenceCounts = [],
                        slotIndexRequested,
                        sequenceIndexEnd,
                        sequenceOldEnd;

                    sequenceCountOld = 0;
                    for (slot = slotsStart; slot !== slotsEnd; slot = slot.next) {
                        if (slot.firstInSequence) {
                            slotFirstInSequence = slot;
                            slotIndexRequested = null;
                            for (i = 0; i < sequenceCountNew; i++) {
                                newSequenceCounts[i] = 0;
                            }
                        }

                        if (slot.indexRequested) {
                            slotIndexRequested = slot;
                        }

                        slotRefresh = slotRefreshFromSlot(slot);
                        if (slotRefresh) {
                            newSequenceCounts[slotRefresh.sequenceNumber]++;
                        }

                        if (slot.lastInSequence) {
                            // Determine which new sequence is the best match for this old one.  Use a simple greedy algorithm to
                            // ensure the relative ordering of matched sequences is the same; out-of-order sequences will require
                            // move notifications.
                            bestMatchCount = 0;
                            for (i = previousBestMatch; i < sequenceCountNew; i++) {
                                if (bestMatchCount < newSequenceCounts[i]) {
                                    bestMatchCount = newSequenceCounts[i];
                                    bestMatch = i;
                                }
                            }

                            sequenceOld = {
                                first: slotFirstInSequence,
                                last: slot,
                                sequenceNew: (bestMatchCount > 0 ? sequencesNew[bestMatch] : undefined),
                                matchingItems: bestMatchCount
                            };

                            if (slotIndexRequested) {
                                sequenceOld.indexRequested = true;
                                sequenceOld.stationarySlot = slotIndexRequested;
                            }

                            sequencesOld[sequenceCountOld] = sequenceOld;

                            if (slot === slotListEnd) {
                                sequenceIndexEnd = sequenceCountOld;
                                sequenceOldEnd = sequenceOld;
                            }

                            sequenceCountOld++;

                            if (sequencesNew[bestMatch].first.index !== undefined) {
                                previousBestMatch = bestMatch;
                            }
                        }
                    }

                    // Special case: split the old start into a separate sequence if the new start isn't its best match
                    if (sequencesOld[0].sequenceNew !== sequencesNew[0]) {
                        splitSequence(slotsStart);
                        sequencesOld[0].first = slotsStart.next;
                        sequencesOld.unshift({
                            first: slotsStart,
                            last: slotsStart,
                            sequenceNew: sequencesNew[0],
                            matchingItems: 1
                        });
                        sequenceIndexEnd++;
                        sequenceCountOld++;
                    }

                    var listEndObserved = !slotListEnd.firstInSequence;

                    // Special case: split the old end into a separate sequence if the new end isn't its best match
                    if (sequenceOldEnd.sequenceNew !== sequencesNew[sequenceCountNew - 1]) {
                        splitSequence(slotListEnd.prev);
                        sequenceOldEnd.last = slotListEnd.prev;
                        sequenceIndexEnd++;
                        sequencesOld.splice(sequenceIndexEnd, 0, {
                            first: slotListEnd,
                            last: slotListEnd,
                            sequenceNew: sequencesNew[sequenceCountNew - 1],
                            matchingItems: 1
                        });
                        sequenceCountOld++;
                        sequenceOldEnd = sequencesOld[sequenceIndexEnd];
                    }

                    // Map new sequences to old sequences
                    for (i = 0; i < sequenceCountOld; i++) {
                        sequenceNew = sequencesOld[i].sequenceNew;
                        if (sequenceNew && sequenceNew.matchingItems < sequencesOld[i].matchingItems) {
                            sequenceNew.matchingItems = sequencesOld[i].matchingItems;
                            sequenceNew.sequenceOld = sequencesOld[i];
                        }
                    }

                    // The old end must always be the best match for the new end (if the new end is also the new start, they will
                    // be merged below).
                    sequencesNew[sequenceCountNew - 1].sequenceOld = sequenceOldEnd;
                    sequenceOldEnd.stationarySlot = slotListEnd;

                    // The old start must always be the best match for the new start
                    sequencesNew[0].sequenceOld = sequencesOld[0];
                    sequencesOld[0].stationarySlot = slotsStart;

                    // Merge additional indexed old sequences when possible

                    // First do a forward pass
                    for (i = 0; i <= sequenceIndexEnd; i++) {
                        sequenceOld = sequencesOld[i];

                        if (sequenceOld.sequenceNew && (sequenceOldBestMatch = sequenceOld.sequenceNew.sequenceOld) === sequenceOldPrev && sequenceOldPrev.last !== slotListEnd) {
                            mergeSequencesForRefresh(sequenceOldBestMatch.last);
                            sequenceOldBestMatch.last = sequenceOld.last;
                            delete sequencesOld[i];
                        } else {
                            sequenceOldPrev = sequenceOld;
                        }
                    }

                    // Now do a reverse pass
                    sequenceOldPrev = null;
                    for (i = sequenceIndexEnd; i >= 0; i--) {
                        sequenceOld = sequencesOld[i];
                        // From this point onwards, some members of sequencesOld may be undefined
                        if (sequenceOld) {
                            if (sequenceOld.sequenceNew && (sequenceOldBestMatch = sequenceOld.sequenceNew.sequenceOld) === sequenceOldPrev && sequenceOld.last !== slotListEnd) {
                                mergeSequencesForRefresh(sequenceOld.last);
                                sequenceOldBestMatch.first = sequenceOld.first;
                                delete sequencesOld[i];
                            } else {
                                sequenceOldPrev = sequenceOld;
                            }
                        }
                    }

                    // Since we may have forced the list end into a separate sequence, the mergedForRefresh flag may be incorrect
                    if (listEndObserved) {
                        delete slotListEnd.mergedForRefresh;
                    }

                    var sequencePairsToMerge = [];

                    // Find unchanged sequences without indices that can be merged with existing sequences without move
                    // notifications.
                    for (i = sequenceIndexEnd + 1; i < sequenceCountOld; i++) {
                        sequenceOld = sequencesOld[i];
                        if (sequenceOld && (!sequenceOld.sequenceNew || sequenceOld.sequenceNew.sequenceOld !== sequenceOld)) {
                            // If the order of the known items in the sequence is unchanged, then the sequence probably has not
                            // moved, but we now know where it belongs relative to at least one other sequence.
                            var orderPreserved = true,
                                slotRefreshFirst = null,
                                slotRefreshLast = null,
                                sequenceLength = 0;
                            slotRefresh = slotRefreshFromSlot(sequenceOld.first);
                            if (slotRefresh) {
                                slotRefreshFirst = slotRefreshLast = slotRefresh;
                                sequenceLength = 1;
                            }
                            for (slot = sequenceOld.first; slot !== sequenceOld.last; slot = slot.next) {
                                var slotRefreshNext = slotRefreshFromSlot(slot.next);

                                if (slotRefresh && slotRefreshNext && (slotRefresh.lastInSequence || slotRefresh.next !== slotRefreshNext)) {
                                    orderPreserved = false;
                                    break;
                                }

                                if (slotRefresh && !slotRefreshFirst) {
                                    slotRefreshFirst = slotRefreshLast = slotRefresh;
                                }

                                if (slotRefreshNext && slotRefreshFirst) {
                                    slotRefreshLast = slotRefreshNext;
                                    sequenceLength++;
                                }

                                slotRefresh = slotRefreshNext;
                            }

                            // If the stationary sequence has indices, verify that there is enough space for this sequence - if
                            // not, then something somewhere has moved after all.
                            if (orderPreserved && slotRefreshFirst && slotRefreshFirst.index !== undefined) {
                                var indexBefore;
                                if (!slotRefreshFirst.firstInSequence) {
                                    slotBefore = slotFromSlotRefresh(slotRefreshFirst.prev);
                                    if (slotBefore) {
                                        indexBefore = slotBefore.index;
                                    }
                                }

                                var indexAfter;
                                if (!slotRefreshLast.lastInSequence) {
                                    slotAfter = slotFromSlotRefresh(slotRefreshLast.next);
                                    if (slotAfter) {
                                        indexAfter = slotAfter.index;
                                    }
                                }

                                if ((!slotAfter || slotAfter.lastInSequence || slotAfter.mergedForRefresh) &&
                                        (indexBefore === undefined || indexAfter === undefined || indexAfter - indexBefore - 1 >= sequenceLength)) {
                                    sequenceOld.locationJustDetermined = true;

                                    // Mark the individual refresh slots as not requiring move notifications
                                    for (slotRefresh = slotRefreshFirst; ; slotRefresh = slotRefresh.next) {
                                        slotRefresh.locationJustDetermined = true;

                                        if (slotRefresh === slotRefreshLast) {
                                            break;
                                        }
                                    }

                                    // Store any adjacent placeholders so they can be merged once the moves and insertions have
                                    // been processed.
                                    var slotFirstInSequence = slotFromSlotRefresh(slotRefreshFirst),
                                        slotLastInSequence = slotFromSlotRefresh(slotRefreshLast);
                                    sequencePairsToMerge.push({
                                        slotBeforeSequence: (slotFirstInSequence.firstInSequence ? null : slotFirstInSequence.prev),
                                        slotFirstInSequence: slotFirstInSequence,
                                        slotLastInSequence: slotLastInSequence,
                                        slotAfterSequence: (slotLastInSequence.lastInSequence ? null : slotLastInSequence.next)
                                    });
                                }
                            }
                        }
                    }

                    // Remove placeholders in old sequences that don't map to new sequences (and don't contain requests for a
                    // specific index or key), as they no longer have meaning.
                    for (i = 0; i < sequenceCountOld; i++) {
                        sequenceOld = sequencesOld[i];
                        if (sequenceOld && !sequenceOld.indexRequested && !sequenceOld.locationJustDetermined && (!sequenceOld.sequenceNew || sequenceOld.sequenceNew.sequenceOld !== sequenceOld)) {
                            sequenceOld.sequenceNew = null;

                            slot = sequenceOld.first;

                            var sequenceEndReached;
                            do {
                                sequenceEndReached = (slot === sequenceOld.last);

                                slotNext = slot.next;

                                if (slot !== slotsStart && slot !== slotListEnd && slot !== slotsEnd && !slot.item && !slot.keyRequested) {
                                    deleteSlot(slot, true);
                                    if (sequenceOld.first === slot) {
                                        if (sequenceOld.last === slot) {
                                            delete sequencesOld[i];
                                            break;
                                        } else {
                                            sequenceOld.first = slot.next;
                                        }
                                    } else if (sequenceOld.last === slot) {
                                        sequenceOld.last = slot.prev;
                                    }
                                }

                                slot = slotNext;
                            } while (!sequenceEndReached);
                        }
                    }

                    // Locate boundaries of new items in new sequences
                    for (i = 0; i < sequenceCountNew; i++) {
                        sequenceNew = sequencesNew[i];
                        for (slotRefresh = sequenceNew.first; !slotFromSlotRefresh(slotRefresh) && !slotRefresh.lastInSequence; slotRefresh = slotRefresh.next) {
                            /*@empty*/
                        }
                        if (slotRefresh.lastInSequence && !slotFromSlotRefresh(slotRefresh)) {
                            sequenceNew.firstInner = sequenceNew.lastInner = null;
                        } else {
                            sequenceNew.firstInner = slotRefresh;
                            for (slotRefresh = sequenceNew.last; !slotFromSlotRefresh(slotRefresh) ; slotRefresh = slotRefresh.prev) {
                                /*@empty*/
                            }
                            sequenceNew.lastInner = slotRefresh;
                        }
                    }

                    // Determine which items to move
                    for (i = 0; i < sequenceCountNew; i++) {
                        sequenceNew = sequencesNew[i];
                        if (sequenceNew && sequenceNew.firstInner) {
                            sequenceOld = sequenceNew.sequenceOld;
                            if (sequenceOld) {
                                // Number the slots in each new sequence with their offset in the corresponding old sequence (or
                                // undefined if in a different old sequence).
                                var ordinal = 0;
                                for (slot = sequenceOld.first; true; slot = slot.next, ordinal++) {
                                    slotRefresh = slotRefreshFromSlot(slot);
                                    if (slotRefresh && slotRefresh.sequenceNumber === sequenceNew.firstInner.sequenceNumber) {
                                        slotRefresh.ordinal = ordinal;
                                    }

                                    if (slot.lastInSequence) {
                                        break;
                                    }
                                }

                                // Determine longest subsequence of items that are in the same order before and after
                                var piles = [];
                                for (slotRefresh = sequenceNew.firstInner; true; slotRefresh = slotRefresh.next) {
                                    ordinal = slotRefresh.ordinal;
                                    if (ordinal !== undefined) {
                                        var searchFirst = 0,
                                            searchLast = piles.length - 1;
                                        while (searchFirst <= searchLast) {
                                            var searchMidpoint = Math.floor(0.5 * (searchFirst + searchLast));
                                            if (piles[searchMidpoint].ordinal < ordinal) {
                                                searchFirst = searchMidpoint + 1;
                                            } else {
                                                searchLast = searchMidpoint - 1;
                                            }
                                        }
                                        piles[searchFirst] = slotRefresh;
                                        if (searchFirst > 0) {
                                            slotRefresh.predecessor = piles[searchFirst - 1];
                                        }
                                    }

                                    if (slotRefresh === sequenceNew.lastInner) {
                                        break;
                                    }
                                }

                                // The items in the longest ordered subsequence don't move; everything else does
                                var stationaryItems = [],
                                    stationaryItemCount = piles.length;
                                slotRefresh = piles[stationaryItemCount - 1];
                                for (j = stationaryItemCount; j--;) {
                                    slotRefresh.stationary = true;
                                    stationaryItems[j] = slotRefresh;
                                    slotRefresh = slotRefresh.predecessor;
                                }
                                sequenceOld.stationarySlot = slotFromSlotRefresh(stationaryItems[0]);

                                // Try to match new items before the first stationary item to placeholders
                                slotRefresh = stationaryItems[0];
                                slot = slotFromSlotRefresh(slotRefresh);
                                slotPrev = slot.prev;
                                var sequenceBoundaryReached = slot.firstInSequence;
                                while (!slotRefresh.firstInSequence) {
                                    slotRefresh = slotRefresh.prev;
                                    slotExisting = slotFromSlotRefresh(slotRefresh);
                                    if (!slotExisting || slotRefresh.locationJustDetermined) {
                                        // Find the next placeholder walking backwards
                                        while (!sequenceBoundaryReached && slotPrev !== slotsStart) {
                                            slot = slotPrev;
                                            slotPrev = slot.prev;
                                            sequenceBoundaryReached = slot.firstInSequence;

                                            if (updateSlotForRefresh(slotExisting, slot, slotRefresh)) {
                                                break;
                                            }
                                        }
                                    }
                                }

                                // Try to match new items between stationary items to placeholders
                                for (j = 0; j < stationaryItemCount - 1; j++) {
                                    slotRefresh = stationaryItems[j];
                                    slot = slotFromSlotRefresh(slotRefresh);
                                    var slotRefreshStop = stationaryItems[j + 1],
                                        slotRefreshMergePoint = null,
                                        slotStop = slotFromSlotRefresh(slotRefreshStop),
                                        slotExisting;
                                    // Find all the new items
                                    slotNext = slot.next;
                                    for (slotRefresh = slotRefresh.next; slotRefresh !== slotRefreshStop && !slotRefreshMergePoint && slot !== slotStop; slotRefresh = slotRefresh.next) {
                                        slotExisting = slotFromSlotRefresh(slotRefresh);
                                        if (!slotExisting || slotRefresh.locationJustDetermined) {
                                            // Find the next placeholder
                                            while (slotNext !== slotStop) {
                                                // If a merge point is reached, match the remainder of the placeholders by walking backwards
                                                if (slotNext.mergedForRefresh) {
                                                    slotRefreshMergePoint = slotRefresh.prev;
                                                    break;
                                                }

                                                slot = slotNext;
                                                slotNext = slot.next;

                                                if (updateSlotForRefresh(slotExisting, slot, slotRefresh)) {
                                                    break;
                                                }
                                            }
                                        }
                                    }

                                    // Walk backwards to the first merge point if necessary
                                    if (slotRefreshMergePoint) {
                                        slotPrev = slotStop.prev;
                                        for (slotRefresh = slotRefreshStop.prev; slotRefresh !== slotRefreshMergePoint && slotStop !== slot; slotRefresh = slotRefresh.prev) {
                                            slotExisting = slotFromSlotRefresh(slotRefresh);
                                            if (!slotExisting || slotRefresh.locationJustDetermined) {
                                                // Find the next placeholder walking backwards
                                                while (slotPrev !== slot) {
                                                    slotStop = slotPrev;
                                                    slotPrev = slotStop.prev;

                                                    if (updateSlotForRefresh(slotExisting, slotStop, slotRefresh)) {
                                                        break;
                                                    }
                                                }
                                            }
                                        }
                                    }

                                    // Delete remaining placeholders, sending notifications
                                    while (slotNext !== slotStop) {
                                        slot = slotNext;
                                        slotNext = slot.next;

                                        if (slot !== slotsStart && isPlaceholder(slot) && !slot.keyRequested) {
                                            // This might occur due to two sequences - requested by different clients - being
                                            // merged.  However, since only sequences with indices are merged, if this placehholder
                                            // is no longer necessary, it means an item actually was removed, so this doesn't count
                                            // as a mirage.
                                            deleteSlot(slot);
                                        }
                                    }
                                }

                                // Try to match new items after the last stationary item to placeholders
                                slotRefresh = stationaryItems[stationaryItemCount - 1];
                                slot = slotFromSlotRefresh(slotRefresh);
                                slotNext = slot.next;
                                sequenceBoundaryReached = slot.lastInSequence;
                                while (!slotRefresh.lastInSequence) {
                                    slotRefresh = slotRefresh.next;
                                    slotExisting = slotFromSlotRefresh(slotRefresh);
                                    if (!slotExisting || slotRefresh.locationJustDetermined) {
                                        // Find the next placeholder
                                        while (!sequenceBoundaryReached && slotNext !== slotListEnd) {
                                            slot = slotNext;
                                            slotNext = slot.next;
                                            sequenceBoundaryReached = slot.lastInSequence;

                                            if (updateSlotForRefresh(slotExisting, slot, slotRefresh)) {
                                                break;
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }

                    // Move items and send notifications
                    for (i = 0; i < sequenceCountNew; i++) {
                        sequenceNew = sequencesNew[i];

                        if (sequenceNew.firstInner) {
                            slotPrev = null;
                            for (slotRefresh = sequenceNew.firstInner; true; slotRefresh = slotRefresh.next) {
                                slot = slotFromSlotRefresh(slotRefresh);
                                if (slot) {
                                    if (!slotRefresh.stationary) {
                                        var slotMoveBefore,
                                            mergeWithPrev = false,
                                            mergeWithNext = false;
                                        if (slotPrev) {
                                            slotMoveBefore = slotPrev.next;
                                            mergeWithPrev = true;
                                        } else {
                                            // The first item will be inserted before the first stationary item, so find that now
                                            var slotRefreshStationary;
                                            for (slotRefreshStationary = sequenceNew.firstInner; !slotRefreshStationary.stationary && slotRefreshStationary !== sequenceNew.lastInner; slotRefreshStationary = slotRefreshStationary.next) {
                                                /*@empty*/
                                            }

                                            if (!slotRefreshStationary.stationary) {
                                                // There are no stationary items, as all the items are moving from another old
                                                // sequence.

                                                index = slotRefresh.index;

                                                // Find the best place to insert the new sequence
                                                if (index === 0) {
                                                    // Index 0 is a special case
                                                    slotMoveBefore = slotsStart.next;
                                                    mergeWithPrev = true;
                                                } else if (index === undefined) {
                                                    slotMoveBefore = slotsEnd;
                                                } else {
                                                    // Use a linear search; unlike successorFromIndex, prefer the last insertion
                                                    // point between sequences over the precise index
                                                    slotMoveBefore = slotsStart.next;
                                                    var lastSequenceStart = null;
                                                    while (true) {
                                                        if (slotMoveBefore.firstInSequence) {
                                                            lastSequenceStart = slotMoveBefore;
                                                        }

                                                        if ((index < slotMoveBefore.index && lastSequenceStart) || slotMoveBefore === slotListEnd) {
                                                            break;
                                                        }

                                                        slotMoveBefore = slotMoveBefore.next;
                                                    }

                                                    if (!slotMoveBefore.firstInSequence && lastSequenceStart) {
                                                        slotMoveBefore = lastSequenceStart;
                                                    }
                                                }
                                            } else {
                                                slotMoveBefore = slotFromSlotRefresh(slotRefreshStationary);
                                                mergeWithNext = true;
                                            }
                                        }

                                        // Preserve merge boundaries
                                        if (slot.mergedForRefresh) {
                                            delete slot.mergedForRefresh;
                                            if (!slot.lastInSequence) {
                                                slot.next.mergedForRefresh = true;
                                            }
                                        }

                                        mergeWithPrev = mergeWithPrev || slotRefresh.mergeWithPrev;
                                        mergeWithNext = mergeWithNext || slotRefresh.mergeWithNext;

                                        var skipNotifications = slotRefresh.locationJustDetermined;

                                        moveSlot(slot, slotMoveBefore, mergeWithPrev, mergeWithNext, skipNotifications);

                                        if (skipNotifications && mergeWithNext) {
                                            // Since this item was moved without a notification, this is an implicit merge of
                                            // sequences.  Mark the item's successor as mergedForRefresh.
                                            slotMoveBefore.mergedForRefresh = true;
                                        }
                                    }

                                    slotPrev = slot;
                                }

                                if (slotRefresh === sequenceNew.lastInner) {
                                    break;
                                }
                            }
                        }
                    }

                    // Insert new items (with new indices) and send notifications
                    for (i = 0; i < sequenceCountNew; i++) {
                        sequenceNew = sequencesNew[i];

                        if (sequenceNew.firstInner) {
                            slotPrev = null;
                            for (slotRefresh = sequenceNew.firstInner; true; slotRefresh = slotRefresh.next) {
                                slot = slotFromSlotRefresh(slotRefresh);
                                if (!slot) {
                                    var slotInsertBefore;
                                    if (slotPrev) {
                                        slotInsertBefore = slotPrev.next;
                                    } else {
                                        // The first item will be inserted *before* the first old item, so find that now
                                        var slotRefreshOld;
                                        for (slotRefreshOld = sequenceNew.firstInner; !slotFromSlotRefresh(slotRefreshOld) ; slotRefreshOld = slotRefreshOld.next) {
                                            /*@empty*/
                                        }
                                        slotInsertBefore = slotFromSlotRefresh(slotRefreshOld);
                                    }

                                    // Create a new slot for the item
                                    slot = addNewSlotFromRefresh(slotRefresh, slotInsertBefore, !!slotPrev);

                                    var slotRefreshNext = slotRefreshFromSlot(slotInsertBefore);

                                    if (!slotInsertBefore.mergedForRefresh && (!slotRefreshNext || !slotRefreshNext.locationJustDetermined)) {
                                        prepareSlotItem(slot);

                                        // Send the notification after the insertion
                                        sendInsertedNotification(slot);
                                    }
                                }
                                slotPrev = slot;

                                if (slotRefresh === sequenceNew.lastInner) {
                                    break;
                                }
                            }
                        }
                    }

                    // Rebuild the indexMap from scratch, so it is possible to detect colliding indices
                    indexMap = [];

                    // Send indexChanged and changed notifications
                    var indexFirst = -1;
                    for (slot = slotsStart, offset = 0; slot !== slotsEnd; offset++) {
                        var slotNext = slot.next;

                        if (slot.firstInSequence) {
                            slotFirstInSequence = slot;
                            offset = 0;
                        }

                        if (indexFirst === undefined) {
                            var indexNew = indexForRefresh(slot);
                            if (indexNew !== undefined) {
                                indexFirst = indexNew - offset;
                            }
                        }

                        // See if the next slot would cause a contradiction, in which case split the sequences
                        if (indexFirst !== undefined && !slot.lastInSequence) {
                            var indexNewNext = indexForRefresh(slot.next);
                            if (indexNewNext !== undefined && indexNewNext !== indexFirst + offset + 1) {
                                splitSequence(slot);

                                // 'Move' the items in-place individually, so move notifications are sent.  In rare cases, this
                                // will result in multiple move notifications being sent for a given item, but that's fine.
                                var first = true;
                                for (var slotMove = slot.next, lastInSequence = false; !lastInSequence && slotMove !== slotListEnd;) {
                                    var slotMoveNext = slotMove.next;

                                    lastInSequence = slotMove.lastInSequence;

                                    moveSlot(slotMove, slotMoveNext, !first, false);

                                    first = false;
                                    slotMove = slotMoveNext;
                                }
                            }
                        }

                        if (slot.lastInSequence) {
                            index = indexFirst;
                            for (var slotUpdate = slotFirstInSequence; slotUpdate !== slotNext;) {
                                var slotUpdateNext = slotUpdate.next;

                                if (index >= refreshCount && slotUpdate !== slotListEnd) {
                                    deleteSlot(slotUpdate, true);
                                } else {
                                    var slotWithIndex = indexMap[index];

                                    if (index !== slotUpdate.index) {
                                        delete indexMap[index];
                                        changeSlotIndex(slotUpdate, index);
                                    } else if (+index === index && indexMap[index] !== slotUpdate) {
                                        indexMap[index] = slotUpdate;
                                    }

                                    if (slotUpdate.itemNew) {
                                        updateSlotItem(slotUpdate);
                                    }

                                    if (slotWithIndex) {
                                        // Two slots' indices have collided - merge them
                                        if (slotUpdate.key) {
                                            sendMirageNotifications(slotUpdate, slotWithIndex, slotUpdate.bindingMap);
                                            mergeSlots(slotUpdate, slotWithIndex);
                                            if (+index === index) {
                                                indexMap[index] = slotUpdate;
                                            }
                                        } else {
                                            sendMirageNotifications(slotWithIndex, slotUpdate, slotWithIndex.bindingMap);
                                            mergeSlots(slotWithIndex, slotUpdate);
                                            if (+index === index) {
                                                indexMap[index] = slotWithIndex;
                                            }
                                        }
                                    }

                                    if (+index === index) {
                                        index++;
                                    }
                                }

                                slotUpdate = slotUpdateNext;
                            }

                            indexFirst = undefined;
                        }

                        slot = slotNext;
                    }

                    // See if any sequences need to be moved and/or merged
                    var indexMax = -2,
                        listEndReached;

                    for (slot = slotsStart, offset = 0; slot !== slotsEnd; offset++) {
                        var slotNext = slot.next;

                        if (slot.firstInSequence) {
                            slotFirstInSequence = slot;
                            offset = 0;
                        }

                        // Clean up during this pass
                        delete slot.mergedForRefresh;

                        if (slot.lastInSequence) {
                            // Move sequence if necessary
                            if (slotFirstInSequence.index === undefined) {
                                slotBefore = slotFirstInSequence.prev;
                                var slotRefreshBefore;
                                if (slotBefore && (slotRefreshBefore = slotRefreshFromSlot(slotBefore)) && !slotRefreshBefore.lastInSequence &&
                                        (slotRefresh = slotRefreshFromSlot(slot)) && slotRefresh.prev === slotRefreshBefore) {
                                    moveSequenceAfter(slotBefore, slotFirstInSequence, slot);
                                    mergeSequences(slotBefore);
                                } else if (slot !== slotListEnd && !listEndReached) {
                                    moveSequenceBefore(slotsEnd, slotFirstInSequence, slot);
                                }
                            } else {
                                if (indexMax < slot.index && !listEndReached) {
                                    indexMax = slot.index;
                                } else {
                                    // Find the correct insertion point
                                    for (slotAfter = slotsStart.next; slotAfter.index < slot.index; slotAfter = slotAfter.next) {
                                        /*@empty*/
                                    }

                                    // Move the items individually, so move notifications are sent
                                    for (var slotMove = slotFirstInSequence; slotMove !== slotNext;) {
                                        var slotMoveNext = slotMove.next;
                                        slotRefresh = slotRefreshFromSlot(slotMove);
                                        moveSlot(slotMove, slotAfter, slotAfter.prev.index === slotMove.index - 1, slotAfter.index === slotMove.index + 1, slotRefresh && slotRefresh.locationJustDetermined);
                                        slotMove = slotMoveNext;
                                    }
                                }

                                // Store slotBefore here since the sequence might have just been moved
                                slotBefore = slotFirstInSequence.prev;

                                // See if this sequence should be merged with the previous one
                                if (slotBefore && slotBefore.index === slotFirstInSequence.index - 1) {
                                    mergeSequences(slotBefore);
                                }
                            }
                        }

                        if (slot === slotListEnd) {
                            listEndReached = true;
                        }

                        slot = slotNext;
                    }

                    indexUpdateDeferred = false;

                    // Now that all the sequences have been moved, merge any colliding slots
                    mergeSequencePairs(sequencePairsToMerge);

                    // Send countChanged notification
                    if (refreshCount !== undefined && refreshCount !== knownCount) {
                        changeCount(refreshCount);
                    }

                    finishNotifications();

                    // Before discarding the refresh slot list, see if any fetch requests can be completed by pretending each range
                    // of refresh slots is an incoming array of results.
                    var fetchResults = [];
                    for (i = 0; i < sequenceCountNew; i++) {
                        sequenceNew = sequencesNew[i];

                        var results = [];

                        slot = null;
                        offset = 0;

                        var slotOffset;

                        for (slotRefresh = sequenceNew.first; true; slotRefresh = slotRefresh.next, offset++) {
                            if (slotRefresh === refreshStart) {
                                results.push(startMarker);
                            } else if (slotRefresh === refreshEnd) {
                                results.push(endMarker);
                            } else {
                                results.push(slotRefresh.item);

                                if (!slot) {
                                    slot = slotFromSlotRefresh(slotRefresh);
                                    slotOffset = offset;
                                }
                            }

                            if (slotRefresh.lastInSequence) {
                                break;
                            }
                        }

                        if (slot) {
                            fetchResults.push({
                                slot: slot,
                                results: results,
                                offset: slotOffset
                            });
                        }
                    }

                    resetRefreshState();
                    refreshInProgress = false;

                    // Complete any promises for newly obtained items
                    callFetchCompleteCallbacks();

                    // Now process the 'extra' results from the refresh list
                    for (i = 0; i < fetchResults.length; i++) {
                        var fetchResult = fetchResults[i];
                        processResults(fetchResult.slot, fetchResult.results, fetchResult.offset, knownCount, fetchResult.slot.index);
                    }

                    if (refreshSignal) {
                        var signal = refreshSignal;

                        refreshSignal = null;

                        signal.complete();
                    }

                    // Finally, kick-start fetches for any remaining placeholders
                    postFetch();
                }