enable and fix a number of lints
diff --git a/analysis_options.yaml b/analysis_options.yaml
new file mode 100644
index 0000000..6b149b2
--- /dev/null
+++ b/analysis_options.yaml
@@ -0,0 +1,83 @@
+include: package:pedantic/analysis_options.yaml
+#analyzer:
+#  strong-mode:
+#    implicit-casts: false
+linter:
+  rules:
+    #- always_declare_return_types
+    #- annotate_overrides
+    - avoid_empty_else
+    - avoid_function_literals_in_foreach_calls
+    - avoid_init_to_null
+    - avoid_null_checks_in_equality_operators
+    - avoid_relative_lib_imports
+    - avoid_renaming_method_parameters
+    - avoid_return_types_on_setters
+    - avoid_returning_null
+    - avoid_returning_null_for_future
+    - avoid_shadowing_type_parameters
+    - avoid_types_as_parameter_names
+    - avoid_unused_constructor_parameters
+    - await_only_futures
+    - camel_case_types
+    - cancel_subscriptions
+    - comment_references
+    #- constant_identifier_names
+    - control_flow_in_finally
+    - directives_ordering
+    - empty_catches
+    - empty_constructor_bodies
+    - empty_statements
+    - hash_and_equals
+    - implementation_imports
+    - invariant_booleans
+    - iterable_contains_unrelated_type
+    - library_names
+    - library_prefixes
+    - list_remove_unrelated_type
+    - literal_only_boolean_expressions
+    - no_adjacent_strings_in_list
+    - no_duplicate_case_values
+    #- non_constant_identifier_names
+    - null_closures
+    #- omit_local_variable_types
+    #- only_throw_errors
+    - overridden_fields
+    - package_api_docs
+    - package_names
+    - package_prefixed_library_names
+    - prefer_adjacent_string_concatenation
+    - prefer_collection_literals
+    - prefer_conditional_assignment
+    - prefer_const_constructors
+    - prefer_contains
+    - prefer_equal_for_default_values
+    #- prefer_final_fields
+    #- prefer_final_locals
+    - prefer_initializing_formals
+    - prefer_interpolation_to_compose_strings
+    - prefer_is_empty
+    - prefer_is_not_empty
+    #- prefer_single_quotes
+    #- prefer_typing_uninitialized_variables
+    - recursive_getters
+    - slash_for_doc_comments
+    - super_goes_last
+    - test_types_in_equals
+    - throw_in_finally
+    - type_init_formals
+    - unawaited_futures
+    - unnecessary_await_in_return
+    - unnecessary_brace_in_string_interps
+    - unnecessary_const
+    - unnecessary_getters_setters
+    - unnecessary_lambdas
+    - unnecessary_new
+    - unnecessary_null_aware_assignments
+    - unnecessary_parenthesis
+    - unnecessary_statements
+    #- unnecessary_this
+    - unrelated_type_equality_checks
+    - use_function_type_syntax_for_parameters
+    - use_rethrow_when_possible
+    - valid_regexps
diff --git a/example/DeltaBlue.dart b/example/DeltaBlue.dart
index f234f74..3732925 100644
--- a/example/DeltaBlue.dart
+++ b/example/DeltaBlue.dart
@@ -19,25 +19,35 @@
 // 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.
- */
+/// 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.
+
 main() {
-  new DeltaBlue().report();
+  const DeltaBlue().report();
 }
 
 /// Benchmark class required to report results.
@@ -50,12 +60,10 @@
   }
 }
 
-/**
- * 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.
- */
+/// 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;
@@ -89,13 +97,13 @@
 }
 
 // Compile time computed constants.
-const REQUIRED = const Strength(0, "required");
-const STRONG_REFERRED = const Strength(1, "strongPreferred");
-const PREFERRED = const Strength(2, "preferred");
-const STRONG_DEFAULT = const Strength(3, "strongDefault");
-const NORMAL = const Strength(4, "normal");
-const WEAK_DEFAULT = const Strength(5, "weakDefault");
-const WEAKEST = const Strength(6, "weakest");
+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;
@@ -103,14 +111,23 @@
   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.
