[roll] Update third-party dart packages

Roller-URL: https://ci.chromium.org/b/8858079893751699984
Cq-Cl-Tag: roller-builder:flutter-with-deps-roller
Cq-Cl-Tag: roller-bid:8858079893751699984
CQ-Do-Not-Cancel-Tryjobs: true
Change-Id: I29185123c5bdee1366a6d287ce030be905738693
Reviewed-on: https://fuchsia-review.googlesource.com/c/third_party/dart-pkg/+/471479
Reviewed-by: GI Roller <global-integration-roller@fuchsia-infra.iam.gserviceaccount.com>
Commit-Queue: GI Roller <global-integration-roller@fuchsia-infra.iam.gserviceaccount.com>
diff --git a/code_builder/.github/workflows/test-package.yml b/code_builder/.github/workflows/test-package.yml
new file mode 100644
index 0000000..28a5086
--- /dev/null
+++ b/code_builder/.github/workflows/test-package.yml
@@ -0,0 +1,72 @@
+name: Dart CI
+
+on:
+  # Run on PRs and pushes to the default branch.
+  push:
+    branches: [ master ]
+  pull_request:
+    branches: [ master ]
+  schedule:
+    - cron: "0 0 * * 0"
+
+env:
+  PUB_ENVIRONMENT: bot.github
+
+jobs:
+  # Check code formatting and static analysis on a single OS (linux)
+  # against Dart dev and 2.7.0.
+  analyze:
+    runs-on: ubuntu-latest
+    strategy:
+      fail-fast: false
+      matrix:
+        sdk: [dev]
+        version: [latest]
+        include:
+          - sdk: stable
+            version: 2.7.0
+    steps:
+      - uses: actions/checkout@v2
+      - uses: cedx/setup-dart@v2 # TODO(dart-lang/setup-dart#3): use the official setup-dart action
+        with:
+          release-channel: ${{ matrix.sdk }}
+          version: ${{ matrix.version }}
+      - id: install
+        name: Install dependencies
+        run: pub get
+      - name: Check formatting
+        run: dartfmt --dry-run --set-exit-if-changed .
+        if: always() && steps.install.outcome == 'success'
+      - name: Analyze code
+        run: dartanalyzer --fatal-infos --fatal-warnings .
+        if: always() && steps.install.outcome == 'success'
+
+  # Run tests on a matrix consisting of two dimensions:
+  # 1. OS: ubuntu-latest, (macos-latest, windows-latest)
+  # 2. release channel: dev, 2.7.0
+  test:
+    needs: analyze
+    runs-on: ${{ matrix.os }}
+    strategy:
+      fail-fast: false
+      matrix:
+        # Add macos-latest and/or windows-latest if relevant for this package.
+        os: [ubuntu-latest]
+        sdk: [dev]
+        version: [latest]
+        include:
+          - os: ubuntu-latest
+            sdk: stable
+            version: 2.7.0
+    steps:
+      - uses: actions/checkout@v2
+      - uses: cedx/setup-dart@v2 # TODO(dart-lang/setup-dart#3): use the official setup-dart action
+        with:
+          release-channel: ${{ matrix.sdk }}
+          version: ${{ matrix.version }}
+      - id: install
+        name: Install dependencies
+        run: pub get
+      - name: Run VM tests
+        run: pub run test --platform vm
+        if: always() && steps.install.outcome == 'success'
diff --git a/code_builder/.travis.yml b/code_builder/.travis.yml
deleted file mode 100644
index dda7d52..0000000
--- a/code_builder/.travis.yml
+++ /dev/null
@@ -1,17 +0,0 @@
-language: dart
-
-dart:
-  - dev
-  - 2.7.0
-
-dart_task:
-- test
-- dartanalyzer: --fatal-infos --fatal-warnings .
-- dartfmt: sdk
-
-branches:
-  only: [master]
-
-cache:
-  directories:
-  - $HOME/.pub-cache
diff --git a/code_builder/BUILD.gn b/code_builder/BUILD.gn
index 8636ee9..96417d0 100644
--- a/code_builder/BUILD.gn
+++ b/code_builder/BUILD.gn
@@ -1,4 +1,4 @@
-# This file is generated by importer.py for code_builder-3.5.0
+# This file is generated by importer.py for code_builder-3.6.0
 
 import("//build/dart/dart_library.gni")
 
@@ -42,6 +42,8 @@
     "src/specs/expression/code.dart",
     "src/specs/expression/invoke.dart",
     "src/specs/expression/literal.dart",
+    "src/specs/extension.dart",
+    "src/specs/extension.g.dart",
     "src/specs/field.dart",
     "src/specs/field.g.dart",
     "src/specs/library.dart",
diff --git a/code_builder/CHANGELOG.md b/code_builder/CHANGELOG.md
index c1dbf3f..b80e4d9 100644
--- a/code_builder/CHANGELOG.md
+++ b/code_builder/CHANGELOG.md
@@ -1,3 +1,8 @@
+## 3.6.0
+
+* Add support for creating `extension` methods.
+* Expand constraint on `built_value` to allow null safe migrated version.
+
 ## 3.5.0
 
 * Add support for defining enums.
