diff --git a/LICENSE b/LICENSE
index ff99443..db5bf46 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1,5 +1,26 @@
-Harness:
-Copyright 2012 Google LLC 
+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/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 1b167e3..0000000
--- a/example/FluidMotion/dart/FluidMotion.dart
+++ /dev/null
@@ -1,511 +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 d0e3cd2..0000000
--- a/example/Tracer/dart/engine.dart
+++ /dev/null
@@ -1,201 +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/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';