@@ -119,14 +136,12 @@
     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(mark) {
+  /// 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) {
@@ -149,17 +164,13 @@
     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.
-   */
+  /// 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 superclass for constraints having a single possible output variable.
 abstract class UnaryConstraint extends Constraint {
   final Variable myOutput;
   bool satisfied = false;
@@ -190,11 +201,9 @@
   /// Returns the current output variable.
   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.
-   */
+  /// 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.
   void recalculate() {
     myOutput.walkStrength = strength;
     myOutput.stay = !isInput();
@@ -214,12 +223,10 @@
   }
 }
 
-/**
- * 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".
- */
+/// 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);
 
@@ -228,10 +235,8 @@
   }
 }
 
-/**
- * A unary input constraint used to mark a variable that the client
- * wishes to change.
- */
+/// 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);
 
@@ -248,10 +253,8 @@
 const int FORWARD = 2;
 const int BACKWARD = 0;
 
-/**
- * Abstract superclass for constraints having two possible output
- * variables.
- */
+/// Abstract superclass for constraints having two possible output
+/// variables.
 abstract class BinaryConstraint extends Constraint {
   Variable v1;
   Variable v2;
@@ -261,11 +264,9 @@
     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.
-   */
+  /// 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.
   void chooseMethod(int mark) {
     if (v1.mark == mark) {
       direction =
@@ -309,11 +310,9 @@
   /// Returns the current output variable.
   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.
-   */
+  /// 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.
   void recalculate() {
     Variable ihn = input(), out = output();
     out.walkStrength = Strength.weakest(strength, ihn.walkStrength);
@@ -338,12 +337,10 @@
   }
 }
 
-/**
- * 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.
- */
+/// 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;
@@ -380,11 +377,9 @@
     }
   }
 
-  /**
-   * 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.
-   */
+  /// 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.
   void recalculate() {
     Variable ihn = input(), out = output();
     out.walkStrength = Strength.weakest(strength, ihn.walkStrength);
@@ -393,9 +388,7 @@
   }
 }
 
-/**
- * Constrains two variables to have the same value.
- */
+/// Constrains two variables to have the same value.
 class EqualityConstraint extends BinaryConstraint {
   EqualityConstraint(Variable v1, Variable v2, Strength strength)
       : super(v1, v2, strength);
@@ -406,12 +399,10 @@
   }
 }
 
-/**
- * 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.
- **/
+/// 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;
@@ -423,10 +414,8 @@
 
   Variable(this.name, this.value);
 
-  /**
-   * Add the given constraint to the set of all constraints that refer
-   * this variable.
-   */
+  /// Add the given constraint to the set of all constraints that refer
+  /// this variable.
   void addConstraint(Constraint c) {
     constraints.add(c);
   }
@@ -441,38 +430,36 @@
 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.
-   */
+  /// 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) {
     int mark = newMark();
     for (Constraint overridden = c.satisfy(mark);
         overridden != null;
-        overridden = overridden.satisfy(mark));
+        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.
-   */
+  /// 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) {
     Variable out = c.output();
     c.markUnsatisfied();
@@ -491,30 +478,28 @@
   /// 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.
-   */
+  /// 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) {
     int mark = newMark();
-    Plan plan = new Plan();
+    Plan plan = Plan();
     List<Constraint> todo = sources;
