Version 2.16.0-52.0.dev

Merge commit 'a98368c2506781c3552c2561f74b3efafd84386e' into 'dev'
diff --git a/sdk/lib/collection/hash_map.dart b/sdk/lib/collection/hash_map.dart
index 2d4f42c..9bc1661 100644
--- a/sdk/lib/collection/hash_map.dart
+++ b/sdk/lib/collection/hash_map.dart
@@ -18,6 +18,8 @@
 
 /// A hash-table based implementation of [Map].
 ///
+/// The [HashMap] is unordered (the order of iteration is not guaranteed).
+///
 /// The keys of a `HashMap` must have consistent [Object.==]
 /// and [Object.hashCode] implementations. This means that the `==` operator
 /// must define a stable equivalence relation on the keys (reflexive,
@@ -25,11 +27,94 @@
 /// must be the same for objects that are considered equal by `==`.
 ///
 /// Iterating the map's keys, values or entries (through [forEach])
-/// may happen in any order.
-/// The iteration order only changes when the map is modified.
-/// Values are iterated in the same order as their associated keys,
+/// may happen in any order. The iteration order only changes when the map is
+/// modified. Values are iterated in the same order as their associated keys,
 /// so iterating the [keys] and [values] in parallel
 /// will give matching key and value pairs.
