diff --git a/.github/workflows/test-package.yml b/.github/workflows/test-package.yml
index e55702c..cdc25d9 100644
--- a/.github/workflows/test-package.yml
+++ b/.github/workflows/test-package.yml
@@ -23,9 +23,9 @@
         sdk: [dev]
     steps:
       - uses: actions/checkout@v2
-      - uses: dart-lang/setup-dart@v0.1
+      - uses: dart-lang/setup-dart@v1.0
         with:
-          channel: ${{ matrix.sdk }}
+          sdk: ${{ matrix.sdk }}
       - id: install
         name: Install dependencies
         run: dart pub get
@@ -47,12 +47,12 @@
       matrix:
         # Add macos-latest and/or windows-latest if relevant for this package.
         os: [ubuntu-latest]
-        sdk: [dev]
+        sdk: [2.12.0, dev]
     steps:
       - uses: actions/checkout@v2
-      - uses: dart-lang/setup-dart@v0.1
+      - uses: dart-lang/setup-dart@v1.0
         with:
-          channel: ${{ matrix.sdk }}
+          sdk: ${{ matrix.sdk }}
       - id: install
         name: Install dependencies
         run: dart pub get
diff --git a/changelog.md b/CHANGELOG.md
similarity index 92%
rename from changelog.md
rename to CHANGELOG.md
index 688b3db..3fe742a 100644
--- a/changelog.md
+++ b/CHANGELOG.md
@@ -1,3 +1,5 @@
+## 2.0.1-dev
+
 ## 2.0.0
 
 - Stable null safety release.
diff --git a/LICENSE b/LICENSE
index ef3edb1..db5bf46 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1,5 +1,26 @@
-Harness:
-Copyright 2012 Google Inc. All Rights Reserved.
+Copyright 2021, the Dart project authors.
 
-Individual benchmarks:
-Each benchmark has an author and license. See benchmark source for details.
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+    * Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
+    * Redistributions in binary form must reproduce the above
+      copyright notice, this list of conditions and the following
+      disclaimer in the documentation and/or other materials provided
+      with the distribution.
+    * Neither the name of Google LLC nor the names of its
+      contributors may be used to endorse or promote products derived
+      from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
\ No newline at end of file
diff --git a/README.md b/README.md
index e1a3a86..63dd914 100644
--- a/README.md
+++ b/README.md
@@ -39,7 +39,7 @@
 2\. Install pub packages
 
 ```
-pub install
+dart pub install
 ```
 
 3\. Add the following import:
@@ -52,10 +52,10 @@
 
 ## Example
 