-    while (todo.length > 0) {
+    while (todo.isNotEmpty) {
       Constraint c = todo.removeLast();
       if (c.output().mark != mark && c.inputsKnown(mark)) {
         plan.addConstraint(c);
@@ -525,10 +510,8 @@
     return plan;
   }
 
-  /**
-   * Extract a plan for resatisfying starting from the output of the
-   * given [constraints], usually a set of input constraints.
-   */
+  /// Extract a plan for resatisfying starting from the output of the
+  /// given [constraints], usually a set of input constraints.
   Plan extractPlanFromConstraints(List<Constraint> constraints) {
     List<Constraint> sources = <Constraint>[];
     for (int i = 0; i < constraints.length; i++) {
@@ -539,22 +522,20 @@
     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.
-   */
+  /// 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) {
     List<Constraint> todo = <Constraint>[c];
-    while (todo.length > 0) {
+    while (todo.isNotEmpty) {
       Constraint d = todo.removeLast();
       if (d.output().mark == mark) {
         incrementalRemove(c);
@@ -566,18 +547,16 @@
     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.
-   */
+  /// 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;
     List<Constraint> unsatisfied = <Constraint>[];
     List<Variable> todo = <Variable>[out];
-    while (todo.length > 0) {
+    while (todo.isNotEmpty) {
       Variable v = todo.removeLast();
       for (int i = 0; i < v.constraints.length; i++) {
         Constraint c = v.constraints[i];
@@ -604,11 +583,9 @@
   }
 }
 
-/**
- * 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.
- */
+/// 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>[];
 
@@ -625,32 +602,30 @@
   }
 }
 
-/**
- * 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.
- */
+/// 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 = new Planner();
-  Variable prev = null, first = null, last = null;
+  planner = Planner();
+  Variable prev, first, last;
   // Build chain of n equality constraints.
   for (int i = 0; i <= n; i++) {
-    Variable v = new Variable("v", 0);
-    if (prev != null) new EqualityConstraint(prev, v, REQUIRED);
+    Variable v = Variable("v", 0);
+    if (prev != null) EqualityConstraint(prev, v, REQUIRED);
     if (i == 0) first = v;
     if (i == n) last = v;
     prev = v;
   }
-  new StayConstraint(last, STRONG_DEFAULT);
-  EditConstraint edit = new EditConstraint(first, PREFERRED);
+  StayConstraint(last, STRONG_DEFAULT);
+  EditConstraint edit = EditConstraint(first, PREFERRED);
   Plan plan = planner.extractPlanFromConstraints(<Constraint>[edit]);
   for (int i = 0; i < 100; i++) {
     first.value = i;
@@ -661,25 +636,23 @@
   }
 }
 
-/**
- * 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.
- */
+/// 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 = new Planner();
-  Variable scale = new Variable("scale", 10);
-  Variable offset = new Variable("offset", 1000);
-  Variable src = null, dst = null;
+  planner = Planner();
+  Variable scale = Variable("scale", 10);
+  Variable offset = Variable("offset", 1000);
+  Variable src, dst;
 
   List<Variable> dests = <Variable>[];
   for (int i = 0; i < n; i++) {
-    src = new Variable("src", i);
-    dst = new Variable("dst", i);
+    src = Variable("src", i);
+    dst = Variable("dst", i);
     dests.add(dst);
-    new StayConstraint(src, NORMAL);
-    new ScaleConstraint(src, scale, offset, dst, REQUIRED);
+    StayConstraint(src, NORMAL);
+    ScaleConstraint(src, scale, offset, dst, REQUIRED);
   }
   change(src, 17);
   if (dst.value != 1170) print("Projection 1 failed");
@@ -696,7 +669,7 @@
 }
 
 void change(Variable v, int newValue) {
-  EditConstraint edit = new EditConstraint(v, PREFERRED);
+  EditConstraint edit = EditConstraint(v, PREFERRED);
   Plan plan = planner.extractPlanFromConstraints(<EditConstraint>[edit]);
   for (int i = 0; i < 10; i++) {
     v.value = newValue;
diff --git a/example/FluidMotion/dart/FluidMotion.dart b/example/FluidMotion/dart/FluidMotion.dart
index 69e3ccb..e8a581f 100644
--- a/example/FluidMotion/dart/FluidMotion.dart
+++ b/example/FluidMotion/dart/FluidMotion.dart
@@ -1,28 +1,26 @@
-/**
- * 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.
- */
+/// 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.
@@ -32,8 +30,58 @@
 
 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.
+
 main() {
-  new FluidMotion().report();
+  const FluidMotion().report();
 }
 
 class FluidMotion extends BenchmarkBase {
@@ -46,7 +94,7 @@
   static void setupFluidMotion() {
     framesTillAddingPoints = 0;
     framesBetweenAddingPoints = 5;
-    solver = new FluidField.create(null, 128, 128, 20);
+    solver = FluidField.create(null, 128, 128, 20);
     solver.setDisplayFunction((a) {});
     solver.setUICallback(prepareFrame);
   }
@@ -136,31 +184,28 @@
   factory FluidField.create(canvas, int hRes, int wRes, int iterations) {
     final res = wRes * hRes;
     if ((res > 0) && (res < 1000000)) {
-      _lastCreated = new FluidField(canvas, hRes, wRes, iterations);
-    } else if (_lastCreated == null) {
-      _lastCreated = new FluidField(canvas, 64, 64, iterations);
+      _lastCreated = FluidField(canvas, hRes, wRes, iterations);
     }
+    _lastCreated ??= FluidField(canvas, 64, 64, iterations);
     assert((canvas == _lastCreated.canvas) &&
         (iterations == _lastCreated.iterations));
     return _lastCreated;
   }
 
-  FluidField(this.canvas, int hRes, int wRes, this.iterations)
-      : width = wRes,
-        height = hRes,
-        rowSize = (wRes + 2),
-        size = (wRes + 2) * (hRes + 2) {
+  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 = new Float64List(size);
-    dens_prev = new Float64List(size);
-    u = new Float64List(size);
-    u_prev = new Float64List(size);
-    v = new Float64List(size);
-    v_prev = new Float64List(size);
+    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) {
@@ -410,14 +455,14 @@
     for (var i = 0; i < size; i++) {
       u[i] = v[i] = d[i] = 0.0;
     }
-    uiCallback(new Field(d, u, v, rowSize));
+    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(new Field(dens, u, v, rowSize));
+    displayFunc(Field(dens, u, v, rowSize));
   }
 }
 
diff --git a/example/Richards.dart b/example/Richards.dart
index 0659bac..2cba39e 100644
--- a/example/Richards.dart
+++ b/example/Richards.dart
@@ -37,31 +37,29 @@
 import 'package:benchmark_harness/benchmark_harness.dart';
 
 main() {
-  new Richards().report();
+  const Richards().report();
 }
 
-/**
- * Richards imulates the task dispatcher of an operating system.
- **/
+/// Richards imulates the task dispatcher of an operating system.
 class Richards extends BenchmarkBase {
   const Richards() : super("Richards");
 
   void run() {
-    Scheduler scheduler = new Scheduler();
+    Scheduler scheduler = Scheduler();
     scheduler.addIdleTask(ID_IDLE, 0, null, COUNT);
 
-    Packet queue = new Packet(null, ID_WORKER, KIND_WORK);
-    queue = new Packet(queue, ID_WORKER, KIND_WORK);
+    Packet queue = Packet(null, ID_WORKER, KIND_WORK);
+    queue = Packet(queue, ID_WORKER, KIND_WORK);
     scheduler.addWorkerTask(ID_WORKER, 1000, queue);
 
-    queue = new Packet(null, ID_DEVICE_A, KIND_DEVICE);
-    queue = new Packet(queue, ID_DEVICE_A, KIND_DEVICE);
-    queue = new Packet(queue, ID_DEVICE_A, KIND_DEVICE);
+    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 = new Packet(null, ID_DEVICE_B, KIND_DEVICE);
-    queue = new Packet(queue, ID_DEVICE_B, KIND_DEVICE);
-    queue = new Packet(queue, ID_DEVICE_B, KIND_DEVICE);
+    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);
@@ -86,13 +84,11 @@
   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.
-   **/
+  /// 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;
 
@@ -108,11 +104,9 @@
   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.
- */
+/// 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;
@@ -120,27 +114,26 @@
   int currentId;
   TaskControlBlock list;
   List<TaskControlBlock> blocks =
-      new List<TaskControlBlock>(Richards.NUMBER_OF_IDS);
+      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, new IdleTask(this, 1, 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, new WorkerTask(this, Richards.ID_HANDLER_A, 0));
+    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, new HandlerTask(this));
+    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, new DeviceTask(this));
+    addTask(id, priority, queue, DeviceTask(this));
   }
 
   /// Add the specified task and mark it as running.
@@ -151,7 +144,7 @@
 
   /// Add the specified task to this scheduler.
   void addTask(int id, int priority, Packet queue, Task task) {
-    currentTcb = new TaskControlBlock(list, id, priority, queue, task);
+    currentTcb = TaskControlBlock(list, id, priority, queue, task);
     list = currentTcb;
     blocks[id] = currentTcb;
   }
@@ -178,32 +171,26 @@
     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.
-   */
+  /// 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.
-   */
+  /// 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.
-   */
+  /// 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) {
     TaskControlBlock t = blocks[packet.id];
     if (t == null) return t;
@@ -214,10 +201,8 @@
   }
 }
 
-/**
- * A task control block manages a task and the queue of work packages associated
- * with it.
- */
+/// 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.
@@ -236,10 +221,8 @@
   /// 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.
-   */
+  /// 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.
@@ -285,11 +268,9 @@
     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).
-   */
+  /// 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;
@@ -301,12 +282,10 @@
     return task;
   }
 
