anchor.diff:    bool get opaque => _opaque;
     bool _opaque;
     void set opaque (bool value) {
  +    assert(_overlay != null);
       if (_opaque == value)
         return;
  -    _opaque = value;
  -    markNeedsBuild();
  +    _overlay.setState(() {
  +      _opaque = value;
  +    });
     }
   
  -  OverlayState _state;
  +  OverlayState _overlay;
  +  final GlobalKey _key = new GlobalKey();
   
     /// Remove this entry from the overlay.
     void remove() {
  -    _state?._remove(this);
  -    _state = null;
  +    _overlay?._remove(this);
  +    _overlay = null;
     }
   
     /// Cause this entry to rebuild during the next pipeline flush.
     ///
     /// You need to call this function if the output of [builder] has changed.
     void markNeedsBuild() {
  -    // TODO(ianh): find a way to make this not rebuild the entire overlay
  -    _state?.setState(() {});
  +    _key.currentState?.setState(() { /* the state that changed is in the builder */ });
     }
   
     String toString() => '$runtimeType@$hashCode(opaque: $opaque)';
  +}
  +
  +class _OverlayEntry extends StatefulComponent {
  +  _OverlayEntry(OverlayEntry entry) : entry = entry, super(key: entry._key);
  +  final OverlayEntry entry;
  +  _OverlayEntryState createState() => new _OverlayEntryState();
  +}
  +class _OverlayEntryState extends State<_OverlayEntry> {
  +  Widget build(BuildContext context) => config.entry.builder(context);
   }
   
   /// A [Stack] of entries that can be managed independently.
  
positive.code:   /// If [above] is non-null, the entry is inserted just above [above].
    /// Otherwise, the entry is inserted on top.
    void insert(OverlayEntry entry, { OverlayEntry above }) {
      assert(entry._state == null);
      assert(above == null || (above._state == this && _entries.contains(above)));
      entry._state = this;
      setState(() {
        int index = above == null ? _entries.length : _entries.indexOf(above) + 1;
        _entries.insert(index, entry);
  
negative.code:   /// If [above] is non-null, the entries are inserted just above [above].
    /// Otherwise, the entries are inserted on top.
    void insertAll(Iterable<OverlayEntry> entries, { OverlayEntry above }) {
      assert(above == null || (above._overlay == this && _entries.contains(above)));
      for (OverlayEntry entry in entries) {
        assert(entry._overlay == null);
        entry._overlay = this;
      }
      setState(() {
        int index = above == null ? _entries.length : _entries.indexOf(above) + 1;
  