anchor.diff:    }
   }
   
  -Widget makeCell(Widget widget) {
  +Widget buildCell(Widget child) {
     return new Container(
       padding: new EdgeDims.all(1.0),
       height: 27.0, width: 27.0,
       decoration: new BoxDecoration(backgroundColor: const Color(0xFFC0C0C0)),
       margin: new EdgeDims.all(2.0),
  -    child: widget);
  -}
  -
  -Widget makeInnerCell(Widget widget) {
  +    child: child
  +  );
  +}
  +
  +Widget buildInnerCell(Widget child) {
     return new Container(
       padding: new EdgeDims.all(1.0),
       margin: new EdgeDims.all(3.0),
       height: 17.0, width: 17.0,
  -    child: widget);
  +    child: child
  +  );
   }
   
   class CoveredMineNode extends Component {
  -  final Game game;
  +
  +  CoveredMineNode({ this.flagged, this.posX, this.posY });
  +
     final bool flagged;
     final int posX;
     final int posY;
  -  Stopwatch stopwatch;
  -
  -  CoveredMineNode(this.game, {this.flagged, this.posX, this.posY});
  -
  -  void _handlePointerDown(sky.PointerEvent event) {
  -    if (event.buttons == 1) {
  -      game.probe(posX, posY);
  -    } else if (event.buttons == 2) {
  -      game.flag(posX, posY);
  -    } else {
  -      // Touch event.
  -      stopwatch = new Stopwatch()..start();
  -    }
  -  }
  -
  -  void _handlePointerUp(sky.PointerEvent event) {
  -    if (stopwatch == null)
  -      return;
  -    // Pointer down was a touch event.
  -    if (stopwatch.elapsedMilliseconds < 250) {
  -      game.probe(posX, posY);
  -    } else {
  -      // Long press flags.
  -      game.flag(posX, posY);
  -    }
  -    stopwatch = null;
  -  }
   
     Widget build() {
  -    Widget text = flagged ?
  -      makeInnerCell(new StyledText(elements : [Game.textStyles[5], '\u2691'])) :
  -      null;
  +    Widget text;
  +    if (flagged)
  +      text = buildInnerCell(new StyledText(elements : [textStyles[5], '\u2691']));
   
       Container inner = new Container(
         margin: new EdgeDims.all(2.0),
         height: 17.0, width: 17.0,
         decoration: new BoxDecoration(backgroundColor: const Color(0xFFD9D9D9)),
  -      child: text);
  -
  -    return makeCell(new Listener(
  -      child: inner,
  -      onPointerDown: _handlePointerDown,
  -      onPointerUp: _handlePointerUp));
  +      child: text
  +    );
  +
  +    return buildCell(inner);
     }
   }
   
   class ExposedMineNode extends Component {
  -  final int state;
  +
  +  ExposedMineNode({ this.state, this.count });
  +
  +  final CellState state;
     final int count;
  -
  -  ExposedMineNode({this.state, this.count});
   
     Widget build() {
       StyledText text;
  -    if (state == Game.clearedCell) {
  +    if (state == CellState.cleared) {
         // Uncovered cell with nearby mine count.
         if (count != 0)
  -        text = new StyledText(elements : [Game.textStyles[count], '$count']);
  +        text = new StyledText(elements : [textStyles[count], '$count']);
       } else {
         // Exploded mine or shown mine for 'game over'.
  -      int color = state == Game.explodedCell ? 3 : 0;
  -      text = new StyledText(elements : [Game.textStyles[color], '\u2600']);
  -    }
  -
  -    return makeCell(makeInnerCell(text));
  -  }
  -}
  -
  -class MineDiggerApp extends App {
  -  Game game;
  -
  -  MineDiggerApp() {
  -    game = new Game(this);
  -  }
  -
  -  Widget build() {
  -    return game.buildUI();
  -  }
  +      int color = state == CellState.exploded ? 3 : 0;
  +      text = new StyledText(elements : [textStyles[color], '\u2600']);
  +    }
  +    return buildCell(buildInnerCell(text));
  +  }
  +
   }
   
   void main() {
  
positive.code: import 'package:sky/rendering/flex.dart';
  import 'package:sky/theme/colors.dart' as colors;
  import 'package:sky/widgets/basic.dart';
  import 'package:sky/widgets/scaffold.dart';
  import 'package:sky/widgets/task_description.dart';
  import 'package:sky/widgets/theme.dart';
  import 'package:sky/widgets/tool_bar.dart';
  
  // Classic minesweeper-inspired game. The mouse controls are standard except
  // for left + right combo which is not implemented. For touch, the duration of
  // the pointer determines probing versus flagging.
  //
  // There are only 3 classes to understand. Game, which is contains all the
  // logic and two UI classes: CoveredMineNode and ExposedMineNode, none of them
  // holding state.
  
  class Game {
    static const int rows = 9;
    static const int cols = 9;
    static const int totalMineCount = 11;
  
    static const int coveredCell = 0;
    static const int explodedCell = 1;
    static const int clearedCell = 2;
    static const int flaggedCell = 3;
    static const int shownCell = 4;
  
    static final List<TextStyle> textStyles = new List<TextStyle>();
  
    final App app;
  
    bool alive;
    bool hasWon;
    int detectedCount;
    int randomSeed;
  
    // |cells| keeps track of the positions of the mines.
    List<List<bool>> cells;
    // |uiState| keeps track of the visible player progess.
    List<List<int>> uiState;
  
    Game(this.app) {
      randomSeed = 22;
      // Colors for each mine count:
      // 0 - none, 1 - blue, 2-green, 3-red, 4-black, 5-dark red .. etc.
      textStyles.add(
        new TextStyle(color: const Color(0xFF555555), fontWeight: bold));
      textStyles.add(
        new TextStyle(color: const Color(0xFF0094FF), fontWeight: bold));
      textStyles.add(
        new TextStyle(color: const Color(0xFF13A023), fontWeight: bold));
      textStyles.add(
        new TextStyle(color: const Color(0xFFDA1414), fontWeight: bold));
      textStyles.add(
        new TextStyle(color: const Color(0xFF1E2347), fontWeight: bold));
      textStyles.add(
        new TextStyle(color: const Color(0xFF7F0037), fontWeight: bold));
      textStyles.add(
        new TextStyle(color: const Color(0xFFE93BE9), fontWeight: bold));
      initialize();
    }
  
    void initialize() {
      alive = true;
      hasWon = false;
      detectedCount = 0;
      // Build the arrays.
      cells = new List<List<bool>>();
      uiState = new List<List<int>>();
      for (int iy = 0; iy != rows; iy++) {
        cells.add(new List<bool>());
        uiState.add(new List<int>());
        for (int ix = 0; ix != cols; ix++) {
          cells[iy].add(false);
          uiState[iy].add(coveredCell);
        }
      }
      // Place the mines.
      Random random = new Random(++randomSeed);
      for (int mc = 0; mc != totalMineCount; mc++) {
        int rx = random.nextInt(rows);
        int ry = random.nextInt(cols);
        if (cells[ry][rx]) {
          // Mine already there. Try again.
          --mc;
        } else {
          cells[ry][rx] = true;
        }
      }
    }
  
    Widget buildBoard() {
      bool hasCoveredCell = false;
      List<Flex> flexRows = new List<Flex>();
      for (int iy = 0; iy != 9; iy++) {
        List<Component> row = new List<Component>();
        for (int ix = 0; ix != 9; ix++) {
          int state = uiState[iy][ix];
          int count = mineCount(ix, iy);
  
          if (!alive) {
            if (state != explodedCell)
              state = cells[iy][ix] ? shownCell : state;
          }
  
          if (state == coveredCell) {
            row.add(new CoveredMineNode(
              this,
              flagged: false,
              posX: ix, posY: iy));
              // Mutating |hasCoveredCell| here is hacky, but convenient, same
              // goes for mutating |hasWon| below.
              hasCoveredCell = true;
          } else if (state == flaggedCell) {
            row.add(new CoveredMineNode(
              this,
              flagged: true,
              posX: ix, posY: iy));
          } else {
            row.add(new ExposedMineNode(
              state: state,
              count: count));
          }
        }
        flexRows.add(
  
negative.code:     }
  
      return new Container(
        padding: new EdgeDims.all(10.0),
        margin: new EdgeDims.all(10.0),
        decoration: new BoxDecoration(backgroundColor: const Color(0xFF6B6B6B)),
        child: new Flex(
          flexRows,
          direction: FlexDirection.vertical
        )
      );
    }
  
    Widget buildToolBar() {
      String toolbarCaption = hasWon ?
        'Awesome!!' : alive ?
          'Mine Digger [$detectedCount-$totalMineCount]': 'Kaboom! [press here]';
  
      return new ToolBar(
        // FIXME: Strange to have the toolbar be tapable.
        center: new Listener(
          onPointerDown: handleToolbarPointerDown,
          child: new Text(toolbarCaption, style: Theme.of(this).text.title)
        )
      );
    }
  
    Widget build() {
      // We build the board before we build the toolbar because we compute the win state during build step.
      Widget board = buildBoard();
      return new TaskDescription(
        label: 'Mine Digger',
  