-  String toString() => "tcb { ${task}@${state} }";
+  String toString() => "tcb { $task@$state }";
 }
 
-/**
- *  Abstract task that manipulates work packets.
- */
+///  Abstract task that manipulates work packets.
 abstract class Task {
   Scheduler scheduler; // The scheduler that manages this task.
 
@@ -315,10 +294,8 @@
   TaskControlBlock run(Packet packet);
 }
 
-/**
- * An idle task doesn't do any work itself but cycles control between the two
- * device tasks.
- */
+/// 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.
@@ -339,10 +316,8 @@
   String toString() => "IdleTask";
 }
 
-/**
- * A task that suspends itself after each time it has been run to simulate
- * waiting for data from an external device.
- */
+/// 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;
 
@@ -362,9 +337,7 @@
   String toString() => "DeviceTask";
 }
 
-/**
- * A task that manipulates work packets.
- */
+/// 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.
@@ -393,9 +366,7 @@
   String toString() => "WorkerTask";
 }
 
-/**
- * A task that manipulates work packets and then suspends itself.
- */
+/// A task that manipulates work packets and then suspends itself.
 class HandlerTask extends Task {
   Packet v1;
   Packet v2;
@@ -433,20 +404,18 @@
   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.
- */
+/// 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;
 
-  List<int> a2 = new List(Richards.DATA_SIZE);
+  List<int> a2 = List(Richards.DATA_SIZE);
 
   Packet(this.link, this.id, this.kind);
 
diff --git a/example/Template.dart b/example/Template.dart
index b930809..2d9d0de 100644
--- a/example/Template.dart
+++ b/example/Template.dart
@@ -8,7 +8,7 @@
   const TemplateBenchmark() : super("Template");
 
   static void main() {
-    new TemplateBenchmark().report();
+    const TemplateBenchmark().report();
   }
 
   // The benchmark code.
diff --git a/example/Tracer/dart/Tracer.dart b/example/Tracer/dart/Tracer.dart
index 4c7bd14..d4dc31c 100644
--- a/example/Tracer/dart/Tracer.dart
+++ b/example/Tracer/dart/Tracer.dart
@@ -41,5 +41,5 @@
 }
 
 void main() {
-  new TracerBenchmark().report();
+  const TracerBenchmark().report();
 }
