Document newton more.
diff --git a/packages/flutter/lib/src/widgets/scrollable.dart b/packages/flutter/lib/src/widgets/scrollable.dart
index 29d02aa..dbc4f26 100644
--- a/packages/flutter/lib/src/widgets/scrollable.dart
+++ b/packages/flutter/lib/src/widgets/scrollable.dart
@@ -20,8 +20,9 @@
 
 /// The accuracy to which scrolling is computed.
 final Tolerance kPixelScrollTolerance = new Tolerance(
-  velocity: 1.0 / (0.050 * ui.window.devicePixelRatio),  // logical pixels per second
-  distance: 1.0 / ui.window.devicePixelRatio  // logical pixels
+  // TODO(ianh): Handle the case of the device pixel ratio changing.
+  velocity: 1.0 / (0.050 * ui.window.devicePixelRatio), // logical pixels per second
+  distance: 1.0 / ui.window.devicePixelRatio // logical pixels
 );
 
 typedef void ScrollListener(double scrollOffset);
diff --git a/packages/newton/lib/newton.dart b/packages/newton/lib/newton.dart
index 94b6df0..c56aa1d 100644
--- a/packages/newton/lib/newton.dart
+++ b/packages/newton/lib/newton.dart
@@ -2,7 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-/// Simple Physics Simulations for Dart. Springs, friction, gravity, etc.
+/// Simple one-dimensional physics simulations, such as springs, friction, and
+/// gravity, for use in user interface animations.
 library newton;
 
 export 'src/clamped_simulation.dart';
diff --git a/packages/newton/lib/src/clamped_simulation.dart b/packages/newton/lib/src/clamped_simulation.dart
index daa172b..82fe080 100644
--- a/packages/newton/lib/src/clamped_simulation.dart
+++ b/packages/newton/lib/src/clamped_simulation.dart
@@ -4,7 +4,23 @@
 
 import 'simulation.dart';
 
