main = main::main;
library from "org-dartlang-test:///lib1.dart" as lib1 {
additionalExports = (main::main,
  main::Class,
  main::Extension)

  export "org-dartlang-test:///main.dart";
  import "org-dartlang-test:///main.dart";
  import "org-dartlang-test:///main.dart" as m;

  extension Extension2 on main::Class* {
    method method2 = lib1::Extension2|method2;
    tearoff method2 = lib1::Extension2|get#method2;
  }
  static method Extension2|method2(lowered final main::Class* #this) → void {}
  static method Extension2|get#method2(lowered final main::Class* #this) → () →* void
    return () → void => lib1::Extension2|method2(#this);
  static method lib1() → dynamic {
    main::Class* a = new main::Class::•();
    main::Extension|method(a);
    lib1::Extension2|method2(a);
    dart.core::print("done");
  }
}
library from "org-dartlang-test:///lib2.dart" as lib2 {

  import "org-dartlang-test:///lib1.dart";
  import "org-dartlang-test:///lib1.dart" as l1;

  extension Extension3 on main::Class* {
    method method3 = lib2::Extension3|method3;
    tearoff method3 = lib2::Extension3|get#method3;
  }
  static method Extension3|method3(lowered final main::Class* #this) → void {}
  static method Extension3|get#method3(lowered final main::Class* #this) → () →* void
    return () → void => lib2::Extension3|method3(#this);
  static method lib2() → dynamic {
    main::Class* a = new main::Class::•();
    main::Extension|method(a);
    lib1::Extension2|method2(a);
    dart.core::print("done");
  }
}
library from "org-dartlang-test:///main.dart" as main {

  import "org-dartlang-test:///lib1.dart";
  import "org-dartlang-test:///lib1.dart" as l1;
  import "org-dartlang-test:///lib2.dart";
  import "org-dartlang-test:///lib2.dart" as l2;

  class Class extends dart.core::Object {
    synthetic constructor •() → main::Class*
      : super dart.core::Object::•()
      ;
    abstract member-signature get _identityHashCode() → dart.core::int*; -> dart.core::Object::_identityHashCode
    abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → dart.core::bool*; -> dart.core::Object::_instanceOf
    abstract member-signature method _simpleInstanceOf(dynamic type) → dart.core::bool*; -> dart.core::Object::_simpleInstanceOf
    abstract member-signature method _simpleInstanceOfTrue(dynamic type) → dart.core::bool*; -> dart.core::Object::_simpleInstanceOfTrue
    abstract member-signature method _simpleInstanceOfFalse(dynamic type) → dart.core::bool*; -> dart.core::Object::_simpleInstanceOfFalse
    abstract member-signature operator ==(dynamic other) → dart.core::bool*; -> dart.core::Object::==
    abstract member-signature get hashCode() → dart.core::int*; -> dart.core::Object::hashCode
    abstract member-signature method toString() → dart.core::String*; -> dart.core::Object::toString
    abstract member-signature method noSuchMethod(dart.core::Invocation* invocation) → dynamic; -> dart.core::Object::noSuchMethod
    abstract member-signature get runtimeType() → dart.core::Type*; -> dart.core::Object::runtimeType
  }
  extension Extension on main::Class* {
    method method = main::Extension|method;
    tearoff method = main::Extension|get#method;
  }
  static method Extension|method(lowered final main::Class* #this) → void {}
  static method Extension|get#method(lowered final main::Class* #this) → () →* void
    return () → void => main::Extension|method(#this);
  static method main() → dynamic {
    main::Class* a = new main::Class::•();
    main::Extension|method(a);
    lib1::Extension2|method2(a);
    lib1::lib1();
    dart.core::print("Done");
  }
}