diff --git a/example/Tracer/dart/app.dart b/example/Tracer/dart/app.dart
index 28c9cb5..add8b30 100644
--- a/example/Tracer/dart/app.dart
+++ b/example/Tracer/dart/app.dart
@@ -23,7 +23,7 @@
         int.parse((querySelector('#imageWidth') as InputElement).value);
     canvas.height =
         int.parse((querySelector('#imageHeight') as InputElement).value);
-    var sw = new Stopwatch()..start();
+    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
index ca2a63e..72253e8 100644
--- a/example/Tracer/dart/color.dart
+++ b/example/Tracer/dart/color.dart
@@ -21,22 +21,22 @@
   }
 
   Color operator +(Color c2) {
-    return new Color(red + c2.red, green + c2.green, blue + c2.blue);
+    return Color(red + c2.red, green + c2.green, blue + c2.blue);
   }
 
   Color addScalar(double s) {
-    var result = new Color(red + s, green + s, blue + s);
+    var result = Color(red + s, green + s, blue + s);
     result.limit();
     return result;
   }
 
   Color operator *(Color c2) {
-    var result = new Color(red * c2.red, green * c2.green, blue * c2.blue);
+    var result = Color(red * c2.red, green * c2.green, blue * c2.blue);
     return result;
   }
 
   Color multiplyScalar(double f) {
-    var result = new Color(red * f, green * f, blue * f);
+    var result = Color(red * f, green * f, blue * f);
     return result;
   }
 
