Implement row.dart and some other minor utility methods
diff --git a/lib/cassowary.dart b/lib/cassowary.dart
index c3cea2d..1666b0d 100644
--- a/lib/cassowary.dart
+++ b/lib/cassowary.dart
@@ -12,3 +12,5 @@
 part 'constant_member.dart';
 part 'solver.dart';
 part 'symbol.dart';
+part 'row.dart';
+part 'utils.dart';
diff --git a/lib/row.dart b/lib/row.dart
new file mode 100644
index 0000000..8fb6156
--- /dev/null
+++ b/lib/row.dart
@@ -0,0 +1,62 @@
+// 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.
+
+part of cassowary;
+
+class Row {
+  final Map<Symbol, double> _cells = new Map<Symbol, double>();
+  double _constant = 0.0;
+
+  double get constant => _constant;
+  Map<Symbol, double> get cells => _cells;
+
+  double add(double value) => _constant += value;
+
+  void insertSymbol(Symbol symbol, [double coefficient = 1.0]) {
+    double val = _elvis(_cells[symbol], 0.0) + coefficient;
+
+    if (_nearZero(val)) {
+      _cells.remove(symbol);
+    } else {
+      _cells[symbol] = val + coefficient;
+    }
+  }
+
+  void insertRow(Row other, [double coefficient = 1.0]) {
+    _constant += other.constant * coefficient;
+    other.cells.forEach((s, v) => insertSymbol(s, v * coefficient));
+  }
+
+  void removeSymbol(Symbol symbol) {
+    _cells.remove(symbol);
+  }
+
+  void reverseSign() => _cells.forEach((s, v) => _cells[s] = -v);
+
+  void solveForSymbol(Symbol symbol) {
+    assert(_cells.containsKey(symbol));
+    double coefficient = -1.0 / _cells[symbol];
+    _cells.remove(symbol);
+    _constant *= coefficient;
+    _cells.forEach((s, v) => _cells[s] = v * coefficient);
+  }
+
+  void solveForSymbols(Symbol lhs, Symbol rhs) {
+    insertSymbol(lhs, -1.0);
+    solveForSymbol(rhs);
+  }
+
+  double coefficientForSymbol(Symbol symbol) => _elvis(_cells[symbol], 0.0);
+
+  void substitute(Symbol symbol, Row row) {
+    double coefficient = _cells[symbol];
+
+    if (coefficient == null) {
+      return;
+    }
+
+    _cells.remove(symbol);
+    insertRow(row, coefficient);
+  }
+}
diff --git a/lib/solver.dart b/lib/solver.dart
index b2a9f34..3d9c91a 100644
--- a/lib/solver.dart
+++ b/lib/solver.dart
@@ -5,6 +5,14 @@
 part of cassowary;
 
 class Solver {
+  final Map<Constraint, Tag> _constraints = new Map<Constraint, Tag>();
+  final Map<Symbol, Row> _rows = new Map<Symbol, Row>();
+  final Map<Variable, Symbol> _vars = new Map<Variable, Symbol>();
+  final Map<Variable, EditInfo> _edits = new Map<Variable, EditInfo>();
+  final List<Symbol> _infeasibleRows = new List<Symbol>();
+  final Row _objective = new Row();
+  final Row _artificial = new Row();
+
   bool addConstraint(Constraint c) {
     return false;
   }
@@ -37,3 +45,16 @@
 
   Solver operator <<(Constraint c) => this..addConstraint(c);
 }
+
+class Tag {
+  Symbol marker;
+  Symbol other;
+
+  Tag(this.marker, this.other);
+}
+
+class EditInfo {
+  Tag tag;
+  Constraint constraint;
+  double constant;
+}
diff --git a/lib/utils.dart b/lib/utils.dart
new file mode 100644
index 0000000..b003269
--- /dev/null
+++ b/lib/utils.dart
@@ -0,0 +1,15 @@
+// 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.
+
+part of cassowary;
+
+bool _nearZero(double value) {
+  const double epsilon = 1.0e-8;
+  return value < 0.0 ? -value < epsilon : value < epsilon;
+}
+
+// Workaround for the lack of a null coalescing operator. Uses a ternary
+// instead. Sadly, due the lack of generic types on functions, we have to use
+// dynamic instead.
+_elvis(a, b) => a != null ? a : b;