+///
+/// **Notice:**
+/// Do not modify a map (add or remove keys) while an operation
+/// is being performed on that map, for example in functions
+/// called during a [forEach] or [putIfAbsent] call,
+/// or while iterating the map ([keys], [values] or [entries]).
+///
+/// Example:
+/// ```dart
+/// final Map<int, String> planets = HashMap(); // Is a HashMap
+/// ```
+/// To add data to a map, use [operator[]=], [addAll] or [addEntries].
+/// ```
+/// planets[3] = 'Earth';
+/// planets.addAll({4: 'Mars'});
+/// final gasGiants = {6: 'Jupiter', 5: 'Saturn'};
+/// planets.addEntries(gasGiants.entries);
+/// print(planets); // fx {5: Saturn, 6: Jupiter, 3: Earth, 4: Mars}
+/// ```
+/// To check if the map is empty, use [isEmpty] or [isNotEmpty].
+/// To find the number of map entries, use [length].
+/// ```
+/// final isEmpty = planets.isEmpty; // false
+/// final length = planets.length; // 4
+/// ```
+/// The [forEach] iterates through all entries of a map.
+/// ```
+/// planets.forEach((key, value) {
+///   print('$key \t $value');
+///   // 5        Saturn
+///   // 4        Mars
+///   // 3        Earth
+///   // 6        Jupiter
+/// });
+/// ```
+/// To check whether the map has an entry with a specific key, use [containsKey].
+/// ```
+/// final keyOneExists = planets.containsKey(4); // true
+/// final keyFiveExists = planets.containsKey(1); // false
+/// ```
+/// To check whether the map has an entry with a specific value,
+/// use [containsValue].
+/// ```
+/// final marsExists = planets.containsValue('Mars'); // true
+/// final venusExists = planets.containsValue('Venus'); // false
+/// ```
+/// To remove an entry with a specific key, use [remove].
+/// ```
+/// final removeValue = planets.remove(5);
+/// print(removeValue); // Jupiter
+/// print(planets); // fx {4: Mars, 3: Earth, 5: Saturn}
+/// ```
+/// To remove multiple entries at the same time, based on their keys and values,
+/// use [removeWhere].
+/// ```
+/// planets.removeWhere((key, value) => key == 5);
+/// print(planets); // fx {3: Earth, 4: Mars}
+/// ```
+/// To conditionally add or modify a value for a specific key, depending on
+/// whether there already is an entry with that key,
+/// use [putIfAbsent] or [update].
+/// ```
+/// planets.update(4, (v) => 'Saturn');
+/// planets.update(8, (v) => '', ifAbsent: () => 'Neptune');
+/// planets.putIfAbsent(4, () => 'Another Saturn');
+/// print(planets); // fx {4: Saturn, 8: Neptune, 3: Earth}
+/// ```
+/// To update the values of all keys, based on the existing key and value,
+/// use [updateAll].
+/// ```
+/// planets.updateAll((key, value) => 'X');
+/// print(planets); // fx {8: X, 3: X, 4: X}
+/// ```
+/// To remove all entries and empty the map, use [clear].
+/// ```
+/// planets.clear();
+/// print(planets); // {}
+/// print(planets.isEmpty); // true
+/// ```
+///
+/// **See also:**
+/// * [Map], the general interface of key/value pair collections.
+/// * [LinkedHashMap] iterates in key insertion order.
+/// * [SplayTreeMap] iterates the keys in sorted order.
 abstract class HashMap<K, V> implements Map<K, V> {
   /// Creates an unordered hash-table based [Map].
   ///
@@ -41,12 +126,12 @@
   /// new keys. If [equals] is omitted, the key's own [Object.==] is used
   /// instead.
   ///
-  /// Similar, if [hashCode] is provided, it is used to produce a hash value
+  /// Similarly, if [hashCode] is provided, it is used to produce a hash value
   /// for keys in order to place them in the map. If [hashCode] is omitted,
   /// the key's own [Object.hashCode] is used.
   ///
   /// The used `equals` and `hashCode` method should always be consistent,
-  /// so that if `equals(a, b)` then `hashCode(a) == hashCode(b)`. The hash
+  /// so that if `equals(a, b)`, then `hashCode(a) == hashCode(b)`. The hash
   /// of an object, or what it compares equal to, should not change while the
   /// object is a key in the map. If it does change, the result is
   /// unpredictable.
@@ -67,7 +152,7 @@
   /// Example:
   /// ```dart template:expression
   /// HashMap<int,int>(equals: (int a, int b) => (b - a) % 5 == 0,
-  ///                  hashCode: (int e) => e % 5)
+  ///                  hashCode: (int e) => e % 5);
   /// ```
   /// This example map does not need an `isValidKey` function to be passed.
   /// The default function accepts precisely `int` values, which can safely be
@@ -90,9 +175,9 @@
   /// Creates an unordered identity-based map.
   ///
   /// Keys of this map are considered equal only to the same object,
-  /// and does not use [Object.==] at all.
+  /// and do not use [Object.==] at all.
   ///
-  /// Effectively a shorthand for:
+  /// Effectively shorthand for:
   /// ```dart
   /// HashMap<K, V>(equals: identical, hashCode: identityHashCode)
   /// ```
@@ -102,6 +187,11 @@
   ///
   /// The keys must all be instances of [K] and the values of [V].
   /// The [other] map itself can have any type.
+  /// ```dart
+  /// final baseMap = {1: 'A', 2: 'B', 3: 'C'};
+  /// final fromBaseMap = HashMap<int, String>.from(baseMap);
+  /// print(fromBaseMap); // {1: A, 2: B, 3: C}
+  /// ```
   factory HashMap.from(Map<dynamic, dynamic> other) {
     HashMap<K, V> result = HashMap<K, V>();
     other.forEach((dynamic k, dynamic v) {
@@ -111,6 +201,12 @@
   }
 
   /// Creates a [HashMap] that contains all key/value pairs of [other].
+  /// Example:
+  /// ```dart
+  /// final baseMap = <int, String>{1: 'A', 2: 'B', 3: 'C'};
+  /// final mapOf = HashMap<num, Object>.of(baseMap);
+  /// print(mapOf); // {1: A, 2: B, 3: C}
+  /// ```
   factory HashMap.of(Map<K, V> other) => HashMap<K, V>()..addAll(other);
 
   /// Creates a [HashMap] where the keys and values are computed from the
@@ -122,8 +218,15 @@
   /// The keys of the key/value pairs do not need to be unique. The last
   /// occurrence of a key will simply overwrite any previous value.
   ///
-  /// If no values are specified for [key] and [value] the default is the
+  /// If no values are specified for [key] and [value], the default is the
   /// identity function.
+  /// Example:
+  /// ```dart
+  /// final numbers = [11, 12, 13, 14];
+  /// final mapFromIterable = HashMap<int, int>.fromIterable(numbers,
+  ///     key: (i) => i, value: (i) => i * i);
+  /// print(mapFromIterable); // {11: 121, 12: 144, 13: 169, 14: 196}
+  /// ```
   factory HashMap.fromIterable(Iterable iterable,
       {K Function(dynamic element)? key, V Function(dynamic element)? value}) {
     HashMap<K, V> map = HashMap<K, V>();
@@ -140,6 +243,14 @@
   /// overwrites the previous value.
   ///
   /// It is an error if the two [Iterable]s don't have the same length.
+  /// Example:
+  /// ```dart
+  /// final keys = ['Mercury', 'Venus', 'Earth', 'Mars'];
+  /// final values = [0.06, 0.81, 1, 0.11];
+  /// final mapFromIterables = HashMap.fromIterables(keys, values);
+  /// print(mapFromIterables);
+  /// // {Earth: 1, Mercury: 0.06, Mars: 0.11, Venus: 0.81}
+  /// ```
   factory HashMap.fromIterables(Iterable<K> keys, Iterable<V> values) {
     HashMap<K, V> map = HashMap<K, V>();
     MapBase._fillMapWithIterables(map, keys, values);
@@ -153,6 +264,13 @@
   ///
   /// If multiple [entries] have the same key,
   /// later occurrences overwrite the earlier ones.
+  ///
+  /// Example:
+  /// ```dart
+  /// final numbers = [11, 12, 13, 14];
+  /// final map = HashMap.fromEntries(numbers.map((i) => MapEntry(i, i * i)));
+  /// print(map); // {11: 121, 12: 144, 13: 169, 14: 196}
+  /// ```
   @Since("2.1")
   factory HashMap.fromEntries(Iterable<MapEntry<K, V>> entries) =>
       HashMap<K, V>()..addEntries(entries);
diff --git a/sdk/lib/collection/hash_set.dart b/sdk/lib/collection/hash_set.dart
index 1f94ffb..29ef55b 100644
--- a/sdk/lib/collection/hash_set.dart
+++ b/sdk/lib/collection/hash_set.dart
@@ -10,17 +10,91 @@
 /// and hashCode implementations. This means that the equals operation
 /// must define a stable equivalence relation on the elements (reflexive,
 /// symmetric, transitive, and consistent over time), and that the hashCode
-/// must consistent with equality, so that the same for objects that are
+/// must be consistent with equality, so that it's the same for objects that are
 /// considered equal.
 ///
 /// Most simple operations on `HashSet` are done in (potentially amortized)
 /// constant time: [add], [contains], [remove], and [length], provided the hash
 /// codes of objects are well distributed.
 ///
-/// The iteration order of the set is not specified and depends on
-/// the hashcodes of the provided elements. However, the order is stable:
+/// **The iteration order of the set is not specified and depends on
+/// the hashcodes of the provided elements.** However, the order is stable:
 /// multiple iterations over the same set produce the same order, as long as
 /// the set is not modified.
+///
+/// **Note:**
+/// Do not modify a set (add or remove elements) while an operation
+/// is being performed on that set, for example in functions
+/// called during a [forEach] or [containsAll] call,
+/// or while iterating the set.
+///
+/// Do not modify elements in a way which changes their equality (and thus their
+/// hash code) while they are in the set. Some specialized kinds of sets may be
+/// more permissive with regards to equality, in which case they should document
+/// their different behavior and restrictions.
+///
+/// Example:
+/// ```dart
+/// final letters = HashSet<String>();
+/// ```
+/// To add data to a set, use  [add] or [addAll].
+/// ```
+/// letters.add('A');
+/// letters.addAll({'B', 'C', 'D'});
+/// ```
+/// To check if the set is empty, use [isEmpty] or [isNotEmpty].
+/// To find the number of elements in the set, use [length].
+/// ```
+/// print(letters.isEmpty); // false
+/// print(letters.length); // 4
+/// print(letters); // fx {A, D, C, B}
+/// ```
+/// To check whether the set has an element with a specific value,
+/// use [contains].
+/// ```
+/// final bExists = letters.contains('B'); // true
+/// ```
+/// The [forEach] method calls a function with each element of the set.
+/// ```
+/// letters.forEach(print);
+/// // A
+/// // D
+/// // C
+/// // B
+/// ```
+/// To make a copy of the set, use [toSet].
+/// ```
+/// final anotherSet = letters.toSet();
+/// print(anotherSet); // fx {A, C, D, B}
+/// ```
+/// To remove an element, use [remove].
+/// ```
+/// final removedValue = letters.remove('A'); // true
+/// print(letters); // fx {B, C, D}
+/// ```
+/// To remove multiple elements at the same time, use [removeWhere] or
+/// [removeAll].
+/// ```
+/// letters.removeWhere((element) => element.startsWith('B'));
+/// print(letters); // fx {D, C}
+/// ```
+/// To removes all elements in this set that do not meet a condition,
+/// use [retainWhere].
+/// ```
+/// letters.retainWhere((element) => element.contains('C'));
+/// print(letters); // {C}
+/// ```
+/// To remove all elements and empty the set, use [clear].
+/// ```
+/// letters.clear();
+/// print(letters.isEmpty); // true
+/// print(letters); // {}
+/// ```
+/// **See also:**
+/// * [Set] is the general interface of collection where each object can
+/// occur only once.
+/// * [LinkedHashSet] objects stored based on insertion order.
+/// * [SplayTreeSet] iterates the objects in sorted order.
 abstract class HashSet<E> implements Set<E> {
   /// Create a hash set using the provided [equals] as equality.
   ///
@@ -31,7 +105,7 @@
   /// the elements' intrinsic [Object.==] and [Object.hashCode].
   ///
   /// If you supply one of [equals] and [hashCode],
-  /// you should generally also to supply the other.
+  /// you should generally also supply the other.
   ///
   /// Some [equals] or [hashCode] functions might not work for all objects.
   /// If [isValidKey] is supplied, it's used to check a potential element
@@ -44,7 +118,7 @@
   /// instance of [E], which means that:
   /// ```dart template:expression
   /// HashSet<int>(equals: (int e1, int e2) => (e1 - e2) % 5 == 0,
-  ///              hashCode: (int e) => e % 5)
+  ///              hashCode: (int e) => e % 5);
   /// ```
   /// does not need an `isValidKey` argument because it defaults to only
   /// accepting `int` values which are accepted by both `equals` and `hashCode`.
@@ -65,7 +139,7 @@
 
   /// Creates an unordered identity-based set.
   ///
-  /// Effectively a shorthand for:
+  /// Effectively shorthand for:
   /// ```dart
   /// HashSet<E>(equals: identical, hashCode: identityHashCode)
   /// ```
@@ -86,6 +160,12 @@
   /// Set<SubType> subSet =
   ///     HashSet<SubType>.from(superSet.whereType<SubType>());
   /// ```
+  /// Example:
+  /// ```dart
+  /// final numbers = <num>[10, 20, 30];
+  /// final hashSetFrom = HashSet<int>.from(numbers);
+  /// print(hashSetFrom); // fx {20, 10, 30}
+  /// ```
   factory HashSet.from(Iterable<dynamic> elements) {
     HashSet<E> result = HashSet<E>();
     for (final e in elements) {
@@ -96,15 +176,21 @@
 
   /// Create a hash set containing all [elements].
   ///
-  /// Creates a hash set as by `new HashSet<E>()` and adds all given [elements]
+  /// Creates a hash set as by `HashSet<E>()` and adds all given [elements]
   /// to the set. The elements are added in order. If [elements] contains
   /// two entries that are equal, but not identical, then the first one is
   /// the one in the resulting set.
+  /// Example:
+  /// ```dart
+  /// final baseSet = <int>{1, 2, 3};
+  /// final hashSetOf = HashSet<num>.of(baseSet);
+  /// print(hashSetOf); // fx {3, 1, 2}
+  /// ```
   factory HashSet.of(Iterable<E> elements) => HashSet<E>()..addAll(elements);
 
   /// Provides an iterator that iterates over the elements of this set.
   ///
   /// The order of iteration is unspecified,
-  /// but consistent between changes to the set.
+  /// but is consistent between changes to the set.
   Iterator<E> get iterator;
 }
diff --git a/sdk/lib/collection/linked_hash_map.dart b/sdk/lib/collection/linked_hash_map.dart
index 646b581..be71118 100644
--- a/sdk/lib/collection/linked_hash_map.dart
+++ b/sdk/lib/collection/linked_hash_map.dart
@@ -4,7 +4,16 @@
 
 part of dart.collection;
 
-/// A hash-table based implementation of [Map].
+/// An insertion-ordered [Map] with expected constant-time lookup.
+///
+/// A non-constant map literal, like `{"a": 42, "b": 7}`, is a `LinkedHashMap`.
+///
+/// The [keys], [values] and [entries] are iterated in key insertion order.
+///
+/// The map uses a hash-table to look up entries, so keys must have
+/// suitable implementations of [Object.operator==] and [Object.hashCode].
+/// If the hash codes are not well-distributed, the performance of map
+/// operations may suffer.
 ///
 /// The insertion order of keys is remembered,
 /// and keys are iterated in the order they were inserted into the map.
@@ -14,11 +23,93 @@
 /// but removing the key and adding it again
 /// will make it be last in the iteration order.
 ///
+/// **Notice:**
+/// Do not modify a map (add or remove keys) while an operation
+/// is being performed on that map, for example in functions
+/// called during a [forEach] or [putIfAbsent] call,
+/// or while iterating the map ([keys], [values] or [entries]).
+///
 /// The keys of a `LinkedHashMap` must have consistent [Object.==]
 /// and [Object.hashCode] implementations. This means that the `==` operator
 /// must define a stable equivalence relation on the keys (reflexive,
 /// symmetric, transitive, and consistent over time), and that `hashCode`
 /// must be the same for objects that are considered equal by `==`.
+///
+/// Example:
+///
+/// ```dart
+/// final planetsByDiameter = {0.949: 'Venus'}; // A new LinkedHashMap
+/// ```
+/// To add data to a map, use [operator[]=], [addAll] or [addEntries].
+/// ```
+/// planetsByDiameter[1] = 'Earth';
+/// planetsByDiameter.addAll({0.532: 'Mars', 11.209: 'Jupiter'});
+/// ```
+/// To check if the map is empty, use [isEmpty] or [isNotEmpty].
+/// To find the number of map entries, use [length].
+/// ```
+/// print(planetsByDiameter.isEmpty); // false
+/// print(planetsByDiameter.length); // 4
+/// print(planetsByDiameter);
+/// // {0.949: Venus, 1.0: Earth, 0.532: Mars, 11.209: Jupiter}
+/// ```
+/// The [forEach] method calls a function for each key/value entry of the map.
+/// ```
+/// planetsByDiameter.forEach((key, value) {
+///   print('$key \t $value');
+///   // 0.949    Venus
+///   // 1.0      Earth
+///   // 0.532    Mars
+///   // 11.209   Jupiter
+/// });
+/// ```
+/// To check whether the map has an entry with a specific key, use [containsKey].
+/// ```
+/// final keyOneExists = planetsByDiameter.containsKey(1); // true
+/// final keyFiveExists = planetsByDiameter.containsKey(5); // false
+/// ```
+/// To check whether the map has an entry with a specific value,
+/// use [containsValue].
+/// ```
+/// final earthExists = planetsByDiameter.containsValue('Earth'); // true
+/// final saturnExists =  planetsByDiameter.containsValue('Saturn'); // false
+/// ```
+/// To remove an entry with a specific key, use [remove].
+/// ```
+/// final removedValue = planetsByDiameter.remove(1);
+/// print(removedValue); // Earth
+/// print(planetsByDiameter); // {0.949: Venus, 0.532: Mars, 11.209: Jupiter}
+/// ```
+/// To remove multiple entries at the same time, based on their keys and values,
+/// use [removeWhere].
+/// ```
+/// planetsByDiameter.removeWhere((key, value) => key == 0.949);
+/// print(planetsByDiameter); // {0.532: Mars, 11.209: Jupiter}
+/// ```
+/// To conditionally add or modify a value for a specific key, depending on
+/// whether there already is an entry with that key,
+/// use [putIfAbsent] or [update].
+/// ```
+/// planetsByDiameter.update(0.949, (v) => 'Venus', ifAbsent: () => 'Venus');
+/// planetsByDiameter.putIfAbsent(0.532, () => "Another Mars if needed");
+/// print(planetsByDiameter); // {0.532: Mars, 11.209: Jupiter, 0.949: Venus}
+/// ```
+/// To update the values of all keys, based on the existing key and value,
+/// use [updateAll].
+/// ```
+/// planetsByDiameter.updateAll((key, value) => 'X');
+/// print(planetsByDiameter); // {0.532: X, 11.209: X, 0.949: X}
+/// ```
+/// To remove all entries and empty the map, use [clear].
+/// ```
+/// planetsByDiameter.clear();
+/// print(planetsByDiameter); // {}
+/// print(planetsByDiameter.isEmpty); // true
+/// ```
+/// **See also:**
+/// * [Map], the general interface of key/value pair collections.
+/// * [HashMap] is unordered (the order of iteration is not guaranteed).
+/// * [SplayTreeMap] iterates the keys in sorted order.
 abstract class LinkedHashMap<K, V> implements Map<K, V> {
   /// Creates an insertion-ordered hash-table based [Map].
   ///
@@ -26,7 +117,7 @@
   /// new keys. If [equals] is omitted, the key's own [Object.==] is used
   /// instead.
   ///
-  /// Similar, if [hashCode] is provided, it is used to produce a hash value
+  /// Similarly, if [hashCode] is provided, it is used to produce a hash value
   /// for keys in order to place them in the hash table. If it is omitted, the
   /// key's own [Object.hashCode] is used.
   ///
@@ -35,7 +126,7 @@
   /// of an object, or what it compares equal to, should not change while the
   /// object is in the table. If it does change, the result is unpredictable.
   ///
-  /// If you supply one of [equals] and [hashCode],
+  /// If you supply one of [equals] or [hashCode],
   /// you should generally also supply the other.
   ///
   /// Some [equals] or [hashCode] functions might not work for all objects.
@@ -73,7 +164,7 @@
 
   /// Creates an insertion-ordered identity-based map.
   ///
-  /// Effectively a shorthand for:
+  /// Effectively shorthand for:
   /// ```dart template:expression
   /// LinkedHashMap<K, V>(equals: identical,
   ///                     hashCode: identityHashCode)
@@ -84,6 +175,12 @@
   ///
   /// The keys must all be instances of [K] and the values to [V].
   /// The [other] map itself can have any type.
+  /// Example:
+  /// ```dart
+  /// final baseMap = <num, Object>{1: 'A', 2: 'B', 3: 'C'};
+  /// final fromBaseMap = LinkedHashMap<int, String>.from(baseMap);
+  /// print(fromBaseMap); // {1: A, 2: B, 3: C}
+  /// ```
   factory LinkedHashMap.from(Map<dynamic, dynamic> other) {
     LinkedHashMap<K, V> result = LinkedHashMap<K, V>();
     other.forEach((dynamic k, dynamic v) {
@@ -93,20 +190,33 @@
   }
 
   /// Creates a [LinkedHashMap] that contains all key value pairs of [other].
+  /// Example:
+  /// ```dart
+  /// final baseMap = <int, String> {3: 'A', 2: 'B', 1: 'C', 4: 'D'};
+  /// final mapOf = LinkedHashMap<num, Object>.of(baseMap);
+  /// print(mapOf); // {3: A, 2: B, 1: C, 4: D}
+  /// ```
   factory LinkedHashMap.of(Map<K, V> other) =>
       LinkedHashMap<K, V>()..addAll(other);
 
   /// Creates a [LinkedHashMap] where the keys and values are computed from the
   /// [iterable].
   ///
-  /// For each element of the [iterable] this constructor computes a key/value
-  /// pair, by applying [key] and [value] respectively.
+  /// For each element of the [iterable], this constructor computes a key/value
+  /// pair by applying [key] and [value] respectively.
   ///
   /// The keys of the key/value pairs do not need to be unique. The last
   /// occurrence of a key will simply overwrite any previous value.
   ///
-  /// If no values are specified for [key] and [value] the default is the
-  /// identity function.
+  /// If no values are specified for [key] and [value], the default is the
+  /// both default to the identity function.
+  /// Example:
+  /// ```dart
+  /// final numbers = [11, 12, 13, 14];
+  /// final mapFromIterable =
+  ///     LinkedHashMap.fromIterable(numbers, key: (i) => i, value: (i) => i * i);
+  /// print(mapFromIterable); // {11: 121, 12: 144, 13: 169, 14: 196}
+  /// ```
   factory LinkedHashMap.fromIterable(Iterable iterable,
       {K Function(dynamic element)? key, V Function(dynamic element)? value}) {
     LinkedHashMap<K, V> map = LinkedHashMap<K, V>();
@@ -123,6 +233,14 @@
   /// overwrites the previous value.
   ///
   /// It is an error if the two [Iterable]s don't have the same length.
+  /// Example:
+  /// ```dart
+  /// final values = [0.06, 0.81, 1, 0.11];
+  /// final keys = ['Mercury', 'Venus', 'Earth', 'Mars'];
+  /// final mapFromIterables = LinkedHashMap.fromIterables(keys, values);
+  /// print(mapFromIterables);
+  /// // {Mercury: 0.06, Venus: 0.81, Earth: 1, Mars: 0.11}
+  /// ```
   factory LinkedHashMap.fromIterables(Iterable<K> keys, Iterable<V> values) {
     LinkedHashMap<K, V> map = LinkedHashMap<K, V>();
     MapBase._fillMapWithIterables(map, keys, values);
@@ -136,6 +254,12 @@
   ///
   /// If multiple [entries] have the same key,
   /// later occurrences overwrite the earlier ones.
+  /// Example:
+  /// ```dart
+  /// final numbers = [11, 12, 13, 14];
+  /// final map = LinkedHashMap.fromEntries(numbers.map((i) => MapEntry(i, i * i)));
+  /// print(map); // {11: 121, 12: 144, 13: 169, 14: 196}
+  /// ```
   @Since("2.1")
   factory LinkedHashMap.fromEntries(Iterable<MapEntry<K, V>> entries) =>
       LinkedHashMap<K, V>()..addEntries(entries);
diff --git a/sdk/lib/collection/linked_hash_set.dart b/sdk/lib/collection/linked_hash_set.dart
index 66be66c..55349c9 100644
--- a/sdk/lib/collection/linked_hash_set.dart
+++ b/sdk/lib/collection/linked_hash_set.dart
@@ -6,7 +6,9 @@
 
 /// A [LinkedHashSet] is a hash-table based [Set] implementation.
 ///
-/// The `LinkedHashSet` also keep track of the order that elements were inserted
+/// The default implementation of [Set] is [LinkedHashSet].
+///
+/// The `LinkedHashSet` also keeps track of the order that elements were inserted
 /// in, and iteration happens in first-to-last insertion order.
 ///
 /// The elements of a `LinkedHashSet` must have consistent [Object.==]
@@ -19,12 +21,88 @@
 /// An element that was added after another will occur later in the iteration.
 /// Adding an element that is already in the set
 /// does not change its position in the iteration order,
-/// but removing an element and adding it again,
+/// but removing an element and adding it again
 /// will make it the last element of an iteration.
 ///
 /// Most simple operations on `HashSet` are done in (potentially amortized)
 /// constant time: [add], [contains], [remove], and [length], provided the hash
-/// codes of objects are well distributed..
+/// codes of objects are well distributed.
+///
+/// **Note:**
+/// Do not modify a set (add or remove elements) while an operation
+/// is being performed on that set, for example in functions
+/// called during a [forEach] or [containsAll] call,
+/// or while iterating the set.
+///
+/// Do not modify elements in a way which changes their equality (and thus their
+/// hash code) while they are in the set. Some specialized kinds of sets may be
+/// more permissive with regards to equality, in which case they should document
+/// their different behavior and restrictions.
+///
+/// Example:
+/// ```dart
+/// final planets = <String>{}; // LinkedHashSet
+/// ```
+/// To add data to a set, use [add] or [addAll].
+/// ```
+/// final uranusAdded = planets.add('Uranus'); // true
+/// planets.addAll({'Venus', 'Mars', 'Earth', 'Jupiter'});
+/// print(planets); // {Uranus, Venus, Mars, Earth, Jupiter}
+/// ```
+/// To check if the set is empty, use [isEmpty] or [isNotEmpty].
+/// To find the number of elements in the set, use [length].
+/// ```
+/// print(planets.isEmpty); // false
+/// print(planets.length); // 5
+/// ```
+/// To check whether the set has an element with a specific value,
+/// use [contains].
+/// ```
+/// final marsExists = planets.contains('Mars'); // true
+/// ```
+/// The [forEach] method calls a function with each element of the set.
+/// ```
+/// planets.forEach(print);
+/// // Uranus
+/// // Venus
+/// // Mars
+/// // Earth
+/// // Jupiter
+/// ```
+///
+/// To make a copy of the set, use [toSet].
+/// ```
+/// final copySet = planets.toSet();
+/// print(copySet); // {Uranus, Venus, Mars, Earth, Jupiter}
+/// ```
+/// To remove an element, use [remove].
+/// ```
+/// final removedValue = planets.remove('Mars'); // Mars
+/// print(planets); // {Uranus, Venus, Earth, Jupiter}
+/// ```
+/// To remove multiple elements at the same time, use [removeWhere] or
+/// [removeAll].
+/// ```
+/// planets.removeWhere((element) => element.startsWith('E'));
+/// print(planets); // {Uranus, Venus, Jupiter}
+/// ```
+/// To removes all elements in this set that do not meet a condition,
+/// use [retainWhere].
+/// ```
+/// planets.retainWhere((element) => element.contains('Jupiter'));
+/// print(planets); // {Jupiter}
+/// ```
+/// To remove all elements and empty the set, use [clear].
+/// ```
+/// planets.clear();
+/// print(planets.isEmpty); // true
+/// print(planets); // {}
+/// ```
+/// **See also:**
+/// * [Set] is the general interface of collection where each object can
+/// occur only once.
+/// * [HashSet] the order of the objects in the iteration is not guaranteed.
+/// * [SplayTreeSet] iterates the objects in sorted order.
 abstract class LinkedHashSet<E> implements Set<E> {
   /// Create an insertion-ordered hash set using the provided
   /// [equals] and [hashCode].
@@ -33,7 +111,7 @@
   /// [hashCode] must be consistent with [equals].
   ///
   /// If you supply one of [equals] and [hashCode],
-  /// you should generally also to supply the other.
+  /// you should generally also supply the other.
   ///
   /// Some [equals] or [hashCode] functions might not work for all objects.
   /// If [isValidKey] is supplied, it's used to check a potential element
@@ -46,12 +124,12 @@
   /// instance of [E], which means that:
   /// ```dart template:expression
   /// LinkedHashSet<int>(equals: (int e1, int e2) => (e1 - e2) % 5 == 0,
-  ///                    hashCode: (int e) => e % 5)
+  ///                    hashCode: (int e) => e % 5);
   /// ```
   /// does not need an `isValidKey` argument, because it defaults to only
   /// accepting `int` values which are accepted by both `equals` and `hashCode`.
   ///
-  /// If neither `equals`, `hashCode`, nor `isValidKey` is provided,
+  /// If neither `equals`, `hashCode`, nor `isValidKey` are provided,
   /// the default `isValidKey` instead accepts all values.
   /// The default equality and hashcode operations are assumed to work on all
   /// objects.
@@ -67,7 +145,7 @@
 
   /// Creates an insertion-ordered identity-based set.
   ///
-  /// Effectively a shorthand for:
+  /// Effectively shorthand for:
   /// ```dart
   /// LinkedHashSet<E>(equals: identical, hashCode: identityHashCode)
   /// ```
@@ -75,7 +153,7 @@
 
   /// Create a linked hash set containing all [elements].
   ///
-  /// Creates a linked hash set as by `new LinkedHashSet<E>()` and adds each
+  /// Creates a linked hash set as by `LinkedHashSet<E>()` and adds each
   /// element of `elements` to this set in the order they are iterated.
   ///
   /// All the [elements] should be instances of [E].
@@ -86,6 +164,12 @@
   /// Iterable<SuperType> tmp = superSet.where((e) => e is SubType);
   /// Set<SubType> subSet = LinkedHashSet<SubType>.from(tmp);
   /// ```
+  /// Example:
+  /// ```dart
+  /// final numbers = <num>[10, 20, 30];
+  /// final setFrom = LinkedHashSet<int>.from(numbers);
+  /// print(setFrom); // {10, 20, 30}
+  /// ```
   factory LinkedHashSet.from(Iterable<dynamic> elements) {
     LinkedHashSet<E> result = LinkedHashSet<E>();
     for (final element in elements) {
@@ -96,8 +180,14 @@
 
   /// Create a linked hash set from [elements].
   ///
-  /// Creates a linked hash set as by `new LinkedHashSet<E>()` and adds each
+  /// Creates a linked hash set as by `LinkedHashSet<E>()` and adds each
   /// element of `elements` to this set in the order they are iterated.
+  /// Example:
+  /// ```dart
+  /// final baseSet = <int>{1, 2, 3};
+  /// final setOf = LinkedHashSet<num>.of(baseSet);
+  /// print(setOf); // {1, 2, 3}
+  /// ```
   factory LinkedHashSet.of(Iterable<E> elements) =>
       LinkedHashSet<E>()..addAll(elements);
 
diff --git a/sdk/lib/collection/linked_list.dart b/sdk/lib/collection/linked_list.dart
index 3e77646..516deee 100644
--- a/sdk/lib/collection/linked_list.dart
+++ b/sdk/lib/collection/linked_list.dart
@@ -28,6 +28,56 @@
 ///
 /// A `LinkedList` also allows constant time adding and removing at either end,
 /// and a constant time length getter.
+///
+/// Example:
+/// ```dart
+/// class EntryItem extends LinkedListEntry<EntryItem> {
+///   final int id;
+///   final String text;
+///   EntryItem(this.id, this.text);
+///
+///   @override
+///   String toString() {
+///     return '$id : $text';
+///   }
+/// }
+///
+/// void main(){
+///   final linkedList = LinkedList<EntryItem>();
+///   linkedList.addAll(
+///       [EntryItem(1, 'A'), EntryItem(2, 'B'), EntryItem(3, 'C')]);
+///   print(linkedList.first); // 1 : A
+///   print(linkedList.last); // 3 : C
+///
+///   // Add new item after first item.
+///   linkedList.first.insertAfter(EntryItem(15, 'E'));
+///   // Add new item before last item.
+///   linkedList.last.insertBefore(EntryItem(10, 'D'));
+///   // Iterate items.
+///   for (var entry in linkedList) {
+///     print(entry);
+///     // 1 : A
+///     // 15 : E
+///     // 2 : B
+///     // 10 : D
+///     // 3 : C
+///   }
+///
+///   // Remove item using index from list.
+///   linkedList.elementAt(2).unlink();
+///   print(linkedList); // (1 : A, 15 : E, 10 : D, 3 : C)
+///   // Remove first item.
+///   linkedList.first.unlink();
+///   print(linkedList); // (15 : E, 10 : D, 3 : C)
+///   // Remove last item from list.
+///   linkedList.remove(linkedList.last);
+///   print(linkedList); // (15 : E, 10 : D)
+///   // Remove all items.
+///   linkedList.clear();
+///   print(linkedList.length); // 0
+///   print(linkedList.isEmpty); // true
+/// }
+/// ```
 class LinkedList<E extends LinkedListEntry<E>> extends Iterable<E> {
   int _modificationCount = 0;
   int _length = 0;
@@ -47,7 +97,7 @@
     _insertBefore(_first, entry, updateFirst: false);
   }
 
-  /// Add [entries] to the end of the linked list.
+  /// Adds [entries] to the end of the linked list.
   void addAll(Iterable<E> entries) {
     entries.forEach(add);
   }
@@ -239,7 +289,7 @@
 
   /// The successor of this element in its linked list.
   ///
-  /// The value is  `null` if there is no successor in the linked list,
+  /// The value is `null` if there is no successor in the linked list,
   /// or if this entry is not currently in any list.
   E? get next {
     if (_list == null || identical(_list!.first, _next)) return null;
diff --git a/sdk/lib/collection/queue.dart b/sdk/lib/collection/queue.dart
index dcdecb4..7f1a6ce 100644
--- a/sdk/lib/collection/queue.dart
+++ b/sdk/lib/collection/queue.dart
@@ -9,12 +9,29 @@
 /// an [Iterator].
 ///
 /// It is generally not allowed to modify the queue (add or remove entries)
-/// while an operation on the queue is being performed, for example during a
+/// while an operation in the queue is being performed, for example during a
 /// call to [forEach].
 /// Modifying the queue while it is being iterated will most likely break the
 /// iteration.
 /// This goes both for using the [iterator] directly, or for iterating an
 /// `Iterable` returned by a method like [map] or [where].
+///
+/// Example:
+/// ```dart
+/// final queue = Queue<int>(); // ListQueue() by default
+/// print(queue.runtimeType); // ListQueue
+///
+/// // Adding items to queue
+/// queue.addAll([1, 2, 3]);
+/// queue.addFirst(0);
+/// queue.addLast(10);
+/// print(queue); // {0, 1, 2, 3, 10}
+///
+/// // Removing items from queue
+/// queue.removeFirst();
+/// queue.removeLast();
+/// print(queue); // {1, 2, 3}
+/// ```
 abstract class Queue<E> implements EfficientLengthIterable<E> {
   /// Creates a queue.
   factory Queue() = ListQueue<E>;
@@ -45,16 +62,16 @@
   /// Any time the queue would produce an element that is not a [T],
   /// the element access will throw.
   ///
-  /// Any time a [T] value is attempted stored into the adapted queue,
-  /// the store will throw unless the value is also an instance of [S].
+  /// When a [T] value is stored into the adapted queue,
+  /// the operation will throw unless the value is also an instance of [S].
   ///
   /// If all accessed elements of [source] are actually instances of [T],
-  /// and if all elements stored into the returned queue are actually instance
+  /// and if all elements stored into the returned queue are actually instances
   /// of [S],
   /// then the returned queue can be used as a `Queue<T>`.
   ///
   /// Methods which accept `Object?` as argument, like [contains] and [remove],
-  /// will pass the argument directly to the this queue's method
+  /// will pass the argument directly to this queue's method
   /// without any checks.
   static Queue<T> castFrom<S, T>(Queue<S> source) => CastQueue<S, T>(source);
 
@@ -65,8 +82,8 @@
   /// that is not an instance of [R], the access will throw instead.
   ///
   /// Elements added to the queue (e.g., by using [addFirst] or [addAll])
-  /// must be instance of [R] to be valid arguments to the adding function,
-  /// and they must be instances of [E] as well to be accepted by
+  /// must be instances of [R] to be valid arguments to the adding function,
+  /// and they must also be instances of [E] to be accepted by
   /// this queue as well.
   ///
   /// Methods which accept `Object?` as argument, like [contains] and [remove],
@@ -95,7 +112,7 @@
   /// Adds [value] at the end of the queue.
   void add(E value);
 
-  /// Remove a single instance of [value] from the queue.
+  /// Removes a single instance of [value] from the queue.
   ///
   /// Returns `true` if a value was removed, or `false` if the queue
   /// contained no element equal to [value].
@@ -437,7 +454,7 @@
   /// [DoubleLinkedQueueEntry.previousEntry()].
   ///
   /// The [action] function can use methods on [DoubleLinkedQueueEntry] to
-  /// remove the entry or it can insert elements before or after then entry.
+  /// remove the entry or it can insert elements before or after the entry.
   /// If the current entry is removed, iteration continues with the entry that
   /// was following the current entry when [action] was called. Any elements
   /// inserted after the current element before it is removed will not be
@@ -509,6 +526,63 @@
 /// amortized constant time add operations.
 ///
 /// The structure is efficient for any queue or stack usage.
+///
+/// Example:
+/// ```dart
+/// final queue = ListQueue<int>();
+/// ```
+/// To add objects to a queue, use [add], [addAll], [addFirst] or[addLast].
+/// ```
+/// queue.add(5);
+/// queue.addFirst(0);
+/// queue.addLast(10);
+/// queue.addAll([1, 2, 3]);
+/// print(queue); // {0, 5, 10, 1, 2, 3}
+/// ```
+/// To check if the queue is empty, use [isEmpty] or [isNotEmpty].
+/// To find the number of queue entries, use [length].
+/// ```
+/// final isEmpty = queue.isEmpty; // false
+/// final queueSize = queue.length; // 6
+/// ```
+/// To get first or last item from queue, use [first] or [last].
+/// ```
+/// final first = queue.first; // 0
+/// final last = queue.last; // 3
+/// ```
+/// To get item value using index, use [elementAt].
+/// ```
+/// final itemAt = queue.elementAt(2); // 10
+/// ```
+/// To convert queue to list, call [toList].
+/// ```
+/// final numbers = queue.toList();
+/// print(numbers); // [0, 5, 10, 1, 2, 3]
+/// ```
+/// To remove item from queue, call [remove], [removeFirst] or [removeLast].
+/// ```
+/// queue.remove(10);
+/// queue.removeFirst();
+/// queue.removeLast();
+/// print(queue); // {5, 1, 2}
+/// ```
+/// To remove multiple elements at the same time, use [removeWhere].
+/// ```
+/// queue.removeWhere((element) => element == 1);
+/// print(queue); // {5, 2}
+/// ```
+/// To remove all elements in this queue that do not meet a condition,
+/// use [retainWhere].
+/// ```
+/// queue.retainWhere((element) => element < 4);
+/// print(queue); // {2}
+/// ```
+/// To remove all items and empty the set, use [clear].
+/// ```
+/// queue.clear();
+/// print(queue.isEmpty); // true
+/// print(queue); // {}
+/// ```
 class ListQueue<E> extends ListIterable<E> implements Queue<E> {
   static const int _INITIAL_CAPACITY = 8;
   List<E?> _table;
@@ -548,6 +622,12 @@
   /// Queue<SubType> subQueue =
   ///     ListQueue<SubType>.from(superQueue.whereType<SubType>());
   /// ```
+  /// Example:
+  /// ```dart
+  /// final numbers = <num>[10, 20, 30];
+  /// final queue = ListQueue<int>.from(numbers);
+  /// print(queue); // {10, 20, 30}
+  /// ```
   factory ListQueue.from(Iterable<dynamic> elements) {
     if (elements is List<dynamic>) {
       int length = elements.length;
@@ -575,6 +655,12 @@
   ///
   /// The elements are added to the queue, as by [addLast], in the order given
   /// by `elements.iterator`.
+  /// Example:
+  /// ```dart
+  /// final baseQueue = ListQueue.of([1.0, 2.0, 3.0]); // A ListQueue<double>
+  /// final numQueue = ListQueue<num>.of(baseQueue);
+  /// print(numQueue); // {1.0, 2.0, 3.0}
+  /// ```
   factory ListQueue.of(Iterable<E> elements) =>
       ListQueue<E>()..addAll(elements);
 
diff --git a/tools/VERSION b/tools/VERSION
index 717f643..5fade91 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
 MAJOR 2
 MINOR 16
 PATCH 0
-PRERELEASE 51
+PRERELEASE 52
 PRERELEASE_PATCH 0
\ No newline at end of file