diff --git a/example/Tracer/dart/engine.dart b/example/Tracer/dart/engine.dart
index 2696059..ab2998f 100644
--- a/example/Tracer/dart/engine.dart
+++ b/example/Tracer/dart/engine.dart
@@ -12,7 +12,7 @@
   var shape, position, normal, color, distance;
 
   IntersectionInfo() {
-    this.color = new Color(0.0, 0.0, 0.0);
+    this.color = Color(0.0, 0.0, 0.0);
   }
 
   String toString() => 'Intersection [$position]';
@@ -27,15 +27,15 @@
   var canvas;
 
   Engine(
-      {this.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}) {
+      {this.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;
   }
@@ -90,7 +90,7 @@
 
   IntersectionInfo testIntersection(Ray ray, Scene scene, BaseShape exclude) {
     int hits = 0;
-    IntersectionInfo best = new IntersectionInfo();
+    IntersectionInfo best = IntersectionInfo();
     best.distance = 2000;
 
     for (var i = 0; i < scene.shapes.length; i++) {
@@ -113,7 +113,7 @@
   Ray getReflectionRay(Vector P, Vector N, Vector V) {
     var c1 = -N.dot(V);
     var R1 = N.multiplyScalar(2 * c1) + V;
-    return new Ray(P, R1);
+    return Ray(P, R1);
   }
 
   Color rayTrace(IntersectionInfo info, Ray ray, Scene scene, int depth) {
@@ -156,16 +156,16 @@
       }
       /* Render shadows and highlights */
 
-      IntersectionInfo shadowInfo = new IntersectionInfo();
+      IntersectionInfo shadowInfo = IntersectionInfo();
 
       if (this.renderShadows) {
-        var shadowRay = new Ray(info.position, v);
+        var shadowRay = 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 * pow(shadowInfo.shape.material.transparency, 0.5));
+          var dB = 0.5 * pow(shadowInfo.shape.material.transparency, 0.5);
           color = vA.addScalar(dB);
         }
       }
diff --git a/example/Tracer/dart/renderscene.dart b/example/Tracer/dart/renderscene.dart
index e995741..c2860f1 100644
--- a/example/Tracer/dart/renderscene.dart
+++ b/example/Tracer/dart/renderscene.dart
@@ -16,31 +16,30 @@
 
 // 'event' null means that we are benchmarking
 void renderScene(event) {
-  var scene = new Scene();
-  scene.camera = new Camera(new Vector(0.0, 0.0, -15.0),
-      new Vector(-0.2, 0.0, 5.0), new Vector(0.0, 1.0, 0.0));
-  scene.background = new Background(new Color(0.5, 0.5, 0.5), 0.4);
+  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 = new Sphere(new Vector(-1.5, 1.5, 2.0), 1.5,
-      new Solid(new Color(0.0, 0.5, 0.5), 0.3, 0.0, 0.0, 2.0));
+  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 = new Sphere(new Vector(1.0, 0.25, 1.0), 0.5,
-      new Solid(new Color(0.9, 0.9, 0.9), 0.1, 0.0, 0.0, 1.5));
+  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 = new Plane(
-      new Vector(0.1, 0.9, -0.5).normalize(),
+  var plane = Plane(
+      Vector(0.1, 0.9, -0.5).normalize(),
       1.2,
-      new Chessboard(new Color(1.0, 1.0, 1.0), new Color(0.0, 0.0, 0.0), 0.2,
-          0.0, 1.0, 0.7));
+      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 = new Light(new Vector(5.0, 10.0, -1.0), new Color(0.8, 0.8, 0.8));
+  var light = Light(Vector(5.0, 10.0, -1.0), Color(0.8, 0.8, 0.8));
 
-  var light1 =
-      new Light(new Vector(-3.0, 5.0, -15.0), new Color(0.8, 0.8, 0.8), 100.0);
+  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);
@@ -76,7 +75,7 @@
   }
   int rayDepth = 2;
 
-  var raytracer = new Engine(
+  var raytracer = Engine(
       canvasWidth: imageWidth,
       canvasHeight: imageHeight,
       pixelWidth: pixelSize,
diff --git a/example/Tracer/dart/scene.dart b/example/Tracer/dart/scene.dart
index 499ec84..92bbe88 100644
--- a/example/Tracer/dart/scene.dart
+++ b/example/Tracer/dart/scene.dart
@@ -32,7 +32,7 @@
         screen - (this.equator.multiplyScalar(vx) - this.up.multiplyScalar(vy));
     pos.y = pos.y * -1.0;
     var dir = pos - this.position;
-    var ray = new Ray(pos, dir.normalize());
+    var ray = Ray(pos, dir.normalize());
     return ray;
   }
 
@@ -54,10 +54,10 @@
   var lights;
   var background;
   Scene() {
-    camera = new Camera(new Vector(0.0, 0.0, -0.5), new Vector(0.0, 0.0, 1.0),
-        new Vector(0.0, 1.0, 0.0));
-    shapes = new List();
-    lights = new List();
-    background = new Background(new Color(0.0, 0.0, 0.5), 0.2);
+    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
index 254ece8..6685b65 100644
--- a/example/Tracer/dart/shapes.dart
+++ b/example/Tracer/dart/shapes.dart
@@ -23,7 +23,7 @@
   Plane(pos, this.d, material) : super(pos, material);
 
   IntersectionInfo intersect(Ray ray) {
-    var info = new IntersectionInfo();
+    var info = IntersectionInfo();
 
     var Vd = this.position.dot(ray.direction);
     if (Vd == 0) return info; // no intersection
@@ -38,7 +38,7 @@
     info.distance = t;
 
     if (this.material.hasTexture) {
-      var vU = new Vector(this.position.y, this.position.z, -this.position.x);
+      var vU = Vector(this.position.y, this.position.z, -this.position.x);
       var vV = vU.cross(this.position);
       var u = info.position.dot(vU);
       var v = info.position.dot(vV);
@@ -60,7 +60,7 @@
   Sphere(pos, this.radius, material) : super(pos, material);
 
   IntersectionInfo intersect(Ray ray) {
-    var info = new IntersectionInfo();
+    var info = IntersectionInfo();
     info.shape = this;
 
     var dst = ray.position - this.position;
diff --git a/example/Tracer/dart/vector.dart b/example/Tracer/dart/vector.dart
index 4763fad..27c1639 100644
--- a/example/Tracer/dart/vector.dart
+++ b/example/Tracer/dart/vector.dart
@@ -18,7 +18,7 @@
 
   Vector normalize() {
     var m = this.magnitude();
-    return new Vector(this.x / m, this.y / m, this.z / m);
+    return Vector(this.x / m, this.y / m, this.z / m);
   }
 
   double magnitude() {
@@ -26,7 +26,7 @@
   }
 
   Vector cross(Vector w) {
-    return new Vector(-this.z * w.y + this.y * w.z, this.z * w.x - this.x * w.z,
+    return 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);
   }
 
@@ -35,19 +35,19 @@
   }
 
   Vector operator +(Vector w) {
-    return new Vector(w.x + x, w.y + y, w.z + z);
+    return Vector(w.x + x, w.y + y, w.z + z);
   }
 
   Vector operator -(Vector w) {
-    return new Vector(x - w.x, y - w.y, z - w.z);
+    return Vector(x - w.x, y - w.y, z - w.z);
   }
 
   Vector operator *(Vector w) {
-    return new Vector(x * w.x, y * w.y, z * w.z);
+    return Vector(x * w.x, y * w.y, z * w.z);
   }
 
   Vector multiplyScalar(double w) {
-    return new Vector(x * w, y * w, z * w);
+    return Vector(x * w, y * w, z * w);
   }
 
   String toString() {
diff --git a/lib/src/benchmark_base.dart b/lib/src/benchmark_base.dart
index 9273ebf..7410a2c 100644
--- a/lib/src/benchmark_base.dart
+++ b/lib/src/benchmark_base.dart
@@ -7,9 +7,7 @@
   final ScoreEmitter emitter;
 
   // Empty constructor.
-  const BenchmarkBase(String name, {ScoreEmitter emitter: const PrintEmitter()})
-      : this.name = name,
-        this.emitter = emitter;
+  const BenchmarkBase(this.name, {this.emitter = const PrintEmitter()});
 
   // The benchmark code.
   // This function is not used, if both [warmup] and [exercise] are overwritten.
@@ -38,7 +36,7 @@
   static double measureFor(Function f, int minimumMillis) {
     int minimumMicros = minimumMillis * 1000;
     int iter = 0;
-    Stopwatch watch = new Stopwatch();
+    Stopwatch watch = Stopwatch();
     watch.start();
     int elapsed = 0;
     while (elapsed < minimumMicros) {
@@ -53,13 +51,9 @@
   double measure() {
     setup();
     // Warmup for at least 100ms. Discard result.
-    measureFor(() {
-      this.warmup();
-    }, 100);
+    measureFor(warmup, 100);
     // Run the benchmark for at least 2000ms.
-    double result = measureFor(() {
-      this.exercise();
-    }, 2000);
+    double result = measureFor(exercise, 2000);
     teardown();
     return result;
   }
diff --git a/pubspec.yaml b/pubspec.yaml
index fab6326..e74c75b 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -1,5 +1,5 @@
 name: benchmark_harness
-version: 1.0.5
+version: 1.0.6-dev
 author: Dart Team <misc@dartlang.org>
 description: The official Dart project benchmark harness.
 homepage: https://github.com/dart-lang/benchmark_harness
@@ -12,4 +12,5 @@
   build_web_compilers: ^0.4.0
   mockito: ^3.0.0
   path: ^1.1.0
+  pedantic: ^1.4.0
   test: ^1.0.0
diff --git a/test/benchmark_harness_test.dart b/test/benchmark_harness_test.dart
index c1b287f..bcb225d 100644
--- a/test/benchmark_harness_test.dart
+++ b/test/benchmark_harness_test.dart
@@ -10,7 +10,7 @@
 void main() {
   group('benchmark_harness', () {
     test('run is called', () {
-      MockBenchmark benchmark = new MockBenchmark();
+      MockBenchmark benchmark = MockBenchmark();
       double micros = benchmark.measure();
       expect(micros, isPositive);
       expect(benchmark.runCount, isPositive);
diff --git a/test/result_emitter_test.dart b/test/result_emitter_test.dart
index 82c45a7..f145c1a 100644
--- a/test/result_emitter_test.dart
+++ b/test/result_emitter_test.dart
@@ -25,14 +25,14 @@
 
 benchmarkHarnessTest() {
   MockResultEmitter createMockEmitter() {
-    MockResultEmitter emitter = new MockResultEmitter();
+    MockResultEmitter emitter = MockResultEmitter();
     return emitter;
   }
 
   group('ResultEmitter', () {
     test('should be called when emitter is provided', () {
       MockResultEmitter emitter = createMockEmitter();
-      var testBenchmark = new BenchmarkWithResultEmitter(emitter);
+      var testBenchmark = BenchmarkWithResultEmitter(emitter);
       testBenchmark.report();
 
       verify(emitter.emit(any, any)).called(1);