diff --git a/packages/flutter/lib/src/widgets/framework.dart b/packages/flutter/lib/src/widgets/framework.dart
index c42c958..12e2802 100644
--- a/packages/flutter/lib/src/widgets/framework.dart
+++ b/packages/flutter/lib/src/widgets/framework.dart
@@ -1870,19 +1870,6 @@
   /// render object is usually short.
   Size get size;
 
-  /// Registers this build context with [ancestor] such that when
-  /// [ancestor]'s widget changes this build context is rebuilt.
-  ///
-  /// Returns `ancestor.widget`.
-  ///
-  /// This method is rarely called directly. Most applications should use
-  /// [inheritFromWidgetOfExactType], which calls this method after finding
-  /// the appropriate [InheritedElement] ancestor.
-  ///
-  /// All of the qualifications about when [inheritFromWidgetOfExactType] can
-  /// be called apply to this method as well.
-  InheritedWidget inheritFromElement(InheritedElement ancestor, { Object aspect });
-
   /// Obtains the nearest widget of the given type, which must be the type of a
   /// concrete [InheritedWidget] subclass, and registers this build context with
   /// that widget such that when that widget changes (or a new widget of that
@@ -1892,7 +1879,7 @@
   /// This is typically called implicitly from `of()` static methods, e.g.
   /// [Theme.of].
   ///
-  /// This method should not be called from widget constructors or from
+  /// This should not be called from widget constructors or from
   /// [State.initState] methods, because those methods would not get called
   /// again if the inherited value were to change. To ensure that the widget
   /// correctly updates itself when the inherited value changes, only call this
@@ -1905,9 +1892,9 @@
   /// It is safe to use this method from [State.deactivate], which is called
   /// whenever the widget is removed from the tree.
   ///
-  /// It is also possible to call this method from interaction event handlers
-  /// (e.g. gesture callbacks) or timers, to obtain a value once, if that value
-  /// is not going to be cached and reused later.
+  /// It is also possible to call this from interaction event handlers (e.g.
+  /// gesture callbacks) or timers, to obtain a value once, if that value is not
+  /// going to be cached and reused later.
   ///
   /// Calling this method is O(1) with a small constant factor, but will lead to
   /// the widget being rebuilt more often.
@@ -1917,12 +1904,7 @@
   /// called, whenever changes occur relating to that widget until the next time
   /// the widget or one of its ancestors is moved (for example, because an
   /// ancestor is added or removed).
-  ///
-  /// The [aspect] parameter is only used when [targetType] is an
-  /// [InheritedWidget] subclasses that supports partial updates, like
-  /// [InheritedModel]. It specifies what "aspect" of the inherited
-  /// widget this context depends on.
-  InheritedWidget inheritFromWidgetOfExactType(Type targetType, { Object aspect });
+  InheritedWidget inheritFromWidgetOfExactType(Type targetType);
 
   /// Obtains the element corresponding to the nearest widget of the given type,
   /// which must be the type of a concrete [InheritedWidget] subclass.
@@ -3244,31 +3226,15 @@
   }
 
   @override