diff --git a/code_builder/README.md b/code_builder/README.md
index a438d7d..89d973f 100644
--- a/code_builder/README.md
+++ b/code_builder/README.md
@@ -1,5 +1,5 @@
 [![Pub package](https://img.shields.io/pub/v/code_builder.svg)](https://pub.dev/packages/code_builder)
-[![Build status](https://travis-ci.org/dart-lang/code_builder.svg)](https://travis-ci.org/dart-lang/code_builder)
+[![Build Status](https://github.com/dart-lang/code_builder/workflows/Dart%20CI/badge.svg?branch=master)](https://github.com/dart-lang/code_builder/actions?query=workflow%3A%22Dart+CI%22+branch%3Amaster)
 [![Gitter chat](https://badges.gitter.im/dart-lang/build.svg)](https://gitter.im/dart-lang/build)
 
 A fluent, builder-based library for generating valid Dart code.
@@ -29,15 +29,16 @@
 ```
 
 Outputs:
+
 ```dart
 class Animal extends Organism {
   void eat() => print('Yum!');
 }
 ```
 
-Have a complicated set of dependencies for your generated code?
-`code_builder` supports automatic scoping of your ASTs to automatically
-use prefixes to avoid symbol conflicts:
+Have a complicated set of dependencies for your generated code? `code_builder`
+supports automatic scoping of your ASTs to automatically use prefixes to avoid
+symbol conflicts:
 
 ```dart
 import 'package:code_builder/code_builder.dart';
@@ -60,6 +61,7 @@
 ```
 
 Outputs:
+
 ```dart
 import 'package:a/a.dart' as _i1;
 import 'package:b/b.dart' as _i2;
@@ -70,8 +72,8 @@
 
 ## Contributing
 
-* Read and help us document common patterns over [at the wiki][wiki].
-* Is there a *bug* in the code? [File an issue][issue].
+- Read and help us document common patterns over [at the wiki][wiki].
+- Is there a _bug_ in the code? [File an issue][issue].
 
 If a feature is missing (the Dart language is always evolving) or you'd like an
 easier or better way to do something, consider [opening a pull request][pull].
@@ -91,9 +93,9 @@
 
 ### Updating generated (`.g.dart`) files
 
-> **NOTE**: There is currently a limitation in `build_runner` that requires
-> a workaround for developing this package. We expect this to be unnecessary
-> in the future.
+> **NOTE**: There is currently a limitation in `build_runner` that requires a
+> workaround for developing this package. We expect this to be unnecessary in
+> the future.
 
 Use [`build_runner`][build_runner]:
 
diff --git a/code_builder/lib/code_builder.dart b/code_builder/lib/code_builder.dart
index 564299a..60adee8 100644
--- a/code_builder/lib/code_builder.dart
+++ b/code_builder/lib/code_builder.dart
@@ -39,6 +39,7 @@
         literalString,
         literalTrue,
         literalFalse;
+export 'src/specs/extension.dart' show Extension, ExtensionBuilder;
 export 'src/specs/field.dart' show Field, FieldBuilder, FieldModifier;
 export 'src/specs/library.dart' show Library, LibraryBuilder;
 export 'src/specs/method.dart'
diff --git a/code_builder/lib/src/emitter.dart b/code_builder/lib/src/emitter.dart
index bd5b32d..b680235 100644
--- a/code_builder/lib/src/emitter.dart
+++ b/code_builder/lib/src/emitter.dart
@@ -10,6 +10,7 @@
 import 'specs/directive.dart';
 import 'specs/enum.dart';
 import 'specs/expression.dart';
+import 'specs/extension.dart';
 import 'specs/field.dart';
 import 'specs/library.dart';
 import 'specs/method.dart';
@@ -234,6 +235,37 @@
   }
 
   @override
+  StringSink visitExtension(Extension spec, [StringSink output]) {
+    output ??= StringBuffer();
+    spec.docs.forEach(output.writeln);
+    spec.annotations.forEach((a) => visitAnnotation(a, output));
+
+    output.write('extension');
+    if (spec.name != null) {
+      output.write(' ${spec.name}');
+    }
+    visitTypeParameters(spec.types.map((r) => r.type), output);
+    if (spec.on != null) {
+      output.write(' on ');
+      spec.on.type.accept(this, output);
+    }
+    output.write(' {');
+    spec.fields.forEach((f) {
+      visitField(f, output);
+      output.writeln();
+    });
+    spec.methods.forEach((m) {
+      visitMethod(m, output);
+      if (_isLambdaMethod(m)) {
+        output.write(';');
+      }
+      output.writeln();
+    });
+    output.writeln(' }');
+    return output;
+  }
+
+  @override
   StringSink visitDirective(Directive spec, [StringSink output]) {
     output ??= StringBuffer();
     switch (spec.type) {
diff --git a/code_builder/lib/src/specs/extension.dart b/code_builder/lib/src/specs/extension.dart
new file mode 100644
index 0000000..9260471
--- /dev/null
+++ b/code_builder/lib/src/specs/extension.dart
@@ -0,0 +1,80 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. 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:built_value/built_value.dart';
+import 'package:built_collection/built_collection.dart';
+import 'package:meta/meta.dart';
+
+import '../../code_builder.dart';
+import '../base.dart';
+import '../mixins/annotations.dart';
+import '../mixins/dartdoc.dart';
+import '../mixins/generics.dart';
+import '../visitors.dart';
+import 'expression.dart';
+import 'field.dart';
+import 'method.dart';
+import 'reference.dart';
+
+part 'extension.g.dart';
+
+@immutable
+abstract class Extension extends Object
+    with HasAnnotations, HasDartDocs, HasGenerics
+    implements Built<Extension, ExtensionBuilder>, Spec {
+  factory Extension([void Function(ExtensionBuilder b) updates]) = _$Extension;
+
+  Extension._();
+
+  @override
+  BuiltList<Expression> get annotations;
+
+  @override
+  BuiltList<String> get docs;
+
+  @nullable
+  Reference get on;
+
+  @override
+  BuiltList<Reference> get types;
+
+  BuiltList<Method> get methods;
+  BuiltList<Field> get fields;
+
+  /// Name of the extension - optional.
+  @nullable
+  String get name;
+
+  @override
+  R accept<R>(
+    SpecVisitor<R> visitor, [
+    R context,
+  ]) =>
+      visitor.visitExtension(this, context);
+}
+
+abstract class ExtensionBuilder extends Object
+    with HasAnnotationsBuilder, HasDartDocsBuilder, HasGenericsBuilder
+    implements Builder<Extension, ExtensionBuilder> {
+  factory ExtensionBuilder() = _$ExtensionBuilder;
+
+  ExtensionBuilder._();
+
+  @override
+  ListBuilder<Expression> annotations = ListBuilder<Expression>();
+
+  @override
+  ListBuilder<String> docs = ListBuilder<String>();
+
+  Reference on;
+
+  @override
+  ListBuilder<Reference> types = ListBuilder<Reference>();
+
+  ListBuilder<Method> methods = ListBuilder<Method>();
+  ListBuilder<Field> fields = ListBuilder<Field>();
+
+  /// Name of the extension - optional.
+  String name;
+}
diff --git a/code_builder/lib/src/specs/extension.g.dart b/code_builder/lib/src/specs/extension.g.dart
new file mode 100644
index 0000000..befd295
--- /dev/null
+++ b/code_builder/lib/src/specs/extension.g.dart
@@ -0,0 +1,256 @@
+// GENERATED CODE - DO NOT MODIFY BY HAND
+
+part of 'extension.dart';
+
+// **************************************************************************
+// BuiltValueGenerator
+// **************************************************************************
+
+class _$Extension extends Extension {
+  @override
+  final BuiltList<Expression> annotations;
+  @override
+  final BuiltList<String> docs;
+  @override
+  final Reference on;
+  @override
+  final BuiltList<Reference> types;
+  @override
+  final BuiltList<Method> methods;
+  @override
+  final BuiltList<Field> fields;
+  @override
+  final String name;
+
+  factory _$Extension([void Function(ExtensionBuilder) updates]) =>
+      (new ExtensionBuilder()..update(updates)).build() as _$Extension;
+
+  _$Extension._(
+      {this.annotations,
+      this.docs,
+      this.on,
+      this.types,
+      this.methods,
+      this.fields,
+      this.name})
+      : super._() {
+    if (annotations == null) {
+      throw new BuiltValueNullFieldError('Extension', 'annotations');
+    }
+    if (docs == null) {
+      throw new BuiltValueNullFieldError('Extension', 'docs');
+    }
+    if (types == null) {
+      throw new BuiltValueNullFieldError('Extension', 'types');
+    }
+    if (methods == null) {
+      throw new BuiltValueNullFieldError('Extension', 'methods');
+    }
+    if (fields == null) {
+      throw new BuiltValueNullFieldError('Extension', 'fields');
+    }
+  }
+
+  @override
+  Extension rebuild(void Function(ExtensionBuilder) updates) =>
+      (toBuilder()..update(updates)).build();
+
+  @override
+  _$ExtensionBuilder toBuilder() => new _$ExtensionBuilder()..replace(this);
+
+  @override
+  bool operator ==(Object other) {
+    if (identical(other, this)) return true;
+    return other is Extension &&
+        annotations == other.annotations &&
+        docs == other.docs &&
+        on == other.on &&
+        types == other.types &&
+        methods == other.methods &&
+        fields == other.fields &&
+        name == other.name;
+  }
+
+  @override
+  int get hashCode {
+    return $jf($jc(
+        $jc(
+            $jc(
+                $jc(
+                    $jc($jc($jc(0, annotations.hashCode), docs.hashCode),
+                        on.hashCode),
+                    types.hashCode),
+                methods.hashCode),
+            fields.hashCode),
+        name.hashCode));
+  }
+
+  @override
+  String toString() {
+    return (newBuiltValueToStringHelper('Extension')
+          ..add('annotations', annotations)
+          ..add('docs', docs)
+          ..add('on', on)
+          ..add('types', types)
+          ..add('methods', methods)
+          ..add('fields', fields)
+          ..add('name', name))
+        .toString();
+  }
+}
+
+class _$ExtensionBuilder extends ExtensionBuilder {
+  _$Extension _$v;
+
+  @override
+  ListBuilder<Expression> get annotations {
+    _$this;
+    return super.annotations ??= new ListBuilder<Expression>();
+  }
+
+  @override
+  set annotations(ListBuilder<Expression> annotations) {
+    _$this;
+    super.annotations = annotations;
+  }
+
+  @override
+  ListBuilder<String> get docs {
+    _$this;
+    return super.docs ??= new ListBuilder<String>();
+  }
+
+  @override
+  set docs(ListBuilder<String> docs) {
+    _$this;
+    super.docs = docs;
+  }
+
+  @override
+  Reference get on {
+    _$this;
+    return super.on;
+  }
+
+  @override
+  set on(Reference on) {
+    _$this;
+    super.on = on;
+  }
+
+  @override
+  ListBuilder<Reference> get types {
+    _$this;
+    return super.types ??= new ListBuilder<Reference>();
+  }
+
+  @override
+  set types(ListBuilder<Reference> types) {
+    _$this;
+    super.types = types;
+  }
+
+  @override
+  ListBuilder<Method> get methods {
+    _$this;
+    return super.methods ??= new ListBuilder<Method>();
+  }
+
+  @override
+  set methods(ListBuilder<Method> methods) {
+    _$this;
+    super.methods = methods;
+  }
+
+  @override
+  ListBuilder<Field> get fields {
+    _$this;
+    return super.fields ??= new ListBuilder<Field>();
+  }
+
+  @override
+  set fields(ListBuilder<Field> fields) {
+    _$this;
+    super.fields = fields;
+  }
+
+  @override
+  String get name {
+    _$this;
+    return super.name;
+  }
+
+  @override
+  set name(String name) {
+    _$this;
+    super.name = name;
+  }
+
+  _$ExtensionBuilder() : super._();
+
+  ExtensionBuilder get _$this {
+    if (_$v != null) {
+      super.annotations = _$v.annotations?.toBuilder();
+      super.docs = _$v.docs?.toBuilder();
+      super.on = _$v.on;
+      super.types = _$v.types?.toBuilder();
+      super.methods = _$v.methods?.toBuilder();
+      super.fields = _$v.fields?.toBuilder();
+      super.name = _$v.name;
+      _$v = null;
+    }
+    return this;
+  }
+
+  @override
+  void replace(Extension other) {
+    if (other == null) {
+      throw new ArgumentError.notNull('other');
+    }
+    _$v = other as _$Extension;
+  }
+
+  @override
+  void update(void Function(ExtensionBuilder) updates) {
+    if (updates != null) updates(this);
+  }
+
+  @override
+  _$Extension build() {
+    _$Extension _$result;
+    try {
+      _$result = _$v ??
+          new _$Extension._(
+              annotations: annotations.build(),
+              docs: docs.build(),
+              on: on,
+              types: types.build(),
+              methods: methods.build(),
+              fields: fields.build(),
+              name: name);
+    } catch (_) {
+      String _$failedField;
+      try {
+        _$failedField = 'annotations';
+        annotations.build();
+        _$failedField = 'docs';
+        docs.build();
+
+        _$failedField = 'types';
+        types.build();
+        _$failedField = 'methods';
+        methods.build();
+        _$failedField = 'fields';
+        fields.build();
+      } catch (e) {
+        throw new BuiltValueNestedFieldError(
+            'Extension', _$failedField, e.toString());
+      }
+      rethrow;
+    }
+    replace(_$result);
+    return _$result;
+  }
+}
+
+// ignore_for_file: always_put_control_body_on_new_line,always_specify_types,annotate_overrides,avoid_annotating_with_dynamic,avoid_as,avoid_catches_without_on_clauses,avoid_returning_this,lines_longer_than_80_chars,omit_local_variable_types,prefer_expression_function_bodies,sort_constructors_first,test_types_in_equals,unnecessary_const,unnecessary_new
diff --git a/code_builder/lib/src/visitors.dart b/code_builder/lib/src/visitors.dart
index 1447b83..ed2ab4d 100644
--- a/code_builder/lib/src/visitors.dart
+++ b/code_builder/lib/src/visitors.dart
@@ -10,6 +10,7 @@
 import 'specs/directive.dart';
 import 'specs/enum.dart';
 import 'specs/expression.dart';
+import 'specs/extension.dart';
 import 'specs/field.dart';
 import 'specs/library.dart';
 import 'specs/method.dart';
@@ -25,6 +26,8 @@
 
   T visitClass(Class spec, [T context]);
 
+  T visitExtension(Extension spec, [T context]);
+
   T visitEnum(Enum spec, [T context]);
 
   T visitConstructor(Constructor spec, String clazz, [T context]);
diff --git a/code_builder/pubspec.yaml b/code_builder/pubspec.yaml
index abc1d67..8c8982d 100644
--- a/code_builder/pubspec.yaml
+++ b/code_builder/pubspec.yaml
@@ -1,5 +1,5 @@
 name: code_builder
-version: 3.5.0
+version: 3.6.0
 
 description: >-
   A fluent, builder-based library for generating valid Dart code
@@ -9,8 +9,8 @@
   sdk: '>=2.7.0 <3.0.0'
 
 dependencies:
-  built_collection: '>=3.0.0 <5.0.0'
-  built_value: ^7.0.0
+  built_collection: '>=3.0.0 <6.0.0'
+  built_value: '>=7.0.0 <9.0.0'
   collection: ^1.14.0
   matcher: ^0.12.0
   meta: ^1.0.5
diff --git a/provider/.gitignore b/provider/.gitignore
index 7dfcccc..03aab06 100644
--- a/provider/.gitignore
+++ b/provider/.gitignore
@@ -3,6 +3,7 @@
 android/
 ios/
 .packages
+
 # Remove the following pattern if you wish to check in your lock file
 pubspec.lock
 
diff --git a/provider/BUILD.gn b/provider/BUILD.gn
index e06057e..67121e9 100644
--- a/provider/BUILD.gn
+++ b/provider/BUILD.gn
@@ -1,4 +1,4 @@
-# This file is generated by importer.py for provider-4.3.2+3
+# This file is generated by importer.py for provider-4.3.2+4
 
 import("//build/dart/dart_library.gni")
 
diff --git a/provider/CHANGELOG.md b/provider/CHANGELOG.md
index ce4aea3..11c0a27 100644
--- a/provider/CHANGELOG.md
+++ b/provider/CHANGELOG.md
@@ -1,3 +1,7 @@
+# 4.3.2+4
+
+`ValueListenableProvider` is no-longer deprecated. Only its default constructor is deprecated (the `.value` constructor is kept)
+
 # 4.3.2+3
 
 Marked `ValueListenableProvider` as deprecated
diff --git a/provider/README.md b/provider/README.md
index e4d8a3f..171f0f8 100644
--- a/provider/README.md
+++ b/provider/README.md
@@ -1,4 +1,4 @@
-[English](https://github.com/rrousselGit/provider/blob/master/README.md) | [Português](https://github.com/rrousselGit/provider/blob/master/resources/translations/pt_br/README.md) | [简体中文](./resources/translations/zh-CN/README.md)
+[English](https://github.com/rrousselGit/provider/blob/master/README.md) | [Português](https://github.com/rrousselGit/provider/blob/master/resources/translations/pt_br/README.md) | [简体中文](https://github.com/rrousselGit/provider/blob/master/resources/translations/zh-CN/README.md) | [Español](https://github.com/rrousselGit/provider/blob/master/resources/translations/es_MX/README.md)
 
 <a href="https://github.com/rrousselGit/provider/actions"><img src="https://github.com/rrousselGit/provider/workflows/Build/badge.svg" alt="Build Status"></a>
 [![codecov](https://codecov.io/gh/rrousselGit/provider/branch/master/graph/badge.svg)](https://codecov.io/gh/rrousselGit/provider) [![Gitter](https://badges.gitter.im/flutter_provider/community.svg)](https://gitter.im/flutter_provider/community?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge)
diff --git a/provider/example/lib/main.dart b/provider/example/lib/main.dart
index 1257582..4dc2a40 100644
--- a/provider/example/lib/main.dart
+++ b/provider/example/lib/main.dart
@@ -75,6 +75,8 @@
         ),
       ),
       floatingActionButton: FloatingActionButton(
+        key: const Key('increment_floatingActionButton'),
+
         /// Calls `context.read` instead of `context.watch` so that it does not rebuild
         /// when [Counter] changes.
         onPressed: () => context.read<Counter>().increment(),
@@ -94,6 +96,7 @@
 
         /// Calls `context.watch` to make [Count] rebuild when [Counter] changes.
         '${context.watch<Counter>().count}',
+        key: const Key('counterState'),
         style: Theme.of(context).textTheme.headline4);
   }
 }
diff --git a/provider/example/pubspec.yaml b/provider/example/pubspec.yaml
index ee9e3d2..14395d3 100644
--- a/provider/example/pubspec.yaml
+++ b/provider/example/pubspec.yaml
@@ -13,8 +13,11 @@
   provider:
 
 dev_dependencies:
+  flutter_driver:
+    sdk: flutter
   flutter_test:
     sdk: flutter
+  test: ^1.15.7
 
 dependency_overrides:
   provider:
diff --git a/provider/example/test_driver/app.dart b/provider/example/test_driver/app.dart
new file mode 100644
index 0000000..9a2786b
--- /dev/null
+++ b/provider/example/test_driver/app.dart
@@ -0,0 +1,11 @@
+import 'package:flutter_driver/driver_extension.dart';
+import 'package:example/main.dart' as app;
+
+void main() {
+  // This line enables the extension.
+  enableFlutterDriverExtension();
+
+  // Call the `main()` function of the app, or call `runApp` with
+  // any widget you are interested in testing.
+  app.main();
+}
diff --git a/provider/example/test_driver/app_test.dart b/provider/example/test_driver/app_test.dart
new file mode 100644
index 0000000..1d55676
--- /dev/null
+++ b/provider/example/test_driver/app_test.dart
@@ -0,0 +1,42 @@
+// Imports the Flutter Driver API.
+import 'package:flutter_driver/flutter_driver.dart';
+import 'package:test/test.dart';
+
+void main() {
+  group('counter app', () {
+    FlutterDriver _driver;
+
+    final incrementFloatingButton =
+        find.byValueKey('increment_floatingActionButton');
+    final appBarText = find.text('Example');
+    final counterState = find.byValueKey('counterState');
+
+    /// connect to [FlutterDriver]
+    setUpAll(() async {
+      _driver = await FlutterDriver.connect();
+    });
+
+    /// close the driver
+    tearDownAll(() async {
+      await _driver?.close();
+    });
+
+    test('AppBar is Flutter Demo Home Page', () async {
+      expect(await _driver.getText(appBarText), 'Example');
+    });
+
+    test('counterText is started with 0', () async {
+      expect(await _driver.getText(counterState), '0');
+    });
+
+    test('pressed increment floating action button twice', () async {
+      // tap floating action button
+      await _driver.tap(incrementFloatingButton);
+      expect(await _driver.getText(counterState), '1');
+
+      // tap floating action button
+      await _driver.tap(incrementFloatingButton);
+      expect(await _driver.getText(counterState), '2');
+    });
+  });
+}
diff --git a/provider/lib/src/provider.dart b/provider/lib/src/provider.dart
index 6fe061f..8c7db2c 100644
--- a/provider/lib/src/provider.dart
+++ b/provider/lib/src/provider.dart
@@ -503,7 +503,7 @@
   /// Widget build(BuildContext context) {
   ///   return RaisedButton(
   ///     onPressed: () {
-  ///       // as performant as the previous previous solution, but resilient to refactoring
+  ///       // as performant as the previous solution, but resilient to refactoring
   ///       context.read<Counter>().increment(),
   ///     },
   ///   );
diff --git a/provider/lib/src/value_listenable_provider.dart b/provider/lib/src/value_listenable_provider.dart
index 21795ee..4f0abea 100644
--- a/provider/lib/src/value_listenable_provider.dart
+++ b/provider/lib/src/value_listenable_provider.dart
@@ -5,7 +5,6 @@
 import 'provider.dart';
 
 /// Listens to a [ValueListenable] and expose its current value.
-@Deprecated('Will be removed in 5.0.0')
 class ValueListenableProvider<T>
     extends DeferredInheritedProvider<ValueListenable<T>, T> {
   /// Creates a [ValueNotifier] using [create] and automatically dispose it
@@ -20,6 +19,11 @@
   ///   * [ValueListenable]
   ///   * [ListenableProvider], similar to [ValueListenableProvider] but for any
   /// kind of [Listenable].
+  @Deprecated(
+    'Will be removed in 5.0.0. '
+    'Instead use a StatefulWidget and manually create/dispose the ValueNotifier, '
+    'then use ValueListenableProvider.value()',
+  )
   ValueListenableProvider({
     Key key,
     @required Create<ValueNotifier<T>> create,
diff --git a/provider/pubspec.yaml b/provider/pubspec.yaml
index 9f57612..f75fa4b 100644
--- a/provider/pubspec.yaml
+++ b/provider/pubspec.yaml
@@ -1,17 +1,17 @@
 name: provider
 description: A wrapper around InheritedWidget to make them easier to use and more reusable.
-version: 4.3.2+3
+version: 4.3.2+4
 homepage: https://github.com/rrousselGit/provider
 
 environment:
   sdk: ">=2.7.0 <3.0.0"
-  flutter: ">= 1.16.0"
+  flutter: ">=1.16.0 <2.0.0"
 
 dependencies:
   collection: ^1.14.13
   flutter:
     sdk: flutter
-  nested: ">= 0.0.4 < 2.0.0"
+  nested: ">=0.0.4 <2.0.0"
 
 dev_dependencies:
   flutter_test:
diff --git a/provider/resources/translations/es_MX/README.md b/provider/resources/translations/es_MX/README.md
new file mode 100644
index 0000000..35cb20d
--- /dev/null
+++ b/provider/resources/translations/es_MX/README.md
@@ -0,0 +1,682 @@
+[English](https://github.com/rrousselGit/provider/blob/master/README.md) | [Português](https://github.com/rrousselGit/provider/blob/master/resources/translations/pt_br/README.md) | [简体中文](https://github.com/rrousselGit/provider/blob/master/resources/translations/zh-CN/README.md) | [Español](./resources/translations/es_MX/README.md)
+
+<a href="https://github.com/rrousselGit/provider/actions"><img src="https://github.com/rrousselGit/provider/workflows/Build/badge.svg" alt="Build Status"></a>
+[![codecov](https://codecov.io/gh/rrousselGit/provider/branch/master/graph/badge.svg)](https://codecov.io/gh/rrousselGit/provider) [![Gitter](https://badges.gitter.im/flutter_provider/community.svg)](https://gitter.im/flutter_provider/community?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge)
+
+[<img src="https://raw.githubusercontent.com/rrousselGit/provider/master/resources/flutter_favorite.png" width="200" />](https://flutter.dev/docs/development/packages-and-plugins/favorites)
+
+
+Un wrapper alrededor de [InheritedWidget]
+para hacerlo más fácil de usar y más utilizable.
+
+Al utilizar `provider` en lugar de escribir manualmente los [InheritedWidget], obtendrás:
+
+- asignación/eliminación simplificada de los recursos
+- lazy-loading
+- un boilerplate muy reducido en lugar de hacer una nueva clase cada vez.
+- compatibilidad con devtools
+- una manera común de consumir esto [InheritedWidget]s (ver  [Provider.of]/[Consumer]/[Selector])
+- incrementa la escalabilidad de tus clases con un mecanismo de escucha (listener) que crece exponencialmente 
+  en complejidad (tales como [ChangeNotifier], el cual es O(N²) al enviar notificaciones)
+
+Para leer más acerca de `provider`, leé su [documentación](https://pub.dev/documentation/provider/latest/provider/provider-library.html).
+
+Ver también:
+
+- [La documentación oficial de Flutter en gestión de estado](https://flutter.dev/docs/development/data-and-backend/state-mgmt/simple), la cual muestra como usar `provider` + [ChangeNotifier]
+- [Ejemplos de arquitectura en Flutter](https://github.com/brianegan/flutter_architecture_samples/tree/master/change_notifier_provider), la cual contiene una implementación de una app usando `provider` + [ChangeNotifier]
+- [flutter_bloc](https://github.com/felangel/bloc) y [Mobx](https://github.com/mobxjs/mobx.dart), los cuales usan `provider`  en su arquitectura.
+
+## Migrar de v3.x.0 a v4.0.0
+
+- Los parámetros `builder` e `initialBuilder` de providers son eliminados.
+  - `initialBuilder` deberá ser reemplazado por `create`.
+  - `builder` de "proxy" providers deberá ser reemplazado por `update`
+  - `builder` de providers clásicos deberá ser reemplazado por `create`.
+
+- las nuevas callbacks `create`/`update` son lazy-loaded, lo cual significa que serán llamadas
+  la primera vez que su valor sea leído, en lugar de la primera vez que el usuario sea creado.
+
+  Si esto no se quiere, puedes deshabilitar el lazy-loading pasando el valor `lazy: false` a
+  el provider de tu elección.
+
+  ```dart
+  FutureProvider(
+    create: (_) async => doSomeHttpRequest(),
+    lazy: false,
+    child: ...
+  )
+  ```
+
+- `ProviderNotFoundError` es renombrado a `ProviderNotFoundException`.
+
+- La interface `SingleChildCloneableWidget` es eliminada y reemplazada por un nuevo tipo
+  de widget `SingleChildWidget`.
+
+  Ve [este issue](https://github.com/rrousselGit/provider/issues/237) para detalles
+  acerca de como migrar.
+
+- [Selector] ahora comparará más profundamente el valor anterior y nuevo si estas son colecciones.
+
+  Si este no quiere, puedes revertir el comportamiento pasando el parámetro `shouldRebuild` al
+  [Selector]
+
+  ```dart
+  Selector<Selected, Consumed>(
+    shouldRebuild: (previous, next) => previous == next,
+    builder: ...,
+  )
+  ```
+
+- `DelegateWidget` y su familia han sido eliminados. En su lugar, para providers personalizados tendrán
+  subclasses directas [InheritedProvider] o un provider existente.
+
+## Uso
+
+### Exponiendo un valor
+
+#### Exponiendo una nueva instancia del objeto
+
+Los providers permiten no solo exponer un valor, sino también crear/escuchar/eliminar.
+
+Para exponer un objeto recién creado, utilice el constructor por defecto de un provider.
+_No uses_ el constructor `.value` si quieres **crear** un objeto, o
+podrías tener efectos secundarios no deseados.
+
+Ve [esta respuesta de stackoverflow](https://stackoverflow.com/questions/52249578/how-to-deal-with-unwanted-widget-build)
+la cual explica en mayor detalle, por qué usar el constructor `.value` para crear nuevos valores no es óptimo.
+
+- **DO** crea un nuevo objeto dentro de `create`.
+
+```dart
+Provider(
+  create: (_) => MyModel(),
+  child: ...
+)
+```
+
+- **DON'T** usar `Provider.value` para crear tu objeto.
+
+```dart
+ChangeNotifierProvider.value(
+  value: MyModel(),
+  child: ...
+)
+```
+
+- **DON'T** crear tu objeto de variables que pueden cambiar en el tiempo.
+
+  En esta situación, tu objeto nunca será actualizado cuando el
+  valor cambie.
+
+```dart
+int count;
+
+Provider(
+  create: (_) => MyModel(count),
+  child: ...
+)
+```
+
+Si quieres pasar variables que puede cambiar en el tiempo de tu objeto,
+considera utilizar `ProxyProvider`:
+
+```dart
+int count;
+
+ProxyProvider0(
+  update: (_, __) => MyModel(count),
+  child: ...
+)
+```
+
+**NOTA**:
+
+Cuando se utiliza la llamada de `create`/`update` de un provider, vale la pena señalar que en esta llamada
+se llama `lazy` por defecto.
+
+Lo que esto significa es que, hasta que el valor sea solicitado al menos una vez, el `create`/`update`
+no se llamarán las callback.
+
+Este comportamiento puede ser desactivado si quieres precalcular algo de lógica, usando el parámetro `lazy`:
+
+```dart
+MyProvider(
+  create: (_) => Something(),
+  lazy: false,
+)
+```
+
+#### Reutilizando una instancia de un objeto existente:
+
+Si ya tienes una instancia de un objeto y quieres exponerlo,
+deberías usar el constructor `.value` de un proveedor.
+
+Si no lo hace, puede llamar al método `dispose` de tu objeto cuando todavía está en uso.
+
+- **DO** usa `ChangeNotifierProvider.value` para un provider tipo
+  [ChangeNotifier] existente.
+
+```dart
+MyChangeNotifier variable;
+
+ChangeNotifierProvider.value(
+  value: variable,
+  child: ...
+)
+```
+
+- **DON'T** reutiliza un [ChangeNotifier] existente usando su constructor por defecto.
+
+```dart
+MyChangeNotifier variable;
+
+ChangeNotifierProvider(
+  create: (_) => variable,
+  child: ...
+)
+```
+
+### Leyendo un valor
+
+La manera mas fácil de leer un valor es usando los métodos de su extensión en [BuildContext]:
+
+- `context.watch<T>()`, el cual hace que el widget escuche los cambios en `T`.
+- `context.read<T>()`, este regresa `T` sin escucharlo.
+- `context.select<T, R>(R cb(T value))`, permite al widget escuchar solo una pequeña parte de `T`.
+
+O utiliza el método estático `Provider.of<T>(context)`, el cual se comporta similar a `watch` y cuando le pasa el valor `false`
+al parámetro `listen` como `Provider.of<T>(context, liste: false)` se comportará similar a `read`
+
+Vale la pena decir que `context.read<T>()` no hará que tu widget haga un rebuild cuando el valor cambia y no puede ser
+llamado dentro de `StatelessWidget.build`/`State.build`. Por otro lado, puede ser llamado libremente fuera de estos métodos.
+
+Estos métodos buscarán en el árbol de los widgets a partir del widget asociado
+con el `BuildContext` pasado, y devolverá la variable de tipo más cercano
+`T` encontrada (o lanzara una `exception` si no encuentra nada).
+
+Vale la pena señalar que esta operación es O(1). No implica realmente recorrer
+en el árbol de los widgets.
+
+Combinado con el primer ejemplo de [exponer un valor](#exposing-a-value), este
+el widget leerá el `String` expuesto y mostrará "Hola Mundo".
+
+```dart
+class Home extends StatelessWidget {
+  @override
+  Widget build(BuildContext context) {
+    return Text(
+      // Don't forget to pass the type of the object you want to obtain to `watch`!
+      context.watch<String>(),
+    );
+  }
+}
+```
+
+Otra opción, en lugar de utilizar estos métodos, podemos usar [Consumer] y [Selector].
+
+Estos pueden ayudar a optimizar el desempeño o cuando es difícil de obtener 
+el `BuildContext` descendiente del provider
+
+Ve las [FAQ](https://github.com/rrousselGit/provider#my-widget-rebuilds-too-often-what-can-i-do) o la documentación de [Consumer](https://pub.dev/documentation/provider/latest/provider/Consumer-class.html)
+y [Selector](https://pub.dev/documentation/provider/latest/provider/Selector-class.html) para más información.
+
+### MultiProvider
+
+Cuando inyectamos muchos valores en una aplicación grande, `Provider` puede convertirse
+muy anidado rápidamente.
+
+```dart
+Provider<Something>(
+  create: (_) => Something(),
+  child: Provider<SomethingElse>(
+    create: (_) => SomethingElse(),
+    child: Provider<AnotherThing>(
+      create: (_) => AnotherThing(),
+      child: someWidget,
+    ),
+  ),
+),
+```
+
+A:
+
+```dart
+MultiProvider(
+  providers: [
+    Provider<Something>(create: (_) => Something()),
+    Provider<SomethingElse>(create: (_) => SomethingElse()),
+    Provider<AnotherThing>(create: (_) => AnotherThing()),
+  ],
+  child: someWidget,
+)
+```
+
+El comportamiento de ambos ejemplos es el mismo. `Multiprovider` solo cambia la
+apariencia del código.
+
+### ProxyProvider
+
+Desde la versión 3.0.0, existe un nuevo tipo de provider: `ProxyProvider`.
+
+`ProxyProvider` es un provider que combina múltiples valores de otros provider
+dentro de un nuevo objeto, y envía el resultado a `Provider`.
+
+Este nuevo objeto será actualizado cuando uno de los providers de los que depende
+sea actualizado.
+
+El siguiente ejemplo usa `ProxyProvider` para construir una traducción de acuerdo a un contador
+que viene de otro provider.
+
+```dart
+Widget build(BuildContext context) {
+  return MultiProvider(
+    providers: [
+      ChangeNotifierProvider(create: (_) => Counter()),
+      ProxyProvider<Counter, Translations>(
+        update: (_, counter, __) => Translations(counter.value),
+      ),
+    ],
+    child: Foo(),
+  );
+}
+
+class Translations {
+  const Translations(this._value);
+
+  final int _value;
+
+  String get title => 'You clicked $_value times';
+}
+```
+
+Viene con múltiples variaciones, tales como:
+
+- `ProxyProvider` vs `ProxyProvider2` vs `ProxyProvider3`, ...
+
+  El dígito después del nombre de la clase es el número de providers que
+  `ProxyProvider` depende.
+
+- `ProxyProvider` vs `ChangeNotifierProxyProvider` vs `ListenableProxyProvider`, ...
+
+  Todos trabajan de manera similar, pero en lugar de enviar el resultado del `Provider`,
+  el `ChangeNotifierProxyProvider` enviará su valor a un `ChangeNotifierProvider`.
+
+### FAQ
+
+#### Puedo ver el contenido de mis objetos?
+
+Flutter viene con [devtools](https://github.com/flutter/devtools), el cual muestra
+cómo el árbol de widgets, está en un momento determinado.
+
+Ya que los providers son widgets, también son visibles en las devtools:
+
+<img src="https://raw.githubusercontent.com/rrousselGit/provider/master/resources/devtools_providers.jpg" width="200" />
+
+De ahí, si tu presionas un provider, serás capaz de ver los valores que contiene:
+
+<img src="https://raw.githubusercontent.com/rrousselGit/provider/master/resources/expanded_devtools.jpg" width="200" />
+
+(screenshot de las devtools usando la carpeta de `example`)
+
+#### Devtool solo muestran "Instance of MyClass". Que puedo hacer?
+
+Por defecto, devtool necesita `toString`, el cual por defecto es "Instance of MyClass".
+
+Para algo más útil, tienes dos opciones:
+
+- Usa el API [Diagnosticable](https://api.flutter.dev/flutter/foundation/Diagnosticable-class.html) de Flutter.
+
+  Para la mayoría de los casos, esto se logrará utilizando [DiagnosticableTreeMixin]
+  en tus objetos, siguiendo la implementación personalizada de [debugFillProperties](https://api.flutter.dev/flutter/foundation/DiagnosticableTreeMixin/debugFillProperties.html).
+
+  ```dart
+  class MyClass with DiagnosticableTreeMixin {
+    MyClass({this.a, this.b});
+
+    final int a;
+    final String b;
+
+    @override
+    void debugFillProperties(DiagnosticPropertiesBuilder properties) {
+      super.debugFillProperties(properties);
+      // list all the properties of your class here.
+      // See the documentation of debugFillProperties for more information.
+      properties.add(IntProperty('a', a));
+      properties.add(StringProperty('b', b));
+    }
+  }
+  ```
+
+- override `toString`.
+
+  Si no puedes usar [DiagnosticableTreeMixin] (como si tu clase estuviera en un paquete
+  que no depende de Flutter), entonces puedes simplemente usar el método override `toString`.
+
+  Esto es más fácil que usar [DiagnosticableTreeMixin] pero es menos poderoso:
+  No podrás expandir/contraer los detalles de tu objeto.
+
+  ```dart
+  class MyClass with DiagnosticableTreeMixin {
+    MyClass({this.a, this.b});
+
+    final int a;
+    final String b;
+
+    @override
+    String toString() {
+      return '$runtimeType(a: $a, b: $b)';
+    }
+  }
+  ```
+
+#### Me aparece una exception cuando obtengo Providers dentro de `initState`. Que puedo hacer?
+
+Esta excepción ocurre porque estás tratando de escuchar a un provider de un
+life-cycle que nunca jamás será llamado de nuevo.
+
+Significa que debes usar otro ciclo de vida (`build`), o explícitamente
+específica que no te importan las actualizaciones.
+
+Entonces, en lugar de:
+
+```dart
+initState() {
+  super.initState();
+  print(context.watch<Foo>().value);
+}
+```
+
+puedes hacer esto:
+
+```dart
+Value value;
+
+Widget build(BuildContext context) {
+  final value = context.watch<Foo>.value;
+  if (value != this.value) {
+    this.value = value;
+    print(value);
+  }
+}
+```
+
+El cual imprime `value` cuando sea que cambie (y solo cuando cambie)
+
+También puedes hacer esto:
+
+```dart
+initState() {
+  super.initState();
+  print(context.read<Foo>().value);
+}
+```
+
+El cual imprimirá `value` una vez _e ignorará las actualizaciones._
+
+#### Como manejar hot-reload en mis objetos?
+
+Puedes hacer que el objeto de tu provider implemente `ReassembleHandler`:
+
+```dart
+class Example extends ChangeNotifier implements ReassembleHandler {
+  @override
+  void reassemble() {
+    print('Did hot-reload');
+  }
+}
+```
+
+Después úsalo de forma normal con `provider`:
+
+```dart
+ChangeNotifierProvider(create: (_) => Example()),
+```
+
+#### Utilizo [ChangeNotifier] y tengo una exception cuando se actualiza, que sucede?
+
+Es probable que esto ocurra porque se está modificando el [ChangeNotifier] de uno de
+sus descendientes, _mientras que el árbol de los widgets se está construyendo_.
+
+Una situación típica en la que esto ocurre es cuando se inicia una petición http, donde
+el futuro está almacenado dentro del notifier:
+
+
+```dart
+initState() {
+  super.initState();
+  context.read<MyNotifier>().fetchSomething();
+}
+```
+
+Esto no está permitido, porque la actualización es inmediata.
+
+Lo que significa que algunos widgets pueden construir _antes_ de la mutación, mientras que otros
+widgets construirán _después_ de la mutación.
+Esto podría causar inconsistencias en su UI y por lo tanto no está permitido.
+
+En su lugar, deberías realizar esa mutación en un lugar que afectará a todo
+el árbol por igual:
+
+- directamente dentro del `create` de tu provider/constructor de tu modelo:
+
+  ```dart
+  class MyNotifier with ChangeNotifier {
+    MyNotifier() {
+      _fetchSomething();
+    }
+
+    Future<void> _fetchSomething() async {}
+  }
+  ```
+
+  Esto es útil cuando no existe un "parámetro externo".
+
+- asincronamente al final del frame
+  ```dart
+  initState() {
+    super.initState();
+    Future.microtask(() =>
+      context.read<MyNotifier>(context).fetchSomething(someValue);
+    );
+  }
+  ```
+  Esto es ligeramente menos ideal, pero permite pasar parámetros a la mutación.
+
+#### Tengo que usar [ChangeNotifier] para estados complejos?
+
+No.
+
+Puedes utilizar un objeto para representar tu estado. Por ejemplo, otra opción
+es usar la arquitectura de `Provider.value()` combinada con `StatefulWidget`.
+
+Aquí está un ejemplo del counter usando tal arquitectura:
+
+```dart
+class Example extends StatefulWidget {
+  const Example({Key key, this.child}) : super(key: key);
+
+  final Widget child;
+
+  @override
+  ExampleState createState() => ExampleState();
+}
+
+class ExampleState extends State<Example> {
+  int _count;
+
+  void increment() {
+    setState(() {
+      _count++;
+    });
+  }
+
+  @override
+  Widget build(BuildContext context) {
+    return Provider.value(
+      value: _count,
+      child: Provider.value(
+        value: this,
+        child: widget.child,
+      ),
+    );
+  }
+}
+```
+
+donde podemos leer el estado haciendo esto:
+
+```dart
+return Text(context.watch<int>().toString());
+```
+
+y modificar el estado con:
+
+```dart
+return FloatingActionButton(
+  onPressed: () => context.read<ExampleState>().increment(),
+  child: Icon(Icons.plus_one),
+);
+```
+
+También, puedes crear tu propio provider.
+
+#### Puedo hacer mi propio Provider?
+
+Si. `provider` muestra todos los pequeños componentes para hacer el tuyo.
+
+Esto incluye:
+
+- `SingleChildStatelessWidget`, para hacer que el widget funcione con `MultiProvider`.  
+  Esta interfaz es expuesta como parte de `package:provider/single_child_widget`
+
+- [InheritedProvider], el `InheritedWidget` genérico obtenido cuando hacemos `context.watch`.
+
+Aquí está un ejemplo de un provider personalizado para usar `ValueNotifier` como estado:
+https://gist.github.com/rrousselGit/4910f3125e41600df3c2577e26967c91
+
+#### Mi widget hace muchos rebuilds, que puedo hacer?
+
+En lugar de usar `context.watch`, puedes usar `context.select` para escuchar solo a un conjunto
+específico de propiedades en el objeto obtenido
+
+Por ejemplo, podrías escribir esto:
+
+```dart
+Widget build(BuildContext context) {
+  final person = context.watch<Person>();
+  return Text(person.name);
+}
+```
+
+Podría provocar que el widget haga rebuild, si otro aparte de `name` cambia.
+
+En su lugar, puedes usar `context.select` para escuchar solo los cambios en la propiedad `name`:
+
+```dart
+Widget build(BuildContext context) {
+  final name = context.select((Person p) => p.name);
+  return Text(name);
+}
+```
+
+De esta manera, el widget no realizará rebuilds innecesarios si algo aparte de `name` cambia.
+
+Similarmente, puedes utilizar [Consumer]/[Selector].
+Su propiedad `child` opcional permite solo hacer rebuild en una parte especifica del
+árbol de widgets.
+
+```dart
+Foo(
+  child: Consumer<A>(
+    builder: (_, a, child) {
+      return Bar(a: a, child: child);
+    },
+    child: Baz(),
+  ),
+)
+```
+
+En este ejemplo, solo `Bar` hará un rebuild cuando `A` actualice. `Foo` y `Baz` no harán builds
+innecesarios.
+
+#### Puedo obtener dos providers diferentes usando el mismo tipo?
+
+No. Aunque puedes tener varios providers compartiendo el mismo tipo, un widget
+será capaz de obtener sólo uno de ellos: el ancestro más cercano.
+
+En cambio, debe dar explícitamente a ambos proveedores un tipo diferente
+
+En lugar de:
+
+```dart
+Provider<String>(
+  create: (_) => 'England',
+  child: Provider<String>(
+    create: (_) => 'London',
+    child: ...,
+  ),
+),
+```
+
+Utiliza:
+
+```dart
+Provider<Country>(
+  create: (_) => Country('England'),
+  child: Provider<City>(
+    create: (_) => City('London'),
+    child: ...,
+  ),
+),
+```
+
+#### Puedo consumir una interfaz y proveer una implementación?
+
+Sí, se debe dar una pista del tipo al compilador para indicar que la interfaz se consumirá, con la implementación prevista en create.
+
+```dart
+abstract class ProviderInterface with ChangeNotifier {
+  ...
+}
+
+class ProviderImplementation with ChangeNotifier implements ProviderInterface {
+  ...
+}
+
+class Foo extends StatelessWidget {
+  @override
+  build(context) {
+    final provider = Provider.of<ProviderInterface>(context);
+    return ...
+  }
+}
+
+ChangeNotifierProvider<ProviderInterface>(
+  create: (_) => ProviderImplementation(),
+  child: Foo(),
+),
+```
+
+### Providers existentes
+
+`provider` nos muestra algunos tipos diferentes de "provider" para diferentes tipos de objetos.
+
+La lista completa de todos los objetos disponibles esta [aquí](https://pub.dev/documentation/provider/latest/provider/provider-library.html)
+
+| Nombre                                                                                                                        | Descripción                                                                                                                                                                               |
+| ----------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | 
+| [Provider](https://pub.dartlang.org/documentation/provider/latest/provider/Provider-class.html)                               | La forma más básica de provider. Toma un valor y lo expone, sea cual sea el valor.                                                                                                        |
+| [ListenableProvider](https://pub.dartlang.org/documentation/provider/latest/provider/ListenableProvider-class.html)           | Un proveedor específico para el objeto Listenable. ListenableProvider escuchará el objeto y pedirá a los widgets que dependen de él que lo reconstruyan siempre que se llame al listener. |
+| [ChangeNotifierProvider](https://pub.dartlang.org/documentation/provider/latest/provider/ChangeNotifierProvider-class.html)   | Se especifica el tipo de ListenableProvider para ChangeNotifier. Este llamará automáticamente `ChangeNotifier.dispose` cuando lo necesite.                                                |
+| [ValueListenableProvider](https://pub.dartlang.org/documentation/provider/latest/provider/ValueListenableProvider-class.html) | Escucha al ValueListenable y solo muestra `ValueListenable.value`.                                                                                                                        |
+| [StreamProvider](https://pub.dartlang.org/documentation/provider/latest/provider/StreamProvider-class.html)                   | Escucha a un Stream y muestra el último valor emitido.                                                                                                                                    |
+| [FutureProvider](https://pub.dartlang.org/documentation/provider/latest/provider/FutureProvider-class.html)                   | Toma un `Future` y actualiza a sus dependientes cuando el futuro es completado.                                                                                                          |
+
+[provider.of]: https://pub.dev/documentation/provider/latest/provider/Provider/of.html
+[selector]: https://pub.dev/documentation/provider/latest/provider/Selector-class.html
+[consumer]: https://pub.dev/documentation/provider/latest/provider/Consumer-class.html
+[changenotifier]: https://api.flutter.dev/flutter/foundation/ChangeNotifier-class.html
+[inheritedwidget]: https://api.flutter.dev/flutter/widgets/InheritedWidget-class.html
+[inheritedprovider]: https://pub.dev/documentation/provider/latest/provider/InheritedProvider-class.html
+[diagnosticabletreemixin]: https://api.flutter.dev/flutter/foundation/DiagnosticableTreeMixin-mixin.html