library;
import self as self;
import "dart:core" as core;

class DeltaBlue extends core::Object {
  synthetic constructor •() → self::DeltaBlue*
    : super core::Object::•()
    ;
  method run() → void {
    self::chainTest(100);
    self::projectionTest(100);
  }
  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
}
class Strength extends core::Object /*hasConstConstructor*/  {
  final field core::int* value;
  final field core::String* name;
  const constructor •(core::int* value, core::String* name) → self::Strength*
    : self::Strength::value = value, self::Strength::name = name, super core::Object::•()
    ;
  method nextWeaker() → self::Strength*
    return (#C19).{core::List::[]}(this.{self::Strength::value});
  static method stronger(self::Strength* s1, self::Strength* s2) → core::bool* {
    return s1.{self::Strength::value}.{core::num::<}(s2.{self::Strength::value});
  }
  static method weaker(self::Strength* s1, self::Strength* s2) → core::bool* {
    return s1.{self::Strength::value}.{core::num::>}(s2.{self::Strength::value});
  }
  static method weakest(self::Strength* s1, self::Strength* s2) → self::Strength* {
    return self::Strength::weaker(s1, s2) ?{self::Strength*} s1 : s2;
  }
  static method strongest(self::Strength* s1, self::Strength* s2) → self::Strength* {
    return self::Strength::stronger(s1, s2) ?{self::Strength*} s1 : s2;
  }
  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
}
abstract class Constraint extends core::Object /*hasConstConstructor*/  {
  final field self::Strength* strength;
  const constructor •(self::Strength* strength) → self::Constraint*
    : self::Constraint::strength = strength, super core::Object::•()
    ;
  abstract method isSatisfied() → core::bool*;
  abstract method markUnsatisfied() → void;
  abstract method addToGraph() → void;
  abstract method removeFromGraph() → void;
  abstract method chooseMethod(core::int* mark) → void;
  abstract method markInputs(core::int* mark) → void;
  abstract method inputsKnown(core::int* mark) → core::bool*;
  abstract method output() → self::Variable*;
  abstract method execute() → void;
  abstract method recalculate() → void;
  method addConstraint() → void {
    this.{self::Constraint::addToGraph}();
    self::planner.{self::Planner::incrementalAdd}(this);
  }
  method satisfy(dynamic mark) → self::Constraint* {
    this.{self::Constraint::chooseMethod}(mark as{TypeError,ForDynamic} core::int*);
    if(!this.{self::Constraint::isSatisfied}()) {
      if(this.{self::Constraint::strength}.{self::Strength::==}(#C22)) {
        core::print("Could not satisfy a required constraint!");
      }
      return null;
    }
    this.{self::Constraint::markInputs}(mark as{TypeError,ForDynamic} core::int*);
    self::Variable* out = this.{self::Constraint::output}();
    self::Constraint* overridden = out.{self::Variable::determinedBy};
    if(!overridden.{self::Constraint::==}(null))
      overridden.{self::Constraint::markUnsatisfied}();
    out.{self::Variable::determinedBy} = this;
    if(!self::planner.{self::Planner::addPropagate}(this, mark as{TypeError,ForDynamic} core::int*))
      core::print("Cycle encountered");
    out.{self::Variable::mark} = mark as{TypeError,ForDynamic} core::int*;
    return overridden;
  }
  method destroyConstraint() → void {
    if(this.{self::Constraint::isSatisfied}())
      self::planner.{self::Planner::incrementalRemove}(this);
    this.{self::Constraint::removeFromGraph}();
  }
  method isInput() → core::bool*
    return false;
  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
}
abstract class UnaryConstraint extends self::Constraint {
  final field self::Variable* myOutput;
  field core::bool* satisfied = false;
  constructor •(self::Variable* myOutput, self::Strength* strength) → self::UnaryConstraint*
    : self::UnaryConstraint::myOutput = myOutput, super self::Constraint::•(strength) {
    this.{self::Constraint::addConstraint}();
  }
  method addToGraph() → void {
    this.{self::UnaryConstraint::myOutput}.{self::Variable::addConstraint}(this);
    this.{self::UnaryConstraint::satisfied} = false;
  }
  method chooseMethod(core::int* mark) → void {
    this.{self::UnaryConstraint::satisfied} = !this.{self::UnaryConstraint::myOutput}.{self::Variable::mark}.{core::num::==}(mark) && self::Strength::stronger(this.{self::Constraint::strength}, this.{self::UnaryConstraint::myOutput}.{self::Variable::walkStrength});
  }
  method isSatisfied() → core::bool*
    return this.{self::UnaryConstraint::satisfied};
  method markInputs(core::int* mark) → void {}
  method output() → self::Variable*
    return this.{self::UnaryConstraint::myOutput};
  method recalculate() → void {
    this.{self::UnaryConstraint::myOutput}.{self::Variable::walkStrength} = this.{self::Constraint::strength};
    this.{self::UnaryConstraint::myOutput}.{self::Variable::stay} = !this.{self::Constraint::isInput}();
    if(this.{self::UnaryConstraint::myOutput}.{self::Variable::stay})
      this.{self::Constraint::execute}();
  }
  method markUnsatisfied() → void {
    this.{self::UnaryConstraint::satisfied} = false;
  }
  method inputsKnown(core::int* mark) → core::bool*
    return true;
  method removeFromGraph() → void {
    if(!this.{self::UnaryConstraint::myOutput}.{self::Variable::==}(null))
      this.{self::UnaryConstraint::myOutput}.{self::Variable::removeConstraint}(this);
    this.{self::UnaryConstraint::satisfied} = false;
  }
}
class StayConstraint extends self::UnaryConstraint {
  constructor •(self::Variable* v, self::Strength* str) → self::StayConstraint*
    : super self::UnaryConstraint::•(v, str)
    ;
  method execute() → void {}
}
class EditConstraint extends self::UnaryConstraint {
  constructor •(self::Variable* v, self::Strength* str) → self::EditConstraint*
    : super self::UnaryConstraint::•(v, str)
    ;
  method isInput() → core::bool*
    return true;
  method execute() → void {}
}
abstract class BinaryConstraint extends self::Constraint {
  field self::Variable* v1;
  field self::Variable* v2;
  field core::int* direction = #C1;
  constructor •(self::Variable* v1, self::Variable* v2, self::Strength* strength) → self::BinaryConstraint*
    : self::BinaryConstraint::v1 = v1, self::BinaryConstraint::v2 = v2, super self::Constraint::•(strength) {
    this.{self::Constraint::addConstraint}();
  }
  method chooseMethod(core::int* mark) → void {
    if(this.{self::BinaryConstraint::v1}.{self::Variable::mark}.{core::num::==}(mark)) {
      this.{self::BinaryConstraint::direction} = !this.{self::BinaryConstraint::v2}.{self::Variable::mark}.{core::num::==}(mark) && self::Strength::stronger(this.{self::Constraint::strength}, this.{self::BinaryConstraint::v2}.{self::Variable::walkStrength}) ?{core::int*} #C4 : #C1;
    }
    if(this.{self::BinaryConstraint::v2}.{self::Variable::mark}.{core::num::==}(mark)) {
      this.{self::BinaryConstraint::direction} = !this.{self::BinaryConstraint::v1}.{self::Variable::mark}.{core::num::==}(mark) && self::Strength::stronger(this.{self::Constraint::strength}, this.{self::BinaryConstraint::v1}.{self::Variable::walkStrength}) ?{core::int*} #C20 : #C1;
    }
    if(self::Strength::weaker(this.{self::BinaryConstraint::v1}.{self::Variable::walkStrength}, this.{self::BinaryConstraint::v2}.{self::Variable::walkStrength})) {
      this.{self::BinaryConstraint::direction} = self::Strength::stronger(this.{self::Constraint::strength}, this.{self::BinaryConstraint::v1}.{self::Variable::walkStrength}) ?{core::int*} #C20 : #C1;
    }
    else {
      this.{self::BinaryConstraint::direction} = self::Strength::stronger(this.{self::Constraint::strength}, this.{self::BinaryConstraint::v2}.{self::Variable::walkStrength}) ?{core::int*} #C4 : #C20;
    }
  }
  method addToGraph() → void {
    this.{self::BinaryConstraint::v1}.{self::Variable::addConstraint}(this);
    this.{self::BinaryConstraint::v2}.{self::Variable::addConstraint}(this);
    this.{self::BinaryConstraint::direction} = #C1;
  }
  method isSatisfied() → core::bool*
    return !this.{self::BinaryConstraint::direction}.{core::num::==}(#C1);
  method markInputs(core::int* mark) → void {
    this.{self::BinaryConstraint::input}().{self::Variable::mark} = mark;
  }
  method input() → self::Variable*
    return this.{self::BinaryConstraint::direction}.{core::num::==}(#C4) ?{self::Variable*} this.{self::BinaryConstraint::v1} : this.{self::BinaryConstraint::v2};
  method output() → self::Variable*
    return this.{self::BinaryConstraint::direction}.{core::num::==}(#C4) ?{self::Variable*} this.{self::BinaryConstraint::v2} : this.{self::BinaryConstraint::v1};
  method recalculate() → void {
    self::Variable* ihn = this.{self::BinaryConstraint::input}();
    self::Variable* out = this.{self::BinaryConstraint::output}();
    out.{self::Variable::walkStrength} = self::Strength::weakest(this.{self::Constraint::strength}, ihn.{self::Variable::walkStrength});
    out.{self::Variable::stay} = ihn.{self::Variable::stay};
    if(out.{self::Variable::stay})
      this.{self::Constraint::execute}();
  }
  method markUnsatisfied() → void {
    this.{self::BinaryConstraint::direction} = #C1;
  }
  method inputsKnown(core::int* mark) → core::bool* {
    self::Variable* i = this.{self::BinaryConstraint::input}();
    return i.{self::Variable::mark}.{core::num::==}(mark) || i.{self::Variable::stay} || i.{self::Variable::determinedBy}.{self::Constraint::==}(null);
  }
  method removeFromGraph() → void {
    if(!this.{self::BinaryConstraint::v1}.{self::Variable::==}(null))
      this.{self::BinaryConstraint::v1}.{self::Variable::removeConstraint}(this);
    if(!this.{self::BinaryConstraint::v2}.{self::Variable::==}(null))
      this.{self::BinaryConstraint::v2}.{self::Variable::removeConstraint}(this);
    this.{self::BinaryConstraint::direction} = #C1;
  }
}
class ScaleConstraint extends self::BinaryConstraint {
  final field self::Variable* scale;
  final field self::Variable* offset;
  constructor •(self::Variable* src, self::Variable* scale, self::Variable* offset, self::Variable* dest, self::Strength* strength) → self::ScaleConstraint*
    : self::ScaleConstraint::scale = scale, self::ScaleConstraint::offset = offset, super self::BinaryConstraint::•(src, dest, strength)
    ;
  method addToGraph() → void {
    super.{self::BinaryConstraint::addToGraph}();
    this.{self::ScaleConstraint::scale}.{self::Variable::addConstraint}(this);
    this.{self::ScaleConstraint::offset}.{self::Variable::addConstraint}(this);
  }
  method removeFromGraph() → void {
    super.{self::BinaryConstraint::removeFromGraph}();
    if(!this.{self::ScaleConstraint::scale}.{self::Variable::==}(null))
      this.{self::ScaleConstraint::scale}.{self::Variable::removeConstraint}(this);
    if(!this.{self::ScaleConstraint::offset}.{self::Variable::==}(null))
      this.{self::ScaleConstraint::offset}.{self::Variable::removeConstraint}(this);
  }
  method markInputs(core::int* mark) → void {
    super.{self::BinaryConstraint::markInputs}(mark);
    this.{self::ScaleConstraint::scale}.{self::Variable::mark} = this.{self::ScaleConstraint::offset}.{self::Variable::mark} = mark;
  }
  method execute() → void {
    if(this.{self::BinaryConstraint::direction}.{core::num::==}(#C4)) {
      this.{self::BinaryConstraint::v2}.{self::Variable::value} = this.{self::BinaryConstraint::v1}.{self::Variable::value}.{core::num::*}(this.{self::ScaleConstraint::scale}.{self::Variable::value}).{core::num::+}(this.{self::ScaleConstraint::offset}.{self::Variable::value});
    }
    else {
      this.{self::BinaryConstraint::v1}.{self::Variable::value} = this.{self::BinaryConstraint::v2}.{self::Variable::value}.{core::num::-}(this.{self::ScaleConstraint::offset}.{self::Variable::value}).{core::num::~/}(this.{self::ScaleConstraint::scale}.{self::Variable::value});
    }
  }
  method recalculate() → void {
    self::Variable* ihn = this.{self::BinaryConstraint::input}();
    self::Variable* out = this.{self::BinaryConstraint::output}();
    out.{self::Variable::walkStrength} = self::Strength::weakest(this.{self::Constraint::strength}, ihn.{self::Variable::walkStrength});
    out.{self::Variable::stay} = ihn.{self::Variable::stay} && this.{self::ScaleConstraint::scale}.{self::Variable::stay} && this.{self::ScaleConstraint::offset}.{self::Variable::stay};
    if(out.{self::Variable::stay})
      this.{self::ScaleConstraint::execute}();
  }
}
class EqualityConstraint extends self::BinaryConstraint {
  constructor •(self::Variable* v1, self::Variable* v2, self::Strength* strength) → self::EqualityConstraint*
    : super self::BinaryConstraint::•(v1, v2, strength)
    ;
  method execute() → void {
    this.{self::BinaryConstraint::output}().{self::Variable::value} = this.{self::BinaryConstraint::input}().{self::Variable::value};
  }
}
class Variable extends core::Object {
  field core::List<self::Constraint*>* constraints = core::_GrowableList::•<self::Constraint*>(0);
  field self::Constraint* determinedBy = null;
  field core::int* mark = 0;
  field self::Strength* walkStrength = #C18;
  field core::bool* stay = true;
  field core::int* value;
  final field core::String* name;
  constructor •(core::String* name, core::int* value) → self::Variable*
    : self::Variable::name = name, self::Variable::value = value, super core::Object::•()
    ;
  method addConstraint(self::Constraint* c) → void {
    this.{self::Variable::constraints}.{core::List::add}(c);
  }
  method removeConstraint(self::Constraint* c) → void {
    this.{self::Variable::constraints}.{core::List::remove}(c);
    if(this.{self::Variable::determinedBy}.{self::Constraint::==}(c))
      this.{self::Variable::determinedBy} = 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
}
class Planner extends core::Object {
  field core::int* currentMark = 0;
  synthetic constructor •() → self::Planner*
    : super core::Object::•()
    ;
  method incrementalAdd(self::Constraint* c) → void {
    core::int* mark = this.{self::Planner::newMark}();
    for (self::Constraint* overridden = c.{self::Constraint::satisfy}(mark); !overridden.{self::Constraint::==}(null); overridden = overridden.{self::Constraint::satisfy}(mark))
      ;
  }
  method incrementalRemove(self::Constraint* c) → void {
    self::Variable* out = c.{self::Constraint::output}();
    c.{self::Constraint::markUnsatisfied}();
    c.{self::Constraint::removeFromGraph}();
    core::List<self::Constraint*>* unsatisfied = this.{self::Planner::removePropagateFrom}(out);
    self::Strength* strength = #C22;
    do {
      for (core::int* i = 0; i.{core::num::<}(unsatisfied.{core::List::length}); i = i.{core::num::+}(1)) {
        self::Constraint* u = unsatisfied.{core::List::[]}(i);
        if(u.{self::Constraint::strength}.{self::Strength::==}(strength))
          this.{self::Planner::incrementalAdd}(u);
      }
      strength = strength.{self::Strength::nextWeaker}();
    }
    while (!strength.{self::Strength::==}(#C18))
  }
  method newMark() → core::int*
    return this.{self::Planner::currentMark} = this.{self::Planner::currentMark}.{core::num::+}(1);
  method makePlan(core::List<self::Constraint*>* sources) → self::Plan* {
    core::int* mark = this.{self::Planner::newMark}();
    self::Plan* plan = new self::Plan::•();
    core::List<self::Constraint*>* todo = sources;
    while (todo.{core::List::length}.{core::num::>}(0)) {
      self::Constraint* c = todo.{core::List::removeLast}();
      if(!c.{self::Constraint::output}().{self::Variable::mark}.{core::num::==}(mark) && c.{self::Constraint::inputsKnown}(mark)) {
        plan.{self::Plan::addConstraint}(c);
        c.{self::Constraint::output}().{self::Variable::mark} = mark;
        this.{self::Planner::addConstraintsConsumingTo}(c.{self::Constraint::output}(), todo);
      }
    }
    return plan;
  }
  method extractPlanFromConstraints(core::List<self::Constraint*>* constraints) → self::Plan* {
    core::List<self::Constraint*>* sources = core::_GrowableList::•<self::Constraint*>(0);
    for (core::int* i = 0; i.{core::num::<}(constraints.{core::List::length}); i = i.{core::num::+}(1)) {
      self::Constraint* c = constraints.{core::List::[]}(i);
      if(c.{self::Constraint::isInput}() && c.{self::Constraint::isSatisfied}())
        sources.{core::List::add}(c);
    }
    return this.{self::Planner::makePlan}(sources);
  }
  method addPropagate(self::Constraint* c, core::int* mark) → core::bool* {
    core::List<self::Constraint*>* todo = core::_GrowableList::_literal1<self::Constraint*>(c);
    while (todo.{core::List::length}.{core::num::>}(0)) {
      self::Constraint* d = todo.{core::List::removeLast}();
      if(d.{self::Constraint::output}().{self::Variable::mark}.{core::num::==}(mark)) {
        this.{self::Planner::incrementalRemove}(c);
        return false;
      }
      d.{self::Constraint::recalculate}();
      this.{self::Planner::addConstraintsConsumingTo}(d.{self::Constraint::output}(), todo);
    }
    return true;
  }
  method removePropagateFrom(self::Variable* out) → core::List<self::Constraint*>* {
    out.{self::Variable::determinedBy} = null;
    out.{self::Variable::walkStrength} = #C18;
    out.{self::Variable::stay} = true;
    core::List<self::Constraint*>* unsatisfied = core::_GrowableList::•<self::Constraint*>(0);
    core::List<self::Variable*>* todo = core::_GrowableList::_literal1<self::Variable*>(out);
    while (todo.{core::List::length}.{core::num::>}(0)) {
      self::Variable* v = todo.{core::List::removeLast}();
      for (core::int* i = 0; i.{core::num::<}(v.{self::Variable::constraints}.{core::List::length}); i = i.{core::num::+}(1)) {
        self::Constraint* c = v.{self::Variable::constraints}.{core::List::[]}(i);
        if(!c.{self::Constraint::isSatisfied}())
          unsatisfied.{core::List::add}(c);
      }
      self::Constraint* determining = v.{self::Variable::determinedBy};
      for (core::int* i = 0; i.{core::num::<}(v.{self::Variable::constraints}.{core::List::length}); i = i.{core::num::+}(1)) {
        self::Constraint* next = v.{self::Variable::constraints}.{core::List::[]}(i);
        if(!next.{self::Constraint::==}(determining) && next.{self::Constraint::isSatisfied}()) {
          next.{self::Constraint::recalculate}();
          todo.{core::List::add}(next.{self::Constraint::output}());
        }
      }
    }
    return unsatisfied;
  }
  method addConstraintsConsumingTo(self::Variable* v, core::List<self::Constraint*>* coll) → void {
    self::Constraint* determining = v.{self::Variable::determinedBy};
    for (core::int* i = 0; i.{core::num::<}(v.{self::Variable::constraints}.{core::List::length}); i = i.{core::num::+}(1)) {
      self::Constraint* c = v.{self::Variable::constraints}.{core::List::[]}(i);
      if(!c.{self::Constraint::==}(determining) && c.{self::Constraint::isSatisfied}())
        coll.{core::List::add}(c);
    }
  }
  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
}
class Plan extends core::Object {
  field core::List<self::Constraint*>* list = core::_GrowableList::•<self::Constraint*>(0);
  synthetic constructor •() → self::Plan*
    : super core::Object::•()
    ;
  method addConstraint(self::Constraint* c) → void {
    this.{self::Plan::list}.{core::List::add}(c);
  }
  method size() → core::int*
    return this.{self::Plan::list}.{core::List::length};
  method execute() → void {
    for (core::int* i = 0; i.{core::num::<}(this.{self::Plan::list}.{core::List::length}); i = i.{core::num::+}(1)) {
      this.{self::Plan::list}.{core::List::[]}(i).{self::Constraint::execute}();
    }
  }
  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 const field self::Strength* REQUIRED = #C22;
static const field self::Strength* STRONG_PREFERRED = #C3;
static const field self::Strength* PREFERRED = #C6;
static const field self::Strength* STRONG_DEFAULT = #C9;
static const field self::Strength* NORMAL = #C12;
static const field self::Strength* WEAK_DEFAULT = #C15;
static const field self::Strength* WEAKEST = #C18;
static const field core::int* NONE = #C1;
static const field core::int* FORWARD = #C4;
static const field core::int* BACKWARD = #C20;
static field self::Planner* planner;
static method main() → dynamic {
  new self::DeltaBlue::•().{self::DeltaBlue::run}();
}
static method chainTest(core::int* n) → void {
  self::planner = new self::Planner::•();
  self::Variable* prev = null;
  self::Variable* first = null;
  self::Variable* last = null;
  for (core::int* i = 0; i.{core::num::<=}(n); i = i.{core::num::+}(1)) {
    self::Variable* v = new self::Variable::•("v${i}", 0);
    if(!prev.{self::Variable::==}(null))
      new self::EqualityConstraint::•(prev, v, #C22);
    if(i.{core::num::==}(0))
      first = v;
    if(i.{core::num::==}(n))
      last = v;
    prev = v;
  }
  new self::StayConstraint::•(last, #C9);
  self::EditConstraint* edit = new self::EditConstraint::•(first, #C6);
  self::Plan* plan = self::planner.{self::Planner::extractPlanFromConstraints}(core::_GrowableList::_literal1<self::Constraint*>(edit));
  for (core::int* i = 0; i.{core::num::<}(100); i = i.{core::num::+}(1)) {
    first.{self::Variable::value} = i;
    plan.{self::Plan::execute}();
    if(!last.{self::Variable::value}.{core::num::==}(i)) {
      core::print("Chain test failed:");
      core::print("Expected last value to be ${i} but it was ${last.{self::Variable::value}}.");
    }
  }
}
static method projectionTest(core::int* n) → void {
  self::planner = new self::Planner::•();
  self::Variable* scale = new self::Variable::•("scale", 10);
  self::Variable* offset = new self::Variable::•("offset", 1000);
  self::Variable* src = null;
  self::Variable* dst = null;
  core::List<self::Variable*>* dests = core::_GrowableList::•<self::Variable*>(0);
  for (core::int* i = 0; i.{core::num::<}(n); i = i.{core::num::+}(1)) {
    src = new self::Variable::•("src", i);
    dst = new self::Variable::•("dst", i);
    dests.{core::List::add}(dst);
    new self::StayConstraint::•(src, #C12);
    new self::ScaleConstraint::•(src, scale, offset, dst, #C22);
  }
  self::change(src, 17);
  if(!dst.{self::Variable::value}.{core::num::==}(1170))
    core::print("Projection 1 failed");
  self::change(dst, 1050);
  if(!src.{self::Variable::value}.{core::num::==}(5))
    core::print("Projection 2 failed");
  self::change(scale, 5);
  for (core::int* i = 0; i.{core::num::<}(n.{core::num::-}(1)); i = i.{core::num::+}(1)) {
    if(!dests.{core::List::[]}(i).{self::Variable::value}.{core::num::==}(i.{core::num::*}(5).{core::num::+}(1000)))
      core::print("Projection 3 failed");
  }
  self::change(offset, 2000);
  for (core::int* i = 0; i.{core::num::<}(n.{core::num::-}(1)); i = i.{core::num::+}(1)) {
    if(!dests.{core::List::[]}(i).{self::Variable::value}.{core::num::==}(i.{core::num::*}(5).{core::num::+}(2000)))
      core::print("Projection 4 failed");
  }
}
static method change(self::Variable* v, core::int* newValue) → void {
  self::EditConstraint* edit = new self::EditConstraint::•(v, #C6);
  self::Plan* plan = self::planner.{self::Planner::extractPlanFromConstraints}(core::_GrowableList::_literal1<self::EditConstraint*>(edit));
  for (core::int* i = 0; i.{core::num::<}(10); i = i.{core::num::+}(1)) {
    v.{self::Variable::value} = newValue;
    plan.{self::Plan::execute}();
  }
  edit.{self::Constraint::destroyConstraint}();
}

constants  {
  #C1 = 1
  #C2 = "strongPreferred"
  #C3 = self::Strength {value:#C1, name:#C2}
  #C4 = 2
  #C5 = "preferred"
  #C6 = self::Strength {value:#C4, name:#C5}
  #C7 = 3
  #C8 = "strongDefault"
  #C9 = self::Strength {value:#C7, name:#C8}
  #C10 = 4
  #C11 = "normal"
  #C12 = self::Strength {value:#C10, name:#C11}
  #C13 = 5
  #C14 = "weakDefault"
  #C15 = self::Strength {value:#C13, name:#C14}
  #C16 = 6
  #C17 = "weakest"
  #C18 = self::Strength {value:#C16, name:#C17}
  #C19 = <self::Strength*>[#C3, #C6, #C9, #C12, #C15, #C18]
  #C20 = 0
  #C21 = "required"
  #C22 = self::Strength {value:#C20, name:#C21}
}


Constructor coverage from constants:
org-dartlang-testcase:///DeltaBlue.dart:
- Strength. (from org-dartlang-testcase:///DeltaBlue.dart:61:9)
- Object. (from org-dartlang-sdk:///sdk/lib/core/object.dart:25:9)