+/// A simulation that applies limits to another simulation.
+///
+/// The limits are only applied to the other simulation's outputs. For example,
+/// if a maximum position was applied to a gravity simulation with the
+/// particle's initial velocity being up, and the accerelation being down, and
+/// the maximum position being between the initial position and the curve's
+/// apogee, then the particle would return to its initial position in the same
+/// amount of time as it would have if the maximum had not been applied; the
+/// difference would just be that the position would be reported as pinned to
+/// the maximum value for the times that it would otherwise have been reported
+/// as higher.
 class ClampedSimulation extends Simulation {
+
+  /// Creates a [ClampedSimulation] that clamps the given simulation.
+  ///
+  /// The named arguments specify the ranges for the clamping behavior, as
+  /// applied to [x] and [dx].
   ClampedSimulation(this.simulation, {
     this.xMin: double.NEGATIVE_INFINITY,
     this.xMax: double.INFINITY,
@@ -16,10 +32,20 @@
     assert(dxMax >= dxMin);
   }
 
+  /// The simulation being clamped. Calls to [x], [dx], and [isDone] are
+  /// forwarded to the simulation.
   final Simulation simulation;
+
+  /// The minimum to apply to [x].
   final double xMin;
+
+  /// The maximum to apply to [x].
   final double xMax;
+
+  /// The minimum to apply to [dx].
   final double dxMin;
+
+  /// The maximum to apply to [dx].
   final double dxMax;
 
   @override
diff --git a/packages/newton/lib/src/friction_simulation.dart b/packages/newton/lib/src/friction_simulation.dart
index 1958655..b138d0f 100644
--- a/packages/newton/lib/src/friction_simulation.dart
+++ b/packages/newton/lib/src/friction_simulation.dart
@@ -7,21 +7,43 @@
 import 'simulation.dart';
 import 'tolerance.dart';
 
+/// A simulation that applies a drag to slow a particle down.
+///
+/// Models a particle affected by fluid drag, e.g. air resistance.
+///
+/// The simulation ends when the velocity of the particle drops to zero (within
+/// the current velocity [tolerance]).
 class FrictionSimulation extends Simulation {
+  /// Creates a [FrictionSimulation] with the given arguments, namely: the fluid
+  /// drag coefficient, a unitless value; the initial position, in the same
+  /// length units as used for [x]; and the initial velocity, in the same
+  /// velocity units as used for [dx].
   FrictionSimulation(double drag, double position, double velocity)
     : _drag = drag,
       _dragLog = math.log(drag),
       _x = position,
       _v = velocity;
 
-  // A friction simulation that starts and ends at the specified positions
-  // and velocities.
+  /// Creates a new friction simulation with its fluid drag coefficient set so
+  /// as to ensure that the simulation starts and ends at the specified
+  /// positions and velocities.
+  ///
+  /// The positions must use the same units as expected from [x], and the
+  /// velocities must use the same units as expected from [dx].
+  ///
+  /// The sign of the start and end velocities must be the same, the magnitude
+  /// of the start velocity must be greater than the magnitude of the end
+  /// velocity, and the velocities must be in the direction appropriate for the
+  /// particle to start from the start position and reach the end position.
   factory FrictionSimulation.through(double startPosition, double endPosition, double startVelocity, double endVelocity) {
+    assert(startVelocity.sign == endVelocity.sign);
+    assert(startVelocity.abs() >= endVelocity.abs());
+    assert((endPosition - startPosition).sign == startVelocity.sign);
     return new FrictionSimulation(
       _dragFor(startPosition, endPosition, startVelocity, endVelocity),
       startPosition,
-      startVelocity)
-      .. tolerance = new Tolerance(velocity: endVelocity.abs());
+      startVelocity
+    )..tolerance = new Tolerance(velocity: endVelocity.abs());
   }
 
   final double _drag;
@@ -50,14 +72,25 @@
   bool isDone(double time) => dx(time).abs() < tolerance.velocity;
 }
 
+/// A [FrictionSimulation] that clamps the modelled particle to a specific range
+/// of values.
 class BoundedFrictionSimulation extends FrictionSimulation {
+  /// Creates a [BoundedFrictionSimulation] with the given arguments, namely:
+  /// the fluid drag coefficient, a unitless value; the initial position, in the
+  /// same length units as used for [x]; the initial velocity, in the same
+  /// velocity units as used for [dx], the minimum value for the position, and
+  /// the maximum value for the position. The minimum and maximum values must be
+  /// in the same units as the initial position, and the initial position must
+  /// be within the given range.
   BoundedFrictionSimulation(
     double drag,
     double position,
     double velocity,
     this._minX,
     this._maxX
-  ) : super(drag, position, velocity);
+  ) : super(drag, position, velocity) {
+    assert(position.clamp(_minX, _maxX) == position);
+  }
 
   final double _minX;
   final double _maxX;
diff --git a/packages/newton/lib/src/gravity_simulation.dart b/packages/newton/lib/src/gravity_simulation.dart
index a53ad93..b75eb93 100644
--- a/packages/newton/lib/src/gravity_simulation.dart
+++ b/packages/newton/lib/src/gravity_simulation.dart
@@ -4,19 +4,46 @@
 
 import 'simulation.dart';
 
+/// A simulation that applies a constant accelerating force.
+///
+/// Models a particle that follows Newton's second law of motion. The simulation
+/// ends when the position reaches a defined point.
 class GravitySimulation extends Simulation {
+  /// Creates a [GravitySimulation] using the given arguments, which are,
+  /// respectively: an acceleration that is to be applied continually over time;
+  /// an initial position relative to an origin; the magnitude of the distance
+  /// from that origin beyond which (in either direction) to consider the
+  /// simulation to be "done", which must be positive; and an initial velocity.
+  ///
+  /// The initial position and maximum distance are measured in arbitrary length
+  /// units L from an arbitrary origin. The units will match those used for [x].
+  ///
+  /// The time unit T used for the arguments to [x], [dx], and [isDone],
+  /// combined with the aforementioned length unit, together determine the units
+  /// that must be used for the velocity and acceleration arguments: L/T and
+  /// L/T² respectively. The same units of velocity are used for the velocity
+  /// obtained from [dx].
+  GravitySimulation(
+    double acceleration,
+    double distance,
+    double endDistance,
+    double velocity
+  ) : _a = acceleration,
+      _x = distance,
+      _v = velocity,
+      _end = endDistance {
+    assert(acceleration != null);
+    assert(distance != null);
+    assert(velocity != null);
+    assert(endDistance != null);
+    assert(endDistance >= 0);
+  }
+
   final double _x;
   final double _v;
   final double _a;
   final double _end;
 
-  GravitySimulation(
-      double acceleration, double distance, double endDistance, double velocity)
-      : _a = acceleration,
-        _x = distance,
-        _v = velocity,
-        _end = endDistance;
-
   @override
   double x(double time) => _x + _v * time + 0.5 * _a * time * time;
 
diff --git a/packages/newton/lib/src/scroll_simulation.dart b/packages/newton/lib/src/scroll_simulation.dart
index fb8d10d..5d9fd97 100644
--- a/packages/newton/lib/src/scroll_simulation.dart
+++ b/packages/newton/lib/src/scroll_simulation.dart
@@ -7,10 +7,25 @@
 import 'simulation.dart';
 import 'spring_simulation.dart';
 
+/// Composite simulation for scrollable interfaces.
+///
 /// Simulates kinetic scrolling behavior between a leading and trailing
-/// boundary. Friction is applied within the extends and a spring action applied
-/// at the boundaries. This simulation can only step forward.
+/// boundary. Friction is applied within the extents and a spring action is
+/// applied at the boundaries. This simulation can only step forward.
 class ScrollSimulation extends SimulationGroup {
+  /// Creates a [ScrollSimulation] with the given parameters.
+  ///
+  /// The position and velocity arguments must use the same units as will be
+  /// expected from the [x] and [dx] methods respectively.
+  ///
+  /// The leading and trailing extents must use the unit of length, the same
+  /// unit as used for the position argument and as expected from the [x]
+  /// method.
+  ///
+  /// The units used with the provided [SpringDescription] must similarly be
+  /// consistent with the other arguments.
+  ///
+  /// The final argument is the coefficient of friction, which is unitless.
   ScrollSimulation(
     double position,
     double velocity,
diff --git a/packages/newton/lib/src/simulation.dart b/packages/newton/lib/src/simulation.dart
index 512f1b6..13357ba 100644
--- a/packages/newton/lib/src/simulation.dart
+++ b/packages/newton/lib/src/simulation.dart
@@ -4,18 +4,47 @@
 
 import 'tolerance.dart';
 
-/// The base class for all simulations. The user is meant to instantiate an
-/// instance of a simulation and query the same for the position and velocity
-/// of the body at a given interval.
+/// The base class for all simulations.
+///
+/// A simulation models an object, in a one-dimensional space, on which particular
+/// forces are being applied, and exposes:
+///
+///  * The object's position, [x]
+///  * The object's velocity, [dx]
+///  * Whether the simulation is "done", [isDone]
+///
+/// A simulation is generally "done" if the object has, to a given [tolerance],
+/// come to a complete rest.
+///
+/// The [x], [dx], and [isDone] functions take a time argument which specifies
+/// the time for which they are to be evaluated. In principle, simulations can
+/// be stateless, and thus can be queried with arbitrary times. In practice,
+/// however, some simulations are not, and calling any of these functions will
+/// advance the simulation to the given time.
+///
+/// As a general rule, therefore, a simulation should only be queried using
+/// times that are equal to or greater than all times previously used for that
+/// simulation.
+///
+/// Simulations do not specify units for distance, velocity, and time. Client
+/// should establish a convention and use that convention consistently with all
+/// related objects.
 abstract class Simulation {
-  Tolerance tolerance = toleranceDefault;
-
-  /// The current position of the object in the simulation
+  /// The position of the object in the simulation at the given time.
   double x(double time);
 
-  /// The current velocity of the object in the simulation
+  /// The velocity of the object in the simulation at the given time.
   double dx(double time);
 
-  /// Returns if the simulation is done at a given time
+  /// Whether the simulation is "done" at the given time.
   bool isDone(double time);
+
+  /// How close to the actual end of the simulation a value at a particular time
+  /// must be before [isDone] considers the simulation to be "done".
+  ///
+  /// A simulation with an asymptotic curve would never technically be "done",
+  /// but once the difference from the value at a particular time and the
+  /// asymptote itself could not be seen, it would be pointless to continue. The
+  /// tolerance defines how to determine if the difference could not be seen.
+  Tolerance tolerance = Tolerance.defaultTolerance;
 }
diff --git a/packages/newton/lib/src/simulation_group.dart b/packages/newton/lib/src/simulation_group.dart
index 83269be..86411bf 100644
--- a/packages/newton/lib/src/simulation_group.dart
+++ b/packages/newton/lib/src/simulation_group.dart
@@ -6,25 +6,50 @@
 import 'tolerance.dart';
 import 'utils.dart';
 
-/// The abstract base class for all composite simulations. Concrete subclasses
-/// must implement the appropriate methods to select the appropriate simulation
-/// at a given time interval. The simulation group takes care to call the `step`
-/// method at appropriate intervals. If more fine grained control over the the
-/// step is necessary, subclasses may override the [x], [dx], and [isDone]
-/// methods.
+/// Base class for composite simulations.
+///
+/// Concrete subclasses must implement the [currentSimulation] getter, the
+/// [currentIntervalOffset] getter, and the [step] function to select the
+/// appropriate simulation at a given time interval. This class implements the
+/// [x], [dx], and [isDone] functions by calling the [step] method if necessary
+/// and then deferring to the [currentSimulation]'s methods with a time offset
+/// by [currentIntervalOffset].
+///
+/// The tolerance of this simulation is pushed to the simulations that are used
+/// by this group as they become active. This mean simulations should not be
+/// shared among different groups that are active at the same time.
 abstract class SimulationGroup extends Simulation {
 
-  /// The currently active simulation
+  /// The currently active simulation.
+  ///
+  /// This getter should return the same value until [step] is called and
+  /// returns true.
   Simulation get currentSimulation;
 
-  /// The time offset applied to the currently active simulation;
+  /// The time offset applied to the currently active simulation when deferring
+  /// [x], [dx], and [isDone] to it.
   double get currentIntervalOffset;
 
   /// Called when a significant change in the interval is detected. Subclasses
-  /// must decide if the the current simulation must be switched (or updated).
-  /// The result is whether the simulation was switched in this step.
+  /// must decide if the current simulation must be switched (or updated).
+  ///
+  /// Must return true if the simulation was switched in this step, otherwise
+  /// false.
+  ///
+  /// If this function returns true, then [currentSimulation] must start
+  /// returning a new value.
   bool step(double time);
 
+  double _lastStep = -1.0;
+  void _stepIfNecessary(double time) {
+    if (nearEqual(_lastStep, time, Tolerance.defaultTolerance.time))
+      return;
+
+    _lastStep = time;
+    if (step(time))
+      currentSimulation.tolerance = tolerance;
+  }
+
   @override
   double x(double time) {
     _stepIfNecessary(time);
@@ -38,26 +63,14 @@
   }
 
   @override
-  void set tolerance(Tolerance t) {
-    this.currentSimulation.tolerance = t;
-    super.tolerance = t;
-  }
-
-  @override
   bool isDone(double time) {
     _stepIfNecessary(time);
     return currentSimulation.isDone(time - currentIntervalOffset);
   }
 
-  double _lastStep = -1.0;
-  void _stepIfNecessary(double time) {
-    if (nearEqual(_lastStep, time, toleranceDefault.time)) {
-      return;
-    }
-
-    _lastStep = time;
-    if (step(time)) {
-      this.currentSimulation.tolerance = this.tolerance;
-    }
+  @override
+  void set tolerance(Tolerance t) {
+    currentSimulation.tolerance = t;
+    super.tolerance = t;
   }
 }
diff --git a/packages/newton/lib/src/spring_simulation.dart b/packages/newton/lib/src/spring_simulation.dart
index c205119..5109ce9 100644
--- a/packages/newton/lib/src/spring_simulation.dart
+++ b/packages/newton/lib/src/spring_simulation.dart
@@ -7,7 +7,135 @@
 import 'simulation.dart';
 import 'utils.dart';
 
-enum SpringType { unknown, criticallyDamped, underDamped, overDamped }
+/// Structure that describes a spring's constants.
+///
+/// Used to configure a [SpringSimulation].
+class SpringDescription {
+  /// Creates a spring given the mass, spring constant and the damping coefficient.
+  ///
+  /// See [mass], [springConstant], and [damping] for the units of the arguments.
+  const SpringDescription({
+    this.mass,
+    this.springConstant,
+    this.damping
+  });
+
+  /// Creates a spring given the mass (m), spring constant (k), and damping
+  /// ratio (ζ). The damping ratio is especially useful trying to determing the
+  /// type of spring to create. A ratio of 1.0 creates a critically damped
+  /// spring, > 1.0 creates an overdamped spring and < 1.0 an underdamped one.
+  ///
+  /// See [mass] and [springConstant] for the units for those arguments. The
+  /// damping ratio is unitless.
+  SpringDescription.withDampingRatio({
+    double mass,
+    double springConstant,
+    double ratio: 1.0
+  }) : mass = mass,
+       springConstant = springConstant,
+       damping = ratio * 2.0 * math.sqrt(mass * springConstant);
+
+  /// The mass of the spring (m). The units are arbitrary, but all springs
+  /// within a system should use the same mass units.
+  final double mass;
+
+  /// The spring constant (k). The units of the spring constant are M/T², where
+  /// M is the mass unit used for the value of the [mass] property, and T is the
+  /// time unit used for driving the [SpringSimulation].
+  final double springConstant;
+
+  /// The damping coefficient (c).
+  ///
+  /// Do not confuse the damping _coefficient_ (c) with the damping _ratio_ (ζ).
+  /// To create a [SpringDescription] with a damping ratio, use the [new
+  /// SpringDescription.withDampingRatio] constructor.
+  ///
+  /// The units of the damping coefficient are M/T, where M is the mass unit
+  /// used for the value of the [mass] property, and T is the time unit used for
+  /// driving the [SpringSimulation].
+  final double damping;
+}
+
+/// The kind of spring solution that the [SpringSimulation] is using to simulate the spring.
+///
+/// See [SpringSimulation.type].
+enum SpringType {
+  /// A spring that does not bounce and returns to its rest position in the
+  /// shortest possible time.
+  criticallyDamped,
+
+  /// A spring that bounces.
+  underDamped,
+
+  /// A spring that does not bounce but takes longer to return to its rest
+  /// position than a [criticallyDamped] one.
+  overDamped,
+}
+
+/// A spring simulation.
+///
+/// Models a particle attached to a spring that follows Hooke's law.
+class SpringSimulation extends Simulation {
+  /// Creates a spring simulation from the provided spring description, start
+  /// distance, end distance, and initial velocity.
+  ///
+  /// The units for the start and end distance arguments are arbitrary, but must
+  /// be consistent with the units used for other lengths in the system.
+  ///
+  /// The units for the velocity are L/T, where L is the aforementioned
+  /// arbitrary unit of length, and T is the time unit used for driving the
+  /// [SpringSimulation].
+  SpringSimulation(
+    SpringDescription desc,
+    double start,
+    double end,
+    double velocity
+  ) : _endPosition = end,
+      _solution = new _SpringSolution(desc, start - end, velocity);
+
+  final double _endPosition;
+  final _SpringSolution _solution;
+
+  /// The kind of spring being simulated, for debugging purposes.
+  ///
+  /// This is derived from the [SpringDescription] provided to the [new
+  /// SpringSimulation] constructor.
+  SpringType get type => _solution.type;
+
+  @override
+  double x(double time) => _endPosition + _solution.x(time);
+
+  @override
+  double dx(double time) => _solution.dx(time);
+
+  @override
+  bool isDone(double time) {
+    return nearZero(_solution.x(time), tolerance.distance) &&
+           nearZero(_solution.dx(time), tolerance.velocity);
+  }
+}
+
+/// A SpringSimulation where the value of [x] is guaranteed to have exactly the
+/// end value when the simulation isDone().
+class ScrollSpringSimulation extends SpringSimulation {
+  /// Creates a spring simulation from the provided spring description, start
+  /// distance, end distance, and initial velocity.
+  ///
+  /// See the [new SpringSimulation] constructor on the superclass for a
+  /// discussion of the arguments' units.
+  ScrollSpringSimulation(
+    SpringDescription desc,
+    double start,
+    double end,
+    double velocity
+  ) : super(desc, start, end, velocity);
+
+  @override
+  double x(double time) => isDone(time) ? _endPosition : super.x(time);
+}
+
+
+// SPRING IMPLEMENTATIONS
 
 abstract class _SpringSolution {
   factory _SpringSolution(
@@ -15,6 +143,12 @@
     double initialPosition,
     double initialVelocity
   ) {
+    assert(desc != null);
+    assert(desc.mass != null);
+    assert(desc.springConstant != null);
+    assert(desc.damping != null);
+    assert(initialPosition != null);
+    assert(initialVelocity != null);
     double cmk = desc.damping * desc.damping - 4 * desc.mass * desc.springConstant;
     if (cmk == 0.0)
       return new _CriticalSolution(desc, initialPosition, initialVelocity);
@@ -140,83 +274,3 @@
   @override
   SpringType get type => SpringType.underDamped;
 }
-
-class SpringDescription {
-  SpringDescription({
-    this.mass,
-    this.springConstant,
-    this.damping
-  }) {
-    assert(mass != null);
-    assert(springConstant != null);
-    assert(damping != null);
-  }
-
-  /// Create a spring given the mass, spring constant and the damping ratio. The
-  /// damping ratio is especially useful trying to determing the type of spring
-  /// to create. A ratio of 1.0 creates a critically damped spring, > 1.0
-  /// creates an overdamped spring and < 1.0 an underdamped one.
-  SpringDescription.withDampingRatio({
-    double mass,
-    double springConstant,
-    double ratio: 1.0
-  }) : mass = mass,
-       springConstant = springConstant,
-       damping = ratio * 2.0 * math.sqrt(mass * springConstant);
-
-  /// The mass of the spring (m)
-  final double mass;
-
-  /// The spring constant (k)
-  final double springConstant;
-
-  /// The damping coefficient.
-  /// Not to be confused with the damping ratio. Use the separate
-  /// constructor provided for this purpose
-  final double damping;
-}
-
-/// Creates a spring simulation. Depending on the spring description, a
-/// critically, under or overdamped spring will be created.
-class SpringSimulation extends Simulation {
-  /// A spring description with the provided spring description, start distance,
-  /// end distance and velocity.
-  SpringSimulation(
-    SpringDescription desc,
-    double start,
-    double end,
-    double velocity
-  ) : _endPosition = end,
-      _solution = new _SpringSolution(desc, start - end, velocity);
-
-  final double _endPosition;
-  final _SpringSolution _solution;
-
-  SpringType get type => _solution.type;
-
-  @override
-  double x(double time) => _endPosition + _solution.x(time);
-
-  @override
-  double dx(double time) => _solution.dx(time);
-
-  @override
-  bool isDone(double time) {
-    return nearZero(_solution.x(time), tolerance.distance) &&
-           nearZero(_solution.dx(time), tolerance.velocity);
-  }
-}
-
-/// A SpringSimulation where the value of x() is guaranteed to have exactly the
-/// end value when the simulation isDone().
-class ScrollSpringSimulation extends SpringSimulation {
-  ScrollSpringSimulation(
-    SpringDescription desc,
-    double start,
-    double end,
-    double velocity
-  ) : super(desc, start, end, velocity);
-
-  @override
-  double x(double time) => isDone(time) ? _endPosition : super.x(time);
-}
diff --git a/packages/newton/lib/src/tolerance.dart b/packages/newton/lib/src/tolerance.dart
index 5ff48c7..47d2afe 100644
--- a/packages/newton/lib/src/tolerance.dart
+++ b/packages/newton/lib/src/tolerance.dart
@@ -2,17 +2,45 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+/// Structure that specifies maximum allowable magnitudes for distances,
+/// durations, and velocity differences to be considered equal.
 class Tolerance {
+  /// Creates a [Tolerance] object. By default, the distance, time, and velocity
+  /// tolerances are all ±0.001; the constructor arguments override this.
+  ///
+  /// The arguments should all be positive values.
+  const Tolerance({
+    this.distance: _kEpsilonDefault,
+    this.time: _kEpsilonDefault,
+    this.velocity: _kEpsilonDefault
+  });
+
+  static const double _kEpsilonDefault = 1e-3;
+
+  /// A default tolerance of 0.001 for all three values.
+  static const Tolerance defaultTolerance = const Tolerance();
+
+  /// The magnitude of the maximum distance between two points for them to be
+  /// considered within tolerance.
+  ///
+  /// The units for the distance tolerance must be the same as the units used
+  /// for the distances that are to be compared to this tolerance.
   final double distance;
+
+  /// The magnitude of the maximum duration between two times for them to be
+  /// considered within tolerance.
+  ///
+  /// The units for the time tolerance must be the same as the units used
+  /// for the times that are to be compared to this tolerance.
   final double time;
+
+  /// The magnitude of the maximum difference between two velocities for them to
+  /// be considered within tolerance.
+  ///
+  /// The units for the velocity tolerance must be the same as the units used
+  /// for the velocities that are to be compared to this tolerance.
   final double velocity;
 
-  const Tolerance({this.distance: epsilonDefault, this.time: epsilonDefault,
-      this.velocity: epsilonDefault});
-
   @override
-  String toString() => 'Tolerance(distance: $distance, time=$time, velocity: $velocity)';
+  String toString() => 'Tolerance(distance: ±$distance, time: ±$time, velocity: ±$velocity)';
 }
-
-const double epsilonDefault = 1e-3;
-const Tolerance toleranceDefault = const Tolerance();
diff --git a/packages/newton/lib/src/utils.dart b/packages/newton/lib/src/utils.dart
index b66bb46..26d8148 100644
--- a/packages/newton/lib/src/utils.dart
+++ b/packages/newton/lib/src/utils.dart
@@ -2,9 +2,15 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+/// Whether two doubles are within a given distance of each other.
+///
+/// The epsilon argument must be positive.
 bool nearEqual(double a, double b, double epsilon) {
   assert(epsilon >= 0.0);
   return (a > (b - epsilon)) && (a < (b + epsilon));
 }
 
+/// Whether a double is within a given distance of zero.
+///
+/// The epsilon argument must be positive.
 bool nearZero(double a, double epsilon) => nearEqual(a, 0.0, epsilon);
diff --git a/packages/newton/test/all.dart b/packages/newton/test/all.dart
index 34f4260..84523ac 100644
--- a/packages/newton/test/all.dart
+++ b/packages/newton/test/all.dart
@@ -2,8 +2,10 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+import 'near_equal_test.dart' as near_equal_test;
 import 'newton_test.dart' as newton_test;
 
 void main() {
+  near_equal_test.main();
   newton_test.main();
 }
diff --git a/packages/newton/test/near_equal_test.dart b/packages/newton/test/near_equal_test.dart
new file mode 100644
index 0000000..f584280
--- /dev/null
+++ b/packages/newton/test/near_equal_test.dart
@@ -0,0 +1,16 @@
+// Copyright (c) 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+import 'package:test/test.dart';
+
+import 'package:newton/newton.dart';
+
+void main() {
+  test('test_friction', () {
+    expect(nearEqual(5.0, 6.0, 2.0), isTrue);
+    expect(nearEqual(6.0, 5.0, 2.0), isTrue);
+    expect(nearEqual(5.0, 6.0, 0.5), isFalse);
+    expect(nearEqual(6.0, 5.0, 0.5), isFalse);
+  });
+}
diff --git a/packages/newton/test/newton_test.dart b/packages/newton/test/newton_test.dart
index cacc584..75d3ba0 100644
--- a/packages/newton/test/newton_test.dart
+++ b/packages/newton/test/newton_test.dart
@@ -2,8 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-library simple_physics.test;
-
 import 'package:test/test.dart';
 
 import 'package:newton/newton.dart';