library /*isNonNullableByDefault*/;
import self as self;
import "mixin_from_dill_lib1.dart" as mix;
import "dart:core" as core;
import "mixin_from_dill_lib2.dart" as mix2;

import "org-dartlang-testcase:///mixin_from_dill_lib1.dart" as lib1;
import "org-dartlang-testcase:///mixin_from_dill_lib2.dart" as lib2;

static method main() → dynamic {
  mix::Foo foo1 = new mix::Foo::•();
  if(foo1 == null)
    throw "what?";
  if(!(foo1 =={mix::_Foo&B&D::==}{(core::Object) → core::bool} foo1))
    throw "what?";
  foo1.{mix::_Foo&B&D::x}(){() → void};
  mix2::Foo foo2 = new mix2::Foo::•();
  if(foo2 == null)
    throw "what?";
  if(!(foo2 =={mix2::_Foo&B&D::==}{(core::Object) → core::bool} foo2))
    throw "what?";
  foo2.{mix2::_Foo&B&D::x}(){() → void};
}

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

abstract class _Foo&B&D = mix2::B with mix2::D /*isAnonymousMixin*/  {
  synthetic constructor •() → mix2::_Foo&B&D
    : super mix2::B::•()
    ;
  mixin-super-stub operator ==(core::Object dynamic) → core::bool
    return super.{mix2::D::==}(dynamic);
  mixin-super-stub method x() → void
    return super.{mix2::D::x}();
}
class Foo extends mix2::_Foo&B&D {
  synthetic constructor •() → mix2::Foo
    : super mix2::_Foo&B&D::•()
    ;
}
abstract class B extends core::Object implements mix2::C {
  synthetic constructor •() → mix2::B
    : super core::Object::•()
    ;
  operator ==(core::Object dynamic) → core::bool {
    core::print("B.==");
    return true;
  }
  method x() → void {
    core::print("B.x");
  }
}
abstract class C extends core::Object {
  synthetic constructor •() → mix2::C
    : super core::Object::•()
    ;
}
abstract class D extends core::Object implements mix2::C {
  synthetic constructor •() → mix2::D
    : super core::Object::•()
    ;
  operator ==(core::Object dynamic) → core::bool {
    core::print("D.==");
    return true;
  }
  method x() → void {
    core::print("D.x");
  }
}

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

abstract class _Foo&B&D extends mix::B implements mix::D /*isAnonymousMixin,isEliminatedMixin*/  {
  synthetic constructor •() → mix::_Foo&B&D
    : super mix::B::•()
    ;
  operator ==(core::Object dynamic) → core::bool {
    core::print("D.==");
    return true;
  }
  method x() → void {
    core::print("D.x");
  }
}
class Foo extends mix::_Foo&B&D {
  synthetic constructor •() → mix::Foo
    : super mix::_Foo&B&D::•()
    ;
}
abstract class B extends core::Object implements mix::C {
  synthetic constructor •() → mix::B
    : super core::Object::•()
    ;
  operator ==(core::Object dynamic) → core::bool {
    core::print("B.==");
    return true;
  }
  method x() → void {
    core::print("B.x");
  }
}
abstract class C extends core::Object {
  synthetic constructor •() → mix::C
    : super core::Object::•()
    ;
}
abstract class D extends core::Object implements mix::C {
  synthetic constructor •() → mix::D
    : super core::Object::•()
    ;
  operator ==(core::Object dynamic) → core::bool {
    core::print("D.==");
    return true;
  }
  method x() → void {
    core::print("D.x");
  }
}
