import 'dart:collection';

class ConstIterable extends IterableBase<int> {
  const ConstIterable();
  Iterator<int> get iterator => <int>[].iterator;
}

const int fortyTwo = 42;
const dynamic fortyTwoAsDynamic = ((fortyTwo as dynamic) * 2) ~/ 2;
const List<String>? nullList = null;
const List<String> foo = ["hello", "world"];
List<String> get fooAsGetter => const ["hello", "world"];
const List<String> bar = [...foo, "!"];
var barAsVar = [...foo, "!"];
List<String> get barAsGetter => const [...foo, "!"];
const List<String> barWithNullSpread = [...foo, ...?nullList];
const List<String> barWithIntSpread = [...foo, ...fortyTwo];
const List<String> barWithIntDynamicSpread = [...foo, ...fortyTwoAsDynamic];
const List<String> barWithMapSpread = [...foo, ...quux];
const List<String> barWithCustomIterableSpread1 = [
  ...bar,
  ...const CustomIterable()
];
const List<String> barWithCustomIterableSpread2 = [...bar, ...CustomIterable()];
const customIterable = const CustomIterable();
const List<String> barWithCustomIterableSpread3 = [...bar, ...customIterable];
const List<String> listConcat = ["Hello"] + ["World"];
const Set<String>? nullSet = null;
const Set<String> baz = {"hello", "world"};
Set<String> get bazAsGetter => const {"hello", "world"};
const Set<String> qux = {...baz, "!"};
Set<String> get quxAsGetter => const {...baz, "!"};
const Set<String> quxWithNullSpread = {...baz, ...?nullSet};
const Set<String> quxWithIntSpread = {...baz, ...fortyTwo};
const Set<String> quxWithMapSpread = {...baz, ...quux};
const Set<String> quxWithCustomIterableSpread1 = {
  ...baz,
  ...const CustomIterable()
};
const Set<String> quxWithCustomIterableSpread2 = {...baz, ...CustomIterable()};
const Set<String> quxWithCustomIterableSpread3 = {...baz, customIterable};
const Set<dynamic> setWithNonPrimitiveEquals = {const WithEquals(42)};
const Set<dynamic> setWithDuplicates = {42, 42};
const Map<String, String>? nullMap = null;
const Map<String, String> quux = {"hello": "world"};
Map<String, String> get quuxAsGetter => const {"hello": "world"};
const Map<String, String> quuz = {...quux, "!": "bye!"};
Map<String, String> get quuzAsGetter => const {...quux, "!": "bye!"};
const Map<String, String> quuzWithNullSpread = {...quux, ...?nullMap};
const Map<String, String> quuzWithIntSpread = {...quux, ...fortyTwo};
const Map<String, String> quuzWithSetSpread = {...quux, ...baz};
const Map<String, String> mapWithSetSpread = {...baz};
const Map<String, String> mapWithCustomMap1 = {...const CustomMap()};
const Map<String, String> mapWithCustomMap2 = {...CustomMap()};
const Map<String, String> customMap = const CustomMap();
const Map<String, String> mapWithCustomMap3 = {...customMap};
const Map<dynamic, int> mapWithNonPrimitiveEqualsKey = {
  const WithEquals(42): 42
};
const Map<int, int> mapWithDuplicates = {42: 42, 42: 42};

class WithEquals {
  final int i;
  const WithEquals(this.i);
  operator ==(Object o) {}
}

class CustomIterable extends IterableBase<String> {
  const CustomIterable();
  Iterator<String> get iterator => <String>[].iterator;
}

class CustomMap implements Map<String, String> {
  const CustomMap();
  @override
  Iterable<MapEntry<String, String>> get entries => [];
  @override
  String operator [](Object? key) => throw new UnimplementedError();
  @override
  void operator []=(String key, String value) => throw new UnimplementedError();
  @override
  Map<RK, RV> cast<RK, RV>() => throw new UnimplementedError();
  @override
  void clear() => throw new UnimplementedError();
  @override
  bool containsKey(Object? key) => throw new UnimplementedError();
  @override
  bool containsValue(Object? value) => throw new UnimplementedError();
  @override
  bool get isEmpty => throw new UnimplementedError();
  @override
  bool get isNotEmpty => throw new UnimplementedError();
  @override
  Iterable<String> get keys => throw new UnimplementedError();
  @override
  int get length => throw new UnimplementedError();
  @override
  String remove(Object? key) => throw new UnimplementedError();
  @override
  Iterable<String> get values => throw new UnimplementedError();
  @override
  void addAll(Map<String, String> other) => throw new UnimplementedError();
  @override
  void addEntries(Iterable<MapEntry<String, String>> newEntries) =>
      throw new UnimplementedError();
  @override
  void forEach(void f(String key, String value)) =>
      throw new UnimplementedError();
  @override
  String putIfAbsent(String key, String ifAbsent()) =>
      throw new UnimplementedError();
  @override
  void updateAll(String update(String key, String value)) =>
      throw new UnimplementedError();
  @override
  void removeWhere(bool predicate(String key, String value)) =>
      throw new UnimplementedError();
  String update(String key, String update(String value),
          {String ifAbsent()?}) =>
      throw new UnimplementedError();
  Map<K2, V2> map<K2, V2>(MapEntry<K2, V2> f(String key, String value)) =>
      throw new UnimplementedError();
}

main() {}