-  InheritedWidget inheritFromElement(InheritedElement ancestor, { Object aspect }) {
-    assert(ancestor != null);
-    assert(() {
-      if (_parent == null) {
-        // We're being deactivated, see deactivateChild()
-        return true;
-      }
-      Element element = _parent;
-      while (ancestor != element && element != null)
-        element = element._parent;
-      return ancestor == element;
-    }());
-    _dependencies ??= new HashSet<InheritedElement>();
-    _dependencies.add(ancestor);
-    ancestor.updateDependencies(this, aspect);
-    return ancestor.widget;
-  }
-
-  @override
-  InheritedWidget inheritFromWidgetOfExactType(Type targetType, { Object aspect }) {
+  InheritedWidget inheritFromWidgetOfExactType(Type targetType) {
     assert(_debugCheckStateIsActiveForAncestorLookup());
     final InheritedElement ancestor = _inheritedWidgets == null ? null : _inheritedWidgets[targetType];
     if (ancestor != null) {
       assert(ancestor is InheritedElement);
-      return inheritFromElement(ancestor, aspect: aspect);
+      _dependencies ??= new HashSet<InheritedElement>();
+      _dependencies.add(ancestor);
+      ancestor._dependents.add(this);
+      return ancestor.widget;
     }
     _hadUnsatisfiedDependencies = true;
     return null;
@@ -3879,13 +3845,11 @@
   }
 
   @override
-  InheritedWidget inheritFromElement(Element ancestor, { Object aspect }) {
-    assert(ancestor != null);
+  InheritedWidget inheritFromWidgetOfExactType(Type targetType) {
     assert(() {
-      final Type targetType = ancestor.widget.runtimeType;
       if (state._debugLifecycleState == _StateLifecycle.created) {
         throw new FlutterError(
-          'inheritFromWidgetOfExactType($targetType) or inheritFromElement() was called before ${_state.runtimeType}.initState() completed.\n'
+          'inheritFromWidgetOfExactType($targetType) was called before ${_state.runtimeType}.initState() completed.\n'
           'When an inherited widget changes, for example if the value of Theme.of() changes, '
           'its dependent widgets are rebuilt. If the dependent widget\'s reference to '
           'the inherited widget is in a constructor or an initState() method, '
@@ -3898,7 +3862,7 @@
       }
       if (state._debugLifecycleState == _StateLifecycle.defunct) {
         throw new FlutterError(
-          'inheritFromWidgetOfExactType($targetType) or inheritFromElement() was called after dispose(): $this\n'
+          'inheritFromWidgetOfExactType($targetType) called after dispose(): $this\n'
           'This error happens if you call inheritFromWidgetOfExactType() on the '
           'BuildContext for a widget that no longer appears in the widget tree '
           '(e.g., whose parent widget no longer includes the widget in its '
@@ -3918,7 +3882,7 @@
       }
       return true;
     }());
-    return super.inheritFromElement(ancestor, aspect: aspect);
+    return super.inheritFromWidgetOfExactType(targetType);
   }
 
   @override
@@ -4068,7 +4032,7 @@
   @override
   InheritedWidget get widget => super.widget;
 
-  final Map<Element, Object> _dependents = new HashMap<Element, Object>();
+  final Set<Element> _dependents = new HashSet<Element>();
 
   @override
   void _updateInheritance() {
@@ -4090,110 +4054,6 @@
     super.debugDeactivated();
   }
 
-  /// Returns the dependencies value recorded for [dependent]
-  /// with [setDependencies].
-  ///
-  /// Each dependent element is mapped to a single object value
-  /// which represents how the element depends on this
-  /// [InheritedElement]. This value is null by default and by default
-  /// dependent elements are rebuilt unconditionally.
-  ///
-  /// Subclasses can manage these values with [updateDependencies]
-  /// so that they can selectively rebuild dependents in
-  /// [notifyDependents].
-  ///
-  /// This method is typically only called in overrides of [updateDependencies].
-  ///
-  /// See also:
-  ///
-  ///  * [updateDependencies], which is called each time a dependency is
-  ///    created with [inheritFromWidgetOfExactType].
-  ///  * [setDependencies], which sets dependencies value for a dependent
-  ///    element.
-  ///  * [notifyDependent], which can be overridden to use a dependent's
-  ///    dependencies value to decide if the dependent needs to be rebuilt.
-  ///  * [InheritedModel], which is an example of a class that uses this method
-  ///    to manage dependency values.
-  @protected
-  Object getDependencies(Element dependent) {
-    return _dependents[dependent];
-  }
-
-  /// Sets the value returned by [getDependencies] value for [dependent].
-  ///
-  /// Each dependent element is mapped to a single object value
-  /// which represents how the element depends on this
-  /// [InheritedElement]. The [updateDependencies] method sets this value to
-  /// null by default so that dependent elements are rebuilt unconditionally.
-  ///
-  /// Subclasses can manage these values with [updateDependencies]
-  /// so that they can selectively rebuild dependents in [notifyDependents].
-  ///
-  /// This method is typically only called in overrides of [updateDependencies].
-  ///
-  /// See also:
-  ///
-  ///  * [updateDependencies], which is called each time a dependency is
-  ///    created with [inheritFromWidgetOfExactType].
-  ///  * [getDependencies], which returns the current value for a dependent
-  ///    element.
-  ///  * [notifyDependent], which can be overridden to use a dependent's
-  ///    [getDependencies] value to decide if the dependent needs to be rebuilt.
-  ///  * [InheritedModel], which is an example of a class that uses this method
-  ///    to manage dependency values.
-  @protected
-  void setDependencies(Element dependent, Object value) {
-    _dependents[dependent] = value;
-  }
-
-  /// Called by [inheritFromWidgetOfExactType] when a new [dependent] is added.
-  ///
-  /// Each dependent element can be mapped to a single object value with
-  /// [setDependencies]. This method can lookup the existing dependencies with
-  /// [getDependencies].
-  ///
-  /// By default this method sets the inherited dependencies for [dependent]
-  /// to null. This only serves to record an unconditional dependency on
-  /// [dependent].
-  ///
-  /// Subclasses can manage their own dependencies values so that they
-  /// can selectively rebuild dependents in [notifyDependents].
-  ///
-  /// See also:
-  ///
-  ///  * [getDependencies], which returns the current value for a dependent
-  ///    element.
-  ///  * [setDependencies], which sets the value for a dependent element.
-  ///  * [notifyDependent], which can be overridden to use a dependent's
-  ///    dependencies value to decide if the dependent needs to be rebuilt.
-  ///  * [InheritedModel], which is an example of a class that uses this method
-  ///    to manage dependency values.
-  @protected
-  void updateDependencies(Element dependent, Object aspect) {
-    setDependencies(dependent, null);
-  }
-
-  /// Called by [notifyClients] for each dependent.
-  ///
-  /// Calls `dependent.didChangeDependencies()` by default.
-  ///
-  /// Subclasses can override this method to selectively call
-  /// [didChangeDependencies] based on the value of [getDependencies].
-  ///
-  /// See also:
-  ///
-  ///  * [updateDependencies], which is called each time a dependency is
-  ///    created with [inheritFromWidgetOfExactType].
-  ///  * [getDependencies], which returns the current value for a dependent
-  ///    element.
-  ///  * [setDependencies], which sets the value for a dependent element.
-  ///  * [InheritedModel], which is an example of a class that uses this method
-  ///    to manage dependency values.
-  @protected
-  void notifyDependent(covariant InheritedWidget oldWidget, Element dependent) {
-    dependent.didChangeDependencies();
-  }
-
   /// Calls [Element.didChangeDependencies] of all dependent elements, if
   /// [InheritedWidget.updateShouldNotify] returns true.
   ///
@@ -4210,7 +4070,7 @@
     if (!widget.updateShouldNotify(oldWidget))
       return;
     assert(_debugCheckOwnerBuildTargetExists('notifyClients'));
-    for (Element dependent in _dependents.keys) {
+    for (Element dependent in _dependents) {
       assert(() {
         // check that it really is our descendant
         Element ancestor = dependent._parent;
@@ -4220,7 +4080,7 @@
       }());
       // check that it really depends on us
       assert(dependent._dependencies.contains(this));
-      notifyDependent(oldWidget, dependent);
+      dependent.didChangeDependencies();
     }
   }
 }
diff --git a/packages/flutter/lib/src/widgets/inherited_model.dart b/packages/flutter/lib/src/widgets/inherited_model.dart
deleted file mode 100644
index 87dcf60..0000000
--- a/packages/flutter/lib/src/widgets/inherited_model.dart
+++ /dev/null
@@ -1,197 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-import 'dart:collection';
-
-import 'package:flutter/foundation.dart';
-
-import 'framework.dart';
-
-/// An [InheritedWidget] that's intended to be used as the base class for
-/// models whose dependents may only depend on one part or "aspect" of the
-/// overall model.
-///
-/// An inherited widget's dependents are unconditionally rebuilt when the
-/// inherited widget changes per [InheritedWidget.updateShouldNotify].
-/// This widget is similar except that dependents aren't rebuilt
-/// unconditionally.
-///
-/// Widgets that depend on an [InheritedModel] qualify their dependence
-/// with a value that indicates what "aspect" of the model they depend
-/// on. When the model is rebuilt, dependents will also be rebuilt, but
-/// only if there was a change in the model that corresponds to the aspect
-/// they provided.
-///
-/// The type parameter `T` is the type of the model aspect objects.
-///
-/// Widgets create a dependency on an [InheritedModel] with a static method:
-/// [InheritedModel.inheritFrom]. This method's `context` parameter
-/// defines the subtree that will be rebuilt when the model changes.
-/// Typically the `inheritFrom` method is called from a model-specific
-/// static `of` method. For example:
-///
-/// ```dart
-/// class MyModel extends InheritedModel<String> {
-///   // ...
-///   static MyModel of(BuildContext context, String aspect) {
-///     return InheritedModel.inheritFrom<MyModel>(context, aspect: aspect);
-///   }
-/// }
-/// ```
-///
-/// Calling `MyModel.of(context, 'foo')` means that `context` should only
-/// be rebuilt when the `foo` aspect of `MyModel` changes. If the aspect
-/// is null, then the model supports all aspects.
-///
-/// When the inherited model is rebuilt the [updateShouldNotify] and
-/// [updateShouldNotifyDependent] methods are used to decide what
-/// should be rebuilt.  If [updateShouldNotify] returns true, then the
-/// inherited model's [updateShouldNotifyDependent] method is tested for
-/// each dependent and the set of aspect objects it depends on.
-/// The [updateShouldNotifyDependent] method must compare the set of aspect
-/// dependencies with the changes in the model itself.
-///
-/// For example:
-///
-/// ```dart
-/// class ABModel extends InheritedModel<String> {
-///   ABModel({ this.a, this.b, Widget child }) : super(child: child);
-///
-///   final int a;
-///   final int b;
-///
-///   @override
-///   bool updateShouldNotify(ABModel old) {
-///     return a != old.a || b != old.b;
-///   }
-///
-///   @override
-///   bool updateShouldNotifyDependent(ABModel old, Set<String> aspects) {
-///     return (a != old.a && aspects.contains('a'))
-///         || (b != old.b && aspects.contains('b'))
-///   }
-///
-///   // ...
-/// }
-/// ```
-///
-/// In the previous example the dependencies checked by
-/// [updateShouldNotifyDependent] are just the aspect strings passed to
-/// `inheritFromWidgetOfExactType`. They're represented as a [Set] because
-/// one Widget can depend on more than one aspect of the model.
-/// If a widget depends on the model but doesn't specify an aspect,
-/// then changes in the model will cause the widget to be rebuilt
-/// unconditionally.
-abstract class InheritedModel<T> extends InheritedWidget {
-  /// Creates an inherited widget that supports dependencies qualified by
-  /// "aspects", i.e. a descendant widget can indicate that it should
-  /// only be rebuilt if a specific aspect of the model changes.
-  const InheritedModel({ Key key, Widget child }) : super(key: key, child: child);
-
-  @override
-  InheritedModelElement<T> createElement() => new InheritedModelElement<T>(this);
-
-  /// Return true if the changes between this model and [oldWidget] match any
-  /// of the [dependencies].
-  @protected
-  bool updateShouldNotifyDependent(covariant InheritedModel<T> oldWidget, Set<T> dependencies);
-
-  /// Returns true if this model supports the given [aspect].
-  ///
-  /// Returns true by default: this model supports all aspects.
-  ///
-  /// Subclasses may override this method to indicate that they do not support
-  /// all model aspects. This is typically done when a model can be used
-  /// to "shadow" some aspects of an ancestor.
-  @protected
-  bool isSupportedAspect(Object aspect) => true;
-
-  // The [result] will be a list of all of context's type T ancestors concluding
-  // with the one that supports the specified model [aspect].
-  static Iterable<InheritedElement> _findModels<T extends InheritedModel<Object>>(BuildContext context, Object aspect) sync* {
-    final InheritedElement model = context.ancestorInheritedElementForWidgetOfExactType(T);
-    if (model == null)
-      return;
-
-    yield model;
-
-    assert(model.widget is T);
-    final T modelWidget = model.widget;
-    if (modelWidget.isSupportedAspect(aspect))
-      return;
-
-    Element modelParent;
-    model.visitAncestorElements((Element ancestor) {
-      modelParent = ancestor;
-      return false;
-    });
-    if (modelParent == null)
-      return;
-
-    yield* _findModels<T>(modelParent, aspect);
-  }
-
-  /// Makes [context] dependent on the specified [aspect] of an [InheritedModel]
-  /// of type T.
-  ///
-  /// When the given [aspect] of the model changes, the [context] will be
-  /// rebuilt. The [updateShouldNotifyDependent] method must determine if a
-  /// change in the model widget corresponds to an [aspect] value.
-  ///
-  /// The dependencies created by this method target all [InheritedModel] ancestors
-  /// of type T up to and including the first one for which [isSupportedAspect]
-  /// returns true.
-  ///
-  /// If [aspect] is null this method is the same as
-  /// `context.inheritFromWidgetOfExactType(T)`.
-  static T inheritFrom<T extends InheritedModel<Object>>(BuildContext context, { Object aspect }) {
-    if (aspect == null)
-      return context.inheritFromWidgetOfExactType(T);
-
-    // Create a dependency on all of the type T ancestor models up until
-    // a model is found for which isSupportedAspect(aspect) is true.
-    final List<InheritedElement> models = _findModels<T>(context, aspect).toList();
-    final InheritedElement lastModel = models.last;
-    for (InheritedElement model in models) {
-      final T value = context.inheritFromElement(model, aspect: aspect);
-      if (model == lastModel)
-        return value;
-    }
-
-    assert(false);
-    return null;
-  }
-}
-
-/// An [Element] that uses a [InheritedModel] as its configuration.
-class InheritedModelElement<T> extends InheritedElement {
-  /// Creates an element that uses the given widget as its configuration.
-  InheritedModelElement(InheritedModel<T> widget) : super(widget);
-
-  @override
-  InheritedModel<T> get widget => super.widget;
-
-  @override
-  void updateDependencies(Element dependent, Object aspect) {
-    final Set<T> dependencies = getDependencies(dependent);
-    if (dependencies != null && dependencies.isEmpty)
-      return;
-
-    if (aspect == null) {
-      setDependencies(dependent, new HashSet<T>());
-    } else {
-      assert(aspect is T);
-      setDependencies(dependent, (dependencies ?? new HashSet<T>())..add(aspect));
-    }
-  }
-
-  @override
-  void notifyDependent(InheritedModel<T> oldWidget, Element dependent) {
-    final Set<T> dependencies = getDependencies(dependent);
-    if (dependencies == null)
-      return;
-    if (dependencies.isEmpty || widget.updateShouldNotifyDependent(oldWidget, dependencies))
-      dependent.didChangeDependencies();
-  }
-}
diff --git a/packages/flutter/lib/widgets.dart b/packages/flutter/lib/widgets.dart
index 8dc2fbc..72920b0 100644
--- a/packages/flutter/lib/widgets.dart
+++ b/packages/flutter/lib/widgets.dart
@@ -46,7 +46,6 @@
 export 'src/widgets/image.dart';
 export 'src/widgets/image_icon.dart';
 export 'src/widgets/implicit_animations.dart';
-export 'src/widgets/inherited_model.dart';
 export 'src/widgets/layout_builder.dart';
 export 'src/widgets/list_wheel_scroll_view.dart';
 export 'src/widgets/localizations.dart';
diff --git a/packages/flutter/test/widgets/inherited_model.dart b/packages/flutter/test/widgets/inherited_model.dart
deleted file mode 100644
index e69de29..0000000
--- a/packages/flutter/test/widgets/inherited_model.dart
+++ /dev/null
diff --git a/packages/flutter/test/widgets/inherited_model_test.dart b/packages/flutter/test/widgets/inherited_model_test.dart
deleted file mode 100644
index aec404f..0000000
--- a/packages/flutter/test/widgets/inherited_model_test.dart
+++ /dev/null
@@ -1,461 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-import 'package:flutter_test/flutter_test.dart';
-
-import 'package:flutter/foundation.dart';
-import 'package:flutter/material.dart';
-
-// A simple "flat" InheritedModel: the data model is just 3 integer
-// valued fields: a, b, c.
-class ABCModel extends InheritedModel<String> {
-  const ABCModel({
-    Key key,
-    this.a,
-    this.b,
-    this.c,
-    this.aspects,
-    Widget child,
-  }) : super(key: key, child: child);
-
-  final int a;
-  final int b;
-  final int c;
-
-  // The aspects (fields) of this model that widgets can depend on with
-  // inheritFrom.
-  //
-  // This property is null by default, which means that the model supports
-  // all 3 fields.
-  final Set<String> aspects;
-
-  @override
-  bool isSupportedAspect(Object aspect) {
-    return aspect == null || aspects == null || aspects.contains(aspect);
-  }
-
-  @override
-  bool updateShouldNotify(ABCModel old) {
-    return !setEquals<String>(aspects, old.aspects) || a != old.a || b != old.b || c != old.c;
-  }
-
-  @override
-  bool updateShouldNotifyDependent(ABCModel old, Set<String> dependencies) {
-    return !setEquals<String>(aspects, old.aspects)
-        || (a != old.a && dependencies.contains('a'))
-        || (b != old.b && dependencies.contains('b'))
-        || (c != old.c && dependencies.contains('c'));
-  }
-
-  static ABCModel of(BuildContext context, { String fieldName }) {
-    return InheritedModel.inheritFrom<ABCModel>(context, aspect: fieldName);
-  }
-}
-
-class ShowABCField extends StatefulWidget {
-  const ShowABCField({ Key key, this.fieldName }) : super(key: key);
-
-  final String fieldName;
-
-  @override
-  _ShowABCFieldState createState() => new _ShowABCFieldState();
-}
-
-class _ShowABCFieldState extends State<ShowABCField> {
-  int _buildCount = 0;
-
-  @override
-  Widget build(BuildContext context) {
-    final ABCModel abc = ABCModel.of(context, fieldName: widget.fieldName);
-    final int value = widget.fieldName == 'a' ? abc.a : (widget.fieldName == 'b' ? abc.b : abc.c);
-    return new Text('${widget.fieldName}: $value [${_buildCount++}]');
-  }
-}
-
-void main() {
-  testWidgets('InheritedModel basics', (WidgetTester tester) async {
-    int _a = 0;
-    int _b = 1;
-    int _c = 2;
-
-    final Widget abcPage = new StatefulBuilder(
-      builder: (BuildContext context, StateSetter setState) {
-        const Widget showA = ShowABCField(fieldName: 'a');
-        const Widget showB = ShowABCField(fieldName: 'b');
-        const Widget showC = ShowABCField(fieldName: 'c');
-
-        // Unconditionally depends on the ABCModel: rebuilt when any
-        // aspect of the model changes.
-        final Widget showABC = new Builder(
-          builder: (BuildContext context) {
-            final ABCModel abc = ABCModel.of(context);
-            return new Text('a: ${abc.a} b: ${abc.b} c: ${abc.c}');
-          }
-        );
-
-        return new Scaffold(
-          body: new StatefulBuilder(
-            builder: (BuildContext context, StateSetter setState) {
-              return new ABCModel(
-                a: _a,
-                b: _b,
-                c: _c,
-                child: new Center(
-                  child: new Column(
-                    mainAxisSize: MainAxisSize.min,
-                    children: <Widget>[
-                      showA,
-                      showB,
-                      showC,
-                      showABC,
-                      new RaisedButton(
-                        child: const Text('Increment a'),
-                        onPressed: () {
-                          // Rebuilds the ABCModel which triggers a rebuild
-                          // of showA because showA depends on the 'a' aspect
-                          // of the ABCModel.
-                          setState(() { _a += 1; });
-                        },
-                      ),
-                      new RaisedButton(
-                        child: const Text('Increment b'),
-                        onPressed: () {
-                          // Rebuilds the ABCModel which triggers a rebuild
-                          // of showB because showB depends on the 'b' aspect
-                          // of the ABCModel.
-                          setState(() { _b += 1; });
-                        },
-                      ),
-                      new RaisedButton(
-                        child: const Text('Increment c'),
-                        onPressed: () {
-                          // Rebuilds the ABCModel which triggers a rebuild
-                          // of showC because showC depends on the 'c' aspect
-                          // of the ABCModel.
-                          setState(() { _c += 1; });
-                        },
-                      ),
-                    ],
-                  ),
-                ),
-              );
-            },
-          ),
-        );
-      },
-    );
-
-    await tester.pumpWidget(new MaterialApp(home: abcPage));
-
-    expect(find.text('a: 0 [0]'), findsOneWidget);
-    expect(find.text('b: 1 [0]'), findsOneWidget);
-    expect(find.text('c: 2 [0]'), findsOneWidget);
-    expect(find.text('a: 0 b: 1 c: 2'), findsOneWidget);
-
-    await tester.tap(find.text('Increment a'));
-    await tester.pumpAndSettle();
-    // Verify that field 'a' was incremented, but only the showA
-    // and showABC widgets were rebuilt.
-    expect(find.text('a: 1 [1]'), findsOneWidget);
-    expect(find.text('b: 1 [0]'), findsOneWidget);
-    expect(find.text('c: 2 [0]'), findsOneWidget);
-    expect(find.text('a: 1 b: 1 c: 2'), findsOneWidget);
-
-    // Verify that field 'a' was incremented, but only the showA
-    // and showABC widgets were rebuilt.
-    await tester.tap(find.text('Increment a'));
-    await tester.pumpAndSettle();
-    expect(find.text('a: 2 [2]'), findsOneWidget);
-    expect(find.text('b: 1 [0]'), findsOneWidget);
-    expect(find.text('c: 2 [0]'), findsOneWidget);
-    expect(find.text('a: 2 b: 1 c: 2'), findsOneWidget);
-
-    // Verify that field 'b' was incremented, but only the showB
-    // and showABC widgets were rebuilt.
-    await tester.tap(find.text('Increment b'));
-    await tester.pumpAndSettle();
-    expect(find.text('a: 2 [2]'), findsOneWidget);
-    expect(find.text('b: 2 [1]'), findsOneWidget);
-    expect(find.text('c: 2 [0]'), findsOneWidget);
-    expect(find.text('a: 2 b: 2 c: 2'), findsOneWidget);
-
-    // Verify that field 'c' was incremented, but only the showC
-    // and showABC widgets were rebuilt.
-    await tester.tap(find.text('Increment c'));
-    await tester.pumpAndSettle();
-    expect(find.text('a: 2 [2]'), findsOneWidget);
-    expect(find.text('b: 2 [1]'), findsOneWidget);
-    expect(find.text('c: 3 [1]'), findsOneWidget);
-    expect(find.text('a: 2 b: 2 c: 3'), findsOneWidget);
-  });
-
-  testWidgets('Inner InheritedModel shadows the outer one', (WidgetTester tester) async {
-    int _a = 0;
-    int _b = 1;
-    int _c = 2;
-
-    // Same as in abcPage in the "InheritedModel basics" test except:
-    // there are two ABCModels and the inner model's "a" and "b"
-    // properties shadow (override) the outer model. Further complicating
-    // matters: the inner model only supports the model's "a" aspect,
-    // so showB and showC will depend on the outer model.
-    final Widget abcPage = new StatefulBuilder(
-      builder: (BuildContext context, StateSetter setState) {
-        const Widget showA = ShowABCField(fieldName: 'a');
-        const Widget showB = ShowABCField(fieldName: 'b');
-        const Widget showC = ShowABCField(fieldName: 'c');
-
-        // Unconditionally depends on the closest ABCModel ancestor.
-        // Which is the inner model, for which b,c are null.
-        final Widget showABC = new Builder(
-          builder: (BuildContext context) {
-            final ABCModel abc = ABCModel.of(context);
-            return new Text('a: ${abc.a} b: ${abc.b} c: ${abc.c}', style: Theme.of(context).textTheme.title);
-          }
-        );
-
-        return new Scaffold(
-          body: new StatefulBuilder(
-            builder: (BuildContext context, StateSetter setState) {
-              return new ABCModel( // The "outer" model
-                a: _a,
-                b: _b,
-                c: _c,
-                child: new ABCModel( // The "inner" model
-                  a: 100 + _a,
-                  b: 100 + _b,
-                  aspects: new Set<String>.of(<String>['a']),
-                  child: new Center(
-                    child: new Column(
-                      mainAxisSize: MainAxisSize.min,
-                      children: <Widget>[
-                        showA,
-                        showB,
-                        showC,
-                        const SizedBox(height: 24.0),
-                        showABC,
-                        const SizedBox(height: 24.0),
-                        new RaisedButton(
-                          child: const Text('Increment a'),
-                          onPressed: () {
-                            setState(() { _a += 1; });
-                          },
-                        ),
-                        new RaisedButton(
-                          child: const Text('Increment b'),
-                          onPressed: () {
-                            setState(() { _b += 1; });
-                          },
-                        ),
-                        new RaisedButton(
-                          child: const Text('Increment c'),
-                          onPressed: () {
-                            setState(() { _c += 1; });
-                          },
-                        ),
-                      ],
-                    ),
-                  ),
-                ),
-              );
-            },
-          ),
-        );
-      },
-    );
-
-    await tester.pumpWidget(new MaterialApp(home: abcPage));
-    expect(find.text('a: 100 [0]'), findsOneWidget);
-    expect(find.text('b: 1 [0]'), findsOneWidget);
-    expect(find.text('c: 2 [0]'), findsOneWidget);
-    expect(find.text('a: 100 b: 101 c: null'), findsOneWidget);
-
-    await tester.tap(find.text('Increment a'));
-    await tester.pumpAndSettle();
-    // Verify that field 'a' was incremented, but only the showA
-    // and showABC widgets were rebuilt.
-    expect(find.text('a: 101 [1]'), findsOneWidget);
-    expect(find.text('b: 1 [0]'), findsOneWidget);
-    expect(find.text('c: 2 [0]'), findsOneWidget);
-    expect(find.text('a: 101 b: 101 c: null'), findsOneWidget);
-
-    await tester.tap(find.text('Increment a'));
-    await tester.pumpAndSettle();
-    // Verify that field 'a' was incremented, but only the showA
-    // and showABC widgets were rebuilt.
-    expect(find.text('a: 102 [2]'), findsOneWidget);
-    expect(find.text('b: 1 [0]'), findsOneWidget);
-    expect(find.text('c: 2 [0]'), findsOneWidget);
-    expect(find.text('a: 102 b: 101 c: null'), findsOneWidget);
-
-    // Verify that field 'b' was incremented, but only the showB
-    // and showABC widgets were rebuilt.
-    await tester.tap(find.text('Increment b'));
-    await tester.pumpAndSettle();
-    expect(find.text('a: 102 [2]'), findsOneWidget);
-    expect(find.text('b: 2 [1]'), findsOneWidget);
-    expect(find.text('c: 2 [0]'), findsOneWidget);
-    expect(find.text('a: 102 b: 102 c: null'), findsOneWidget);
-
-    // Verify that field 'c' was incremented, but only the showC
-    // and showABC widgets were rebuilt.
-    await tester.tap(find.text('Increment c'));
-    await tester.pumpAndSettle();
-    expect(find.text('a: 102 [2]'), findsOneWidget);
-    expect(find.text('b: 2 [1]'), findsOneWidget);
-    expect(find.text('c: 3 [1]'), findsOneWidget);
-    expect(find.text('a: 102 b: 102 c: null'), findsOneWidget);
-  });
-
-  testWidgets('InheritedModel inner models supported aspect change', (WidgetTester tester) async {
-    int _a = 0;
-    int _b = 1;
-    int _c = 2;
-    Set<String> _innerModelAspects = new Set<String>.of(<String>['a']);
-
-    // Same as in abcPage in the "Inner InheritedModel shadows the outer one"
-    // test except: the "Add b aspect" changes adds 'b' to the set of
-    // aspects supported by the inner model.
-    final Widget abcPage = new StatefulBuilder(
-      builder: (BuildContext context, StateSetter setState) {
-        const Widget showA = ShowABCField(fieldName: 'a');
-        const Widget showB = ShowABCField(fieldName: 'b');
-        const Widget showC = ShowABCField(fieldName: 'c');
-
-        // Unconditionally depends on the closest ABCModel ancestor.
-        // Which is the inner model, for which b,c are null.
-        final Widget showABC = new Builder(
-          builder: (BuildContext context) {
-            final ABCModel abc = ABCModel.of(context);
-            return new Text('a: ${abc.a} b: ${abc.b} c: ${abc.c}', style: Theme.of(context).textTheme.title);
-          }
-        );
-
-        return new Scaffold(
-          body: new StatefulBuilder(
-            builder: (BuildContext context, StateSetter setState) {
-              return new ABCModel( // The "outer" model
-                a: _a,
-                b: _b,
-                c: _c,
-                child: new ABCModel( // The "inner" model
-                  a: 100 + _a,
-                  b: 100 + _b,
-                  aspects: _innerModelAspects,
-                  child: new Center(
-                    child: new Column(
-                      mainAxisSize: MainAxisSize.min,
-                      children: <Widget>[
-                        showA,
-                        showB,
-                        showC,
-                        const SizedBox(height: 24.0),
-                        showABC,
-                        const SizedBox(height: 24.0),
-                        new RaisedButton(
-                          child: const Text('Increment a'),
-                          onPressed: () {
-                            setState(() { _a += 1; });
-                          },
-                        ),
-                        new RaisedButton(
-                          child: const Text('Increment b'),
-                          onPressed: () {
-                            setState(() { _b += 1; });
-                          },
-                        ),
-                        new RaisedButton(
-                          child: const Text('Increment c'),
-                          onPressed: () {
-                            setState(() { _c += 1; });
-                          },
-                        ),
-                        new RaisedButton(
-                          child: const Text('rebuild'),
-                          onPressed: () {
-                            setState(() {
-                              // Rebuild both models
-                            });
-                          },
-                        ),
-                      ],
-                    ),
-                  ),
-                ),
-              );
-            },
-          ),
-        );
-      },
-    );
-
-    _innerModelAspects = new Set<String>.of(<String>['a']);
-    await tester.pumpWidget(new MaterialApp(home: abcPage));
-    expect(find.text('a: 100 [0]'), findsOneWidget); // showA depends on the inner model
-    expect(find.text('b: 1 [0]'), findsOneWidget); // showB depends on the outer model
-    expect(find.text('c: 2 [0]'), findsOneWidget);
-    expect(find.text('a: 100 b: 101 c: null'), findsOneWidget); // inner model's a, b, c
-
-    _innerModelAspects = new Set<String>.of(<String>['a', 'b']);
-    await tester.tap(find.text('rebuild'));
-    await tester.pumpAndSettle();
-    expect(find.text('a: 100 [1]'), findsOneWidget); // rebuilt showA still depend on the inner model
-    expect(find.text('b: 101 [1]'), findsOneWidget); // rebuilt showB now depends on the inner model
-    expect(find.text('c: 2 [1]'), findsOneWidget); // rebuilt showC still depends on the outer model
-    expect(find.text('a: 100 b: 101 c: null'), findsOneWidget); // inner model's a, b, c
-
-    // Verify that field 'a' was incremented, but only the showA
-    // and showABC widgets were rebuilt.
-    await tester.tap(find.text('Increment a'));
-    await tester.pumpAndSettle();
-    expect(find.text('a: 101 [2]'), findsOneWidget); // rebuilt showA still depends on the inner model
-    expect(find.text('b: 101 [1]'), findsOneWidget);
-    expect(find.text('c: 2 [1]'), findsOneWidget);
-    expect(find.text('a: 101 b: 101 c: null'), findsOneWidget);
-
-    // Verify that field 'b' was incremented, but only the showB
-    // and showABC widgets were rebuilt.
-    await tester.tap(find.text('Increment b'));
-    await tester.pumpAndSettle();
-    expect(find.text('a: 101 [2]'), findsOneWidget); // rebuilt showB still depends on the inner model
-    expect(find.text('b: 102 [2]'), findsOneWidget);
-    expect(find.text('c: 2 [1]'), findsOneWidget);
-    expect(find.text('a: 101 b: 102 c: null'), findsOneWidget);
-
-    // Verify that field 'c' was incremented, but only the showC
-    // and showABC widgets were rebuilt.
-    await tester.tap(find.text('Increment c'));
-    await tester.pumpAndSettle();
-    expect(find.text('a: 101 [2]'), findsOneWidget);
-    expect(find.text('b: 102 [2]'), findsOneWidget);
-    expect(find.text('c: 3 [2]'), findsOneWidget); // rebuilt showC still depends on the outer model
-    expect(find.text('a: 101 b: 102 c: null'), findsOneWidget);
-
-    _innerModelAspects = new Set<String>.of(<String>['a', 'b', 'c']);
-    await tester.tap(find.text('rebuild'));
-    await tester.pumpAndSettle();
-    expect(find.text('a: 101 [3]'), findsOneWidget); // rebuilt showA still depend on the inner model
-    expect(find.text('b: 102 [3]'), findsOneWidget); // rebuilt showB still depends on the inner model
-    expect(find.text('c: null [3]'), findsOneWidget); // rebuilt showC now depends on the inner model
-    expect(find.text('a: 101 b: 102 c: null'), findsOneWidget); // inner model's a, b, c
-
-    // Now the inner model supports no aspects
-    _innerModelAspects = new Set<String>.of(<String>[]);
-    await tester.tap(find.text('rebuild'));
-    await tester.pumpAndSettle();
-    expect(find.text('a: 1 [4]'), findsOneWidget); // rebuilt showA now depends on the outer model
-    expect(find.text('b: 2 [4]'), findsOneWidget); // rebuilt showB now depends on the outer model
-    expect(find.text('c: 3 [4]'), findsOneWidget); // rebuilt showC now depends on the outer model
-    expect(find.text('a: 101 b: 102 c: null'), findsOneWidget); // inner model's a, b, c
-
-    // Now the inner model supports all aspects
-    _innerModelAspects = null;
-    await tester.tap(find.text('rebuild'));
-    await tester.pumpAndSettle();
-    expect(find.text('a: 101 [5]'), findsOneWidget); // rebuilt showA now depends on the inner model
-    expect(find.text('b: 102 [5]'), findsOneWidget); // rebuilt showB now depends on the inner model
-    expect(find.text('c: null [5]'), findsOneWidget); // rebuilt showC now depends on the inner model
-    expect(find.text('a: 101 b: 102 c: null'), findsOneWidget); // inner model's a, b, c
-  });
-}