-Create a dart file in the [`benchmark/`](https://www.dartlang.org/tools/pub/package-layout#tests-and-benchmarks)
+Create a dart file in the [`benchmark/`](https://dart.dev/tools/pub/package-layout#tests-and-benchmarks)
 folder of your package.
 
-```
+```dart
 // Import BenchmarkBase class.
 import 'package:benchmark_harness/benchmark_harness.dart';
 
@@ -64,24 +64,23 @@
   const TemplateBenchmark() : super('Template');
 
   static void main() {
-    TemplateBenchmark().report();
+    const TemplateBenchmark().report();
   }
 
   // The benchmark code.
   @override
-  void run() {
-  }
+  void run() {}
 
   // Not measured setup code executed prior to the benchmark runs.
   @override
-  void setup() { }
+  void setup() {}
 
   // Not measured teardown code executed after the benchmark runs.
   @override
-  void teardown() { }
+  void teardown() {}
 }
 
-main() {
+void main() {
   // Run TemplateBenchmark
   TemplateBenchmark.main();
 }
diff --git a/example/DeltaBlue.dart b/example/DeltaBlue.dart
deleted file mode 100644
index 02fb696..0000000
--- a/example/DeltaBlue.dart
+++ /dev/null
@@ -1,710 +0,0 @@
-// @dart=2.8
-// Copyright 2011 Google Inc. All Rights Reserved.
-// Copyright 1996 John Maloney and Mario Wolczko
-//
-// This file is part of GNU Smalltalk.
-//
-// GNU Smalltalk is free software; you can redistribute it and/or modify it
-// under the terms of the GNU General Public License as published by the Free
-// Software Foundation; either version 2, or (at your option) any later version.
-//
-// GNU Smalltalk is distributed in the hope that it will be useful, but WITHOUT
-// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-// FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
-// details.
-//
-// You should have received a copy of the GNU General Public License along with
-// GNU Smalltalk; see the file COPYING.  If not, write to the Free Software
-// Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-//
-// Translated first from Smalltalk to JavaScript, and finally to
-// Dart by Google 2008-2010.
-
-/// A Dart implementation of the DeltaBlue constraint-solving
-/// algorithm, as described in:
-///
-/// "The DeltaBlue Algorithm: An Incremental Constraint Hierarchy Solver"
-///   Bjorn N. Freeman-Benson and John Maloney
-///   January 1990 Communications of the ACM,
-///   also available as University of Washington TR 89-08-06.
-///
-/// Beware: this benchmark is written in a grotesque style where
-/// the constraint model is built by side-effects from constructors.
-/// I've kept it this way to avoid deviating too much from the original
-/// implementation.
-
-import 'package:benchmark_harness/benchmark_harness.dart';
-
-/// algorithm, as described in:
-///
-/// "The DeltaBlue Algorithm: An Incremental Constraint Hierarchy Solver"
-///   Bjorn N. Freeman-Benson and John Maloney
-///   January 1990 Communications of the ACM,
-///   also available as University of Washington TR 89-08-06.
-///
-/// Beware: this benchmark is written in a grotesque style where
-/// the constraint model is built by side-effects from constructors.
-/// I've kept it this way to avoid deviating too much from the original
-/// implementation.
-
-void main() {
-  const DeltaBlue().report();
-}
-
-/// Benchmark class required to report results.
-class DeltaBlue extends BenchmarkBase {
-  const DeltaBlue() : super('DeltaBlue');
-
-  @override
-  void run() {
-    chainTest(100);
-    projectionTest(100);
-  }
-}
-
-/// Strengths are used to measure the relative importance of constraints.
-/// New strengths may be inserted in the strength hierarchy without
-/// disrupting current constraints.  Strengths cannot be created outside
-/// this class, so == can be used for value comparison.
-class Strength {
-  final int value;
-  final String name;
-
-  const Strength(this.value, this.name);
-
-  Strength nextWeaker() => const <Strength>[
-        WEAKEST,
-        WEAK_DEFAULT,
-        NORMAL,
-        STRONG_DEFAULT,
-        PREFERRED,
-        STRONG_REFERRED
-      ][value];
-
-  static bool stronger(Strength s1, Strength s2) {
-    return s1.value < s2.value;
-  }
-
-  static bool weaker(Strength s1, Strength s2) {
-    return s1.value > s2.value;
-  }
-
-  static Strength weakest(Strength s1, Strength s2) {
-    return weaker(s1, s2) ? s1 : s2;
-  }
-
-  static Strength strongest(Strength s1, Strength s2) {
-    return stronger(s1, s2) ? s1 : s2;
-  }
-}
-
-// Compile time computed constants.
-const REQUIRED = Strength(0, 'required');
-const STRONG_REFERRED = Strength(1, 'strongPreferred');
-const PREFERRED = Strength(2, 'preferred');
-const STRONG_DEFAULT = Strength(3, 'strongDefault');
-const NORMAL = Strength(4, 'normal');
-const WEAK_DEFAULT = Strength(5, 'weakDefault');
-const WEAKEST = Strength(6, 'weakest');
-
-abstract class Constraint {
-  final Strength strength;
-
-  const Constraint(this.strength);
-
-  bool isSatisfied();
-
-  void markUnsatisfied();
-
-  void addToGraph();
-
-  void removeFromGraph();
-
-  void chooseMethod(int mark);
-
-  void markInputs(int mark);
-
-  bool inputsKnown(int mark);
-
-  Variable output();
-
-  void execute();
-
-  void recalculate();
-
-  /// Activate this constraint and attempt to satisfy it.
-  void addConstraint() {
-    addToGraph();
-    planner.incrementalAdd(this);
-  }
-
-  /// Attempt to find a way to enforce this constraint. If successful,
-  /// record the solution, perhaps modifying the current dataflow
-  /// graph. Answer the constraint that this constraint overrides, if
-  /// there is one, or nil, if there isn't.
-  /// Assume: I am not already satisfied.
-  Constraint satisfy(int mark) {
-    chooseMethod(mark);
-    if (!isSatisfied()) {
-      if (strength == REQUIRED) {
-        print('Could not satisfy a required constraint!');
-      }
-      return null;
-    }
-    markInputs(mark);
-    var out = output();
-    var overridden = out.determinedBy;
-    if (overridden != null) overridden.markUnsatisfied();
-    out.determinedBy = this;
-    if (!planner.addPropagate(this, mark)) print('Cycle encountered');
-    out.mark = mark;
-    return overridden;
-  }
-
-  void destroyConstraint() {
-    if (isSatisfied()) planner.incrementalRemove(this);
-    removeFromGraph();
-  }
-
-  /// Normal constraints are not input constraints.  An input constraint
-  /// is one that depends on external state, such as the mouse, the
-  /// keybord, a clock, or some arbitraty piece of imperative code.
-  bool isInput() => false;
-}
-
-/// Abstract superclass for constraints having a single possible output variable.
-abstract class UnaryConstraint extends Constraint {
-  final Variable myOutput;
-  bool satisfied = false;
-
-  UnaryConstraint(this.myOutput, Strength strength) : super(strength) {
-    addConstraint();
-  }
-
-  /// Adds this constraint to the constraint graph
-  @override
-  void addToGraph() {
-    myOutput.addConstraint(this);
-    satisfied = false;
-  }
-
-  /// Decides if this constraint can be satisfied and records that decision.
-  @override
-  void chooseMethod(int mark) {
-    satisfied = (myOutput.mark != mark) &&
-        Strength.stronger(strength, myOutput.walkStrength);
-  }
-
-  /// Returns true if this constraint is satisfied in the current solution.
-  @override
-  bool isSatisfied() => satisfied;
-
-  @override
-  void markInputs(int mark) {
-    // has no inputs.
-  }
-
-  /// Returns the current output variable.
-  @override
-  Variable output() => myOutput;
-
-  /// Calculate the walkabout strength, the stay flag, and, if it is
-  /// 'stay', the value for the current output of this constraint. Assume
-  /// this constraint is satisfied.
-  @override
-  void recalculate() {
-    myOutput.walkStrength = strength;
-    myOutput.stay = !isInput();
-    if (myOutput.stay) execute(); // Stay optimization.
-  }
-
-  /// Records that this constraint is unsatisfied.
-  @override
-  void markUnsatisfied() {
-    satisfied = false;
-  }
-
-  @override
-  bool inputsKnown(int mark) => true;
-
-  @override
-  void removeFromGraph() {
-    if (myOutput != null) myOutput.removeConstraint(this);
-    satisfied = false;
-  }
-}
-
-/// Variables that should, with some level of preference, stay the same.
-/// Planners may exploit the fact that instances, if satisfied, will not
-/// change their output during plan execution.  This is called "stay
-/// optimization".
-class StayConstraint extends UnaryConstraint {
-  StayConstraint(Variable v, Strength str) : super(v, str);
-
-  @override
-  void execute() {
-    // Stay constraints do nothing.
-  }
-}
-
-/// A unary input constraint used to mark a variable that the client
-/// wishes to change.
-class EditConstraint extends UnaryConstraint {
-  EditConstraint(Variable v, Strength str) : super(v, str);
-
-  /// Edits indicate that a variable is to be changed by imperative code.
-  @override
-  bool isInput() => true;
-
-  @override
-  void execute() {
-    // Edit constraints do nothing.
-  }
-}
-
-// Directions.
-const int NONE = 1;
-const int FORWARD = 2;
-const int BACKWARD = 0;
-
-/// Abstract superclass for constraints having two possible output
-/// variables.
-abstract class BinaryConstraint extends Constraint {
-  Variable v1;
-  Variable v2;
-  int direction = NONE;
-
-  BinaryConstraint(this.v1, this.v2, Strength strength) : super(strength) {
-    addConstraint();
-  }
-
-  /// Decides if this constraint can be satisfied and which way it
-  /// should flow based on the relative strength of the variables related,
-  /// and record that decision.
-  @override
-  void chooseMethod(int mark) {
-    if (v1.mark == mark) {
-      direction =
-          (v2.mark != mark && Strength.stronger(strength, v2.walkStrength))
-              ? FORWARD
-              : NONE;
-    }
-    if (v2.mark == mark) {
-      direction =
-          (v1.mark != mark && Strength.stronger(strength, v1.walkStrength))
-              ? BACKWARD
-              : NONE;
-    }
-    if (Strength.weaker(v1.walkStrength, v2.walkStrength)) {
-      direction =
-          Strength.stronger(strength, v1.walkStrength) ? BACKWARD : NONE;
-    } else {
-      direction =
-          Strength.stronger(strength, v2.walkStrength) ? FORWARD : BACKWARD;
-    }
-  }
-
-  /// Add this constraint to the constraint graph.
-  @override
-  void addToGraph() {
-    v1.addConstraint(this);
-    v2.addConstraint(this);
-    direction = NONE;
-  }
-
-  /// Answer true if this constraint is satisfied in the current solution.
-  @override
-  bool isSatisfied() => direction != NONE;
-
-  /// Mark the input variable with the given mark.
-  @override
-  void markInputs(int mark) {
-    input().mark = mark;
-  }
-
-  /// Returns the current input variable
-  Variable input() => direction == FORWARD ? v1 : v2;
-
-  /// Returns the current output variable.
-  @override
-  Variable output() => direction == FORWARD ? v2 : v1;
-
-  /// Calculate the walkabout strength, the stay flag, and, if it is
-  /// 'stay', the value for the current output of this
-  /// constraint. Assume this constraint is satisfied.
-  @override
-  void recalculate() {
-    var ihn = input(), out = output();
-    out.walkStrength = Strength.weakest(strength, ihn.walkStrength);
-    out.stay = ihn.stay;
-    if (out.stay) execute();
-  }
-
-  /// Record the fact that this constraint is unsatisfied.
-  @override
-  void markUnsatisfied() {
-    direction = NONE;
-  }
-
-  @override
-  bool inputsKnown(int mark) {
-    var i = input();
-    return i.mark == mark || i.stay || i.determinedBy == null;
-  }
-
-  @override
-  void removeFromGraph() {
-    if (v1 != null) v1.removeConstraint(this);
-    if (v2 != null) v2.removeConstraint(this);
-    direction = NONE;
-  }
-}
-
-/// Relates two variables by the linear scaling relationship: "v2 =
-/// (v1 * scale) + offset". Either v1 or v2 may be changed to maintain
-/// this relationship but the scale factor and offset are considered
-/// read-only.
-
-class ScaleConstraint extends BinaryConstraint {
-  final Variable scale;
-  final Variable offset;
-
-  ScaleConstraint(
-      Variable src, this.scale, this.offset, Variable dest, Strength strength)
-      : super(src, dest, strength);
-
-  /// Adds this constraint to the constraint graph.
-  @override
-  void addToGraph() {
-    super.addToGraph();
-    scale.addConstraint(this);
-    offset.addConstraint(this);
-  }
-
-  @override
-  void removeFromGraph() {
-    super.removeFromGraph();
-    if (scale != null) scale.removeConstraint(this);
-    if (offset != null) offset.removeConstraint(this);
-  }
-
-  @override
-  void markInputs(int mark) {
-    super.markInputs(mark);
-    scale.mark = offset.mark = mark;
-  }
-
-  /// Enforce this constraint. Assume that it is satisfied.
-  @override
-  void execute() {
-    if (direction == FORWARD) {
-      v2.value = v1.value * scale.value + offset.value;
-    } else {
-      v1.value = (v2.value - offset.value) ~/ scale.value;
-    }
-  }
-
-  /// Calculate the walkabout strength, the stay flag, and, if it is
-  /// 'stay', the value for the current output of this constraint. Assume
-  /// this constraint is satisfied.
-  @override
-  void recalculate() {
-    var ihn = input(), out = output();
-    out.walkStrength = Strength.weakest(strength, ihn.walkStrength);
-    out.stay = ihn.stay && scale.stay && offset.stay;
-    if (out.stay) execute();
-  }
-}
-
-/// Constrains two variables to have the same value.
-class EqualityConstraint extends BinaryConstraint {
-  EqualityConstraint(Variable v1, Variable v2, Strength strength)
-      : super(v1, v2, strength);
-
-  /// Enforce this constraint. Assume that it is satisfied.
-  @override
-  void execute() {
-    output().value = input().value;
-  }
-}
-
-/// A constrained variable. In addition to its value, it maintain the
-/// structure of the constraint graph, the current dataflow graph, and
-/// various parameters of interest to the DeltaBlue incremental
-/// constraint solver.
-class Variable {
-  List<Constraint> constraints = <Constraint>[];
-  Constraint determinedBy;
-  int mark = 0;
-  Strength walkStrength = WEAKEST;
-  bool stay = true;
-  int value;
-  final String name;
-
-  Variable(this.name, this.value);
-
-  /// Add the given constraint to the set of all constraints that refer
-  /// this variable.
-  void addConstraint(Constraint c) {
-    constraints.add(c);
-  }
-
-  /// Removes all traces of c from this variable.
-  void removeConstraint(Constraint c) {
-    constraints.removeWhere((e) => c == e);
-    if (determinedBy == c) determinedBy = null;
-  }
-}
-
-class Planner {
-  int currentMark = 0;
-
-  /// Attempt to satisfy the given constraint and, if successful,
-  /// incrementally update the dataflow graph.  Details: If satifying
-  /// the constraint is successful, it may override a weaker constraint
-  /// on its output. The algorithm attempts to resatisfy that
-  /// constraint using some other method. This process is repeated
-  /// until either a) it reaches a variable that was not previously
-  /// determined by any constraint or b) it reaches a constraint that
-  /// is too weak to be satisfied using any of its methods. The
-  /// variables of constraints that have been processed are marked with
-  /// a unique mark value so that we know where we've been. This allows
-  /// the algorithm to avoid getting into an infinite loop even if the
-  /// constraint graph has an inadvertent cycle.
-  void incrementalAdd(Constraint c) {
-    var mark = newMark();
-    for (var overridden = c.satisfy(mark);
-        overridden != null;
-        overridden = overridden.satisfy(mark)) {
-      // NOOP
-    }
-  }
-
-  /// Entry point for retracting a constraint. Remove the given
-  /// constraint and incrementally update the dataflow graph.
-  /// Details: Retracting the given constraint may allow some currently
-  /// unsatisfiable downstream constraint to be satisfied. We therefore collect
-  /// a list of unsatisfied downstream constraints and attempt to
-  /// satisfy each one in turn. This list is traversed by constraint
-  /// strength, strongest first, as a heuristic for avoiding
-  /// unnecessarily adding and then overriding weak constraints.
-  /// Assume: [c] is satisfied.
-  void incrementalRemove(Constraint c) {
-    var out = c.output();
-    c.markUnsatisfied();
-    c.removeFromGraph();
-    var unsatisfied = removePropagateFrom(out);
-    var strength = REQUIRED;
-    do {
-      for (var i = 0; i < unsatisfied.length; i++) {
-        var u = unsatisfied[i];
-        if (u.strength == strength) incrementalAdd(u);
-      }
-      strength = strength.nextWeaker();
-    } while (strength != WEAKEST);
-  }
-
-  /// Select a previously unused mark value.
-  int newMark() => ++currentMark;
-
-  /// Extract a plan for resatisfaction starting from the given source
-  /// constraints, usually a set of input constraints. This method
-  /// assumes that stay optimization is desired; the plan will contain
-  /// only constraints whose output variables are not stay. Constraints
-  /// that do no computation, such as stay and edit constraints, are
-  /// not included in the plan.
-  /// Details: The outputs of a constraint are marked when it is added
-  /// to the plan under construction. A constraint may be appended to
-  /// the plan when all its input variables are known. A variable is
-  /// known if either a) the variable is marked (indicating that has
-  /// been computed by a constraint appearing earlier in the plan), b)
-  /// the variable is 'stay' (i.e. it is a constant at plan execution
-  /// time), or c) the variable is not determined by any
-  /// constraint. The last provision is for past states of history
-  /// variables, which are not stay but which are also not computed by
-  /// any constraint.
-  /// Assume: [sources] are all satisfied.
-  Plan makePlan(List<Constraint> sources) {
-    var mark = newMark();
-    var plan = Plan();
-    var todo = sources;
-    while (todo.isNotEmpty) {
-      var c = todo.removeLast();
-      if (c.output().mark != mark && c.inputsKnown(mark)) {
-        plan.addConstraint(c);
-        c.output().mark = mark;
-        addConstraintsConsumingTo(c.output(), todo);
-      }
-    }
-    return plan;
-  }
-
-  /// Extract a plan for resatisfying starting from the output of the
-  /// given [constraints], usually a set of input constraints.
-  Plan extractPlanFromConstraints(List<Constraint> constraints) {
-    var sources = <Constraint>[];
-    for (var i = 0; i < constraints.length; i++) {
-      var c = constraints[i];
-      // if not in plan already and eligible for inclusion.
-      if (c.isInput() && c.isSatisfied()) sources.add(c);
-    }
-    return makePlan(sources);
-  }
-
-  /// Recompute the walkabout strengths and stay flags of all variables
-  /// downstream of the given constraint and recompute the actual
-  /// values of all variables whose stay flag is true. If a cycle is
-  /// detected, remove the given constraint and answer
-  /// false. Otherwise, answer true.
-  /// Details: Cycles are detected when a marked variable is
-  /// encountered downstream of the given constraint. The sender is
-  /// assumed to have marked the inputs of the given constraint with
-  /// the given mark. Thus, encountering a marked node downstream of
-  /// the output constraint means that there is a path from the
-  /// constraint's output to one of its inputs.
-  bool addPropagate(Constraint c, int mark) {
-    var todo = <Constraint>[c];
-    while (todo.isNotEmpty) {
-      var d = todo.removeLast();
-      if (d.output().mark == mark) {
-        incrementalRemove(c);
-        return false;
-      }
-      d.recalculate();
-      addConstraintsConsumingTo(d.output(), todo);
-    }
-    return true;
-  }
-
-  /// Update the walkabout strengths and stay flags of all variables
-  /// downstream of the given constraint. Answer a collection of
-  /// unsatisfied constraints sorted in order of decreasing strength.
-  List<Constraint> removePropagateFrom(Variable out) {
-    out.determinedBy = null;
-    out.walkStrength = WEAKEST;
-    out.stay = true;
-    var unsatisfied = <Constraint>[];
-    var todo = <Variable>[out];
-    while (todo.isNotEmpty) {
-      var v = todo.removeLast();
-      for (var i = 0; i < v.constraints.length; i++) {
-        var c = v.constraints[i];
-        if (!c.isSatisfied()) unsatisfied.add(c);
-      }
-      var determining = v.determinedBy;
-      for (var i = 0; i < v.constraints.length; i++) {
-        var next = v.constraints[i];
-        if (next != determining && next.isSatisfied()) {
-          next.recalculate();
-          todo.add(next.output());
-        }
-      }
-    }
-    return unsatisfied;
-  }
-
-  void addConstraintsConsumingTo(Variable v, List<Constraint> coll) {
-    var determining = v.determinedBy;
-    for (var i = 0; i < v.constraints.length; i++) {
-      var c = v.constraints[i];
-      if (c != determining && c.isSatisfied()) coll.add(c);
-    }
-  }
-}
-
-/// A Plan is an ordered list of constraints to be executed in sequence
-/// to resatisfy all currently satisfiable constraints in the face of
-/// one or more changing inputs.
-class Plan {
-  List<Constraint> list = <Constraint>[];
-
-  void addConstraint(Constraint c) {
-    list.add(c);
-  }
-
-  int size() => list.length;
-
-  void execute() {
-    for (var i = 0; i < list.length; i++) {
-      list[i].execute();
-    }
-  }
-}
-
-/// This is the standard DeltaBlue benchmark. A long chain of equality
-/// constraints is constructed with a stay constraint on one end. An
-/// edit constraint is then added to the opposite end and the time is
-/// measured for adding and removing this constraint, and extracting
-/// and executing a constraint satisfaction plan. There are two cases.
-/// In case 1, the added constraint is stronger than the stay
-/// constraint and values must propagate down the entire length of the
-/// chain. In case 2, the added constraint is weaker than the stay
-/// constraint so it cannot be accomodated. The cost in this case is,
-/// of course, very low. Typical situations lie somewhere between these
-/// two extremes.
-void chainTest(int n) {
-  planner = Planner();
-  Variable prev, first, last;
-  // Build chain of n equality constraints.
-  for (var i = 0; i <= n; i++) {
-    var v = Variable('v', 0);
-    if (prev != null) EqualityConstraint(prev, v, REQUIRED);
-    if (i == 0) first = v;
-    if (i == n) last = v;
-    prev = v;
-  }
-  StayConstraint(last, STRONG_DEFAULT);
-  var edit = EditConstraint(first, PREFERRED);
-  var plan = planner.extractPlanFromConstraints(<Constraint>[edit]);
-  for (var i = 0; i < 100; i++) {
-    first.value = i;
-    plan.execute();
-    if (last.value != i) {
-      print('Chain test failed.\n{last.value)\n{i}');
-    }
-  }
-}
-
-/// This test constructs a two sets of variables related to each
-/// other by a simple linear transformation (scale and offset). The
-/// time is measured to change a variable on either side of the
-/// mapping and to change the scale and offset factors.
-void projectionTest(int n) {
-  planner = Planner();
-  var scale = Variable('scale', 10);
-  var offset = Variable('offset', 1000);
-  Variable src, dst;
-
-  var dests = <Variable>[];
-  for (var i = 0; i < n; i++) {
-    src = Variable('src', i);
-    dst = Variable('dst', i);
-    dests.add(dst);
-    StayConstraint(src, NORMAL);
-    ScaleConstraint(src, scale, offset, dst, REQUIRED);
-  }
-  change(src, 17);
-  if (dst.value != 1170) print('Projection 1 failed');
-  change(dst, 1050);
-  if (src.value != 5) print('Projection 2 failed');
-  change(scale, 5);
-  for (var i = 0; i < n - 1; i++) {
-    if (dests[i].value != i * 5 + 1000) print('Projection 3 failed');
-  }
-  change(offset, 2000);
-  for (var i = 0; i < n - 1; i++) {
-    if (dests[i].value != i * 5 + 2000) print('Projection 4 failed');
-  }
-}
-
-void change(Variable v, int newValue) {
-  var edit = EditConstraint(v, PREFERRED);
-  var plan = planner.extractPlanFromConstraints(<EditConstraint>[edit]);
-  for (var i = 0; i < 10; i++) {
-    v.value = newValue;
-    plan.execute();
-  }
-  edit.destroyConstraint();
-}
-
-Planner planner;
diff --git a/example/FluidMotion/dart/FluidMotion.dart b/example/FluidMotion/dart/FluidMotion.dart
deleted file mode 100644
index e580713..0000000
--- a/example/FluidMotion/dart/FluidMotion.dart
+++ /dev/null
@@ -1,507 +0,0 @@
-// @dart=2.8
-import 'dart:html';
-
-/// Copyright 2013 the V8 project authors. All rights reserved.
-/// Copyright 2009 Oliver Hunt <http://nerget.com>
-///
-/// Permission is hereby granted, free of charge, to any person
-/// obtaining a copy of this software and associated documentation
-/// files (the 'Software'), to deal in the Software without
-/// restriction, including without limitation the rights to use,
-/// copy, modify, merge, publish, distribute, sublicense, and/or sell
-/// copies of the Software, and to permit persons to whom the
-/// Software is furnished to do so, subject to the following
-/// conditions:
-///
-/// The above copyright notice and this permission notice shall be
-/// included in all copies or substantial portions of the Software.
-///
-/// THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
-/// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
-/// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-/// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
-/// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
-/// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-/// OTHER DEALINGS IN THE SOFTWARE.
-
-// Ported from the v8 benchmark suite by Google 2013.
-// Uses Float64List for data.
-
-import 'dart:math';
-import 'dart:typed_data';
-
-import 'package:benchmark_harness/benchmark_harness.dart';
-
-/// Copyright 2009 Oliver Hunt <http://nerget.com>
-///
-/// Permission is hereby granted, free of charge, to any person
-/// obtaining a copy of this software and associated documentation
-/// files (the 'Software'), to deal in the Software without
-/// restriction, including without limitation the rights to use,
-/// copy, modify, merge, publish, distribute, sublicense, and/or sell
-/// copies of the Software, and to permit persons to whom the
-/// Software is furnished to do so, subject to the following
-/// conditions:
-///
-/// The above copyright notice and this permission notice shall be
-/// included in all copies or substantial portions of the Software.
-///
-/// THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
-/// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
-/// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-/// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
-/// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
-/// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-/// OTHER DEALINGS IN THE SOFTWARE.
-// Ported from the v8 benchmark suite by Google 2013.
-// Uses Float64List for data.
-
-/// Copyright 2009 Oliver Hunt <http://nerget.com>
-///
-/// Permission is hereby granted, free of charge, to any person
-/// obtaining a copy of this software and associated documentation
-/// files (the 'Software'), to deal in the Software without
-/// restriction, including without limitation the rights to use,
-/// copy, modify, merge, publish, distribute, sublicense, and/or sell
-/// copies of the Software, and to permit persons to whom the
-/// Software is furnished to do so, subject to the following
-/// conditions:
-///
-/// The above copyright notice and this permission notice shall be
-/// included in all copies or substantial portions of the Software.
-///
-/// THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
-/// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
-/// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-/// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
-/// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
-/// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-/// OTHER DEALINGS IN THE SOFTWARE.
-// Ported from the v8 benchmark suite by Google 2013.
-// Uses Float64List for data.
-
-void main() {
-  const FluidMotion().report();
-}
-
-class FluidMotion extends BenchmarkBase {
-  static FluidField solver;
-  static int framesTillAddingPoints = 0;
-  static int framesBetweenAddingPoints = 5;
-
-  const FluidMotion() : super('FluidMotion');
-
-  static void setupFluidMotion() {
-    framesTillAddingPoints = 0;
-    framesBetweenAddingPoints = 5;
-    solver = FluidField.create(null, 128, 128, 20);
-    solver.setDisplayFunction((a) {});
-    solver.setUICallback(prepareFrame);
-  }
-
-  static void runFluidMotion() {
-    setupFluidMotion();
-    for (var i = 0; i < 10; i++) {
-      solver.update();
-    }
-    solver.validate(758.9012130174812, -352.56376676179076, -357.3690235879736);
-  }
-
-  static void main() {
-    runFluidMotion();
-  }
-
-  static void addPoints(Field field) {
-    var n = 64;
-    for (var i = 1; i <= n; i++) {
-      field.setVelocity(i, i, n.toDouble(), n.toDouble());
-      field.setDensity(i, i, 5.0);
-      field.setVelocity(i, n - i, -n.toDouble(), -n.toDouble());
-      field.setDensity(i, n - i, 20.0);
-      field.setVelocity(128 - i, n + i, -n.toDouble(), -n.toDouble());
-      field.setDensity(128 - i, n + i, 30.0);
-    }
-  }
-
-  static void prepareFrame(Field field) {
-    if (framesTillAddingPoints == 0) {
-      addPoints(field);
-      framesTillAddingPoints = framesBetweenAddingPoints;
-      framesBetweenAddingPoints++;
-    } else {
-      framesTillAddingPoints--;
-    }
-  }
-
-  // Overrides of BenchmarkBase.
-
-  @override
-  void warmup() {
-    runFluidMotion();
-  }
-
-  @override
-  void exercise() {
-    runFluidMotion();
-  }
-}
-
-// Code from Oliver Hunt (http://nerget.com/fluidSim/pressure.js) starts here.
-
-class FluidField {
-  final CanvasElement canvas;
-  final int iterations;
-  final double dt = 0.1;
-  final int size;
-  Float64List dens, dens_prev;
-  Float64List u, u_prev;
-  Float64List v, v_prev;
-  final int width, height;
-  final int rowSize;
-  void Function(Field) displayFunc;
-
-  static FluidField _lastCreated;
-
-  static bool approxEquals(double a, double b) => (a - b).abs() < 0.000001;
-
-  void validate(double expectedDens, double expectedU, double expectedV) {
-    var sumDens = 0.0;
-    var sumU = 0.0;
-    var sumV = 0.0;
-    for (var i = 0; i < dens.length; i++) {
-      sumDens += dens[i];
-      sumU += u[i];
-      sumV += v[i];
-    }
-
-    if (!approxEquals(sumDens, expectedDens) ||
-        !approxEquals(sumU, expectedU) ||
-        !approxEquals(sumV, expectedV)) {
-      throw 'Incorrect result';
-    }
-  }
-
-  // Allocates a new FluidField or return previously allocated field if the
-  // size is too large.
-  factory FluidField.create(
-      CanvasElement canvas, int hRes, int wRes, int iterations) {
-    final res = wRes * hRes;
-    if ((res > 0) && (res < 1000000)) {
-      _lastCreated = FluidField(canvas, hRes, wRes, iterations);
-    }
-    _lastCreated ??= FluidField(canvas, 64, 64, iterations);
-    assert((canvas == _lastCreated.canvas) &&
-        (iterations == _lastCreated.iterations));
-    return _lastCreated;
-  }
-
-  FluidField(this.canvas, this.height, this.width, this.iterations)
-      : rowSize = width + 2,
-        size = (width + 2) * (height + 2) {
-    reset();
-  }
-
-  void reset() {
-    // All Float64List elements are initialized to 0.0.
-    dens = Float64List(size);
-    dens_prev = Float64List(size);
-    u = Float64List(size);
-    u_prev = Float64List(size);
-    v = Float64List(size);
-    v_prev = Float64List(size);
-  }
-
-  void addFields(Float64List x, Float64List s, double dt) {
-    for (var i = 0; i < size; i++) {
-      x[i] += dt * s[i];
-    }
-  }
-
-  void set_bnd(int b, Float64List x) {
-    if (b == 1) {
-      var i = 1;
-      for (; i <= width; i++) {
-        x[i] = x[i + rowSize];
-        x[i + (height + 1) * rowSize] = x[i + height * rowSize];
-      }
-
-      for (var j = 1; j <= height; j++) {
-        x[j * rowSize] = x[1 + j * rowSize];
-        x[(width + 1) + j * rowSize] = -1 * x[width + j * rowSize];
-      }
-    } else if (b == 2) {
-      for (var i = 1; i <= width; i++) {
-        x[i] = -1 * x[i + rowSize];
-        x[i + (height + 1) * rowSize] = -1 * x[i + height * rowSize];
-      }
-
-      for (var j = 1; j <= height; j++) {
-        x[j * rowSize] = x[1 + j * rowSize];
-        x[(width + 1) + j * rowSize] = x[width + j * rowSize];
-      }
-    } else {
-      for (var i = 1; i <= width; i++) {
-        x[i] = x[i + rowSize];
-        x[i + (height + 1) * rowSize] = x[i + height * rowSize];
-      }
-
-      for (var j = 1; j <= height; j++) {
-        x[j * rowSize] = x[1 + j * rowSize];
-        x[(width + 1) + j * rowSize] = x[width + j * rowSize];
-      }
-    }
-    var maxEdge = (height + 1) * rowSize;
-    x[0] = 0.5 * (x[1] + x[rowSize]);
-    x[maxEdge] = 0.5 * (x[1 + maxEdge] + x[height * rowSize]);
-    x[(width + 1)] = 0.5 * (x[width] + x[(width + 1) + rowSize]);
-    x[(width + 1) + maxEdge] =
-        0.5 * (x[width + maxEdge] + x[(width + 1) + height * rowSize]);
-  }
-
-  void lin_solve(int b, Float64List x, Float64List x0, int a, int c) {
-    if (a == 0 && c == 1) {
-      for (var j = 1; j <= height; j++) {
-        var currentRow = j * rowSize;
-        ++currentRow;
-        for (var i = 0; i < width; i++) {
-          x[currentRow] = x0[currentRow];
-          ++currentRow;
-        }
-      }
-      set_bnd(b, x);
-    } else {
-      var invC = 1 / c;
-      for (var k = 0; k < iterations; k++) {
-        for (var j = 1; j <= height; j++) {
-          var lastRow = (j - 1) * rowSize;
-          var currentRow = j * rowSize;
-          var nextRow = (j + 1) * rowSize;
-          var lastX = x[currentRow];
-          ++currentRow;
-          for (var i = 1; i <= width; i++) {
-            lastX = x[currentRow] = (x0[currentRow] +
-                    a *
-                        (lastX +
-                            x[++currentRow] +
-                            x[++lastRow] +
-                            x[++nextRow])) *
-                invC;
-          }
-        }
-        set_bnd(b, x);
-      }
-    }
-  }
-
-  void diffuse(int b, Float64List x, Float64List x0, double dt) {
-    var a = 0;
-    lin_solve(b, x, x0, a, 1 + 4 * a);
-  }
-
-  void lin_solve2(Float64List x, Float64List x0, Float64List y, Float64List y0,
-      int a, int c) {
-    if (a == 0 && c == 1) {
-      for (var j = 1; j <= height; j++) {
-        var currentRow = j * rowSize;
-        ++currentRow;
-        for (var i = 0; i < width; i++) {
-          x[currentRow] = x0[currentRow];
-          y[currentRow] = y0[currentRow];
-          ++currentRow;
-        }
-      }
-      set_bnd(1, x);
-      set_bnd(2, y);
-    } else {
-      var invC = 1 / c;
-      for (var k = 0; k < iterations; k++) {
-        for (var j = 1; j <= height; j++) {
-          var lastRow = (j - 1) * rowSize;
-          var currentRow = j * rowSize;
-          var nextRow = (j + 1) * rowSize;
-          var lastX = x[currentRow];
-          var lastY = y[currentRow];
-          ++currentRow;
-          for (var i = 1; i <= width; i++) {
-            lastX = x[currentRow] = (x0[currentRow] +
-                    a * (lastX + x[currentRow] + x[lastRow] + x[nextRow])) *
-                invC;
-            lastY = y[currentRow] = (y0[currentRow] +
-                    a *
-                        (lastY +
-                            y[++currentRow] +
-                            y[++lastRow] +
-                            y[++nextRow])) *
-                invC;
-          }
-        }
-        set_bnd(1, x);
-        set_bnd(2, y);
-      }
-    }
-  }
-
-  void diffuse2(
-      Float64List x, Float64List x0, Float64List y, Float64List y0, double dt) {
-    var a = 0;
-    lin_solve2(x, x0, y, y0, a, 1 + 4 * a);
-  }
-
-  void advect(int b, Float64List d, Float64List d0, Float64List u,
-      Float64List v, double dt) {
-    var Wdt0 = dt * width;
-    var Hdt0 = dt * height;
-    var Wp5 = width + 0.5;
-    var Hp5 = height + 0.5;
-    for (var j = 1; j <= height; j++) {
-      var pos = j * rowSize;
-      for (var i = 1; i <= width; i++) {
-        var x = i - Wdt0 * u[++pos];
-        var y = j - Hdt0 * v[pos];
-        if (x < 0.5) {
-          x = 0.5;
-        } else if (x > Wp5) x = Wp5;
-        var i0 = x.toInt();
-        var i1 = i0 + 1;
-        if (y < 0.5) {
-          y = 0.5;
-        } else if (y > Hp5) y = Hp5;
-        var j0 = y.toInt();
-        var j1 = j0 + 1;
-        var s1 = x - i0;
-        var s0 = 1 - s1;
-        var t1 = y - j0;
-        var t0 = 1 - t1;
-        var row1 = j0 * rowSize;
-        var row2 = j1 * rowSize;
-        d[pos] = s0 * (t0 * d0[i0 + row1] + t1 * d0[i0 + row2]) +
-            s1 * (t0 * d0[i1 + row1] + t1 * d0[i1 + row2]);
-      }
-    }
-    set_bnd(b, d);
-  }
-
-  void project(Float64List u, Float64List v, Float64List p, Float64List div) {
-    var h = -0.5 / sqrt(width * height);
-    for (var j = 1; j <= height; j++) {
-      var row = j * rowSize;
-      var previousRow = (j - 1) * rowSize;
-      var prevValue = row - 1;
-      var currentRow = row;
-      var nextValue = row + 1;
-      var nextRow = (j + 1) * rowSize;
-      for (var i = 1; i <= width; i++) {
-        div[++currentRow] = h *
-            (u[++nextValue] - u[++prevValue] + v[++nextRow] - v[++previousRow]);
-        p[currentRow] = 0.0;
-      }
-    }
-    set_bnd(0, div);
-    set_bnd(0, p);
-
-    lin_solve(0, p, div, 1, 4);
-    var wScale = 0.5 * width;
-    var hScale = 0.5 * height;
-    for (var j = 1; j <= height; j++) {
-      var prevPos = j * rowSize - 1;
-      var currentPos = j * rowSize;
-      var nextPos = j * rowSize + 1;
-      var prevRow = (j - 1) * rowSize;
-      var nextRow = (j + 1) * rowSize;
-
-      for (var i = 1; i <= width; i++) {
-        u[++currentPos] -= wScale * (p[++nextPos] - p[++prevPos]);
-        v[currentPos] -= hScale * (p[++nextRow] - p[++prevRow]);
-      }
-    }
-    set_bnd(1, u);
-    set_bnd(2, v);
-  }
-
-  void dens_step(
-      Float64List x, Float64List x0, Float64List u, Float64List v, double dt) {
-    addFields(x, x0, dt);
-    diffuse(0, x0, x, dt);
-    advect(0, x, x0, u, v, dt);
-  }
-
-  void vel_step(
-      Float64List u, Float64List v, Float64List u0, Float64List v0, double dt) {
-    addFields(u, u0, dt);
-    addFields(v, v0, dt);
-    var temp = u0;
-    u0 = u;
-    u = temp;
-    temp = v0;
-    v0 = v;
-    v = temp;
-    diffuse2(u, u0, v, v0, dt);
-    project(u, v, u0, v0);
-    temp = u0;
-    u0 = u;
-    u = temp;
-    temp = v0;
-    v0 = v;
-    v = temp;
-    advect(1, u, u0, u0, v0, dt);
-    advect(2, v, v0, u0, v0, dt);
-    project(u, v, u0, v0);
-  }
-
-  void Function(Field) uiCallback;
-
-  void setDisplayFunction(void Function(Field) func) {
-    displayFunc = func;
-  }
-
-  void setUICallback(void Function(Field) callback) {
-    uiCallback = callback;
-  }
-
-  void queryUI(Float64List d, Float64List u, Float64List v) {
-    for (var i = 0; i < size; i++) {
-      u[i] = v[i] = d[i] = 0.0;
-    }
-    uiCallback(Field(d, u, v, rowSize));
-  }
-
-  void update() {
-    queryUI(dens_prev, u_prev, v_prev);
-    vel_step(u, v, u_prev, v_prev, dt);
-    dens_step(dens, dens_prev, u, v, dt);
-    displayFunc(Field(dens, u, v, rowSize));
-  }
-}
-
-// Difference from JS version: Field takes an argument rowSize, but this
-// used for display purpose only.
-class Field {
-  final Float64List dens, u, v;
-  final int rowSize;
-
-  Field(this.dens, this.u, this.v, this.rowSize);
-
-  void setDensity(int x, int y, double d) {
-    dens[(x + 1) + (y + 1) * rowSize] = d;
-  }
-
-  double getDensity(int x, int y) {
-    return dens[(x + 1) + (y + 1) * rowSize]; // rowSize from FluidField?
-  }
-
-  void setVelocity(int x, int y, double xv, double yv) {
-    u[(x + 1) + (y + 1) * rowSize] = xv;
-    v[(x + 1) + (y + 1) * rowSize] = yv;
-  }
-
-  double getXVelocity(int x, int y) {
-    return u[(x + 1) + (y + 1) * rowSize];
-  }
-
-  double getYVelocity(int x, int y) {
-    return v[(x + 1) + (y + 1) * rowSize];
-  }
-}
diff --git a/example/FluidMotion/js/FluidMotion.js b/example/FluidMotion/js/FluidMotion.js
deleted file mode 100644
index 326b4e1..0000000
--- a/example/FluidMotion/js/FluidMotion.js
+++ /dev/null
@@ -1,413 +0,0 @@
-/**
- * Copyright 2012 the V8 project authors. All rights reserved.
- * Copyright 2009 Oliver Hunt <http://nerget.com>
- *
- * Permission is hereby granted, free of charge, to any person
- * obtaining a copy of this software and associated documentation
- * files (the "Software"), to deal in the Software without
- * restriction, including without limitation the rights to use,
- * copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following
- * conditions:
- *
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- */
-
-// Addapted by Google 2013.
-
-var solver = null;
-
-var framesTillAddingPoints = 0;
-var framesBetweenAddingPoints = 5;
-
-function runFluidMotion()
-{
-    setupFluidMotion();
-    for (var i = 0; i < 10; i++) {
-        solver.update();
-    }
-    solver.validate(758.9012130174812, -352.56376676179076, -357.3690235879736);
-}
-
-function setupFluidMotion()
-{
-    framesTillAddingPoints = 0;
-    framesBetweenAddingPoints = 5;
-    solver = new FluidField(null);
-    solver.setResolution(128, 128);
-    solver.setIterations(20);
-    solver.setDisplayFunction(function(){});
-    solver.setUICallback(prepareFrame);
-}
-
-function tearDownFluidMotion()
-{
-    solver = null;
-}
-
-function addPoints(field) {
-    var n = 64;
-    for (var i = 1; i <= n; i++) {
-        field.setVelocity(i, i, n, n);
-        field.setDensity(i, i, 5);
-        field.setVelocity(i, n - i, -n, -n);
-        field.setDensity(i, n - i, 20);
-        field.setVelocity(128 - i, n + i, -n, -n);
-        field.setDensity(128 - i, n + i, 30);
-    }
-}
-
-function prepareFrame(field)
-{
-    if (framesTillAddingPoints == 0) {
-        addPoints(field);
-        framesTillAddingPoints = framesBetweenAddingPoints;
-        framesBetweenAddingPoints++;
-    } else {
-        framesTillAddingPoints--;
-    }
-}
-
-// Code from Oliver Hunt (http://nerget.com/fluidSim/pressure.js) starts here.
-function FluidField(canvas) {
-  
-    function approxEquals(a, b) {
-        return Math.abs(a - b) < 0.000001;
-    }
-    
-    function validate(expectedDens, expectedU, expectedV) {
-        var sumDens = 0.0;
-        var sumU = 0.0;
-        var sumV = 0.0;
-        for (var i = 0; i < dens.length; i++) {
-          sumDens += dens[i];
-          sumU += u[i];
-          sumV += v[i];
-        }
-
-        if (!approxEquals(sumDens, expectedDens) ||
-            !approxEquals(sumU, expectedU) ||
-            !approxEquals(sumV, expectedV)) {
-          throw "Incorrect result";
-        }
-    }
-    this.validate = validate;
-  
-    function addFields(x, s, dt)
-    {
-        for (var i=0; i<size ; i++ ) x[i] += dt*s[i];
-    }
-
-    function set_bnd(b, x)
-    {
-        if (b===1) {
-            for (var i = 1; i <= width; i++) {
-                x[i] =  x[i + rowSize];
-                x[i + (height+1) *rowSize] = x[i + height * rowSize];
-            }
-
-            for (var j = 1; j <= height; j++) {
-                x[j * rowSize] = -x[1 + j * rowSize];
-                x[(width + 1) + j * rowSize] = -x[width + j * rowSize];
-            }
-        } else if (b === 2) {
-            for (var i = 1; i <= width; i++) {
-                x[i] = -x[i + rowSize];
-                x[i + (height + 1) * rowSize] = -x[i + height * rowSize];
-            }
-
-            for (var j = 1; j <= height; j++) {
-                x[j * rowSize] =  x[1 + j * rowSize];
-                x[(width + 1) + j * rowSize] =  x[width + j * rowSize];
-            }
-        } else {
-            for (var i = 1; i <= width; i++) {
-                x[i] =  x[i + rowSize];
-                x[i + (height + 1) * rowSize] = x[i + height * rowSize];
-            }
-
-            for (var j = 1; j <= height; j++) {
-                x[j * rowSize] =  x[1 + j * rowSize];
-                x[(width + 1) + j * rowSize] =  x[width + j * rowSize];
-            }
-        }
-        var maxEdge = (height + 1) * rowSize;
-        x[0]                 = 0.5 * (x[1] + x[rowSize]);
-        x[maxEdge]           = 0.5 * (x[1 + maxEdge] + x[height * rowSize]);
-        x[(width+1)]         = 0.5 * (x[width] + x[(width + 1) + rowSize]);
-        x[(width+1)+maxEdge] = 0.5 * (x[width + maxEdge] + x[(width + 1) + height * rowSize]);
-    }
-
-    function lin_solve(b, x, x0, a, c)
-    {
-        if (a === 0 && c === 1) {
-            for (var j=1 ; j<=height; j++) {
-                var currentRow = j * rowSize;
-                ++currentRow;
-                for (var i = 0; i < width; i++) {
-                    x[currentRow] = x0[currentRow];
-                    ++currentRow;
-                }
-            }
-            set_bnd(b, x);
-        } else {
-            var invC = 1 / c;
-            for (var k=0 ; k<iterations; k++) {
-                for (var j=1 ; j<=height; j++) {
-                    var lastRow = (j - 1) * rowSize;
-                    var currentRow = j * rowSize;
-                    var nextRow = (j + 1) * rowSize;
-                    var lastX = x[currentRow];
-                    ++currentRow;
-                    for (var i=1; i<=width; i++)
-                        lastX = x[currentRow] = (x0[currentRow] + a*(lastX+x[++currentRow]+x[++lastRow]+x[++nextRow])) * invC;
-                }
-                set_bnd(b, x);
-            }
-        }
-    }
-
-    function diffuse(b, x, x0, dt)
-    {
-        var a = 0;
-        lin_solve(b, x, x0, a, 1 + 4*a);
-    }
-
-    function lin_solve2(x, x0, y, y0, a, c)
-    {
-        if (a === 0 && c === 1) {
-            for (var j=1 ; j <= height; j++) {
-                var currentRow = j * rowSize;
-                ++currentRow;
-                for (var i = 0; i < width; i++) {
-                    x[currentRow] = x0[currentRow];
-                    y[currentRow] = y0[currentRow];
-                    ++currentRow;
-                }
-            }
-            set_bnd(1, x);
-            set_bnd(2, y);
-        } else {
-            var invC = 1/c;
-            for (var k=0 ; k<iterations; k++) {
-                for (var j=1 ; j <= height; j++) {
-                    var lastRow = (j - 1) * rowSize;
-                    var currentRow = j * rowSize;
-                    var nextRow = (j + 1) * rowSize;
-                    var lastX = x[currentRow];
-                    var lastY = y[currentRow];
-                    ++currentRow;
-                    for (var i = 1; i <= width; i++) {
-                        lastX = x[currentRow] = (x0[currentRow] + a * (lastX + x[currentRow] + x[lastRow] + x[nextRow])) * invC;
-                        lastY = y[currentRow] = (y0[currentRow] + a * (lastY + y[++currentRow] + y[++lastRow] + y[++nextRow])) * invC;
-                    }
-                }
-                set_bnd(1, x);
-                set_bnd(2, y);
-            }
-        }
-    }
-
-    function diffuse2(x, x0, y, y0, dt)
-    {
-        var a = 0;
-        lin_solve2(x, x0, y, y0, a, 1 + 4 * a);
-    }
-
-    function advect(b, d, d0, u, v, dt)
-    {
-        var Wdt0 = dt * width;
-        var Hdt0 = dt * height;
-        var Wp5 = width + 0.5;
-        var Hp5 = height + 0.5;
-        for (var j = 1; j<= height; j++) {
-            var pos = j * rowSize;
-            for (var i = 1; i <= width; i++) {
-                var x = i - Wdt0 * u[++pos];
-                var y = j - Hdt0 * v[pos];
-                if (x < 0.5)
-                    x = 0.5;
-                else if (x > Wp5)
-                    x = Wp5;
-                var i0 = x | 0;
-                var i1 = i0 + 1;
-                if (y < 0.5)
-                    y = 0.5;
-                else if (y > Hp5)
-                    y = Hp5;
-                var j0 = y | 0;
-                var j1 = j0 + 1;
-                var s1 = x - i0;
-                var s0 = 1 - s1;
-                var t1 = y - j0;
-                var t0 = 1 - t1;
-                var row1 = j0 * rowSize;
-                var row2 = j1 * rowSize;
-                d[pos] = s0 * (t0 * d0[i0 + row1] + t1 * d0[i0 + row2]) + s1 * (t0 * d0[i1 + row1] + t1 * d0[i1 + row2]);
-            }
-        }
-        set_bnd(b, d);
-    }
-
-    function project(u, v, p, div)
-    {
-        var h = -0.5 / Math.sqrt(width * height);
-        for (var j = 1 ; j <= height; j++ ) {
-            var row = j * rowSize;
-            var previousRow = (j - 1) * rowSize;
-            var prevValue = row - 1;
-            var currentRow = row;
-            var nextValue = row + 1;
-            var nextRow = (j + 1) * rowSize;
-            for (var i = 1; i <= width; i++ ) {
-                div[++currentRow] = h * (u[++nextValue] - u[++prevValue] + v[++nextRow] - v[++previousRow]);
-                p[currentRow] = 0;
-            }
-        }
-        set_bnd(0, div);
-        set_bnd(0, p);
-
-        lin_solve(0, p, div, 1, 4 );
-        var wScale = 0.5 * width;
-        var hScale = 0.5 * height;
-        for (var j = 1; j<= height; j++ ) {
-            var prevPos = j * rowSize - 1;
-            var currentPos = j * rowSize;
-            var nextPos = j * rowSize + 1;
-            var prevRow = (j - 1) * rowSize;
-            var currentRow = j * rowSize;
-            var nextRow = (j + 1) * rowSize;
-
-            for (var i = 1; i<= width; i++) {
-                u[++currentPos] -= wScale * (p[++nextPos] - p[++prevPos]);
-                v[currentPos]   -= hScale * (p[++nextRow] - p[++prevRow]);
-            }
-        }
-        set_bnd(1, u);
-        set_bnd(2, v);
-    }
-
-    function dens_step(x, x0, u, v, dt)
-    {
-        addFields(x, x0, dt);
-        diffuse(0, x0, x, dt );
-        advect(0, x, x0, u, v, dt );
-    }
-
-    function vel_step(u, v, u0, v0, dt)
-    {
-        addFields(u, u0, dt );
-        addFields(v, v0, dt );
-        var temp = u0; u0 = u; u = temp;
-        var temp = v0; v0 = v; v = temp;
-        diffuse2(u,u0,v,v0, dt);
-        project(u, v, u0, v0);
-        var temp = u0; u0 = u; u = temp;
-        var temp = v0; v0 = v; v = temp;
-        advect(1, u, u0, u0, v0, dt);
-        advect(2, v, v0, u0, v0, dt);
-        project(u, v, u0, v0 );
-    }
-    var uiCallback = function(d,u,v) {};
-
-    function Field(dens, u, v) {
-        // Just exposing the fields here rather than using accessors is a measurable win during display (maybe 5%)
-        // but makes the code ugly.
-        this.setDensity = function(x, y, d) {
-             dens[(x + 1) + (y + 1) * rowSize] = d;
-        }
-        this.getDensity = function(x, y) {
-             return dens[(x + 1) + (y + 1) * rowSize];
-        }
-        this.setVelocity = function(x, y, xv, yv) {
-             u[(x + 1) + (y + 1) * rowSize] = xv;
-             v[(x + 1) + (y + 1) * rowSize] = yv;
-        }
-        this.getXVelocity = function(x, y) {
-             return u[(x + 1) + (y + 1) * rowSize];
-        }
-        this.getYVelocity = function(x, y) {
-             return v[(x + 1) + (y + 1) * rowSize];
-        }
-        this.width = function() { return width; }
-        this.height = function() { return height; }
-    }
-    function queryUI(d, u, v)
-    {
-        for (var i = 0; i < size; i++)
-            u[i] = v[i] = d[i] = 0.0;
-        uiCallback(new Field(d, u, v));
-    }
-
-    this.update = function () {
-        queryUI(dens_prev, u_prev, v_prev);
-        vel_step(u, v, u_prev, v_prev, dt);
-        dens_step(dens, dens_prev, u, v, dt);
-        displayFunc(new Field(dens, u, v));
-    }
-    this.setDisplayFunction = function(func) {
-        displayFunc = func;
-    }
-
-    this.iterations = function() { return iterations; }
-    this.setIterations = function(iters) {
-        if (iters > 0 && iters <= 100)
-           iterations = iters;
-    }
-    this.setUICallback = function(callback) {
-        uiCallback = callback;
-    }
-    var iterations = 10;
-    var visc = 0.5;
-    var dt = 0.1;
-    var dens;
-    var dens_prev;
-    var u;
-    var u_prev;
-    var v;
-    var v_prev;
-    var width;
-    var height;
-    var rowSize;
-    var size;
-    var displayFunc;
-    function reset()
-    {
-        rowSize = width + 2;
-        size = (width+2)*(height+2);
-        dens = new Float64Array(size);
-        dens_prev = new Float64Array(size);
-        u = new Float64Array(size);
-        u_prev = new Float64Array(size);
-        v = new Float64Array(size);
-        v_prev = new Float64Array(size);
-        for (var i = 0; i < size; i++)
-            dens_prev[i] = u_prev[i] = v_prev[i] = dens[i] = u[i] = v[i] = 0;
-    }
-    this.reset = reset;
-    this.setResolution = function (hRes, wRes)
-    {
-        var res = wRes * hRes;
-        if (res > 0 && res < 1000000 && (wRes != width || hRes != height)) {
-            width = wRes;
-            height = hRes;
-            reset();
-            return true;
-        }
-        return false;
-    }
-    this.setResolution(64, 64);
-}
-
-Benchmark.report("FluidMotion", runFluidMotion, runFluidMotion);
diff --git a/example/Richards.dart b/example/Richards.dart
deleted file mode 100644
index 4b5f2ea..0000000
--- a/example/Richards.dart
+++ /dev/null
@@ -1,449 +0,0 @@
-// @dart=2.8
-// Copyright 2006-2008 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-//       notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-//       copyright notice, this list of conditions and the following
-//       disclaimer in the documentation and/or other materials provided
-//       with the distribution.
-//     * Neither the name of Google Inc. nor the names of its
-//       contributors may be used to endorse or promote products derived
-//       from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// 'AS IS' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// Ported by the Dart team to Dart.
-
-// This is a Dart implementation of the Richards benchmark from:
-//
-//    http://www.cl.cam.ac.uk/~mr10/Bench.html
-//
-// The benchmark was originally implemented in BCPL by
-// Martin Richards.
-
-import 'package:benchmark_harness/benchmark_harness.dart';
-
-void main() {
-  const Richards().report();
-}
-
-/// Richards imulates the task dispatcher of an operating system.
-class Richards extends BenchmarkBase {
-  const Richards() : super('Richards');
-
-  @override
-  void run() {
-    var scheduler = Scheduler();
-    scheduler.addIdleTask(ID_IDLE, 0, null, COUNT);
-
-    var queue = Packet(null, ID_WORKER, KIND_WORK);
-    queue = Packet(queue, ID_WORKER, KIND_WORK);
-    scheduler.addWorkerTask(ID_WORKER, 1000, queue);
-
-    queue = Packet(null, ID_DEVICE_A, KIND_DEVICE);
-    queue = Packet(queue, ID_DEVICE_A, KIND_DEVICE);
-    queue = Packet(queue, ID_DEVICE_A, KIND_DEVICE);
-    scheduler.addHandlerTask(ID_HANDLER_A, 2000, queue);
-
-    queue = Packet(null, ID_DEVICE_B, KIND_DEVICE);
-    queue = Packet(queue, ID_DEVICE_B, KIND_DEVICE);
-    queue = Packet(queue, ID_DEVICE_B, KIND_DEVICE);
-    scheduler.addHandlerTask(ID_HANDLER_B, 3000, queue);
-
-    scheduler.addDeviceTask(ID_DEVICE_A, 4000, null);
-
-    scheduler.addDeviceTask(ID_DEVICE_B, 5000, null);
-
-    scheduler.schedule();
-
-    if (scheduler.queueCount != EXPECTED_QUEUE_COUNT ||
-        scheduler.holdCount != EXPECTED_HOLD_COUNT) {
-      print('Error during execution: queueCount = ${scheduler.queueCount}'
-          ', holdCount = ${scheduler.holdCount}.');
-    }
-    if (EXPECTED_QUEUE_COUNT != scheduler.queueCount) {
-      throw 'bad scheduler queue-count';
-    }
-    if (EXPECTED_HOLD_COUNT != scheduler.holdCount) {
-      throw 'bad scheduler hold-count';
-    }
-  }
-
-  static const int DATA_SIZE = 4;
-  static const int COUNT = 1000;
-
-  /// These two constants specify how many times a packet is queued and
-  /// how many times a task is put on hold in a correct run of richards.
-  /// They don't have any meaning a such but are characteristic of a
-  /// correct run so if the actual queue or hold count is different from
-  /// the expected there must be a bug in the implementation.
-  static const int EXPECTED_QUEUE_COUNT = 2322;
-  static const int EXPECTED_HOLD_COUNT = 928;
-
-  static const int ID_IDLE = 0;
-  static const int ID_WORKER = 1;
-  static const int ID_HANDLER_A = 2;
-  static const int ID_HANDLER_B = 3;
-  static const int ID_DEVICE_A = 4;
-  static const int ID_DEVICE_B = 5;
-  static const int NUMBER_OF_IDS = 6;
-
-  static const int KIND_DEVICE = 0;
-  static const int KIND_WORK = 1;
-}
-
-/// A scheduler can be used to schedule a set of tasks based on their relative
-/// priorities.  Scheduling is done by maintaining a list of task control blocks
-/// which holds tasks and the data queue they are processing.
-class Scheduler {
-  int queueCount = 0;
-  int holdCount = 0;
-  TaskControlBlock currentTcb;
-  int currentId;
-  TaskControlBlock list;
-  List<TaskControlBlock> blocks =
-      // ignore: deprecated_member_use
-      List<TaskControlBlock>(Richards.NUMBER_OF_IDS);
-
-  /// Add an idle task to this scheduler.
-  void addIdleTask(int id, int priority, Packet queue, int count) {
-    addRunningTask(id, priority, queue, IdleTask(this, 1, count));
-  }
-
-  /// Add a work task to this scheduler.
-  void addWorkerTask(int id, int priority, Packet queue) {
-    addTask(id, priority, queue, WorkerTask(this, Richards.ID_HANDLER_A, 0));
-  }
-
-  /// Add a handler task to this scheduler.
-  void addHandlerTask(int id, int priority, Packet queue) {
-    addTask(id, priority, queue, HandlerTask(this));
-  }
-
-  /// Add a handler task to this scheduler.
-  void addDeviceTask(int id, int priority, Packet queue) {
-    addTask(id, priority, queue, DeviceTask(this));
-  }
-
-  /// Add the specified task and mark it as running.
-  void addRunningTask(int id, int priority, Packet queue, Task task) {
-    addTask(id, priority, queue, task);
-    currentTcb.setRunning();
-  }
-
-  /// Add the specified task to this scheduler.
-  void addTask(int id, int priority, Packet queue, Task task) {
-    currentTcb = TaskControlBlock(list, id, priority, queue, task);
-    list = currentTcb;
-    blocks[id] = currentTcb;
-  }
-
-  /// Execute the tasks managed by this scheduler.
-  void schedule() {
-    currentTcb = list;
-    while (currentTcb != null) {
-      if (currentTcb.isHeldOrSuspended()) {
-        currentTcb = currentTcb.link;
-      } else {
-        currentId = currentTcb.id;
-        currentTcb = currentTcb.run();
-      }
-    }
-  }
-
-  /// Release a task that is currently blocked and return the next block to run.
-  TaskControlBlock release(int id) {
-    var tcb = blocks[id];
-    if (tcb == null) return tcb;
-    tcb.markAsNotHeld();
-    if (tcb.priority > currentTcb.priority) return tcb;
-    return currentTcb;
-  }
-
-  /// Block the currently executing task and return the next task control block
-  /// to run.  The blocked task will not be made runnable until it is explicitly
-  /// released, even if new work is added to it.
-  TaskControlBlock holdCurrent() {
-    holdCount++;
-    currentTcb.markAsHeld();
-    return currentTcb.link;
-  }
-
-  /// Suspend the currently executing task and return the next task
-  /// control block to run.
-  /// If new work is added to the suspended task it will be made runnable.
-  TaskControlBlock suspendCurrent() {
-    currentTcb.markAsSuspended();
-    return currentTcb;
-  }
-
-  /// Add the specified packet to the end of the worklist used by the task
-  /// associated with the packet and make the task runnable if it is currently
-  /// suspended.
-  TaskControlBlock queue(Packet packet) {
-    var t = blocks[packet.id];
-    if (t == null) return t;
-    queueCount++;
-    packet.link = null;
-    packet.id = currentId;
-    return t.checkPriorityAdd(currentTcb, packet);
-  }
-}
-
-/// A task control block manages a task and the queue of work packages associated
-/// with it.
-class TaskControlBlock {
-  TaskControlBlock link;
-  int id; // The id of this block.
-  int priority; // The priority of this block.
-  Packet queue; // The queue of packages to be processed by the task.
-  Task task;
-  int state;
-
-  TaskControlBlock(this.link, this.id, this.priority, this.queue, this.task) {
-    state = queue == null ? STATE_SUSPENDED : STATE_SUSPENDED_RUNNABLE;
-  }
-
-  /// The task is running and is currently scheduled.
-  static const int STATE_RUNNING = 0;
-
-  /// The task has packets left to process.
-  static const int STATE_RUNNABLE = 1;
-
-  /// The task is not currently running. The task is not blocked as such and may
-  /// be started by the scheduler.
-  static const int STATE_SUSPENDED = 2;
-
-  /// The task is blocked and cannot be run until it is explicitly released.
-  static const int STATE_HELD = 4;
-
-  static const int STATE_SUSPENDED_RUNNABLE = STATE_SUSPENDED | STATE_RUNNABLE;
-  static const int STATE_NOT_HELD = ~STATE_HELD;
-
-  void setRunning() {
-    state = STATE_RUNNING;
-  }
-
-  void markAsNotHeld() {
-    state = state & STATE_NOT_HELD;
-  }
-
-  void markAsHeld() {
-    state = state | STATE_HELD;
-  }
-
-  bool isHeldOrSuspended() {
-    return (state & STATE_HELD) != 0 || (state == STATE_SUSPENDED);
-  }
-
-  void markAsSuspended() {
-    state = state | STATE_SUSPENDED;
-  }
-
-  void markAsRunnable() {
-    state = state | STATE_RUNNABLE;
-  }
-
-  /// Runs this task, if it is ready to be run, and returns the next task to run.
-  TaskControlBlock run() {
-    Packet packet;
-    if (state == STATE_SUSPENDED_RUNNABLE) {
-      packet = queue;
-      queue = packet.link;
-      state = queue == null ? STATE_RUNNING : STATE_RUNNABLE;
-    } else {
-      packet = null;
-    }
-    return task.run(packet);
-  }
-
-  /// Adds a packet to the worklist of this block's task, marks this as
-  /// runnable if necessary, and returns the next runnable object to run
-  /// (the one with the highest priority).
-  TaskControlBlock checkPriorityAdd(TaskControlBlock task, Packet packet) {
-    if (queue == null) {
-      queue = packet;
-      markAsRunnable();
-      if (priority > task.priority) return this;
-    } else {
-      queue = packet.addTo(queue);
-    }
-    return task;
-  }
-
-  @override
-  String toString() => 'tcb { $task@$state }';
-}
-
-///  Abstract task that manipulates work packets.
-abstract class Task {
-  Scheduler scheduler; // The scheduler that manages this task.
-
-  Task(this.scheduler);
-
-  TaskControlBlock run(Packet packet);
-}
-
-/// An idle task doesn't do any work itself but cycles control between the two
-/// device tasks.
-class IdleTask extends Task {
-  int v1; // A seed value that controls how the device tasks are scheduled.
-  int count; // The number of times this task should be scheduled.
-
-  IdleTask(Scheduler scheduler, this.v1, this.count) : super(scheduler);
-
-  @override
-  TaskControlBlock run(Packet packet) {
-    count--;
-    if (count == 0) return scheduler.holdCurrent();
-    if ((v1 & 1) == 0) {
-      v1 = v1 >> 1;
-      return scheduler.release(Richards.ID_DEVICE_A);
-    }
-    v1 = (v1 >> 1) ^ 0xD008;
-    return scheduler.release(Richards.ID_DEVICE_B);
-  }
-
-  @override
-  String toString() => 'IdleTask';
-}
-
-/// A task that suspends itself after each time it has been run to simulate
-/// waiting for data from an external device.
-class DeviceTask extends Task {
-  Packet v1;
-
-  DeviceTask(Scheduler scheduler) : super(scheduler);
-
-  @override
-  TaskControlBlock run(Packet packet) {
-    if (packet == null) {
-      if (v1 == null) return scheduler.suspendCurrent();
-      var v = v1;
-      v1 = null;
-      return scheduler.queue(v);
-    }
-    v1 = packet;
-    return scheduler.holdCurrent();
-  }
-
-  @override
-  String toString() => 'DeviceTask';
-}
-
-/// A task that manipulates work packets.
-class WorkerTask extends Task {
-  int v1; // A seed used to specify how work packets are manipulated.
-  int v2; // Another seed used to specify how work packets are manipulated.
-
-  WorkerTask(Scheduler scheduler, this.v1, this.v2) : super(scheduler);
-
-  @override
-  TaskControlBlock run(Packet packet) {
-    if (packet == null) {
-      return scheduler.suspendCurrent();
-    }
-    if (v1 == Richards.ID_HANDLER_A) {
-      v1 = Richards.ID_HANDLER_B;
-    } else {
-      v1 = Richards.ID_HANDLER_A;
-    }
-    packet.id = v1;
-    packet.a1 = 0;
-    for (var i = 0; i < Richards.DATA_SIZE; i++) {
-      v2++;
-      if (v2 > 26) v2 = 1;
-      packet.a2[i] = v2;
-    }
-    return scheduler.queue(packet);
-  }
-
-  @override
-  String toString() => 'WorkerTask';
-}
-
-/// A task that manipulates work packets and then suspends itself.
-class HandlerTask extends Task {
-  Packet v1;
-  Packet v2;
-
-  HandlerTask(Scheduler scheduler) : super(scheduler);
-
-  @override
-  TaskControlBlock run(Packet packet) {
-    if (packet != null) {
-      if (packet.kind == Richards.KIND_WORK) {
-        v1 = packet.addTo(v1);
-      } else {
-        v2 = packet.addTo(v2);
-      }
-    }
-    if (v1 != null) {
-      var count = v1.a1;
-      Packet v;
-      if (count < Richards.DATA_SIZE) {
-        if (v2 != null) {
-          v = v2;
-          v2 = v2.link;
-          v.a1 = v1.a2[count];
-          v1.a1 = count + 1;
-          return scheduler.queue(v);
-        }
-      } else {
-        v = v1;
-        v1 = v1.link;
-        return scheduler.queue(v);
-      }
-    }
-    return scheduler.suspendCurrent();
-  }
-
-  @override
-  String toString() => 'HandlerTask';
-}
-
-/// A simple package of data that is manipulated by the tasks.  The exact layout
-/// of the payload data carried by a packet is not importaint, and neither is the
-/// nature of the work performed on packets by the tasks.
-/// Besides carrying data, packets form linked lists and are hence used both as
-/// data and worklists.
-class Packet {
-  Packet link; // The tail of the linked list of packets.
-  int id; // An ID for this packet.
-  int kind; // The type of this packet.
-  int a1 = 0;
-
-  // ignore: deprecated_member_use
-  List<int> a2 = List(Richards.DATA_SIZE);
-
-  Packet(this.link, this.id, this.kind);
-
-  /// Add this packet to the end of a worklist, and return the worklist.
-  Packet addTo(Packet queue) {
-    link = null;
-    if (queue == null) return this;
-    Packet peek, next = queue;
-    while ((peek = next.link) != null) {
-      next = peek;
-    }
-    next.link = this;
-    return queue;
-  }
-
-  @override
-  String toString() => 'Packet';
-}
diff --git a/example/Template.dart b/example/Template.dart
index 879732d..43db1cd 100644
--- a/example/Template.dart
+++ b/example/Template.dart
@@ -1,5 +1,7 @@
 // @dart=2.8
-// Copyright 2012 Google Inc. All Rights Reserved.
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
 
 // Import BenchmarkBase class.
 import 'package:benchmark_harness/benchmark_harness.dart';
diff --git a/example/Tracer/dart/Tracer.dart b/example/Tracer/dart/Tracer.dart
deleted file mode 100644
index d3c02b2..0000000
--- a/example/Tracer/dart/Tracer.dart
+++ /dev/null
@@ -1,44 +0,0 @@
-// @dart=2.8
-// The ray tracer code in this file is written by Adam Burmister. It
-// is available in its original form from:
-//
-//   http://labs.flog.co.nz/raytracer/
-//
-// Ported from the v8 benchmark suite by Google 2012.
-
-library ray_trace;
-
-import 'dart:html';
-import 'dart:math';
-
-import 'package:benchmark_harness/benchmark_harness.dart';
-
-part 'color.dart';
-part 'engine.dart';
-part 'materials.dart';
-part 'scene.dart';
-part 'shapes.dart';
-part 'vector.dart';
-part 'renderscene.dart';
-
-// Variable used to hold a number that can be used to verify that
-// the scene was ray traced correctly.
-int checkNumber;
-
-class TracerBenchmark extends BenchmarkBase {
-  const TracerBenchmark() : super('Tracer');
-
-  @override
-  void warmup() {
-    renderScene(null);
-  }
-
-  @override
-  void exercise() {
-    renderScene(null);
-  }
-}
-
-void main() {
-  const TracerBenchmark().report();
-}
diff --git a/example/Tracer/dart/app.dart b/example/Tracer/dart/app.dart
deleted file mode 100644
index 7c6c359..0000000
--- a/example/Tracer/dart/app.dart
+++ /dev/null
@@ -1,32 +0,0 @@
-// @dart=2.8
-library ray_trace;
-
-import 'dart:html';
-import 'dart:math';
-
-part 'color.dart';
-part 'engine.dart';
-part 'materials.dart';
-part 'scene.dart';
-part 'shapes.dart';
-part 'vector.dart';
-part 'renderscene.dart';
-
-// used to check if raytrace was correct (used by benchmarks)
-int checkNumber;
-
-void main() {
-  var button = querySelector('#render');
-  var canvas = querySelector('#canvas') as CanvasElement;
-  var time = querySelector('#time');
-  button.onClick.listen((e) {
-    canvas.width =
-        int.parse((querySelector('#imageWidth') as InputElement).value);
-    canvas.height =
-        int.parse((querySelector('#imageHeight') as InputElement).value);
-    var sw = Stopwatch()..start();
-    renderScene(e);
-    sw.stop();
-    time.text = sw.elapsedMilliseconds.toString();
-  });
-}
diff --git a/example/Tracer/dart/color.dart b/example/Tracer/dart/color.dart
deleted file mode 100644
index 5892ce8..0000000
--- a/example/Tracer/dart/color.dart
+++ /dev/null
@@ -1,63 +0,0 @@
-// @dart=2.8
-// The ray tracer code in this file is written by Adam Burmister. It
-// is available in its original form from:
-//
-//   http://labs.flog.co.nz/raytracer/
-//
-// Ported from the v8 benchmark suite by Google 2012.
-part of ray_trace;
-
-class Color {
-  double red;
-  double green;
-  double blue;
-
-  Color(this.red, this.green, this.blue);
-
-  void limit() {
-    red = (red > 0.0) ? ((red > 1.0) ? 1.0 : red) : 0.0;
-    green = (green > 0.0) ? ((green > 1.0) ? 1.0 : green) : 0.0;
-    blue = (blue > 0.0) ? ((blue > 1.0) ? 1.0 : blue) : 0.0;
-  }
-
-  Color operator +(Color c2) {
-    return Color(red + c2.red, green + c2.green, blue + c2.blue);
-  }
-
-  Color addScalar(double s) {
-    var result = Color(red + s, green + s, blue + s);
-    result.limit();
-    return result;
-  }
-
-  Color operator *(Color c2) {
-    var result = Color(red * c2.red, green * c2.green, blue * c2.blue);
-    return result;
-  }
-
-  Color multiplyScalar(double f) {
-    var result = Color(red * f, green * f, blue * f);
-    return result;
-  }
-
-  Color blend(Color c2, double w) {
-    var result = multiplyScalar(1.0 - w) + c2.multiplyScalar(w);
-    return result;
-  }
-
-  int brightness() {
-    var r = (red * 255).toInt();
-    var g = (green * 255).toInt();
-    var b = (blue * 255).toInt();
-    return (r * 77 + g * 150 + b * 29) >> 8;
-  }
-
-  @override
-  String toString() {
-    var r = (red * 255).toInt();
-    var g = (green * 255).toInt();
-    var b = (blue * 255).toInt();
-
-    return 'rgb($r,$g,$b)';
-  }
-}
diff --git a/example/Tracer/dart/engine.dart b/example/Tracer/dart/engine.dart
deleted file mode 100644
index 03aaacb..0000000
--- a/example/Tracer/dart/engine.dart
+++ /dev/null
@@ -1,200 +0,0 @@
-// @dart=2.8
-// The ray tracer code in this file is written by Adam Burmister. It
-// is available in its original form from:
-//
-//   http://labs.flog.co.nz/raytracer/
-//
-// Ported from the v8 benchmark suite by Google 2012.
-part of ray_trace;
-
-class IntersectionInfo {
-  bool isHit = false;
-  int hitCount = 0;
-  BaseShape shape;
-  Vector position;
-  Vector normal;
-  Color color;
-  double distance;
-
-  IntersectionInfo() {
-    color = Color(0.0, 0.0, 0.0);
-  }
-
-  @override
-  String toString() => 'Intersection [$position]';
-}
-
-class Engine {
-  int canvasWidth;
-  int canvasHeight;
-  int pixelWidth, pixelHeight;
-  bool renderDiffuse, renderShadows, renderHighlights, renderReflections;
-  int rayDepth;
-  CanvasRenderingContext2D canvas;
-
-  Engine(
-      {canvasWidth = 100,
-      this.canvasHeight = 100,
-      this.pixelWidth = 2,
-      this.pixelHeight = 2,
-      this.renderDiffuse = false,
-      this.renderShadows = false,
-      this.renderHighlights = false,
-      this.renderReflections = false,
-      this.rayDepth = 2}) {
-    canvasHeight = canvasHeight ~/ pixelHeight;
-    canvasWidth = canvasWidth ~/ pixelWidth;
-  }
-
-  void setPixel(int x, int y, Color color) {
-    int pxW, pxH;
-    pxW = pixelWidth;
-    pxH = pixelHeight;
-
-    if (canvas != null) {
-      canvas.fillStyle = color.toString();
-      canvas.fillRect(x * pxW, y * pxH, pxW, pxH);
-    } else {
-      if (x == y) {
-        checkNumber += color.brightness();
-      }
-    }
-  }
-
-  // 'canvas' can be null if raytracer runs as benchmark
-  void renderScene(Scene scene, CanvasElement canvas) {
-    checkNumber = 0;
-    /* Get canvas */
-    this.canvas = canvas?.context2D;
-
-    var canvasHeight = this.canvasHeight;
-    var canvasWidth = this.canvasWidth;
-
-    for (var y = 0; y < canvasHeight; y++) {
-      for (var x = 0; x < canvasWidth; x++) {
-        var yp = y * 1.0 / canvasHeight * 2 - 1;
-        var xp = x * 1.0 / canvasWidth * 2 - 1;
-
-        var ray = scene.camera.getRay(xp, yp);
-        setPixel(x, y, getPixelColor(ray, scene));
-      }
-    }
-    if ((canvas == null) && (checkNumber != 2321)) {
-      // Used for benchmarking.
-      throw 'Scene rendered incorrectly';
-    }
-  }
-
-  Color getPixelColor(Ray ray, Scene scene) {
-    var info = testIntersection(ray, scene, null);
-    if (info.isHit) {
-      var color = rayTrace(info, ray, scene, 0);
-      return color;
-    }
-    return scene.background.color;
-  }
-
-  IntersectionInfo testIntersection(Ray ray, Scene scene, BaseShape exclude) {
-    var hits = 0;
-    var best = IntersectionInfo();
-    best.distance = 2000;
-
-    for (var i = 0; i < scene.shapes.length; i++) {
-      var shape = scene.shapes[i];
-
-      if (shape != exclude) {
-        var info = shape.intersect(ray);
-        if (info.isHit &&
-            (info.distance >= 0) &&
-            (info.distance < best.distance)) {
-          best = info;
-          hits++;
-        }
-      }
-    }
-    best.hitCount = hits;
-    return best;
-  }
-
-  Ray getReflectionRay(Vector P, Vector N, Vector V) {
-    var c1 = -N.dot(V);
-    var R1 = N.multiplyScalar(2 * c1) + V;
-    return Ray(P, R1);
-  }
-
-  Color rayTrace(IntersectionInfo info, Ray ray, Scene scene, int depth) {
-    // Calc ambient
-    var color = info.color.multiplyScalar(scene.background.ambience);
-    var shininess = pow(10, info.shape.material.gloss + 1);
-
-    for (var i = 0; i < scene.lights.length; i++) {
-      var light = scene.lights[i];
-
-      // Calc diffuse lighting
-      var v = (light.position - info.position).normalize();
-
-      if (renderDiffuse) {
-        var L = v.dot(info.normal);
-        if (L > 0.0) {
-          color = color + info.color * light.color.multiplyScalar(L);
-        }
-      }
-
-      // The greater the depth the more accurate the colours, but
-      // this is exponentially (!) expensive
-      if (depth <= rayDepth) {
-        // calculate reflection ray
-        if (renderReflections && info.shape.material.reflection > 0) {
-          var reflectionRay =
-              getReflectionRay(info.position, info.normal, ray.direction);
-          var refl = testIntersection(reflectionRay, scene, info.shape);
-
-          if (refl.isHit && refl.distance > 0) {
-            refl.color = rayTrace(refl, reflectionRay, scene, depth + 1);
-          } else {
-            refl.color = scene.background.color;
-          }
-
-          color = color.blend(refl.color, info.shape.material.reflection);
-        }
-        // Refraction
-        /* TODO */
-      }
-      /* Render shadows and highlights */
-
-      var shadowInfo = IntersectionInfo();
-
-      if (renderShadows) {
-        var shadowRay = Ray(info.position, v);
-
-        shadowInfo = testIntersection(shadowRay, scene, info.shape);
-        if (shadowInfo.isHit && shadowInfo.shape != info.shape
-            /*&& shadowInfo.shape.type != 'PLANE'*/) {
-          var vA = color.multiplyScalar(0.5);
-          var dB = 0.5 * pow(shadowInfo.shape.material.transparency, 0.5);
-          color = vA.addScalar(dB);
-        }
-      }
-      // Phong specular highlights
-      if (renderHighlights &&
-          !shadowInfo.isHit &&
-          (info.shape.material.gloss > 0)) {
-        var Lv = (info.shape.position - light.position).normalize();
-
-        var E = (scene.camera.position - info.shape.position).normalize();
-
-        var H = (E - Lv).normalize();
-
-        var glossWeight = pow(max(info.normal.dot(H), 0), shininess).toDouble();
-        color = light.color.multiplyScalar(glossWeight) + color;
-      }
-    }
-    color.limit();
-    return color;
-  }
-
-  @override
-  String toString() {
-    return 'Engine [canvasWidth: $canvasWidth, canvasHeight: $canvasHeight]';
-  }
-}
diff --git a/example/Tracer/dart/index.html b/example/Tracer/dart/index.html
deleted file mode 100644
index dba6329..0000000
--- a/example/Tracer/dart/index.html
+++ /dev/null
@@ -1,38 +0,0 @@
-<!DOCTYPE html>
-
-<html>
-  <head>
-    <title>index</title>
-  </head>
-
-  <body>
-    <canvas id="canvas" width="100" height="100" style="border:1px solid black"></canvas>
-
-    <div>
-      Width: <input type="text" id="imageWidth" value="500">
-    </div>
-    <div>
-      Height: <input type="text" id="imageHeight" value="500">
-    </div>
-    <div>
-      Pixel Size: <input type="text" id="pixelSize" value="1,1">
-    </div>
-    <div>
-      Diffuse: <input type="checkbox" id="renderDiffuse" checked>
-    </div>
-    <div>
-      Shadows: <input type="checkbox" id="renderShadows" checked>
-    </div>
-    <div>
-      Highlights: <input type="checkbox" id="renderHighlights" checked>
-    </div>
-    <div>
-      Reflections: <input type="checkbox" id="renderReflections" checked>
-    </div>
-    <button id="render">Render</button>
-    <div>
-      Time (ms): <span id="time"></span>
-    </div>
-    <script defer src="app.dart.js"></script>
-  </body>
-</html>
diff --git a/example/Tracer/dart/materials.dart b/example/Tracer/dart/materials.dart
deleted file mode 100644
index de2e0dc..0000000
--- a/example/Tracer/dart/materials.dart
+++ /dev/null
@@ -1,63 +0,0 @@
-// @dart=2.8
-// The ray tracer code in this file is written by Adam Burmister. It
-// is available in its original form from:
-//
-//   http://labs.flog.co.nz/raytracer/
-//
-// Ported from the v8 benchmark suite by Google 2012.
-part of ray_trace;
-
-abstract class Materials {
-  final double gloss; // [0...infinity] 0 = matt
-  final double transparency; // 0=opaque
-  final double reflection; // [0...infinity] 0 = no reflection
-  var refraction = 0.50;
-  var hasTexture = false;
-
-  Materials(this.reflection, this.transparency, this.gloss);
-
-  Color getColor(double u, double v);
-
-  double wrapUp(double t) {
-    t = t % 2.0;
-    if (t < -1) t += 2.0;
-    if (t >= 1) t -= 2.0;
-    return t;
-  }
-}
-
-class Chessboard extends Materials {
-  Color colorEven, colorOdd;
-  double density;
-
-  Chessboard(this.colorEven, this.colorOdd, double reflection,
-      double transparency, double gloss, this.density)
-      : super(reflection, transparency, gloss) {
-    hasTexture = true;
-  }
-
-  @override
-  Color getColor(double u, double v) {
-    var t = wrapUp(u * density) * wrapUp(v * density);
-
-    if (t < 0.0) {
-      return colorEven;
-    } else {
-      return colorOdd;
-    }
-  }
-}
-
-class Solid extends Materials {
-  Color color;
-
-  Solid(this.color, double reflection, double refraction, double transparency,
-      double gloss)
-      : super(reflection, transparency, gloss) {
-    hasTexture = false;
-    this.refraction = refraction;
-  }
-
-  @override
-  Color getColor(num u, num v) => color;
-}
diff --git a/example/Tracer/dart/readme.md b/example/Tracer/dart/readme.md
deleted file mode 100644
index dc3b17d..0000000
--- a/example/Tracer/dart/readme.md
+++ /dev/null
@@ -1,4 +0,0 @@
-To run:
-
- 1) `pub run build_runner serve example` from the root
- 2) Navigate to http://localhost:8080/Tracer/dart/
diff --git a/example/Tracer/dart/renderscene.dart b/example/Tracer/dart/renderscene.dart
deleted file mode 100644
index 4a25738..0000000
--- a/example/Tracer/dart/renderscene.dart
+++ /dev/null
@@ -1,91 +0,0 @@
-// @dart=2.8
-// The ray tracer code in this file is written by Adam Burmister. It
-// is available in its original form from:
-//
-//   http://labs.flog.co.nz/raytracer/
-//
-// Ported from the v8 benchmark suite by Google 2012.
-part of ray_trace;
-
-class Light {
-  final Vector position;
-  final Color color;
-  final double intensity;
-
-  Light(this.position, this.color, [this.intensity = 10.0]);
-}
-
-// 'event' null means that we are benchmarking
-void renderScene(event) {
-  var scene = Scene();
-  scene.camera = Camera(
-      Vector(0.0, 0.0, -15.0), Vector(-0.2, 0.0, 5.0), Vector(0.0, 1.0, 0.0));
-  scene.background = Background(Color(0.5, 0.5, 0.5), 0.4);
-
-  var sphere = Sphere(Vector(-1.5, 1.5, 2.0), 1.5,
-      Solid(Color(0.0, 0.5, 0.5), 0.3, 0.0, 0.0, 2.0));
-
-  var sphere1 = Sphere(Vector(1.0, 0.25, 1.0), 0.5,
-      Solid(Color(0.9, 0.9, 0.9), 0.1, 0.0, 0.0, 1.5));
-
-  var plane = Plane(
-      Vector(0.1, 0.9, -0.5).normalize(),
-      1.2,
-      Chessboard(
-          Color(1.0, 1.0, 1.0), Color(0.0, 0.0, 0.0), 0.2, 0.0, 1.0, 0.7));
-
-  scene.shapes.add(plane);
-  scene.shapes.add(sphere);
-  scene.shapes.add(sphere1);
-
-  var light = Light(Vector(5.0, 10.0, -1.0), Color(0.8, 0.8, 0.8));
-
-  var light1 = Light(Vector(-3.0, 5.0, -15.0), Color(0.8, 0.8, 0.8), 100.0);
-
-  scene.lights.add(light);
-  scene.lights.add(light1);
-
-  int imageWidth, imageHeight, pixelSize;
-  bool renderDiffuse, renderShadows, renderHighlights, renderReflections;
-  CanvasElement canvas;
-  if (event == null) {
-    imageWidth = 100;
-    imageHeight = 100;
-    pixelSize = 5;
-    renderDiffuse = true;
-    renderShadows = true;
-    renderHighlights = true;
-    renderReflections = true;
-    canvas = null;
-  } else {
-    imageWidth =
-        int.parse((querySelector('#imageWidth') as InputElement).value);
-    imageHeight =
-        int.parse((querySelector('#imageHeight') as InputElement).value);
-    pixelSize = int.parse(
-        (querySelector('#pixelSize') as InputElement).value.split(',')[0]);
-    renderDiffuse =
-        (querySelector('#renderDiffuse') as CheckboxInputElement).checked;
-    renderShadows =
-        (querySelector('#renderShadows') as CheckboxInputElement).checked;
-    renderHighlights =
-        (querySelector('#renderHighlights') as CheckboxInputElement).checked;
-    renderReflections =
-        (querySelector('#renderReflections') as CheckboxInputElement).checked;
-    canvas = querySelector('#canvas') as CanvasElement;
-  }
-  var rayDepth = 2;
-
-  var raytracer = Engine(
-      canvasWidth: imageWidth,
-      canvasHeight: imageHeight,
-      pixelWidth: pixelSize,
-      pixelHeight: pixelSize,
-      renderDiffuse: renderDiffuse,
-      renderShadows: renderShadows,
-      renderReflections: renderReflections,
-      renderHighlights: renderHighlights,
-      rayDepth: rayDepth);
-
-  raytracer.renderScene(scene, canvas);
-}
diff --git a/example/Tracer/dart/scene.dart b/example/Tracer/dart/scene.dart
deleted file mode 100644
index 9465ac9..0000000
--- a/example/Tracer/dart/scene.dart
+++ /dev/null
@@ -1,67 +0,0 @@
-// @dart=2.8
-// The ray tracer code in this file is written by Adam Burmister. It
-// is available in its original form from:
-//
-//   http://labs.flog.co.nz/raytracer/
-//
-// Ported from the v8 benchmark suite by Google 2012.
-part of ray_trace;
-
-class Ray {
-  final Vector position;
-  final Vector direction;
-
-  Ray(this.position, this.direction);
-
-  @override
-  String toString() {
-    return 'Ray [$position, $direction]';
-  }
-}
-
-class Camera {
-  final Vector position;
-  final Vector lookAt;
-  final Vector up;
-  Vector equator, screen;
-
-  Camera(this.position, this.lookAt, this.up) {
-    equator = lookAt.normalize().cross(up);
-    screen = position + lookAt;
-  }
-
-  Ray getRay(double vx, double vy) {
-    var pos = screen - (equator.multiplyScalar(vx) - up.multiplyScalar(vy));
-    pos.y = pos.y * -1.0;
-    var dir = pos - position;
-    var ray = Ray(pos, dir.normalize());
-    return ray;
-  }
-
-  @override
-  String toString() {
-    return 'Camera []';
-  }
-}
-
-class Background {
-  final Color color;
-  final double ambience;
-
-  Background(this.color, this.ambience);
-}
-
-class Scene {
-  Camera camera;
-  List<BaseShape> shapes;
-  List<Light> lights;
-  Background background;
-
-  Scene() {
-    camera = Camera(
-        Vector(0.0, 0.0, -0.5), Vector(0.0, 0.0, 1.0), Vector(0.0, 1.0, 0.0));
-    shapes = [];
-    lights = [];
-    background = Background(Color(0.0, 0.0, 0.5), 0.2);
-  }
-}
diff --git a/example/Tracer/dart/shapes.dart b/example/Tracer/dart/shapes.dart
deleted file mode 100644
index c7d1ff6..0000000
--- a/example/Tracer/dart/shapes.dart
+++ /dev/null
@@ -1,99 +0,0 @@
-// @dart=2.8
-// The ray tracer code in this file is written by Adam Burmister. It
-// is available in its original form from:
-//
-//   http://labs.flog.co.nz/raytracer/
-//
-// Ported from the v8 benchmark suite by Google 2012.
-part of ray_trace;
-
-abstract class BaseShape {
-  final Vector position;
-  final Materials material;
-
-  BaseShape(this.position, this.material);
-
-  IntersectionInfo intersect(Ray ray);
-
-  @override
-  String toString() {
-    return 'BaseShape';
-  }
-}
-
-class Plane extends BaseShape {
-  final double d;
-
-  Plane(Vector pos, this.d, Materials material) : super(pos, material);
-
-  @override
-  IntersectionInfo intersect(Ray ray) {
-    var info = IntersectionInfo();
-
-    var Vd = position.dot(ray.direction);
-    if (Vd == 0) return info; // no intersection
-
-    var t = -(position.dot(ray.position) + d) / Vd;
-    if (t <= 0) return info;
-
-    info.shape = this;
-    info.isHit = true;
-    info.position = ray.position + ray.direction.multiplyScalar(t);
-    info.normal = position;
-    info.distance = t;
-
-    if (material.hasTexture) {
-      var vU = Vector(position.y, position.z, -position.x);
-      var vV = vU.cross(position);
-      var u = info.position.dot(vU);
-      var v = info.position.dot(vV);
-      info.color = material.getColor(u, v);
-    } else {
-      info.color = material.getColor(0, 0);
-    }
-
-    return info;
-  }
-
-  @override
-  String toString() {
-    return 'Plane [$position, d=$d]';
-  }
-}
-
-class Sphere extends BaseShape {
-  double radius;
-
-  Sphere(Vector pos, this.radius, Materials material) : super(pos, material);
-
-  @override
-  IntersectionInfo intersect(Ray ray) {
-    var info = IntersectionInfo();
-    info.shape = this;
-
-    var dst = ray.position - position;
-
-    var B = dst.dot(ray.direction);
-    var C = dst.dot(dst) - (radius * radius);
-    var D = (B * B) - C;
-
-    if (D > 0) {
-      // intersection!
-      info.isHit = true;
-      info.distance = (-B) - sqrt(D);
-      info.position =
-          ray.position + ray.direction.multiplyScalar(info.distance);
-      info.normal = (info.position - position).normalize();
-
-      info.color = material.getColor(0, 0);
-    } else {
-      info.isHit = false;
-    }
-    return info;
-  }
-
-  @override
-  String toString() {
-    return 'Sphere [position=$position, radius=$radius]';
-  }
-}
diff --git a/example/Tracer/dart/vector.dart b/example/Tracer/dart/vector.dart
deleted file mode 100644
index d8d7ad6..0000000
--- a/example/Tracer/dart/vector.dart
+++ /dev/null
@@ -1,57 +0,0 @@
-// @dart=2.8
-// The ray tracer code in this file is written by Adam Burmister. It
-// is available in its original form from:
-//
-//   http://labs.flog.co.nz/raytracer/
-//
-// Ported from the v8 benchmark suite by Google 2012.
-part of ray_trace;
-
-class Vector {
-  double x, y, z;
-  Vector(this.x, this.y, this.z);
-
-  void copy(Vector v) {
-    x = v.x;
-    y = v.y;
-    z = v.z;
-  }
-
-  Vector normalize() {
-    var m = magnitude();
-    return Vector(x / m, y / m, z / m);
-  }
-
-  double magnitude() {
-    return sqrt((x * x) + (y * y) + (z * z));
-  }
-
-  Vector cross(Vector w) {
-    return Vector(-z * w.y + y * w.z, z * w.x - x * w.z, -y * w.x + x * w.y);
-  }
-
-  double dot(Vector w) {
-    return x * w.x + y * w.y + z * w.z;
-  }
-
-  Vector operator +(Vector w) {
-    return Vector(w.x + x, w.y + y, w.z + z);
-  }
-
-  Vector operator -(Vector w) {
-    return Vector(x - w.x, y - w.y, z - w.z);
-  }
-
-  Vector operator *(Vector w) {
-    return Vector(x * w.x, y * w.y, z * w.z);
-  }
-
-  Vector multiplyScalar(double w) {
-    return Vector(x * w, y * w, z * w);
-  }
-
-  @override
-  String toString() {
-    return 'Vector [$x, $y ,$z ]';
-  }
-}
diff --git a/example/Tracer/js/Tracer.js b/example/Tracer/js/Tracer.js
deleted file mode 100644
index 52744e5..0000000
--- a/example/Tracer/js/Tracer.js
+++ /dev/null
@@ -1,749 +0,0 @@
-// The ray tracer code in this file is written by Adam Burmister. It
-// is available in its original form from:
-//
-//   http://labs.flog.nz.co/raytracer/
-//
-// It has been modified slightly by Google to work as a standalone
-// benchmark, but the all the computational code remains
-// untouched. This file also contains a copy of parts of the Prototype
-// JavaScript framework which is used by the ray tracer.
-
-"use strict";
-var scope = this;
-
-// Variable used to hold a number that can be used to verify that
-// the scene was ray traced correctly.
-var checkNumber;
-
-// ------------------------------------------------------------------------
-// ------------------------------------------------------------------------
-
-// The following is a copy of parts of the Prototype JavaScript library:
-
-// Prototype JavaScript framework, version 1.5.0
-// (c) 2005-2007 Sam Stephenson
-//
-// Prototype is freely distributable under the terms of an MIT-style license.
-// For details, see the Prototype web site: http://prototype.conio.net/
-
-Object.extend = function(destination, source) {
-  Object.keys(source).forEach(function(p) {
-    destination[p] = source[p];
-  })
-  return destination;
-};
-
-
-// ------------------------------------------------------------------------
-// ------------------------------------------------------------------------
-
-// The rest of this file is the actual ray tracer written by Adam
-// Burmister. It's a concatenation of the following files:
-//
-//   flog/color.js
-//   flog/light.js
-//   flog/vector.js
-//   flog/ray.js
-//   flog/scene.js
-//   flog/material/basematerial.js
-//   flog/material/solid.js
-//   flog/material/chessboard.js
-//   flog/shape/baseshape.js
-//   flog/shape/sphere.js
-//   flog/shape/plane.js
-//   flog/intersectioninfo.js
-//   flog/camera.js
-//   flog/background.js
-//   flog/engine.js
-
-/* Fake a Flog.* namespace */
-if(typeof(scope.Flog) == 'undefined') {
-  var Flog = scope.Flog = { RayTracer: { Shape: {}, Material: {} } };
-}
-
-var Color =
-Flog.RayTracer.Color = function(r, g, b) {
-  this.red = r;
-  this.green = g;
-  this.blue = b;
-};
-Color.prototype = {
-  add: function(c){
-    return new Color(
-      this.red   + c.red,
-      this.green + c.green,
-      this.blue  + c.blue
-    );
-  },
-
-  addScalar: function(s){
-    var result = new Color(
-      this.red   + s,
-      this.green + s,
-      this.blue  + s);
-    result.limit();
-    return result;
-  },
-
-  subtract: function(c1, c2){
-    return new Color(
-      c1.red   - c2.red,
-      c1.green - c2.green,
-      c1.blue  - c2.blue
-    );
-  },
-
-  multiply: function(c) {
-    return new Color(
-      this.red   * c.red,
-      this.green * c.green,
-      this.blue  * c.blue
-    );
-  },
-
-  multiplyScalar: function(f) {
-    return new Color(
-      this.red   * f,
-      this.green * f,
-      this.blue  * f
-    );
-  },
-
-  divideFactor: function(c1, f) {
-    return new Color(
-      c1.red   / f,
-      c1.green / f,
-      c1.blue  / f
-    );
-  },
-
-  limit: function() {
-    this.red = (this.red > 0.0) ?
-                  ( (this.red > 1.0) ? 1.0 : this.red ) : 0.0;
-    this.green = (this.green > 0.0) ?
-                  ( (this.green > 1.0) ? 1.0 : this.green ) : 0.0;
-    this.blue = (this.blue > 0.0) ?
-                  ( (this.blue > 1.0) ? 1.0 : this.blue ) : 0.0;
-  },
-
-  distance : function(color) {
-    return  Math.abs(this.red   - color.red) +
-            Math.abs(this.green - color.green) +
-            Math.abs(this.blue  - color.blue);
-  },
-
-  blend: function(c, w){
-    return this.multiplyScalar(1-w).add(c.multiplyScalar(w));
-  },
-
-  brightness : function() {
-    var r = Math.floor(this.red*255);
-    var g = Math.floor(this.green*255);
-    var b = Math.floor(this.blue*255);
-    return (r * 77 + g * 150 + b * 29) >> 8;
-  },
-
-  toString : function () {
-    var r = Math.floor(this.red*255);
-    var g = Math.floor(this.green*255);
-    var b = Math.floor(this.blue*255);
-    return "rgb("+ r +","+ g +","+ b +")";
-  }
-};
-
-var Light =
-Flog.RayTracer.Light = function (pos, color, intensity) {
-  this.position = pos;
-  this.color = color;
-  this.intensity = (intensity ? intensity : 10.0);
-};
-Light.prototype = {
-  toString : function () {
-    var pos = this.position;
-    return 'Light [' + pos.x + ','
-                     + pos.y + ','
-                     + pos.z + ']';
-  }
-};
-
-var Vector =
-Flog.RayTracer.Vector = function (x, y, z) {
-  this.x = x;
-  this.y = y;
-  this.z = z;
-};
-Vector.prototype = {
-  copy: function(v){
-    this.x = v.x;
-    this.y = v.y;
-    this.z = v.z;
-  },
-
-  normalize : function() {
-    var m = this.magnitude();
-    return new Vector(
-      this.x / m,
-      this.y / m,
-      this.z / m
-    );
-  },
-
-  magnitude : function() {
-    return Math.sqrt(this.x*this.x + this.y*this.y + this.z*this.z);
-  },
-
-  cross : function(w) {
-    return new Vector(
-      -this.z * w.y + this.y * w.z,
-       this.z * w.x - this.x * w.z,
-      -this.y * w.x + this.x * w.y);
-  },
-
-  dot : function(w) {
-    return this.x * w.x + this.y * w.y + this.z * w.z;
-  },
-
-  add: function(w) {
-    return new Vector(w.x + this.x,
-                      w.y + this.y,
-                      w.z + this.z);
-  },
-
-  subtract: function(w) {
-    return new Vector(this.x - w.x,
-                      this.y - w.y,
-                      this.z - w.z);
-  },
-
-  multiplyScalar: function(w) {
-    return new Vector(this.x * w,
-                      this.y * w,
-                      this.z * w);
-  },
-
-  toString : function () {
-    return 'Vector [' + this.x + ',' + this.y + ',' + this.z + ']';
-  }
-};
-
-var Ray =
-Flog.RayTracer.Ray = function(pos, dir) {
-  this.position = pos;
-  this.direction = dir;
-};
-Ray.prototype = {
-  toString : function () {
-    return 'Ray [' + this.position + ',' + this.direction + ']';
-  }
-};
-
-var Scene =
-Flog.RayTracer.Scene = function() {
-  this.camera = new Camera(
-    new Vector(0,0,-5),
-    new Vector(0,0,1),
-    new Vector(0,1,0)
-  );
-  this.shapes = [];
-  this.lights = [];
-  this.background = new Background(new Color(0,0,0.5), 0.2);
-};
-
-var BaseMaterial =
-Flog.RayTracer.Material.BaseMaterial = function(reflection,
-                                                transparency,
-                                                glass) {
-  this.gloss = glass;
-  this.transparency = transparency;
-  this.reflection = reflection;
-  this.refraction = 0.50;
-  this.hasTexture = false;
-};
-BaseMaterial.prototype = {
-  wrapUp: function(t){
-    t = t % 2.0;
-    if(t < -1) t += 2.0;
-    if(t >= 1) t -= 2.0;
-    return t;
-  },
-
-  toString : function () {
-    return 'Material [gloss=' + this.gloss + ', transparency=' + this.transparency + ', hasTexture=' + this.hasTexture +']';
-  }
-}
-
-var Solid =
-Flog.RayTracer.Material.Solid = function(color, reflection, refraction, transparency, gloss) {
-  this.color = color;
-  this.reflection = reflection;
-  this.transparency = transparency;
-  this.gloss = gloss;
-  this.hasTexture = false;
-};
-Solid.prototype = Object.create(BaseMaterial.prototype, {
-  getColor: {
-    value: function() { return this.color; },
-  },
-  toString: {
-    value: function() {
-      return 'SolidMaterial [gloss=' + this.gloss +
-                          ', transparency=' + this.transparency +
-                          ', hasTexture=' + this.hasTexture +']';
-    }
-  }
-});
-
-var Chessboard =
-Flog.RayTracer.Material.Chessboard = function(
-    colorEven,
-    colorOdd,
-    reflection,
-    transparency,
-    gloss,
-    density) {
-  this.colorEven = colorEven;
-  this.colorOdd = colorOdd;
-  this.reflection = reflection;
-  this.transparency = transparency;
-  this.gloss = gloss;
-  this.density = density;
-  this.hasTexture = true;
-};
-
-Chessboard.prototype = Object.create(BaseMaterial.prototype, {
-  getColor: {
-    value: function(u, v){
-      var t = this.wrapUp(u * this.density) * this.wrapUp(v * this.density);
-      if(t < 0.0) {
-        return this.colorEven;
-      } else {
-        return this.colorOdd;
-      }
-    }
-  },
-  toString: {
-    value: function(){
-      return 'ChessMaterial [gloss=' + this.gloss +
-                          ', transparency=' + this.transparency +
-                          ', hasTexture=' + this.hasTexture +']';
-    }
-  }
-});
-
-
-var Sphere =
-Flog.RayTracer.Shape.Sphere = function(pos, radius, material) {
-  this.radius = radius;
-  this.position = pos;
-  this.material = material;
-};
-Sphere.prototype = {
-
-  _foundIntersection: function(B, D, info, ray) {
-    info.isHit = true;
-    info.distance = (-B) - Math.sqrt(D);
-    info.position =
-      ray.position.add(ray.direction.multiplyScalar(info.distance));
-    info.normal = info.position.subtract(this.position).normalize();
-    info.color = this.material.getColor(0,0);
-  },
-
-  intersect: function(ray){
-    var info = new IntersectionInfo();
-    info.shape = this;
-    info.isHit = false;
-
-    var dst = ray.position.subtract(this.position);
-    var B = dst.dot(ray.direction);
-    var C = dst.dot(dst) - (this.radius * this.radius);
-    var D = (B * B) - C;
-
-    if(D > 0) { // intersection!
-      this._foundIntersection(B, D, info, ray);
-    }
-    return info;
-  },
-
-  toString : function () {
-    return 'Sphere [position=' + this.position +
-                 ', radius=' + this.radius + ']';
-  }
-}
-
-var Plane =
-Plane = function(pos, d, material) {
-  this.position = pos;
-  this.d = d;
-  this.material = material;
-};
-Plane.prototype = {
-  _hasTexture: function() {
-
-  },
-  intersect: function(ray){
-    var info = new IntersectionInfo();
-    var pos = this.position;
-    var mat = this.material;
-
-    var Vd = pos.dot(ray.direction);
-    if(Vd == 0) return info; // no intersection
-
-    var t = -(pos.dot(ray.position) + this.d) / Vd;
-    if(t <= 0) { return info; }
-
-    info.shape = this;
-    info.isHit = true;
-    info.position = ray.position.add(ray.direction.multiplyScalar(t));
-    info.normal = pos;
-    info.distance = t;
-
-    if(mat.hasTexture){
-      var vU = new Vector(pos.y, pos.z, -pos.x);
-      var vV = vU.cross(pos);
-      var u = info.position.dot(vU);
-      var v = info.position.dot(vV);
-      info.color = mat.getColor(u,v);
-    } else {
-      info.color = mat.getColor(0,0);
-    }
-    return info;
-  },
-
-  toString : function () {
-    return 'Plane [' + this.position + ', d=' + this.d + ']';
-  }
-}
-
-var IntersectionInfo =
-Flog.RayTracer.IntersectionInfo = function(shape) {
-  this.color = new Color(0,0,0);
-  this.isHit = false;
-  this.hitCount = 0;
-  this.shape = null;
-  this.position = null;
-  this.normal = null;
-  this.color = null;
-  this.distance = null;
-};
-IntersectionInfo.prototype = {
-  toString : function () {
-    return 'Intersection [' + this.position + ']';
-  }
-}
-
-var Camera =
-Flog.RayTracer.Camera = function(pos, lookAt, up) {
-  this.position = pos;
-  this.lookAt = lookAt;
-  this.up = up;
-  this.equator = lookAt.normalize().cross(this.up);
-  this.screen = this.position.add(this.lookAt);
-};
-Camera.prototype = {
-  getRay: function(vx, vy){
-    var pos = this.screen.subtract(
-      this.equator.multiplyScalar(vx).subtract(this.up.multiplyScalar(vy))
-    );
-    pos.y = pos.y * -1;
-    var dir = pos.subtract(this.position);
-    return new Ray(pos, dir.normalize());
-  },
-
-  toString : function () { return 'Ray []'; }
-}
-
-var Background =
-Flog.RayTracer.Background = function(color, ambience) {
-  this.color = color;
-  this.ambience = ambience;
-};
-
-var Engine =
-Flog.RayTracer.Engine = function(options){
-  this.options = Object.extend({
-    canvasHeight: 100,
-    canvasWidth: 100,
-    pixelWidth: 2,
-    pixelHeight: 2,
-    renderDiffuse: false,
-    renderShadows: false,
-    renderHighlights: false,
-    renderReflections: false,
-    rayDepth: 2
-  }, options || {});
-
-  this.options.canvasHeight /= this.options.pixelHeight;
-  this.options.canvasWidth /= this.options.pixelWidth;
-  this.canvas = null;
-  /* TODO: dynamically include other scripts */
-};
-Engine.prototype = {
-  setPixel: function(x, y, color){
-    var pxW, pxH;
-    pxW = this.options.pixelWidth;
-    pxH = this.options.pixelHeight;
-
-    if (this.canvas) {
-      this.canvas.fillStyle = color.toString();
-      this.canvas.fillRect (x * pxW, y * pxH, pxW, pxH);
-    } else {
-      if (x ===  y) {
-        checkNumber += color.brightness();
-      }
-      // print(x * pxW, y * pxH, pxW, pxH);
-    }
-  },
-
-  renderScene: function(scene, canvas){
-    checkNumber = 0;
-    /* Get canvas */
-    if (canvas) {
-      this.canvas = canvas.getContext("2d");
-    } else {
-      this.canvas = null;
-    }
-
-    var canvasHeight = this.options.canvasHeight;
-    var canvasWidth = this.options.canvasWidth;
-
-    for(var y=0; y < canvasHeight; y++){
-      for(var x=0; x < canvasWidth; x++){
-          var yp = y * 1.0 / canvasHeight * 2 - 1;
-
-    		var xp = x * 1.0 / canvasWidth * 2 - 1;
-    		var ray = scene.camera.getRay(xp, yp);
-    		var color = this.getPixelColor(ray, scene);
-      	this.setPixel(x, y, color);
-      }
-    }
-    if (canvas == null && checkNumber !== 2321) {
-      throw new Error("Scene rendered incorrectly");
-    }
-  },
-
-  getPixelColor: function(ray, scene){
-    var info = this.testIntersection(ray, scene, null);
-    if(info.isHit){
-      return this.rayTrace(info, ray, scene, 0);
-    }
-    return scene.background.color;
-  },
-
-  // FIXME(slightlyoff): HOT!
-  testIntersection: function(ray, scene, exclude){
-    var hits = 0;
-    var best = new IntersectionInfo();
-    best.distance = 2000;
-    var info;
-    var distance = 0|0;
-
-    var shapesLength = scene.shapes.length;
-    for(var i = 0; i < shapesLength; i++){
-      if(scene.shapes[i] !== exclude){
-        info = scene.shapes[i].intersect(ray);
-        distance = info.distance;
-        if(info.isHit && distance >= 0 && distance < best.distance) {
-          best = info;
-          hits++;
-        }
-      }
-    }
-    best.hitCount = hits;
-    return best;
-  },
-
-  getReflectionRay: function(P,N,V){
-    var c1 = -N.dot(V);
-    var R1 = N.multiplyScalar(2*c1).add(V);
-    return new Ray(P, R1);
-  },
-
-  rayTrace: function(info, ray, scene, depth) {
-    // Calc ambient
-    var color = info.color.multiplyScalar(scene.background.ambience);
-    var oldColor = color;
-    var shininess = Math.pow(10, info.shape.material.gloss + 1);
-
-    for(var i=0; i<scene.lights.length; i++) {
-      var light = scene.lights[i];
-
-      // Calc diffuse lighting
-      var v = light.position.subtract(info.position).normalize();
-
-      if(this.options.renderDiffuse){
-        var L = v.dot(info.normal);
-        if(L > 0){
-          color = color.add(
-                    info.color.multiply(
-                      light.color.multiplyScalar(L)
-                    )
-                  );
-        }
-      }
-
-      // The greater the depth the more accurate the colours, but
-      // this is exponentially (!) expensive
-      if(depth <= this.options.rayDepth){
-        // calculate reflection ray
-        if(this.options.renderReflections &&
-           info.shape.material.reflection > 0) {
-
-          var reflectionRay = this.getReflectionRay(
-                info.position, info.normal, ray.direction);
-          var refl = this.testIntersection(reflectionRay, scene, info.shape);
-
-          if (refl.isHit && refl.distance > 0){
-            refl.color = this.rayTrace(refl, reflectionRay, scene, depth + 1);
-          } else {
-            refl.color = scene.background.color;
-          }
-
-          color = color.blend(
-            refl.color, info.shape.material.reflection
-          );
-        }
-          // Refraction
-          /* TODO */
-      }
-
-      /* Render shadows and highlights */
-      var shadowInfo = new IntersectionInfo();
-
-      if(this.options.renderShadows) {
-        var shadowRay = new Ray(info.position, v);
-
-        shadowInfo = this.testIntersection(shadowRay, scene,
-                                           info.shape);
-        if(shadowInfo.isHit && shadowInfo.shape != info.shape
-            /*&& shadowInfo.shape.type != 'PLANE'*/) {
-          var vA = color.multiplyScalar(0.5);
-          var dB = (0.5 * Math.pow(shadowInfo.shape.material.transparency, 0.5));
-          color = vA.addScalar(dB);
-        }
-      }
-
-      // Phong specular highlights
-      if(this.options.renderHighlights && !shadowInfo.isHit && info.shape.material.gloss > 0) {
-        var Lv = info.shape.position.subtract(light.position)
-                  .normalize();
-        var E = scene.camera.position.subtract(info.shape.position)
-                  .normalize();
-        var H = E.subtract(Lv).normalize();
-        var glossWeight =
-              Math.pow(Math.max(info.normal.dot(H), 0), shininess);
-        color = light.color.multiplyScalar(glossWeight).add(color);
-      }
-    }
-    color.limit();
-    return color;
-  }
-};
-
-// 'event' null means that we are benchmarking
-var renderScene =
-scope.renderScene = function(event){
-  var scene = new Scene();
-
-  scene.camera = new Camera(
-                   new Vector(0, 0, -15),
-                   new Vector(-0.2, 0, 5),
-                   new Vector(0, 1, 0)
-                 );
-
-  scene.background = new Background(new Color(0.5, 0.5, 0.5), 0.4 );
-
-  var sphere = new Sphere(
-    new Vector(-1.5, 1.5, 2),
-    1.5,
-    new Solid(
-      new Color(0,0.5,0.5),
-      0.3,
-      0.0,
-      0.0,
-      2.0
-    )
-  );
-
-  var sphere1 = new Sphere(
-    new Vector(1, 0.25, 1),
-    0.5,
-    new Solid(
-      new Color(0.9,0.9,0.9),
-      0.1,
-      0.0,
-      0.0,
-      1.5
-    )
-  );
-
-  var plane = new Plane(
-    new Vector(0.1, 0.9, -0.5).normalize(),
-    1.2,
-    new Chessboard(
-      new Color(1,1,1),
-      new Color(0,0,0),
-      0.2,
-      0.0,
-      1.0,
-      0.7
-    )
-  );
-
-  scene.shapes.push(plane);
-  scene.shapes.push(sphere);
-  scene.shapes.push(sphere1);
-
-  var light = new Light(
-    new Vector(5, 10, -1),
-    new Color(0.8, 0.8, 0.8)
-  );
-
-  var light1 = new Light(
-    new Vector(-3, 5, -15),
-    new Color(0.8, 0.8, 0.8),
-    100
-  );
-
-  scene.lights.push(light);
-  scene.lights.push(light1);
-
-  var imageWidth, imageHeight, pixelSize;
-  var renderDiffuse, renderShadows, renderHighlights, renderReflections;
-  var canvas;
-
-  if (typeof(event) == 'undefined' || event == null) {
-	  imageWidth = 100;
-	  imageHeight = 100;
-	  pixelSize = "5,5".split(',');
-	  renderDiffuse = true;
-	  renderShadows = true;
-	  renderHighlights = true;
-	  renderReflections = true;
-	  canvas = null;
-	} else {
-	  imageWidth = parseInt(document.getElementById('imageWidth').value);
-	  imageHeight = parseInt(document.getElementById('imageHeight').value);
-	  pixelSize = document.getElementById('pixelSize').value.split(',');
-	  renderDiffuse = document.getElementById('renderDiffuse').checked;
-	  renderShadows = document.getElementById('renderShadows').checked;
-	  renderHighlights = document.getElementById('renderHighlights').checked;
-	  renderReflections = document.getElementById('renderReflections').checked;
-	  canvas = document.getElementById("canvas");
-	}
-
-  var rayDepth = 2;//$F('rayDepth');
-
-  var raytracer = new Engine({
-    canvasWidth: imageWidth,
-    canvasHeight: imageHeight,
-    pixelWidth: parseInt(pixelSize[0]),
-    pixelHeight: parseInt(pixelSize[1]),
-    "renderDiffuse": renderDiffuse,
-    "renderHighlights": renderHighlights,
-    "renderShadows": renderShadows,
-    "renderReflections": renderReflections,
-    "rayDepth": rayDepth
-  });
-
-  raytracer.renderScene(scene, canvas, 0);
-};
diff --git a/example/Tracer/js/app.js b/example/Tracer/js/app.js
deleted file mode 100644
index 52cabec..0000000
--- a/example/Tracer/js/app.js
+++ /dev/null
@@ -1,17 +0,0 @@
-(function() {
-
-  var button = document.getElementById('render');
-  var canvas = document.getElementById('canvas');
-  var time = document.getElementById('time');
-
-  var run = function(e) {
-    canvas.width = parseInt(document.getElementById('imageWidth').value);
-    canvas.height = parseInt(document.getElementById('imageHeight').value);
-    canvas.getContext("2d").clearRect(0,0,canvas.width,canvas.height)
-    var start = performance.now();
-    renderScene(e);
-    var stop = performance.now();
-    time.innerHTML = Number(stop - start).toFixed(2).toString();
-  };
-  button.addEventListener('click', run);
-})();
diff --git a/example/Tracer/js/bench.js b/example/Tracer/js/bench.js
deleted file mode 100644
index dda992c..0000000
--- a/example/Tracer/js/bench.js
+++ /dev/null
@@ -1,31 +0,0 @@
-var Benchmark = {
-  measureFor: function(f, timeMinimum) {
-    "use asm";
-    var elapsed = 0;
-    var iterations = 0;
-    var start = +(performance.now());
-    while (elapsed < timeMinimum) {
-      iterations++;
-      f();
-      elapsed = +(+(performance.now()) - start);
-    }
-    return 1000 * elapsed / iterations;
-  },
-
-  measure: function(warmup, exercise) {
-    if (!exercise) {
-      exercise = function() {
-        for (var i = 0; i < 10; i++) {
-          warmup();
-        }
-      };
-    }
-    this.measureFor(warmup, 100);
-    return this.measureFor(exercise, 2000);
-  },
-
-  report: function(name, warmup, exercise) {
-    var score = this.measure(warmup, exercise);
-    print(name + "(RunTime): " + Number(score).toFixed(2) + " us.");
-  }
-};
diff --git a/example/Tracer/js/benchmark_tracer.js b/example/Tracer/js/benchmark_tracer.js
deleted file mode 100644
index 3aac5b5..0000000
--- a/example/Tracer/js/benchmark_tracer.js
+++ /dev/null
@@ -1 +0,0 @@
-Benchmark.report("Tracer", renderScene, renderScene);
\ No newline at end of file
diff --git a/example/Tracer/js/index.html b/example/Tracer/js/index.html
deleted file mode 100644
index 3b6fe8d..0000000
--- a/example/Tracer/js/index.html
+++ /dev/null
@@ -1,39 +0,0 @@
-<!DOCTYPE html>
-
-<html>
-  <head>
-    <title>index</title>
-  </head>
-
-  <body>
-    <canvas id="canvas" width="100" height="100" style="border:1px solid black"></canvas>
-
-    <div>
-      Width: <input type="text" id="imageWidth" value="500">
-    </div>
-    <div>
-      Height: <input type="text" id="imageHeight" value="500">
-    </div>
-    <div>
-      Pixel Size: <input type="text" id="pixelSize" value="1,1">
-    </div>
-    <div>
-      Diffuse: <input type="checkbox" id="renderDiffuse" checked>
-    </div>
-    <div>
-      Shadows: <input type="checkbox" id="renderShadows" checked>
-    </div>
-    <div>
-      Highlights: <input type="checkbox" id="renderHighlights" checked>
-    </div>
-    <div>
-      Reflections: <input type="checkbox" id="renderReflections" checked>
-    </div>
-    <button id="render">Render</button>
-    <div>
-      Time (ms): <span id="time"></span>
-    </div>
-    <script src="Tracer.js"></script>
-    <script src="app.js"></script>
-  </body>
-</html>
diff --git a/example/Tracer/js/run.sh b/example/Tracer/js/run.sh
deleted file mode 100755
index 567a3c5..0000000
--- a/example/Tracer/js/run.sh
+++ /dev/null
@@ -1,6 +0,0 @@
-#!/bin/sh
-
-# d8 is a tool included with V8:
-# https://code.google.com/p/v8/
-
-d8 bench.js Tracer.js benchmark_tracer.js
diff --git a/lib/benchmark_harness.dart b/lib/benchmark_harness.dart
index 5cea7bf..46153a0 100644
--- a/lib/benchmark_harness.dart
+++ b/lib/benchmark_harness.dart
@@ -1,3 +1,7 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
 library benchmark_harness;
 
 part 'src/benchmark_base.dart';
