library;
import self as self;
import "dart:core" as core;
import "issue41180_lib.dart" as iss;

import "org-dartlang-testcase:///issue41180_lib.dart";

class D<Y extends core::Object* = dynamic> extends core::Object {
  synthetic constructor •() → self::D<self::D::Y*>*
    : super core::Object::•()
    ;
  method method() → iss::C<self::D::Y*>*
    return new iss::C::•<self::D::Y*>(() → Null => null);
  abstract member-signature get _identityHashCode() → core::int*; -> core::Object::_identityHashCode
  abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*; -> core::Object::_instanceOf
  abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOf
  abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfTrue
  abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfFalse
  abstract member-signature operator ==(dynamic other) → core::bool*; -> core::Object::==
  abstract member-signature get hashCode() → core::int*; -> core::Object::hashCode
  abstract member-signature method toString() → core::String*; -> core::Object::toString
  abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic; -> core::Object::noSuchMethod
  abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType
}
static method main() → void {
  iss::foo(() → Null => null);
  iss::bar = () → iss::Map<core::String*, core::String*>* => null;
  new self::D::•<core::int*>().{self::D::method}(){() →* iss::C<core::int*>*};
  self::findKey(new iss::Map::•<core::String*, core::String*>("foo", "bar"), "bar");
}
static method findKey(iss::Map<core::String*, dynamic>* m, dynamic search) → void {
  core::print(let final core::MapEntry<core::String*, dynamic>* #t1 = m.{iss::Map::entries}{iss::Iterable<core::MapEntry<core::String*, dynamic>*>*}.{iss::Iterable::singleWhere}((core::MapEntry<core::String*, dynamic>* entry) → core::bool* => entry.{core::MapEntry::value}{dynamic} =={core::Object::==}{(core::Object*) →* core::bool*} search, orElse: () → Null => null){((core::MapEntry<core::String*, dynamic>*) →* core::bool*, {orElse: () →* core::MapEntry<core::String*, dynamic>*}) →* core::MapEntry<core::String*, dynamic>*} in #t1 == null ?{core::String*} null : #t1.{core::MapEntry::key}{core::String*});
}

library /*isNonNullableByDefault*/;
import self as iss;
import "dart:core" as core;

class C<X extends core::Object? = dynamic> extends core::Object {
  constructor •(() → iss::Map<core::String, core::String> f) → iss::C<iss::C::X%>
    : super core::Object::•() {
    core::print(f.{core::Object::runtimeType}{core::Type});
  }
}
class Map<K extends core::Object? = dynamic, V extends core::Object? = dynamic> extends core::Object {
  final field iss::Map::K% key;
  final field iss::Map::V% value;
  constructor •(iss::Map::K% key, iss::Map::V% value) → iss::Map<iss::Map::K%, iss::Map::V%>
    : iss::Map::key = key, iss::Map::value = value, super core::Object::•()
    ;
  get entries() → iss::Iterable<core::MapEntry<iss::Map::K%, iss::Map::V%>>
    return new iss::Iterable::•<core::MapEntry<iss::Map::K%, iss::Map::V%>>(new core::MapEntry::_<iss::Map::K%, iss::Map::V%>(this.{iss::Map::key}{iss::Map::K%}, this.{iss::Map::value}{iss::Map::V%}));
}
class Iterable<E extends core::Object? = dynamic> extends core::Object {
  final field iss::Iterable::E% element;
  constructor •(iss::Iterable::E% element) → iss::Iterable<iss::Iterable::E%>
    : iss::Iterable::element = element, super core::Object::•()
    ;
  method singleWhere((iss::Iterable::E%) → core::bool test, {covariant-by-class () →? iss::Iterable::E% orElse = #C1}) → iss::Iterable::E% {
    if(test(this.{iss::Iterable::element}{iss::Iterable::E%}){(iss::Iterable::E%) → core::bool}) {
      return this.{iss::Iterable::element}{iss::Iterable::E%};
    }
    if(!(orElse == null))
      return orElse{() → iss::Iterable::E%}(){() → iss::Iterable::E%};
    throw "error";
  }
}
static method foo(() → iss::Map<core::String, core::String> f) → void {
  core::print(f.{core::Object::runtimeType}{core::Type});
}
static set bar(() → iss::Map<core::String, core::String> f) → void {
  core::print(f.{core::Object::runtimeType}{core::Type});
}

constants  {
  #C1 = null
}
