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() {}