diff --git a/lib/src/benchmark_base.dart b/lib/src/benchmark_base.dart
index 2165828..f416ebf 100644
--- a/lib/src/benchmark_base.dart
+++ b/lib/src/benchmark_base.dart
@@ -1,4 +1,6 @@
-// Copyright 2011 Google Inc. All Rights Reserved.
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
 
 part of benchmark_harness;
 
diff --git a/lib/src/score_emitter.dart b/lib/src/score_emitter.dart
index 0e807d7..e88749d 100644
--- a/lib/src/score_emitter.dart
+++ b/lib/src/score_emitter.dart
@@ -1,3 +1,7 @@
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
 part of benchmark_harness;
 
 abstract class ScoreEmitter {
diff --git a/pubspec.yaml b/pubspec.yaml
index 7a57cca..702a84d 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -1,15 +1,14 @@
 name: benchmark_harness
-version: 2.0.0
-author: Dart Team <misc@dartlang.org>
+version: 2.0.1-dev
 description: The official Dart project benchmark harness.
-homepage: https://github.com/dart-lang/benchmark_harness
+repository: https://github.com/dart-lang/benchmark_harness
 
 environment:
-  sdk: '>=2.12.0-0 <3.0.0'
+  sdk: '>=2.12.0 <3.0.0'
 
 dev_dependencies:
-  build_runner: ^1.1.0
-  build_web_compilers: '>=1.0.0 <3.0.0'
-  path: ^1.8.0-nullsafety
-  pedantic: ^1.10.0-nullsafety
-  test: ^1.16.0-nullsafety
+  build_runner: ^2.0.0
+  build_web_compilers: ^3.0.0
+  path: ^1.8.0
+  pedantic: ^1.10.0
+  test: ^1.16.0
diff --git a/test/benchmark_harness_test.dart b/test/benchmark_harness_test.dart
index 836d812..bc85579 100644
--- a/test/benchmark_harness_test.dart
+++ b/test/benchmark_harness_test.dart
@@ -1,6 +1,6 @@
-// Copyright (c) 2014, Google Inc. Please see the AUTHORS file for details.
-// All rights reserved. Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
 
 library benchmark_harness_test;
 
diff --git a/test/result_emitter_test.dart b/test/result_emitter_test.dart
index 540175b..b5165a6 100644
--- a/test/result_emitter_test.dart
+++ b/test/result_emitter_test.dart
@@ -1,3 +1,7 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
 library result_emitter_test;
 
 import 'package:benchmark_harness/benchmark_harness.dart';
