anchor.diff:        walker(child);
     }
   
  -  void insertChildRenderObject(RenderObjectWrapper child, dynamic slot) {
  +  void insertChildRenderObject(RenderObjectWrapper child, Widget slot) {
       final renderObject = this.renderObject; // TODO(ianh): Remove this once the analyzer is cleverer
  -    assert(slot == null || slot is RenderObject);
  +    RenderObject nextSibling = slot != null ? slot.renderObject : null;
  +    assert(nextSibling == null || nextSibling is RenderObject);
       assert(renderObject is ContainerRenderObjectMixin);
  -    renderObject.add(child.renderObject, before: slot);
  +    renderObject.add(child.renderObject, before: nextSibling);
       assert(renderObject == this.renderObject); // TODO(ianh): Remove this once the analyzer is cleverer
     }
   
  
positive.code:   bool retainStatefulNodeIfPossible(StatefulComponent newNode) {
      assert(!_disqualifiedFromEverAppearingAgain);
      assert(newNode != null);
      assert(runtimeType == newNode.runtimeType);
      assert(key == newNode.key);
      assert(_child != null);
      newNode._disqualifiedFromEverAppearingAgain = true;
  
  
negative.code:     assert(renderObject is ContainerRenderObjectMixin);
      assert(old == null || old.renderObject == renderObject);
  
      // This attempts to diff the new child list (this.children) with
      // the old child list (old.children), and update our renderObject
      // accordingly.
  
      // The cases it tries to optimise for are:
      //  - the old list is empty
      //  - the lists are identical
      //  - there is an insertion or removal of one or more widgets in
      //    only one place in the list
      // If a widget with a key is in both lists, it will be synced.
      // Widgets without keys might be synced but there is no guarantee.
  
      // The general approach is to sync the entire new list backwards, as follows:
      // 1. Walk the lists from the top until you no longer have
      //    matching nodes. We don't sync these yet, but we now know to
      //    skip them below. We do this because at each sync we need to
      //    pass the pointer to the new next widget as the slot, which
      //    we can't do until we've synced the next child.
      // 2. Walk the lists from the bottom, syncing nodes, until you no
      //    longer have matching nodes.
      // At this point we narrowed the old and new lists to the point
      // where the nodes no longer match.
      // 3. Walk the narrowed part of the old list to get the list of
      //    keys and sync null with non-keyed items.
      // 4. Walk the narrowed part of the new list backwards:
      //     * Sync unkeyed items with null
      //     * Sync keyed items with the source if it exists, else with null.
      // 5. Walk the top list again but backwards, syncing the nodes.
      // 6. Sync null with any items in the list of keys that are still
      //    mounted.
  
      final List<Widget> newChildren = children;
      final List<Widget> oldChildren = old == null ? const <Widget>[] : old.children;
      int childrenTop = 0;
      int newChildrenBottom = newChildren.length-1;
      int oldChildrenBottom = oldChildren.length-1;
  
      // top of the lists
      while ((childrenTop <= oldChildrenBottom) && (childrenTop <= newChildrenBottom)) {
        Widget oldChild = oldChildren[childrenTop];
        assert(oldChild.mounted);
        Widget newChild = newChildren[childrenTop];
        assert(newChild == oldChild || !newChild.mounted);
        if (!_canSync(oldChild, newChild))
          break;
        childrenTop += 1;
      }
  
      Widget nextSibling;
  
      // bottom of the lists
      while ((childrenTop <= oldChildrenBottom) && (childrenTop <= newChildrenBottom)) {
        Widget oldChild = oldChildren[oldChildrenBottom];
        assert(oldChild.mounted);
        Widget newChild = newChildren[newChildrenBottom];
        assert(newChild == oldChild || !newChild.mounted);
        if (!_canSync(oldChild, newChild))
          break;
        newChild = syncChild(newChild, oldChild, nextSibling);
        assert(newChild.mounted);
        assert(oldChild == newChild || !oldChild.mounted);
        newChildren[newChildrenBottom] = newChild;
        nextSibling = newChild;
        oldChildrenBottom -= 1;
        newChildrenBottom -= 1;
      }
  
      // middle of the lists - old list
      bool haveOldNodes = childrenTop <= oldChildrenBottom;
      Map<Key, Widget> oldKeyedChildren;
      if (haveOldNodes) {
        oldKeyedChildren = new Map<Key, Widget>();
        while (childrenTop <= oldChildrenBottom) {
          Widget oldChild = oldChildren[oldChildrenBottom];
          assert(oldChild.mounted);
          if (oldChild.key != null) {
            oldKeyedChildren[oldChild.key] = oldChild;
          } else {
            syncChild(null, oldChild, null);
          }
          oldChildrenBottom -= 1;
        }      
      }
  
      // middle of the lists - new list
      while (childrenTop <= newChildrenBottom) {
        Widget oldChild;
        Widget newChild = newChildren[newChildrenBottom];
        if (haveOldNodes) {
          Key key = newChild.key;
          if (key != null) {
            oldChild = oldKeyedChildren[newChild.key];
            if (oldChild != null) {
              if (oldChild.runtimeType != newChild.runtimeType)
                oldChild = null;
              oldKeyedChildren.remove(key);
            }
          }
        }
        assert(newChild == oldChild || !newChild.mounted);
        newChild = syncChild(newChild, oldChild, nextSibling);
        assert(newChild.mounted);
        assert(oldChild == newChild || oldChild == null || !oldChild.mounted);
        newChildren[newChildrenBottom] = newChild;
        nextSibling = newChild;
        newChildrenBottom -= 1;
      }
      assert(oldChildrenBottom == newChildrenBottom);
      assert(childrenTop == newChildrenBottom+1);
  
      // now sync the top of the list
      while (childrenTop > 0) {
        childrenTop -= 1;
        Widget oldChild = oldChildren[childrenTop];
        assert(oldChild.mounted);
        Widget newChild = newChildren[childrenTop];
        assert(newChild == oldChild || !newChild.mounted);
        assert(_canSync(oldChild, newChild));
        newChild = syncChild(newChild, oldChild, nextSibling);
        assert(newChild.mounted);
        assert(oldChild == newChild || oldChild == null || !oldChild.mounted);
        newChildren[childrenTop] = newChild;
        nextSibling = newChild;
      }
  
      if (haveOldNodes && !oldKeyedChildren.isEmpty) {
        for (Widget oldChild in oldKeyedChildren.values)
          syncChild(null, oldChild, null);
      }
  
      assert(renderObject == this.renderObject); // TODO(ianh): Remove this once the analyzer is cleverer
  