anchor.diff:        }
         if (ancestor != null && badAncestors.isEmpty)
           return true;
  -      debugPrint(widget.debugDescribeInvalidAncestorChain(
  +      throw new WidgetError('Incorrect use of ParentDataWidget.', widget.debugDescribeInvalidAncestorChain(
           description: "$this",
           ownershipChain: parent.debugGetOwnershipChain(10),
           foundValidAncestor: ancestor != null,
           badAncestors: badAncestors
         ));
  -      assert('Incorrect use of ParentDataWidget. See console log for details.' == true);
  -      return true;
       });
       super.mount(parent, slot);
     }
  
positive.code:     // dirty, e.g. if they have a builder callback. (Builder callbacks have a
      // 'BuildContext' argument which you can pass to Theme.of() and other
      // InheritedWidget APIs which eventually trigger a rebuild.)
      debugPrint('$runtimeType failed to implement reinvokeBuilders(), but got marked dirty');
      assert(() {
        'reinvokeBuilders() not implemented';
        return false;
      });
    }
  
  
negative.code:     assert(widget == newWidget);
      _children = updateChildren(_children, widget.children);
    }
  }
  
  class WidgetError extends Error {
    WidgetError(String message, [ String rawDetails = '' ]) {
      rawDetails = rawDetails.trimRight(); // remove trailing newlines
      if (rawDetails != '')
        _message = '$message\n$rawDetails';
      else
        _message = message;
    }
    String _message;
    String toString() => _message;
  }
  
  typedef void WidgetsExceptionHandler(String context, dynamic exception, StackTrace stack);
  