Remove Dart packages which have moved to flutter.dart
diff --git a/examples/BUILD.gn b/examples/BUILD.gn
deleted file mode 100644
index 01a2d5f..0000000
--- a/examples/BUILD.gn
+++ /dev/null
@@ -1,14 +0,0 @@
-# Copyright 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.
-
-group("examples") {
-  testonly = true
-
-  deps = [
-    "//examples/fitness",
-    "//examples/game",
-    "//examples/mine_digger",
-    "//examples/stocks",
-  ]
-}
diff --git a/examples/README.md b/examples/README.md
deleted file mode 100644
index 2078c3a..0000000
--- a/examples/README.md
+++ /dev/null
@@ -1,23 +0,0 @@
-Flutter Examples
-================
-
-This directory contains several examples of using Flutter.  Each of these is an
-individual Dart application package.
-
-To run a sample with the `flutter` tool, run `pub get` inside its directory,
-then run `flutter start`. (See the
-[getting started guide](https://flutter.github.io/getting-started/) to install
-the `flutter` tool.)
-
-Available examples include:
-
-- *Hello, world.* The [hello world app](hello_world) is a basic app that shows
-   the text "hello, world."
-
-- *Stocks.* The [stocks app](stocks) is an example of a typical mobile app
-   built using Flutter. The app shows a list of all the stocks in the NASDAQ.
-
-- *Widgets.* The [widget apps](widgets) demonstrate a number of Flutter widgets
-   so you can experiment with them in a simple container. There is no main.dart
-   in this directory because each file is a standalone sample. To run a
-   particular file, use `flutter start -t filename.dart`.
diff --git a/examples/address_book/lib/main.dart b/examples/address_book/lib/main.dart
deleted file mode 100644
index e1066a1..0000000
--- a/examples/address_book/lib/main.dart
+++ /dev/null
@@ -1,98 +0,0 @@
-// Copyright 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:flutter/material.dart';
-
-class Field extends StatelessComponent {
-  Field({
-    Key key,
-    this.inputKey,
-    this.icon,
-    this.placeholder
-  }) : super(key: key);
-
-  final GlobalKey inputKey;
-  final String icon;
-  final String placeholder;
-
-  Widget build(BuildContext context) {
-    return new Row(<Widget>[
-        new Padding(
-          padding: const EdgeDims.symmetric(horizontal: 16.0),
-          child: new Icon(icon: icon)
-        ),
-        new Flexible(
-          child: new Input(
-            key: inputKey,
-            placeholder: placeholder
-          )
-        )
-      ]
-    );
-  }
-}
-
-class AddressBookHome extends StatelessComponent {
-  Widget buildToolBar(BuildContext context) {
-    return new ToolBar(
-        left: new IconButton(icon: "navigation/arrow_back"),
-        right: <Widget>[new IconButton(icon: "navigation/check")]
-      );
-  }
-
-  Widget buildFloatingActionButton(BuildContext context) {
-    return new FloatingActionButton(
-      child: new Icon(icon: 'image/photo_camera'),
-      backgroundColor: Theme.of(context).accentColor
-    );
-  }
-
-  static final GlobalKey nameKey = new GlobalKey(label: 'name field');
-  static final GlobalKey phoneKey = new GlobalKey(label: 'phone field');
-  static final GlobalKey emailKey = new GlobalKey(label: 'email field');
-  static final GlobalKey addressKey = new GlobalKey(label: 'address field');
-  static final GlobalKey ringtoneKey = new GlobalKey(label: 'ringtone field');
-  static final GlobalKey noteKey = new GlobalKey(label: 'note field');
-
-  Widget buildBody(BuildContext context) {
-    return new Block(<Widget>[
-      new AspectRatio(
-        aspectRatio: 16.0 / 9.0,
-        child: new Container(
-          decoration: new BoxDecoration(backgroundColor: Colors.purple[300])
-        )
-      ),
-      new Field(inputKey: nameKey, icon: "social/person", placeholder: "Name"),
-      new Field(inputKey: phoneKey, icon: "communication/phone", placeholder: "Phone"),
-      new Field(inputKey: emailKey, icon: "communication/email", placeholder: "Email"),
-      new Field(inputKey: addressKey, icon: "maps/place", placeholder: "Address"),
-      new Field(inputKey: ringtoneKey, icon: "av/volume_up", placeholder: "Ringtone"),
-      new Field(inputKey: noteKey, icon: "content/add", placeholder: "Add note"),
-    ]);
-  }
-
-  Widget build(BuildContext context) {
-    return new Scaffold(
-      toolBar: buildToolBar(context),
-      body: buildBody(context),
-      floatingActionButton: buildFloatingActionButton(context)
-    );
-  }
-}
-
-final ThemeData theme = new ThemeData(
-  brightness: ThemeBrightness.light,
-  primarySwatch: Colors.teal,
-  accentColor: Colors.pinkAccent[100]
-);
-
-void main() {
-  runApp(new MaterialApp(
-    title: 'Address Book',
-    theme: theme,
-    routes: <String, RouteBuilder>{
-      '/': (RouteArguments args) => new AddressBookHome()
-    }
-  ));
-}
diff --git a/examples/address_book/pubspec.yaml b/examples/address_book/pubspec.yaml
deleted file mode 100644
index 46f0b6d..0000000
--- a/examples/address_book/pubspec.yaml
+++ /dev/null
@@ -1,10 +0,0 @@
-name: address_book
-dependencies:
-  flutter: 
-    '0.0.16'
-  sky_tools: any
-dependency_overrides:
-  material_design_icons:
-    path: ../../sky/packages/material_design_icons
-  flutter:
-    path: ../../sky/packages/sky
diff --git a/examples/fitness/BUILD.gn b/examples/fitness/BUILD.gn
deleted file mode 100644
index c24ac93..0000000
--- a/examples/fitness/BUILD.gn
+++ /dev/null
@@ -1,21 +0,0 @@
-# Copyright 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("//sky/build/sky_app.gni")
-
-sky_app("fitness") {
-  main_dart = "lib/main.dart"
-  manifest = "flutter.yaml"
-
-  if (is_android) {
-    apk_name = "Fitness"
-
-    deps = [
-      "//examples/fitness/apk:resources",
-    ]
-  } else if (is_mac) {
-    info_plist = "mac/Info.plist"
-    xibs = [ "mac/sky_mac.xib" ]
-  }
-}
diff --git a/examples/fitness/apk/AndroidManifest.xml b/examples/fitness/apk/AndroidManifest.xml
deleted file mode 100644
index 83967b2..0000000
--- a/examples/fitness/apk/AndroidManifest.xml
+++ /dev/null
@@ -1,23 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright 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.
- -->
-<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="org.domokit.fitness" android:versionCode="4" android:versionName="0.0.4">
-
-    <uses-sdk android:minSdkVersion="14" android:targetSdkVersion="21" />
-    <uses-permission android:name="android.permission.INTERNET" />
-
-    <application android:icon="@mipmap/ic_launcher" android:label="Fitness" android:name="org.domokit.sky.shell.SkyApplication">
-        <activity android:configChanges="orientation|keyboardHidden|keyboard|screenSize" android:hardwareAccelerated="true" android:launchMode="singleTask" android:name="org.domokit.sky.shell.SkyActivity" android:theme="@android:style/Theme.Black.NoTitleBar">
-            <intent-filter>
-                <action android:name="android.intent.action.MAIN" />
-                <category android:name="android.intent.category.LAUNCHER" />
-            </intent-filter>
-        </activity>
-        <service
-            android:name="org.domokit.sky.shell.UpdateService"
-            android:exported="false"
-            android:process=":remote"/>
-    </application>
- </manifest>
diff --git a/examples/fitness/apk/BUILD.gn b/examples/fitness/apk/BUILD.gn
deleted file mode 100644
index dd7817d..0000000
--- a/examples/fitness/apk/BUILD.gn
+++ /dev/null
@@ -1,14 +0,0 @@
-# Copyright 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.
-
-assert(is_android)
-
-import("//build/config/android/config.gni")
-import("//build/config/android/rules.gni")
-
-
-android_resources("resources") {
-  resource_dirs = [ "res" ]
-  android_manifest = "AndroidManifest.xml"
-}
diff --git a/examples/fitness/apk/README.md b/examples/fitness/apk/README.md
deleted file mode 100644
index f2443e9..0000000
--- a/examples/fitness/apk/README.md
+++ /dev/null
@@ -1,10 +0,0 @@
-Icon image comes from:
-https://openclipart.org/detail/22309/apple-icon
-and is public domain.
-
-Icon resources were generated using:
-http://romannurik.github.io/AndroidAssetStudio/icons-launcher.html
-with settings:
-http://romannurik.github.io/AndroidAssetStudio/icons-launcher.html#foreground.type=image&foreground.space.trim=1&foreground.space.pad=0&foreColor=607d8b%2C0&crop=0&backgroundShape=none&backColor=ffffff%2C100&effects=none
-which produces art under CC 3.0:
-http://creativecommons.org/licenses/by/3.0/
diff --git a/examples/fitness/apk/release_notes/0.0.2.txt b/examples/fitness/apk/release_notes/0.0.2.txt
deleted file mode 100644
index fc4b001..0000000
--- a/examples/fitness/apk/release_notes/0.0.2.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-Still barely works
-Fixed crash when entering an invalid number
-Made date list look less-awful.
diff --git a/examples/fitness/apk/release_notes/0.0.3.txt b/examples/fitness/apk/release_notes/0.0.3.txt
deleted file mode 100644
index 5934f86..0000000
--- a/examples/fitness/apk/release_notes/0.0.3.txt
+++ /dev/null
@@ -1 +0,0 @@
-Adds very basic charting support
diff --git a/examples/fitness/apk/release_notes/0.0.4.txt b/examples/fitness/apk/release_notes/0.0.4.txt
deleted file mode 100644
index 5e8ff76..0000000
--- a/examples/fitness/apk/release_notes/0.0.4.txt
+++ /dev/null
@@ -1 +0,0 @@
-Now supports setting goal weight.
diff --git a/examples/fitness/apk/res/mipmap-hdpi/ic_launcher.png b/examples/fitness/apk/res/mipmap-hdpi/ic_launcher.png
deleted file mode 100644
index bf78cc1..0000000
--- a/examples/fitness/apk/res/mipmap-hdpi/ic_launcher.png
+++ /dev/null
Binary files differ
diff --git a/examples/fitness/apk/res/mipmap-mdpi/ic_launcher.png b/examples/fitness/apk/res/mipmap-mdpi/ic_launcher.png
deleted file mode 100644
index 8d4fed6..0000000
--- a/examples/fitness/apk/res/mipmap-mdpi/ic_launcher.png
+++ /dev/null
Binary files differ
diff --git a/examples/fitness/apk/res/mipmap-xhdpi/ic_launcher.png b/examples/fitness/apk/res/mipmap-xhdpi/ic_launcher.png
deleted file mode 100644
index 3771235..0000000
--- a/examples/fitness/apk/res/mipmap-xhdpi/ic_launcher.png
+++ /dev/null
Binary files differ
diff --git a/examples/fitness/apk/res/mipmap-xxhdpi/ic_launcher.png b/examples/fitness/apk/res/mipmap-xxhdpi/ic_launcher.png
deleted file mode 100644
index 509d51d..0000000
--- a/examples/fitness/apk/res/mipmap-xxhdpi/ic_launcher.png
+++ /dev/null
Binary files differ
diff --git a/examples/fitness/apk/res/mipmap-xxxhdpi/ic_launcher.png b/examples/fitness/apk/res/mipmap-xxxhdpi/ic_launcher.png
deleted file mode 100644
index 2c7aff7..0000000
--- a/examples/fitness/apk/res/mipmap-xxxhdpi/ic_launcher.png
+++ /dev/null
Binary files differ
diff --git a/examples/fitness/flutter.yaml b/examples/fitness/flutter.yaml
deleted file mode 100644
index 942a5de..0000000
--- a/examples/fitness/flutter.yaml
+++ /dev/null
@@ -1,15 +0,0 @@
-name: fitness
-version: 0.0.1
-update-url: http://localhost:9888/
-material-design-icons:
-  - name: action/assessment
-  - name: action/help
-  - name: action/settings
-  - name: action/view_list
-  - name: av/stop
-  - name: content/add
-  - name: maps/directions_run
-  - name: navigation/arrow_back
-  - name: navigation/close
-  - name: navigation/menu
-  - name: navigation/more_vert
diff --git a/examples/fitness/ios/Info.plist b/examples/fitness/ios/Info.plist
deleted file mode 100644
index 1afd934..0000000
--- a/examples/fitness/ios/Info.plist
+++ /dev/null
@@ -1,58 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
-<plist version="1.0">
-<dict>
-  <key>CFBundleDevelopmentRegion</key>
-  <string>en</string>
-
-  <!--
-    This executable name must match the name of the app provided to the
-    ios_app GN template
-  -->
-  <key>CFBundleExecutable</key>
-  <string>fitness_app</string>
-
-  <key>CFBundleDisplayName</key>
-  <string>Fitness</string>
-
-  <key>UILaunchStoryboardName</key>
-  <string>LaunchScreen</string>
-
-  <key>CFBundleIdentifier</key>
-  <string>com.google.SkyFitness</string>
-  
-  <key>CFBundleInfoDictionaryVersion</key>
-  <string>6.0</string>
-  <key>CFBundleName</key>
-  <string>game_app</string>
-  <key>CFBundlePackageType</key>
-  <string>APPL</string>
-  <key>CFBundleShortVersionString</key>
-  <string>1.0</string>
-  <key>CFBundleVersion</key>
-  <string>1</string>
-  <key>LSRequiresIPhoneOS</key>
-  <true/>
-  <key>UIRequiredDeviceCapabilities</key>
-  <array>
-    <string>armv7</string>
-  </array>
-  <key>DTPlatformName</key>
-  <string>iphonesimulator</string>
-  <key>DTSDKName</key>
-  <string>iphonesimulator8.3</string>
-  <key>LSRequiresIPhoneOS</key>
-  <true/>
-  <key>MinimumOSVersion</key>
-  <string>7.0</string>
-  <key>UIDeviceFamily</key>
-  <array>
-    <integer>1</integer>
-    <integer>2</integer>
-  </array>
-  <key>CFBundleSupportedPlatforms</key>
-  <array>
-    <string>iPhoneSimulator</string>
-  </array>
-</dict>
-</plist>
diff --git a/examples/fitness/ios/LaunchScreen.storyboardc/01J-lp-oVM-view-Ze5-6b-2t3.nib b/examples/fitness/ios/LaunchScreen.storyboardc/01J-lp-oVM-view-Ze5-6b-2t3.nib
deleted file mode 100644
index 1aa489d..0000000
--- a/examples/fitness/ios/LaunchScreen.storyboardc/01J-lp-oVM-view-Ze5-6b-2t3.nib
+++ /dev/null
Binary files differ
diff --git a/examples/fitness/ios/LaunchScreen.storyboardc/Info.plist b/examples/fitness/ios/LaunchScreen.storyboardc/Info.plist
deleted file mode 100644
index 32288e8..0000000
--- a/examples/fitness/ios/LaunchScreen.storyboardc/Info.plist
+++ /dev/null
Binary files differ
diff --git a/examples/fitness/ios/LaunchScreen.storyboardc/UIViewController-01J-lp-oVM.nib b/examples/fitness/ios/LaunchScreen.storyboardc/UIViewController-01J-lp-oVM.nib
deleted file mode 100644
index 8de9bed..0000000
--- a/examples/fitness/ios/LaunchScreen.storyboardc/UIViewController-01J-lp-oVM.nib
+++ /dev/null
Binary files differ
diff --git a/examples/fitness/lib/date_utils.dart b/examples/fitness/lib/date_utils.dart
deleted file mode 100644
index ccaaf5d..0000000
--- a/examples/fitness/lib/date_utils.dart
+++ /dev/null
@@ -1,87 +0,0 @@
-// Copyright 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.
-
-// Forked from https://github.com/dart-lang/sdk/blob/master/samples-dev/swarm/swarm_ui_lib/util/DateUtils.dart
-class DateUtils {
-
-  static const WEEKDAYS = const ['Monday', 'Tuesday', 'Wednesday', 'Thursday',
-                                 'Friday', 'Saturday', 'Sunday'];
-
-  static const YESTERDAY = 'Yesterday';
-
-  static const MS_IN_WEEK = DateTime.DAYS_PER_WEEK * Duration.MILLISECONDS_PER_DAY;
-
-  // TODO(jmesserly): locale specific date format
-  static String _twoDigits(int n) {
-    if (n >= 10)
-      return '$n';
-    return '0$n';
-  }
-
-  /// Formats a time in H:MM A format
-  static String toHourMinutesString(Duration duration) {
-    assert(duration.inDays == 0);
-    int hours = duration.inHours;
-    String a;
-    if (hours >= 12) {
-      a = 'pm';
-      if (hours != 12)
-        hours -= 12;
-    } else {
-      a = 'am';
-      if (hours == 0)
-        hours += 12;
-    }
-    String twoDigits(int n) {
-      if (n >= 10)
-        return '$n';
-      return '0$n';
-    }
-    String mm = twoDigits(duration.inMinutes.remainder(Duration.MINUTES_PER_HOUR));
-    return '$hours:$mm $a';
-  }
-
-  /// A date/time formatter that takes into account the current date/time:
-  ///  - if it's from today, just show the time
-  ///  - if it's from yesterday, just show 'Yesterday'
-  ///  - if it's from the same week, just show the weekday
-  ///  - otherwise, show just the date
-  static String toRecentTimeString(DateTime then) {
-    bool datesAreEqual(DateTime d1, DateTime d2) {
-      return (d1.year == d2.year) &&
-             (d1.month == d2.month) &&
-             (d1.day == d2.day);
-    }
-
-    final now = new DateTime.now();
-    if (datesAreEqual(then, now)) {
-      return toHourMinutesString(new Duration(
-        days: 0,
-        hours: then.hour,
-        minutes: then.minute,
-        seconds: then.second,
-        milliseconds: then.millisecond)
-      );
-    }
-
-    final today = new DateTime(now.year, now.month, now.day, 0, 0, 0, 0);
-    Duration delta = today.difference(then);
-    if (delta.inMilliseconds < Duration.MILLISECONDS_PER_DAY) {
-      return YESTERDAY;
-    } else if (delta.inMilliseconds < MS_IN_WEEK) {
-      return WEEKDAYS[then.weekday];
-    } else {
-      String twoDigitMonth = _twoDigits(then.month);
-      String twoDigitDay = _twoDigits(then.day);
-      return '${then.year}-$twoDigitMonth-$twoDigitDay';
-    }
-  }
-
-  static String toDateString(DateTime then) {
-    // TODO(jmesserly): locale specific date format
-    String twoDigitMonth = _twoDigits(then.month);
-    String twoDigitDay = _twoDigits(then.day);
-    return '${then.year}-$twoDigitMonth-$twoDigitDay';
-  }
-}
diff --git a/examples/fitness/lib/feed.dart b/examples/fitness/lib/feed.dart
deleted file mode 100644
index b17aa34..0000000
--- a/examples/fitness/lib/feed.dart
+++ /dev/null
@@ -1,267 +0,0 @@
-// Copyright 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 fitness;
-
-class FitnessItemList extends StatelessComponent {
-  FitnessItemList({ Key key, this.items, this.onDismissed }) : super(key: key) {
-    assert(items != null);
-    assert(onDismissed != null);
-  }
-
-  final List<FitnessItem> items;
-  final FitnessItemHandler onDismissed;
-
-  Widget build(BuildContext context) {
-    return new ScrollableList<FitnessItem>(
-      padding: const EdgeDims.all(4.0),
-      items: items,
-      itemExtent: kFitnessItemHeight,
-      itemBuilder: (BuildContext context, FitnessItem item) => item.toRow(onDismissed: onDismissed)
-    );
-  }
-}
-
-class DialogMenuItem extends StatelessComponent {
-  DialogMenuItem(this.children, { Key key, this.onPressed }) : super(key: key);
-
-  List<Widget> children;
-  Function onPressed;
-
-  Widget build(BuildContext context) {
-    return new Container(
-      height: 48.0,
-      child: new InkWell(
-        onTap: onPressed,
-        child: new Padding(
-          padding: const EdgeDims.symmetric(horizontal: 16.0),
-          child: new Row(children)
-        )
-      )
-    );
-  }
-}
-
-class FeedFragment extends StatefulComponent {
-  FeedFragment({ this.userData, this.onItemCreated, this.onItemDeleted });
-
-  final UserData userData;
-  final FitnessItemHandler onItemCreated;
-  final FitnessItemHandler onItemDeleted;
-
-  FeedFragmentState createState() => new FeedFragmentState();
-}
-
-class FeedFragmentState extends State<FeedFragment> {
-  final GlobalKey<PlaceholderState> _snackBarPlaceholderKey = new GlobalKey<PlaceholderState>();
-  FitnessMode _fitnessMode = FitnessMode.feed;
-
-  void _handleFitnessModeChange(FitnessMode value) {
-    setState(() {
-      _fitnessMode = value;
-    });
-    Navigator.of(context).pop();
-  }
-
-  void _showDrawer() {
-    showDrawer(
-      context: context,
-      child: new Block(<Widget>[
-        new DrawerHeader(child: new Text('Fitness')),
-        new DrawerItem(
-          icon: 'action/view_list',
-          onPressed: () => _handleFitnessModeChange(FitnessMode.feed),
-          selected: _fitnessMode == FitnessMode.feed,
-          child: new Text('Feed')),
-        new DrawerItem(
-          icon: 'action/assessment',
-          onPressed: () => _handleFitnessModeChange(FitnessMode.chart),
-          selected: _fitnessMode == FitnessMode.chart,
-          child: new Text('Chart')),
-        new DrawerDivider(),
-        new DrawerItem(
-          icon: 'action/settings',
-          onPressed: _handleShowSettings,
-          child: new Text('Settings')),
-        new DrawerItem(
-          icon: 'action/help',
-          child: new Text('Help & Feedback'))
-      ])
-    );
-  }
-
-  void _handleShowSettings() {
-    Navigator.of(context)..pop()
-                         ..pushNamed('/settings');
-  }
-
-  // TODO(jackson): We should be localizing
-  String get fitnessModeTitle {
-    switch(_fitnessMode) {
-      case FitnessMode.feed: return "Feed";
-      case FitnessMode.chart: return "Chart";
-    }
-  }
-
-  Widget buildToolBar() {
-    return new ToolBar(
-      left: new IconButton(
-        icon: "navigation/menu",
-        onPressed: _showDrawer),
-      center: new Text(fitnessModeTitle)
-    );
-  }
-
-  void _handleItemDismissed(FitnessItem item) {
-    config.onItemDeleted(item);
-    showSnackBar(
-      context: context,
-      placeholderKey: _snackBarPlaceholderKey,
-      content: new Text("Item deleted."),
-      actions: <SnackBarAction>[new SnackBarAction(label: "UNDO", onPressed: () {
-        config.onItemCreated(item);
-        Navigator.of(context).pop();
-      })]
-    );
-  }
-
-  Widget buildChart() {
-    double startX;
-    double endX;
-    double startY;
-    double endY;
-    List<Point> dataSet = new List<Point>();
-    for (FitnessItem item in config.userData.items) {
-      if (item is Measurement) {
-          double x = item.when.millisecondsSinceEpoch.toDouble();
-          double y = item.weight;
-          if (startX == null || startX > x)
-            startX = x;
-          if (endX == null || endX < x)
-          endX = x;
-          if (startY == null || startY > y)
-            startY = y;
-          if (endY == null || endY < y)
-            endY = y;
-          dataSet.add(new Point(x, y));
-      }
-    }
-    if (config.userData.goalWeight != null && config.userData.goalWeight > 0.0) {
-      startY = math.min(startY, config.userData.goalWeight);
-      endY = math.max(endY, config.userData.goalWeight);
-    }
-    playfair.ChartData data = new playfair.ChartData(
-      startX: startX,
-      startY: startY,
-      endX: endX,
-      endY: endY,
-      dataSet: dataSet,
-      numHorizontalGridlines: 5,
-      roundToPlaces: 1,
-      indicatorLine: config.userData.goalWeight,
-      indicatorText: "GOAL WEIGHT"
-    );
-    return new playfair.Chart(data: data);
-  }
-
-  Widget buildBody() {
-    TextStyle style = Theme.of(context).text.title;
-    if (config.userData == null)
-      return new Container();
-    if (config.userData.items.length == 0) {
-      return new Row(
-        <Widget>[new Text("No data yet.\nAdd some!", style: style)],
-        justifyContent: FlexJustifyContent.center
-      );
-    }
-    switch (_fitnessMode) {
-      case FitnessMode.feed:
-        return new FitnessItemList(
-          items: config.userData.items.reversed.toList(),
-          onDismissed: _handleItemDismissed
-        );
-      case FitnessMode.chart:
-        return new Container(
-          padding: const EdgeDims.all(20.0),
-          child: buildChart()
-        );
-    }
-  }
-
-  void _handleActionButtonPressed() {
-    showDialog(context: context, child: new AddItemDialog()).then((routeName) {
-      if (routeName != null)
-        Navigator.of(context).pushNamed(routeName);
-    });
-  }
-
-  Widget buildFloatingActionButton() {
-    switch (_fitnessMode) {
-      case FitnessMode.feed:
-        return new FloatingActionButton(
-          child: new Icon(icon: 'content/add'),
-          onPressed: _handleActionButtonPressed
-        );
-      case FitnessMode.chart:
-        return null;
-    }
-  }
-
-  Widget build(BuildContext context) {
-    return new Scaffold(
-      toolBar: buildToolBar(),
-      body: buildBody(),
-      snackBar: new Placeholder(key: _snackBarPlaceholderKey),
-      floatingActionButton: buildFloatingActionButton()
-    );
-  }
-}
-
-class AddItemDialog extends StatefulComponent {
-  AddItemDialogState createState() => new AddItemDialogState();
-}
-
-class AddItemDialogState extends State<AddItemDialog> {
-  // TODO(jackson): Internationalize
-  static final Map<String, String> _labels = <String, String>{
-    '/measurements/new': 'Measure',
-    '/meals/new': 'Eat',
-  };
-
-  String _addItemRoute = _labels.keys.first;
-
-  void _handleAddItemRouteChanged(String routeName) {
-    setState(() {
-        _addItemRoute = routeName;
-    });
-  }
-
-  Widget build(BuildContext context) {
-    List<Widget> menuItems = <Widget>[];
-    for (String routeName in _labels.keys) {
-      menuItems.add(new DialogMenuItem(<Widget>[
-        new Flexible(child: new Text(_labels[routeName])),
-        new Radio<String>(value: routeName, groupValue: _addItemRoute, onChanged: _handleAddItemRouteChanged),
-      ], onPressed: () => _handleAddItemRouteChanged(routeName)));
-    }
-    return new Dialog(
-      title: new Text("What are you doing?"),
-      content: new Block(menuItems),
-      actions: <Widget>[
-        new FlatButton(
-          child: new Text('CANCEL'),
-          onPressed: () {
-            Navigator.of(context).pop();
-          }
-        ),
-        new FlatButton(
-          child: new Text('ADD'),
-          onPressed: () {
-            Navigator.of(context).pop(_addItemRoute);
-          }
-        ),
-      ]
-    );
-  }
-}
diff --git a/examples/fitness/lib/fitness_item.dart b/examples/fitness/lib/fitness_item.dart
deleted file mode 100644
index 8b90af3..0000000
--- a/examples/fitness/lib/fitness_item.dart
+++ /dev/null
@@ -1,61 +0,0 @@
-// Copyright 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 fitness;
-
-typedef void FitnessItemHandler(FitnessItem item);
-
-// TODO(eseidel): This should be a constant on a SingleLineTile class
-// https://www.google.com/design/spec/components/lists.html#lists-specs
-const double kFitnessItemHeight = 48.0;
-
-abstract class FitnessItem {
-  FitnessItem.fromJson(Map json) : when = DateTime.parse(json['when']);
-
-  FitnessItem({ this.when }) {
-    assert(when != null);
-  }
-  final DateTime when;
-
-  Map toJson() => { 'when' : when.toIso8601String() };
-
-  // TODO(jackson): Internationalize
-  String get displayDate => DateUtils.toDateString(when);
-
-  FitnessItemRow toRow({ FitnessItemHandler onDismissed });
-}
-
-abstract class FitnessItemRow extends StatelessComponent {
-
-  FitnessItemRow({ FitnessItem item, this.onDismissed })
-   : this.item = item,
-     super(key: new ValueKey<DateTime>(item.when)) {
-    assert(onDismissed != null);
-  }
-
-  final FitnessItem item;
-  final FitnessItemHandler onDismissed;
-
-  Widget buildContent(BuildContext context);
-
-  Widget build(BuildContext context) {
-    return new Dismissable(
-      onDismissed: () => onDismissed(item),
-      child: new Container(
-        height: kFitnessItemHeight,
-        // TODO(eseidel): Padding top should be 16px for a single-line tile:
-        // https://www.google.com/design/spec/components/lists.html#lists-specs
-        padding: const EdgeDims.all(10.0),
-        // TODO(eseidel): This line should be drawn by the list as it should
-        // stay put even when the tile is dismissed!
-        decoration: new BoxDecoration(
-          border: new Border(
-            bottom: new BorderSide(color: Theme.of(context).dividerColor)
-          )
-        ),
-        child: buildContent(context)
-      )
-    );
-  }
-}
diff --git a/examples/fitness/lib/fitness_types.dart b/examples/fitness/lib/fitness_types.dart
deleted file mode 100644
index 42d6617..0000000
--- a/examples/fitness/lib/fitness_types.dart
+++ /dev/null
@@ -1,8 +0,0 @@
-// Copyright 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 fitness;
-
-enum FitnessMode { feed, chart }
-enum BackupMode { enabled, disabled }
diff --git a/examples/fitness/lib/main.dart b/examples/fitness/lib/main.dart
deleted file mode 100644
index a8feff0..0000000
--- a/examples/fitness/lib/main.dart
+++ /dev/null
@@ -1,166 +0,0 @@
-// Copyright 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.
-
-library fitness;
-
-import 'package:playfair/playfair.dart' as playfair;
-import 'package:flutter/material.dart';
-import 'package:flutter/painting.dart';
-
-import 'user_data.dart';
-import 'date_utils.dart';
-import 'dart:async';
-import 'dart:math' as math;
-
-part 'feed.dart';
-part 'fitness_item.dart';
-part 'fitness_types.dart';
-part 'meal.dart';
-part 'measurement.dart';
-part 'settings.dart';
-
-abstract class UserData {
-  BackupMode get backupMode;
-  double get goalWeight;
-  List<FitnessItem> get items;
-}
-
-class UserDataImpl extends UserData {
-  UserDataImpl();
-
-  List<FitnessItem> _items = <FitnessItem>[];
-
-  BackupMode _backupMode;
-  BackupMode get backupMode => _backupMode;
-  void set backupMode(BackupMode value) {
-    _backupMode = value;
-  }
-
-  double _goalWeight;
-  double get goalWeight => _goalWeight;
-  void set goalWeight(double value) {
-    _goalWeight = value;
-  }
-
-  List<FitnessItem> get items => _items;
-
-  void sort() {
-    _items.sort((FitnessItem a, FitnessItem b) => a.when.compareTo(b.when));
-  }
-
-  void add(FitnessItem item) {
-    _items.add(item);
-    sort();
-  }
-
-  void remove(FitnessItem item) {
-    _items.remove(item);
-  }
-
-  Future save() => saveFitnessData(this);
-
-  UserDataImpl.fromJson(Map json) {
-    json['items'].forEach((item) {
-      _items.add(new Measurement.fromJson(item));
-    });
-    try {
-      _backupMode = BackupMode.values.firstWhere((BackupMode mode) {
-        return mode.toString() == json['backupMode'];
-      });
-    } catch(e) {
-      print("Failed to load backup mode: $e");
-    }
-    _goalWeight = json['goalWeight'];
-  }
-
-  Map toJson() {
-    Map json = new Map();
-    json['items'] = _items.map((FitnessItem item) => item.toJson()).toList();
-    json['backupMode'] = _backupMode.toString();
-    json['goalWeight'] = _goalWeight;
-    return json;
-  }
-}
-
-class FitnessApp extends StatefulComponent {
-  FitnessAppState createState() => new FitnessAppState();
-}
-
-class FitnessAppState extends State<FitnessApp> {
-  UserDataImpl _userData;
-
-  void initState() {
-    super.initState();
-    loadFitnessData().then((UserData data) {
-      setState(() => _userData = data);
-    }).catchError((e) {
-      print("Failed to load data: $e");
-      setState(() => _userData = new UserDataImpl());
-    });
-  }
-
-  void _handleItemCreated(FitnessItem item) {
-    setState(() {
-      _userData.add(item);
-      _userData.save();
-    });
-  }
-
-  void _handleItemDeleted(FitnessItem item) {
-    setState(() {
-      _userData.remove(item);
-      _userData.save();
-    });
-  }
-
-  void settingsUpdater({ BackupMode backup, double goalWeight }) {
-    setState(() {
-      if (backup != null)
-        _userData.backupMode = backup;
-      if (goalWeight != null)
-        _userData.goalWeight = goalWeight;
-      _userData.save();
-    });
-  }
-
-  Widget build(BuildContext) {
-    return new MaterialApp(
-      theme: new ThemeData(
-        brightness: ThemeBrightness.light,
-        primarySwatch: Colors.indigo,
-        accentColor: Colors.pinkAccent[200]
-      ),
-      title: 'Fitness',
-      routes: <String, RouteBuilder>{
-        '/': (RouteArguments args) {
-          return new FeedFragment(
-            userData: _userData,
-            onItemCreated: _handleItemCreated,
-            onItemDeleted: _handleItemDeleted
-          );
-        },
-        '/meals/new': (RouteArguments args) {
-          return new MealFragment(
-            onCreated: _handleItemCreated
-          );
-        },
-        '/measurements/new': (RouteArguments args) {
-          return new MeasurementFragment(
-            onCreated: _handleItemCreated
-          );
-        },
-        '/settings': (RouteArguments args) {
-          return new SettingsFragment(
-            userData: _userData,
-            updater: settingsUpdater
-          );
-        }
-      }
-    );
-  }
-}
-
-void main() {
-  runApp(new FitnessApp());
-}
diff --git a/examples/fitness/lib/meal.dart b/examples/fitness/lib/meal.dart
deleted file mode 100644
index 945ea98..0000000
--- a/examples/fitness/lib/meal.dart
+++ /dev/null
@@ -1,105 +0,0 @@
-// Copyright 2014 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 fitness;
-
-class Meal extends FitnessItem {
-  Meal({ DateTime when, this.description }) : super(when: when);
-
-  final String description;
-
-  FitnessItemRow toRow({ FitnessItemHandler onDismissed }) {
-    return new MealRow(meal: this, onDismissed: onDismissed);
-  }
-}
-
-class MealRow extends FitnessItemRow {
-  MealRow({ Meal meal, FitnessItemHandler onDismissed })
-    : super(item: meal, onDismissed: onDismissed);
-
-  Widget buildContent(BuildContext context) {
-    Meal meal = item;
-    List<Widget> children = <Widget>[
-      new Flexible(
-        child: new Text(
-          meal.description,
-          style: const TextStyle(textAlign: TextAlign.right)
-        )
-      ),
-      new Flexible(
-        child: new Text(
-          meal.displayDate,
-          style: Theme.of(context).text.caption.copyWith(textAlign: TextAlign.right)
-        )
-      )
-    ];
-    return new Row(
-      children,
-      alignItems: FlexAlignItems.baseline,
-      textBaseline: DefaultTextStyle.of(context).textBaseline
-    );
-  }
-}
-
-class MealFragment extends StatefulComponent {
-  MealFragment({ this.onCreated });
-
-  FitnessItemHandler onCreated;
-
-  MealFragmentState createState() => new MealFragmentState();
-}
-
-class MealFragmentState extends State<MealFragment> {
-  String _description = "";
-
-  void _handleSave() {
-    config.onCreated(new Meal(when: new DateTime.now(), description: _description));
-    Navigator.of(context).pop();
-  }
-
-  Widget buildToolBar() {
-    return new ToolBar(
-      left: new IconButton(
-        icon: "navigation/close",
-        onPressed: Navigator.of(context).pop),
-      center: new Text('New Meal'),
-      right: <Widget>[
-        // TODO(abarth): Should this be a FlatButton?
-        new InkWell(
-          onTap: _handleSave,
-          child: new Text('SAVE')
-        )
-      ]
-    );
-  }
-
-  void _handleDescriptionChanged(String description) {
-    setState(() {
-      _description = description;
-    });
-  }
-
-  static final GlobalKey descriptionKey = new GlobalKey();
-
-  Widget buildBody() {
-    Meal meal = new Meal(when: new DateTime.now());
-    return new Block(<Widget>[
-        new Text(meal.displayDate),
-        new Input(
-          key: descriptionKey,
-          placeholder: 'Describe meal',
-          onChanged: _handleDescriptionChanged
-        ),
-      ],
-      padding: const EdgeDims.all(20.0)
-    );
-  }
-
-  Widget build(BuildContext context) {
-    return new Scaffold(
-      toolBar: buildToolBar(),
-      body: buildBody()
-    );
-  }
-}
diff --git a/examples/fitness/lib/measurement.dart b/examples/fitness/lib/measurement.dart
deleted file mode 100644
index 8429215..0000000
--- a/examples/fitness/lib/measurement.dart
+++ /dev/null
@@ -1,205 +0,0 @@
-// Copyright 2014 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 fitness;
-
-class Measurement extends FitnessItem {
-  Measurement({ DateTime when, this.weight }) : super(when: when);
-  Measurement.fromJson(Map json) : weight = json['weight'], super.fromJson(json);
-
-  final double weight;
-
-  // TODO(jackson): Internationalize
-  String get displayWeight => "${weight.toStringAsFixed(1)} lbs";
-
-  @override
-  Map toJson() {
-    Map json = super.toJson();
-    json['weight'] = weight;
-    json['type'] = runtimeType.toString();
-    return json;
-  }
-
-  FitnessItemRow toRow({ FitnessItemHandler onDismissed }) {
-    return new MeasurementRow(measurement: this, onDismissed: onDismissed);
-  }
-}
-
-class MeasurementRow extends FitnessItemRow {
-  MeasurementRow({ Measurement measurement, FitnessItemHandler onDismissed })
-    : super(item: measurement, onDismissed: onDismissed);
-
-  Widget buildContent(BuildContext context) {
-    Measurement measurement = item;
-    List<Widget> children = <Widget>[
-      new Flexible(
-        child: new Text(
-          measurement.displayWeight,
-          style: Theme.of(context).text.subhead
-        )
-      ),
-      new Flexible(
-        child: new Text(
-          measurement.displayDate,
-          style: Theme.of(context).text.caption.copyWith(textAlign: TextAlign.right)
-        )
-      )
-    ];
-    return new Row(
-      children,
-      alignItems: FlexAlignItems.baseline,
-      textBaseline: DefaultTextStyle.of(context).textBaseline
-    );
-  }
-}
-
-class MeasurementDateDialog extends StatefulComponent {
-  MeasurementDateDialog({ this.previousDate });
-
-  final DateTime previousDate;
-
-  MeasurementDateDialogState createState() => new MeasurementDateDialogState();
-}
-
-class MeasurementDateDialogState extends State<MeasurementDateDialog> {
-  @override
-  void initState() {
-    _selectedDate = config.previousDate;
-  }
-
-  DateTime _selectedDate;
-
-  void _handleDateChanged(DateTime value) {
-    setState(() {
-      _selectedDate = value;
-    });
-  }
-
-  Widget build(BuildContext context) {
-    return new Dialog(
-      content: new DatePicker(
-        selectedDate: _selectedDate,
-        firstDate: new DateTime(2015, 8),
-        lastDate: new DateTime(2101),
-        onChanged: _handleDateChanged
-      ),
-      contentPadding: EdgeDims.zero,
-      actions: <Widget>[
-        new FlatButton(
-          child: new Text('CANCEL'),
-          onPressed: () {
-            Navigator.of(context).pop();
-          }
-        ),
-        new FlatButton(
-          child: new Text('OK'),
-          onPressed: () {
-            Navigator.of(context).pop(_selectedDate);
-          }
-        ),
-      ]
-    );
-  }
-}
-
-class MeasurementFragment extends StatefulComponent {
-  MeasurementFragment({ this.onCreated });
-
-  final FitnessItemHandler onCreated;
-
-  MeasurementFragmentState createState() => new MeasurementFragmentState();
-}
-
-class MeasurementFragmentState extends State<MeasurementFragment> {
-  final GlobalKey<PlaceholderState> _snackBarPlaceholderKey = new GlobalKey<PlaceholderState>();
-
-  String _weight = "";
-  DateTime _when = new DateTime.now();
-
-  void _handleSave() {
-    double parsedWeight;
-    try {
-      parsedWeight = double.parse(_weight);
-    } on FormatException catch(e) {
-      print("Exception $e");
-      showSnackBar(
-        context: context,
-        placeholderKey: _snackBarPlaceholderKey,
-        content: new Text('Save failed')
-      );
-    }
-    config.onCreated(new Measurement(when: _when, weight: parsedWeight));
-    Navigator.of(context).pop();
-  }
-
-  Widget buildToolBar() {
-    return new ToolBar(
-      left: new IconButton(
-        icon: "navigation/close",
-        onPressed: Navigator.of(context).pop),
-      center: new Text('New Measurement'),
-      right: <Widget>[
-        // TODO(abarth): Should this be a FlatButton?
-        new InkWell(
-          onTap: _handleSave,
-          child: new Text('SAVE')
-        )
-      ]
-    );
-  }
-
-  void _handleWeightChanged(String weight) {
-    setState(() {
-      _weight = weight;
-    });
-  }
-
-  static final GlobalKey weightKey = new GlobalKey();
-
-  Future _handleDatePressed() async {
-    DateTime value = await showDialog(
-      context: context,
-      child: new MeasurementDateDialog(previousDate: _when)
-    );
-    if (value != null) {
-      setState(() {
-        _when = value;
-      });
-    }
-  }
-
-  Widget buildBody(BuildContext context) {
-    Measurement measurement = new Measurement(when: _when);
-    // TODO(jackson): Revisit the layout of this pane to be more maintainable
-    return new Container(
-      padding: const EdgeDims.all(20.0),
-      child: new Column(<Widget>[
-        new GestureDetector(
-          onTap: _handleDatePressed,
-          child: new Container(
-            height: 50.0,
-            child: new Column(<Widget>[
-              new Text('Measurement Date'),
-              new Text(measurement.displayDate, style: Theme.of(context).text.caption),
-            ], alignItems: FlexAlignItems.start)
-          )
-        ),
-        new Input(
-          key: weightKey,
-          placeholder: 'Enter weight',
-          keyboardType: KeyboardType.NUMBER,
-          onChanged: _handleWeightChanged
-        ),
-      ], alignItems: FlexAlignItems.stretch)
-    );
-  }
-
-  Widget build(BuildContext context) {
-    return new Scaffold(
-      toolBar: buildToolBar(),
-      body: buildBody(context),
-      snackBar: new Placeholder(key: _snackBarPlaceholderKey)
-    );
-  }
-}
diff --git a/examples/fitness/lib/settings.dart b/examples/fitness/lib/settings.dart
deleted file mode 100644
index 21404f9..0000000
--- a/examples/fitness/lib/settings.dart
+++ /dev/null
@@ -1,121 +0,0 @@
-// Copyright 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 fitness;
-
-typedef void SettingsUpdater({
-  BackupMode backup,
-  double goalWeight
-});
-
-class SettingsFragment extends StatefulComponent {
-  SettingsFragment({ this.userData, this.updater });
-
-  final UserData userData;
-  final SettingsUpdater updater;
-
-  SettingsFragmentState createState() => new SettingsFragmentState();
-}
-
-class SettingsFragmentState extends State<SettingsFragment> {
-  void _handleBackupChanged(bool value) {
-    assert(config.updater != null);
-    config.updater(backup: value ? BackupMode.enabled : BackupMode.disabled);
-  }
-
-  Widget buildToolBar() {
-    return new ToolBar(
-      left: new IconButton(
-        icon: "navigation/arrow_back",
-        onPressed: () => Navigator.of(context).pop()
-      ),
-      center: new Text('Settings')
-    );
-  }
-
-  String get goalWeightText {
-    if (config.userData.goalWeight == null || config.userData.goalWeight == 0.0)
-      return "None";
-    return "${config.userData.goalWeight}";
-  }
-
-  static final GlobalKey weightGoalKey = new GlobalKey();
-
-  double _goalWeight;
-
-  void _handleGoalWeightChanged(String goalWeight) {
-    // TODO(jackson): Looking for null characters to detect enter key is a hack
-    if (goalWeight.endsWith("\u{0}")) {
-      Navigator.of(context).pop(double.parse(goalWeight.replaceAll("\u{0}", "")));
-    } else {
-      setState(() {
-        try {
-          _goalWeight = double.parse(goalWeight);
-        } on FormatException {
-          _goalWeight = 0.0;
-        }
-      });
-    }
-  }
-
-  Future _handleGoalWeightPressed() async {
-    double goalWeight = await showDialog(
-      context: context,
-      child: new Dialog(
-        title: new Text("Goal Weight"),
-        content: new Input(
-          key: weightGoalKey,
-          placeholder: 'Goal weight in lbs',
-          keyboardType: KeyboardType.NUMBER,
-          onChanged: _handleGoalWeightChanged
-        ),
-        actions: <Widget>[
-          new FlatButton(
-            child: new Text('CANCEL'),
-            onPressed: () {
-              Navigator.of(context).pop();
-            }
-          ),
-          new FlatButton(
-            child: new Text('SAVE'),
-            onPressed: () {
-              Navigator.of(context).pop(_goalWeight);
-            }
-          ),
-        ]
-      )
-    );
-    config.updater(goalWeight: goalWeight);
-  }
-
-  Widget buildSettingsPane(BuildContext context) {
-    return new Block(<Widget>[
-        new DrawerItem(
-          onPressed: () { _handleBackupChanged(!(config.userData.backupMode == BackupMode.enabled)); },
-          child: new Row(<Widget>[
-            new Flexible(child: new Text('Back up data to the cloud')),
-            new Switch(value: config.userData.backupMode == BackupMode.enabled, onChanged: _handleBackupChanged),
-          ])
-        ),
-        new DrawerItem(
-          onPressed: () => _handleGoalWeightPressed(),
-          child: new Column(<Widget>[
-              new Text('Goal Weight'),
-              new Text(goalWeightText, style: Theme.of(context).text.caption),
-            ],
-            alignItems: FlexAlignItems.start
-          )
-        ),
-      ],
-      padding: const EdgeDims.symmetric(vertical: 20.0)
-    );
-  }
-
-  Widget build(BuildContext context) {
-    return new Scaffold(
-      toolBar: buildToolBar(),
-      body: buildSettingsPane(context)
-    );
-  }
-}
diff --git a/examples/fitness/lib/user_data.dart b/examples/fitness/lib/user_data.dart
deleted file mode 100644
index ef6eabb..0000000
--- a/examples/fitness/lib/user_data.dart
+++ /dev/null
@@ -1,40 +0,0 @@
-// Copyright 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 'dart:convert';
-import 'dart:io';
-import 'dart:async';
-
-import 'package:path/path.dart' as path;
-
-import 'main.dart';
-import 'package:flutter/services.dart';
-
-String cachedDataFilePath = null;
-
-Future<String> dataFilePath() async {
-  if (cachedDataFilePath == null) {
-    String dataDir = await getFilesDir();
-    cachedDataFilePath = path.join(dataDir, 'data.json');
-  }
-  return cachedDataFilePath;
-}
-
-Future<UserData> loadFitnessData() async {
-  String dataPath = await dataFilePath();
-  print("Loading from $dataPath");
-  JsonDecoder decoder = new JsonDecoder();
-  Map data = await decoder.convert(await new File(dataPath).readAsString());
-  return new UserDataImpl.fromJson(data);
-}
-
-// Intentionally synchronous for execution just before shutdown.
-Future saveFitnessData(UserDataImpl data) async {
-  String dataPath = await dataFilePath();
-  print("Saving to $dataPath");
-  JsonEncoder encoder = new JsonEncoder();
-  String contents = await encoder.convert(data);
-  File dataFile = await new File(dataPath).writeAsString(contents);
-  print("Success! $dataFile");
-}
diff --git a/examples/fitness/mac/Info.plist b/examples/fitness/mac/Info.plist
deleted file mode 100644
index 5f3286b..0000000
--- a/examples/fitness/mac/Info.plist
+++ /dev/null
@@ -1,34 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
-<plist version="1.0">
-<dict>
-	<key>CFBundleDevelopmentRegion</key>
-	<string>en</string>
-	<key>CFBundleExecutable</key>
-	<string>fitness_app</string>
-	<key>CFBundleIconFile</key>
-	<string></string>
-	<key>CFBundleIdentifier</key>
-	<string>org.domokit.sky.fitness</string>
-	<key>CFBundleInfoDictionaryVersion</key>
-	<string>6.0</string>
-	<key>CFBundleName</key>
-	<string>Asteroids</string>
-	<key>CFBundlePackageType</key>
-	<string>APPL</string>
-	<key>CFBundleShortVersionString</key>
-	<string>1.0</string>
-	<key>CFBundleSignature</key>
-	<string>????</string>
-	<key>CFBundleVersion</key>
-	<string>1</string>
-	<key>LSMinimumSystemVersion</key>
-	<string>10.6</string>
-	<key>NSHumanReadableCopyright</key>
-	<string>Copyright © 2015 The Chromium Authors. All rights reserved.</string>
-	<key>NSMainNibFile</key>
-	<string>sky_mac</string>
-	<key>NSPrincipalClass</key>
-	<string>SkyApplication</string>
-</dict>
-</plist>
diff --git a/examples/fitness/mac/sky_mac.xib b/examples/fitness/mac/sky_mac.xib
deleted file mode 100644
index 0173ec3..0000000
--- a/examples/fitness/mac/sky_mac.xib
+++ /dev/null
@@ -1,695 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="7702" systemVersion="14E46" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
-    <dependencies>
-        <plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="7702"/>
-    </dependencies>
-    <objects>
-        <customObject id="-2" userLabel="File's Owner" customClass="SkyApplication">
-            <connections>
-                <outlet property="delegate" destination="Voe-Tx-rLC" id="GzC-gU-4Uq"/>
-            </connections>
-        </customObject>
-        <customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
-        <customObject id="-3" userLabel="Application" customClass="NSObject"/>
-        <customObject id="Voe-Tx-rLC" customClass="SkyAppDelegate">
-            <connections>
-                <outlet property="window" destination="QvC-M9-y7g" id="gIp-Ho-8D9"/>
-            </connections>
-        </customObject>
-        <customObject id="YLy-65-1bz" customClass="NSFontManager"/>
-        <menu title="Main Menu" systemMenu="main" id="AYu-sK-qS6">
-            <items>
-                <menuItem title="Sky" id="1Xt-HY-uBw">
-                    <modifierMask key="keyEquivalentModifierMask"/>
-                    <menu key="submenu" title="Sky" systemMenu="apple" id="uQy-DD-JDr">
-                        <items>
-                            <menuItem title="About Sky" id="5kV-Vb-QxS">
-                                <modifierMask key="keyEquivalentModifierMask"/>
-                                <connections>
-                                    <action selector="orderFrontStandardAboutPanel:" target="-1" id="Exp-CZ-Vem"/>
-                                </connections>
-                            </menuItem>
-                            <menuItem isSeparatorItem="YES" id="VOq-y0-SEH"/>
-                            <menuItem title="Preferences…" keyEquivalent="," id="BOF-NM-1cW"/>
-                            <menuItem isSeparatorItem="YES" id="wFC-TO-SCJ"/>
-                            <menuItem title="Services" id="NMo-om-nkz">
-                                <modifierMask key="keyEquivalentModifierMask"/>
-                                <menu key="submenu" title="Services" systemMenu="services" id="hz9-B4-Xy5"/>
-                            </menuItem>
-                            <menuItem isSeparatorItem="YES" id="4je-JR-u6R"/>
-                            <menuItem title="Hide Sky" keyEquivalent="h" id="Olw-nP-bQN">
-                                <connections>
-                                    <action selector="hide:" target="-1" id="PnN-Uc-m68"/>
-                                </connections>
-                            </menuItem>
-                            <menuItem title="Hide Others" keyEquivalent="h" id="Vdr-fp-XzO">
-                                <modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
-                                <connections>
-                                    <action selector="hideOtherApplications:" target="-1" id="VT4-aY-XCT"/>
-                                </connections>
-                            </menuItem>
-                            <menuItem title="Show All" id="Kd2-mp-pUS">
-                                <modifierMask key="keyEquivalentModifierMask"/>
-                                <connections>
-                                    <action selector="unhideAllApplications:" target="-1" id="Dhg-Le-xox"/>
-                                </connections>
-                            </menuItem>
-                            <menuItem isSeparatorItem="YES" id="kCx-OE-vgT"/>
-                            <menuItem title="Quit Sky" keyEquivalent="q" id="4sb-4s-VLi">
-                                <connections>
-                                    <action selector="terminate:" target="-1" id="Te7-pn-YzF"/>
-                                </connections>
-                            </menuItem>
-                        </items>
-                    </menu>
-                </menuItem>
-                <menuItem title="File" id="dMs-cI-mzQ">
-                    <modifierMask key="keyEquivalentModifierMask"/>
-                    <menu key="submenu" title="File" id="bib-Uj-vzu">
-                        <items>
-                            <menuItem title="New" keyEquivalent="n" id="Was-JA-tGl">
-                                <connections>
-                                    <action selector="newDocument:" target="-1" id="4Si-XN-c54"/>
-                                </connections>
-                            </menuItem>
-                            <menuItem title="Open…" keyEquivalent="o" id="IAo-SY-fd9">
-                                <connections>
-                                    <action selector="openDocument:" target="-1" id="bVn-NM-KNZ"/>
-                                </connections>
-                            </menuItem>
-                            <menuItem title="Open Recent" id="tXI-mr-wws">
-                                <modifierMask key="keyEquivalentModifierMask"/>
-                                <menu key="submenu" title="Open Recent" systemMenu="recentDocuments" id="oas-Oc-fiZ">
-                                    <items>
-                                        <menuItem title="Clear Menu" id="vNY-rz-j42">
-                                            <modifierMask key="keyEquivalentModifierMask"/>
-                                            <connections>
-                                                <action selector="clearRecentDocuments:" target="-1" id="Daa-9d-B3U"/>
-                                            </connections>
-                                        </menuItem>
-                                    </items>
-                                </menu>
-                            </menuItem>
-                            <menuItem isSeparatorItem="YES" id="m54-Is-iLE"/>
-                            <menuItem title="Close" keyEquivalent="w" id="DVo-aG-piG">
-                                <connections>
-                                    <action selector="performClose:" target="-1" id="HmO-Ls-i7Q"/>
-                                </connections>
-                            </menuItem>
-                            <menuItem title="Save…" keyEquivalent="s" id="pxx-59-PXV">
-                                <connections>
-                                    <action selector="saveDocument:" target="-1" id="teZ-XB-qJY"/>
-                                </connections>
-                            </menuItem>
-                            <menuItem title="Save As…" keyEquivalent="S" id="Bw7-FT-i3A">
-                                <connections>
-                                    <action selector="saveDocumentAs:" target="-1" id="mDf-zr-I0C"/>
-                                </connections>
-                            </menuItem>
-                            <menuItem title="Revert to Saved" id="KaW-ft-85H">
-                                <modifierMask key="keyEquivalentModifierMask"/>
-                                <connections>
-                                    <action selector="revertDocumentToSaved:" target="-1" id="iJ3-Pv-kwq"/>
-                                </connections>
-                            </menuItem>
-                            <menuItem isSeparatorItem="YES" id="aJh-i4-bef"/>
-                            <menuItem title="Page Setup…" keyEquivalent="P" id="qIS-W8-SiK">
-                                <modifierMask key="keyEquivalentModifierMask" shift="YES" command="YES"/>
-                                <connections>
-                                    <action selector="runPageLayout:" target="-1" id="Din-rz-gC5"/>
-                                </connections>
-                            </menuItem>
-                            <menuItem title="Print…" keyEquivalent="p" id="aTl-1u-JFS">
-                                <connections>
-                                    <action selector="print:" target="-1" id="qaZ-4w-aoO"/>
-                                </connections>
-                            </menuItem>
-                        </items>
-                    </menu>
-                </menuItem>
-                <menuItem title="Edit" id="5QF-Oa-p0T">
-                    <modifierMask key="keyEquivalentModifierMask"/>
-                    <menu key="submenu" title="Edit" id="W48-6f-4Dl">
-                        <items>
-                            <menuItem title="Undo" keyEquivalent="z" id="dRJ-4n-Yzg">
-                                <connections>
-                                    <action selector="undo:" target="-1" id="M6e-cu-g7V"/>
-                                </connections>
-                            </menuItem>
-                            <menuItem title="Redo" keyEquivalent="Z" id="6dh-zS-Vam">
-                                <connections>
-                                    <action selector="redo:" target="-1" id="oIA-Rs-6OD"/>
-                                </connections>
-                            </menuItem>
-                            <menuItem isSeparatorItem="YES" id="WRV-NI-Exz"/>
-                            <menuItem title="Cut" keyEquivalent="x" id="uRl-iY-unG">
-                                <connections>
-                                    <action selector="cut:" target="-1" id="YJe-68-I9s"/>
-                                </connections>
-                            </menuItem>
-                            <menuItem title="Copy" keyEquivalent="c" id="x3v-GG-iWU">
-                                <connections>
-                                    <action selector="copy:" target="-1" id="G1f-GL-Joy"/>
-                                </connections>
-                            </menuItem>
-                            <menuItem title="Paste" keyEquivalent="v" id="gVA-U4-sdL">
-                                <connections>
-                                    <action selector="paste:" target="-1" id="UvS-8e-Qdg"/>
-                                </connections>
-                            </menuItem>
-                            <menuItem title="Paste and Match Style" keyEquivalent="V" id="WeT-3V-zwk">
-                                <modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
-                                <connections>
-                                    <action selector="pasteAsPlainText:" target="-1" id="cEh-KX-wJQ"/>
-                                </connections>
-                            </menuItem>
-                            <menuItem title="Delete" id="pa3-QI-u2k">
-                                <modifierMask key="keyEquivalentModifierMask"/>
-                                <connections>
-                                    <action selector="delete:" target="-1" id="0Mk-Ml-PaM"/>
-                                </connections>
-                            </menuItem>
-                            <menuItem title="Select All" keyEquivalent="a" id="Ruw-6m-B2m">
-                                <connections>
-                                    <action selector="selectAll:" target="-1" id="VNm-Mi-diN"/>
-                                </connections>
-                            </menuItem>
-                            <menuItem isSeparatorItem="YES" id="uyl-h8-XO2"/>
-                            <menuItem title="Find" id="4EN-yA-p0u">
-                                <modifierMask key="keyEquivalentModifierMask"/>
-                                <menu key="submenu" title="Find" id="1b7-l0-nxx">
-                                    <items>
-                                        <menuItem title="Find…" tag="1" keyEquivalent="f" id="Xz5-n4-O0W">
-                                            <connections>
-                                                <action selector="performFindPanelAction:" target="-1" id="cD7-Qs-BN4"/>
-                                            </connections>
-                                        </menuItem>
-                                        <menuItem title="Find and Replace…" tag="12" keyEquivalent="f" id="YEy-JH-Tfz">
-                                            <modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
-                                            <connections>
-                                                <action selector="performFindPanelAction:" target="-1" id="WD3-Gg-5AJ"/>
-                                            </connections>
-                                        </menuItem>
-                                        <menuItem title="Find Next" tag="2" keyEquivalent="g" id="q09-fT-Sye">
-                                            <connections>
-                                                <action selector="performFindPanelAction:" target="-1" id="NDo-RZ-v9R"/>
-                                            </connections>
-                                        </menuItem>
-                                        <menuItem title="Find Previous" tag="3" keyEquivalent="G" id="OwM-mh-QMV">
-                                            <connections>
-                                                <action selector="performFindPanelAction:" target="-1" id="HOh-sY-3ay"/>
-                                            </connections>
-                                        </menuItem>
-                                        <menuItem title="Use Selection for Find" tag="7" keyEquivalent="e" id="buJ-ug-pKt">
-                                            <connections>
-                                                <action selector="performFindPanelAction:" target="-1" id="U76-nv-p5D"/>
-                                            </connections>
-                                        </menuItem>
-                                        <menuItem title="Jump to Selection" keyEquivalent="j" id="S0p-oC-mLd">
-                                            <connections>
-                                                <action selector="centerSelectionInVisibleArea:" target="-1" id="IOG-6D-g5B"/>
-                                            </connections>
-                                        </menuItem>
-                                    </items>
-                                </menu>
-                            </menuItem>
-                            <menuItem title="Spelling and Grammar" id="Dv1-io-Yv7">
-                                <modifierMask key="keyEquivalentModifierMask"/>
-                                <menu key="submenu" title="Spelling" id="3IN-sU-3Bg">
-                                    <items>
-                                        <menuItem title="Show Spelling and Grammar" keyEquivalent=":" id="HFo-cy-zxI">
-                                            <connections>
-                                                <action selector="showGuessPanel:" target="-1" id="vFj-Ks-hy3"/>
-                                            </connections>
-                                        </menuItem>
-                                        <menuItem title="Check Document Now" keyEquivalent=";" id="hz2-CU-CR7">
-                                            <connections>
-                                                <action selector="checkSpelling:" target="-1" id="fz7-VC-reM"/>
-                                            </connections>
-                                        </menuItem>
-                                        <menuItem isSeparatorItem="YES" id="bNw-od-mp5"/>
-                                        <menuItem title="Check Spelling While Typing" id="rbD-Rh-wIN">
-                                            <modifierMask key="keyEquivalentModifierMask"/>
-                                            <connections>
-                                                <action selector="toggleContinuousSpellChecking:" target="-1" id="7w6-Qz-0kB"/>
-                                            </connections>
-                                        </menuItem>
-                                        <menuItem title="Check Grammar With Spelling" id="mK6-2p-4JG">
-                                            <modifierMask key="keyEquivalentModifierMask"/>
-                                            <connections>
-                                                <action selector="toggleGrammarChecking:" target="-1" id="muD-Qn-j4w"/>
-                                            </connections>
-                                        </menuItem>
-                                        <menuItem title="Correct Spelling Automatically" id="78Y-hA-62v">
-                                            <modifierMask key="keyEquivalentModifierMask"/>
-                                            <connections>
-                                                <action selector="toggleAutomaticSpellingCorrection:" target="-1" id="2lM-Qi-WAP"/>
-                                            </connections>
-                                        </menuItem>
-                                    </items>
-                                </menu>
-                            </menuItem>
-                            <menuItem title="Substitutions" id="9ic-FL-obx">
-                                <modifierMask key="keyEquivalentModifierMask"/>
-                                <menu key="submenu" title="Substitutions" id="FeM-D8-WVr">
-                                    <items>
-                                        <menuItem title="Show Substitutions" id="z6F-FW-3nz">
-                                            <modifierMask key="keyEquivalentModifierMask"/>
-                                            <connections>
-                                                <action selector="orderFrontSubstitutionsPanel:" target="-1" id="oku-mr-iSq"/>
-                                            </connections>
-                                        </menuItem>
-                                        <menuItem isSeparatorItem="YES" id="gPx-C9-uUO"/>
-                                        <menuItem title="Smart Copy/Paste" id="9yt-4B-nSM">
-                                            <modifierMask key="keyEquivalentModifierMask"/>
-                                            <connections>
-                                                <action selector="toggleSmartInsertDelete:" target="-1" id="3IJ-Se-DZD"/>
-                                            </connections>
-                                        </menuItem>
-                                        <menuItem title="Smart Quotes" id="hQb-2v-fYv">
-                                            <modifierMask key="keyEquivalentModifierMask"/>
-                                            <connections>
-                                                <action selector="toggleAutomaticQuoteSubstitution:" target="-1" id="ptq-xd-QOA"/>
-                                            </connections>
-                                        </menuItem>
-                                        <menuItem title="Smart Dashes" id="rgM-f4-ycn">
-                                            <modifierMask key="keyEquivalentModifierMask"/>
-                                            <connections>
-                                                <action selector="toggleAutomaticDashSubstitution:" target="-1" id="oCt-pO-9gS"/>
-                                            </connections>
-                                        </menuItem>
-                                        <menuItem title="Smart Links" id="cwL-P1-jid">
-                                            <modifierMask key="keyEquivalentModifierMask"/>
-                                            <connections>
-                                                <action selector="toggleAutomaticLinkDetection:" target="-1" id="Gip-E3-Fov"/>
-                                            </connections>
-                                        </menuItem>
-                                        <menuItem title="Data Detectors" id="tRr-pd-1PS">
-                                            <modifierMask key="keyEquivalentModifierMask"/>
-                                            <connections>
-                                                <action selector="toggleAutomaticDataDetection:" target="-1" id="R1I-Nq-Kbl"/>
-                                            </connections>
-                                        </menuItem>
-                                        <menuItem title="Text Replacement" id="HFQ-gK-NFA">
-                                            <modifierMask key="keyEquivalentModifierMask"/>
-                                            <connections>
-                                                <action selector="toggleAutomaticTextReplacement:" target="-1" id="DvP-Fe-Py6"/>
-                                            </connections>
-                                        </menuItem>
-                                    </items>
-                                </menu>
-                            </menuItem>
-                            <menuItem title="Transformations" id="2oI-Rn-ZJC">
-                                <modifierMask key="keyEquivalentModifierMask"/>
-                                <menu key="submenu" title="Transformations" id="c8a-y6-VQd">
-                                    <items>
-                                        <menuItem title="Make Upper Case" id="vmV-6d-7jI">
-                                            <modifierMask key="keyEquivalentModifierMask"/>
-                                            <connections>
-                                                <action selector="uppercaseWord:" target="-1" id="sPh-Tk-edu"/>
-                                            </connections>
-                                        </menuItem>
-                                        <menuItem title="Make Lower Case" id="d9M-CD-aMd">
-                                            <modifierMask key="keyEquivalentModifierMask"/>
-                                            <connections>
-                                                <action selector="lowercaseWord:" target="-1" id="iUZ-b5-hil"/>
-                                            </connections>
-                                        </menuItem>
-                                        <menuItem title="Capitalize" id="UEZ-Bs-lqG">
-                                            <modifierMask key="keyEquivalentModifierMask"/>
-                                            <connections>
-                                                <action selector="capitalizeWord:" target="-1" id="26H-TL-nsh"/>
-                                            </connections>
-                                        </menuItem>
-                                    </items>
-                                </menu>
-                            </menuItem>
-                            <menuItem title="Speech" id="xrE-MZ-jX0">
-                                <modifierMask key="keyEquivalentModifierMask"/>
-                                <menu key="submenu" title="Speech" id="3rS-ZA-NoH">
-                                    <items>
-                                        <menuItem title="Start Speaking" id="Ynk-f8-cLZ">
-                                            <modifierMask key="keyEquivalentModifierMask"/>
-                                            <connections>
-                                                <action selector="startSpeaking:" target="-1" id="654-Ng-kyl"/>
-                                            </connections>
-                                        </menuItem>
-                                        <menuItem title="Stop Speaking" id="Oyz-dy-DGm">
-                                            <modifierMask key="keyEquivalentModifierMask"/>
-                                            <connections>
-                                                <action selector="stopSpeaking:" target="-1" id="dX8-6p-jy9"/>
-                                            </connections>
-                                        </menuItem>
-                                    </items>
-                                </menu>
-                            </menuItem>
-                        </items>
-                    </menu>
-                </menuItem>
-                <menuItem title="Format" id="jxT-CU-nIS">
-                    <modifierMask key="keyEquivalentModifierMask"/>
-                    <menu key="submenu" title="Format" id="GEO-Iw-cKr">
-                        <items>
-                            <menuItem title="Font" id="Gi5-1S-RQB">
-                                <modifierMask key="keyEquivalentModifierMask"/>
-                                <menu key="submenu" title="Font" systemMenu="font" id="aXa-aM-Jaq">
-                                    <items>
-                                        <menuItem title="Show Fonts" keyEquivalent="t" id="Q5e-8K-NDq">
-                                            <connections>
-                                                <action selector="orderFrontFontPanel:" target="YLy-65-1bz" id="WHr-nq-2xA"/>
-                                            </connections>
-                                        </menuItem>
-                                        <menuItem title="Bold" tag="2" keyEquivalent="b" id="GB9-OM-e27">
-                                            <connections>
-                                                <action selector="addFontTrait:" target="YLy-65-1bz" id="hqk-hr-sYV"/>
-                                            </connections>
-                                        </menuItem>
-                                        <menuItem title="Italic" tag="1" keyEquivalent="i" id="Vjx-xi-njq">
-                                            <connections>
-                                                <action selector="addFontTrait:" target="YLy-65-1bz" id="IHV-OB-c03"/>
-                                            </connections>
-                                        </menuItem>
-                                        <menuItem title="Underline" keyEquivalent="u" id="WRG-CD-K1S">
-                                            <connections>
-                                                <action selector="underline:" target="-1" id="FYS-2b-JAY"/>
-                                            </connections>
-                                        </menuItem>
-                                        <menuItem isSeparatorItem="YES" id="5gT-KC-WSO"/>
-                                        <menuItem title="Bigger" tag="3" keyEquivalent="+" id="Ptp-SP-VEL">
-                                            <connections>
-                                                <action selector="modifyFont:" target="YLy-65-1bz" id="Uc7-di-UnL"/>
-                                            </connections>
-                                        </menuItem>
-                                        <menuItem title="Smaller" tag="4" keyEquivalent="-" id="i1d-Er-qST">
-                                            <connections>
-                                                <action selector="modifyFont:" target="YLy-65-1bz" id="HcX-Lf-eNd"/>
-                                            </connections>
-                                        </menuItem>
-                                        <menuItem isSeparatorItem="YES" id="kx3-Dk-x3B"/>
-                                        <menuItem title="Kern" id="jBQ-r6-VK2">
-                                            <modifierMask key="keyEquivalentModifierMask"/>
-                                            <menu key="submenu" title="Kern" id="tlD-Oa-oAM">
-                                                <items>
-                                                    <menuItem title="Use Default" id="GUa-eO-cwY">
-                                                        <modifierMask key="keyEquivalentModifierMask"/>
-                                                        <connections>
-                                                            <action selector="useStandardKerning:" target="-1" id="6dk-9l-Ckg"/>
-                                                        </connections>
-                                                    </menuItem>
-                                                    <menuItem title="Use None" id="cDB-IK-hbR">
-                                                        <modifierMask key="keyEquivalentModifierMask"/>
-                                                        <connections>
-                                                            <action selector="turnOffKerning:" target="-1" id="U8a-gz-Maa"/>
-                                                        </connections>
-                                                    </menuItem>
-                                                    <menuItem title="Tighten" id="46P-cB-AYj">
-                                                        <modifierMask key="keyEquivalentModifierMask"/>
-                                                        <connections>
-                                                            <action selector="tightenKerning:" target="-1" id="hr7-Nz-8ro"/>
-                                                        </connections>
-                                                    </menuItem>
-                                                    <menuItem title="Loosen" id="ogc-rX-tC1">
-                                                        <modifierMask key="keyEquivalentModifierMask"/>
-                                                        <connections>
-                                                            <action selector="loosenKerning:" target="-1" id="8i4-f9-FKE"/>
-                                                        </connections>
-                                                    </menuItem>
-                                                </items>
-                                            </menu>
-                                        </menuItem>
-                                        <menuItem title="Ligatures" id="o6e-r0-MWq">
-                                            <modifierMask key="keyEquivalentModifierMask"/>
-                                            <menu key="submenu" title="Ligatures" id="w0m-vy-SC9">
-                                                <items>
-                                                    <menuItem title="Use Default" id="agt-UL-0e3">
-                                                        <modifierMask key="keyEquivalentModifierMask"/>
-                                                        <connections>
-                                                            <action selector="useStandardLigatures:" target="-1" id="7uR-wd-Dx6"/>
-                                                        </connections>
-                                                    </menuItem>
-                                                    <menuItem title="Use None" id="J7y-lM-qPV">
-                                                        <modifierMask key="keyEquivalentModifierMask"/>
-                                                        <connections>
-                                                            <action selector="turnOffLigatures:" target="-1" id="iX2-gA-Ilz"/>
-                                                        </connections>
-                                                    </menuItem>
-                                                    <menuItem title="Use All" id="xQD-1f-W4t">
-                                                        <modifierMask key="keyEquivalentModifierMask"/>
-                                                        <connections>
-                                                            <action selector="useAllLigatures:" target="-1" id="KcB-kA-TuK"/>
-                                                        </connections>
-                                                    </menuItem>
-                                                </items>
-                                            </menu>
-                                        </menuItem>
-                                        <menuItem title="Baseline" id="OaQ-X3-Vso">
-                                            <modifierMask key="keyEquivalentModifierMask"/>
-                                            <menu key="submenu" title="Baseline" id="ijk-EB-dga">
-                                                <items>
-                                                    <menuItem title="Use Default" id="3Om-Ey-2VK">
-                                                        <modifierMask key="keyEquivalentModifierMask"/>
-                                                        <connections>
-                                                            <action selector="unscript:" target="-1" id="0vZ-95-Ywn"/>
-                                                        </connections>
-                                                    </menuItem>
-                                                    <menuItem title="Superscript" id="Rqc-34-cIF">
-                                                        <modifierMask key="keyEquivalentModifierMask"/>
-                                                        <connections>
-                                                            <action selector="superscript:" target="-1" id="3qV-fo-wpU"/>
-                                                        </connections>
-                                                    </menuItem>
-                                                    <menuItem title="Subscript" id="I0S-gh-46l">
-                                                        <modifierMask key="keyEquivalentModifierMask"/>
-                                                        <connections>
-                                                            <action selector="subscript:" target="-1" id="Q6W-4W-IGz"/>
-                                                        </connections>
-                                                    </menuItem>
-                                                    <menuItem title="Raise" id="2h7-ER-AoG">
-                                                        <modifierMask key="keyEquivalentModifierMask"/>
-                                                        <connections>
-                                                            <action selector="raiseBaseline:" target="-1" id="4sk-31-7Q9"/>
-                                                        </connections>
-                                                    </menuItem>
-                                                    <menuItem title="Lower" id="1tx-W0-xDw">
-                                                        <modifierMask key="keyEquivalentModifierMask"/>
-                                                        <connections>
-                                                            <action selector="lowerBaseline:" target="-1" id="OF1-bc-KW4"/>
-                                                        </connections>
-                                                    </menuItem>
-                                                </items>
-                                            </menu>
-                                        </menuItem>
-                                        <menuItem isSeparatorItem="YES" id="Ndw-q3-faq"/>
-                                        <menuItem title="Show Colors" keyEquivalent="C" id="bgn-CT-cEk">
-                                            <connections>
-                                                <action selector="orderFrontColorPanel:" target="-1" id="mSX-Xz-DV3"/>
-                                            </connections>
-                                        </menuItem>
-                                        <menuItem isSeparatorItem="YES" id="iMs-zA-UFJ"/>
-                                        <menuItem title="Copy Style" keyEquivalent="c" id="5Vv-lz-BsD">
-                                            <modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
-                                            <connections>
-                                                <action selector="copyFont:" target="-1" id="GJO-xA-L4q"/>
-                                            </connections>
-                                        </menuItem>
-                                        <menuItem title="Paste Style" keyEquivalent="v" id="vKC-jM-MkH">
-                                            <modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
-                                            <connections>
-                                                <action selector="pasteFont:" target="-1" id="JfD-CL-leO"/>
-                                            </connections>
-                                        </menuItem>
-                                    </items>
-                                </menu>
-                            </menuItem>
-                            <menuItem title="Text" id="Fal-I4-PZk">
-                                <modifierMask key="keyEquivalentModifierMask"/>
-                                <menu key="submenu" title="Text" id="d9c-me-L2H">
-                                    <items>
-                                        <menuItem title="Align Left" keyEquivalent="{" id="ZM1-6Q-yy1">
-                                            <connections>
-                                                <action selector="alignLeft:" target="-1" id="zUv-R1-uAa"/>
-                                            </connections>
-                                        </menuItem>
-                                        <menuItem title="Center" keyEquivalent="|" id="VIY-Ag-zcb">
-                                            <connections>
-                                                <action selector="alignCenter:" target="-1" id="spX-mk-kcS"/>
-                                            </connections>
-                                        </menuItem>
-                                        <menuItem title="Justify" id="J5U-5w-g23">
-                                            <modifierMask key="keyEquivalentModifierMask"/>
-                                            <connections>
-                                                <action selector="alignJustified:" target="-1" id="ljL-7U-jND"/>
-                                            </connections>
-                                        </menuItem>
-                                        <menuItem title="Align Right" keyEquivalent="}" id="wb2-vD-lq4">
-                                            <connections>
-                                                <action selector="alignRight:" target="-1" id="r48-bG-YeY"/>
-                                            </connections>
-                                        </menuItem>
-                                        <menuItem isSeparatorItem="YES" id="4s2-GY-VfK"/>
-                                        <menuItem title="Writing Direction" id="H1b-Si-o9J">
-                                            <modifierMask key="keyEquivalentModifierMask"/>
-                                            <menu key="submenu" title="Writing Direction" id="8mr-sm-Yjd">
-                                                <items>
-                                                    <menuItem title="Paragraph" enabled="NO" id="ZvO-Gk-QUH">
-                                                        <modifierMask key="keyEquivalentModifierMask"/>
-                                                    </menuItem>
-                                                    <menuItem id="YGs-j5-SAR">
-                                                        <string key="title">	Default</string>
-                                                        <modifierMask key="keyEquivalentModifierMask"/>
-                                                        <connections>
-                                                            <action selector="makeBaseWritingDirectionNatural:" target="-1" id="qtV-5e-UBP"/>
-                                                        </connections>
-                                                    </menuItem>
-                                                    <menuItem id="Lbh-J2-qVU">
-                                                        <string key="title">	Left to Right</string>
-                                                        <modifierMask key="keyEquivalentModifierMask"/>
-                                                        <connections>
-                                                            <action selector="makeBaseWritingDirectionLeftToRight:" target="-1" id="S0X-9S-QSf"/>
-                                                        </connections>
-                                                    </menuItem>
-                                                    <menuItem id="jFq-tB-4Kx">
-                                                        <string key="title">	Right to Left</string>
-                                                        <modifierMask key="keyEquivalentModifierMask"/>
-                                                        <connections>
-                                                            <action selector="makeBaseWritingDirectionRightToLeft:" target="-1" id="5fk-qB-AqJ"/>
-                                                        </connections>
-                                                    </menuItem>
-                                                    <menuItem isSeparatorItem="YES" id="swp-gr-a21"/>
-                                                    <menuItem title="Selection" enabled="NO" id="cqv-fj-IhA">
-                                                        <modifierMask key="keyEquivalentModifierMask"/>
-                                                    </menuItem>
-                                                    <menuItem id="Nop-cj-93Q">
-                                                        <string key="title">	Default</string>
-                                                        <modifierMask key="keyEquivalentModifierMask"/>
-                                                        <connections>
-                                                            <action selector="makeTextWritingDirectionNatural:" target="-1" id="lPI-Se-ZHp"/>
-                                                        </connections>
-                                                    </menuItem>
-                                                    <menuItem id="BgM-ve-c93">
-                                                        <string key="title">	Left to Right</string>
-                                                        <modifierMask key="keyEquivalentModifierMask"/>
-                                                        <connections>
-                                                            <action selector="makeTextWritingDirectionLeftToRight:" target="-1" id="caW-Bv-w94"/>
-                                                        </connections>
-                                                    </menuItem>
-                                                    <menuItem id="RB4-Sm-HuC">
-                                                        <string key="title">	Right to Left</string>
-                                                        <modifierMask key="keyEquivalentModifierMask"/>
-                                                        <connections>
-                                                            <action selector="makeTextWritingDirectionRightToLeft:" target="-1" id="EXD-6r-ZUu"/>
-                                                        </connections>
-                                                    </menuItem>
-                                                </items>
-                                            </menu>
-                                        </menuItem>
-                                        <menuItem isSeparatorItem="YES" id="fKy-g9-1gm"/>
-                                        <menuItem title="Show Ruler" id="vLm-3I-IUL">
-                                            <modifierMask key="keyEquivalentModifierMask"/>
-                                            <connections>
-                                                <action selector="toggleRuler:" target="-1" id="FOx-HJ-KwY"/>
-                                            </connections>
-                                        </menuItem>
-                                        <menuItem title="Copy Ruler" keyEquivalent="c" id="MkV-Pr-PK5">
-                                            <modifierMask key="keyEquivalentModifierMask" control="YES" command="YES"/>
-                                            <connections>
-                                                <action selector="copyRuler:" target="-1" id="71i-fW-3W2"/>
-                                            </connections>
-                                        </menuItem>
-                                        <menuItem title="Paste Ruler" keyEquivalent="v" id="LVM-kO-fVI">
-                                            <modifierMask key="keyEquivalentModifierMask" control="YES" command="YES"/>
-                                            <connections>
-                                                <action selector="pasteRuler:" target="-1" id="cSh-wd-qM2"/>
-                                            </connections>
-                                        </menuItem>
-                                    </items>
-                                </menu>
-                            </menuItem>
-                        </items>
-                    </menu>
-                </menuItem>
-                <menuItem title="View" id="H8h-7b-M4v">
-                    <modifierMask key="keyEquivalentModifierMask"/>
-                    <menu key="submenu" title="View" id="HyV-fh-RgO">
-                        <items>
-                            <menuItem title="Show Toolbar" keyEquivalent="t" id="snW-S8-Cw5">
-                                <modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
-                                <connections>
-                                    <action selector="toggleToolbarShown:" target="-1" id="BXY-wc-z0C"/>
-                                </connections>
-                            </menuItem>
-                            <menuItem title="Customize Toolbar…" id="1UK-8n-QPP">
-                                <modifierMask key="keyEquivalentModifierMask"/>
-                                <connections>
-                                    <action selector="runToolbarCustomizationPalette:" target="-1" id="pQI-g3-MTW"/>
-                                </connections>
-                            </menuItem>
-                        </items>
-                    </menu>
-                </menuItem>
-                <menuItem title="Window" id="aUF-d1-5bR">
-                    <modifierMask key="keyEquivalentModifierMask"/>
-                    <menu key="submenu" title="Window" systemMenu="window" id="Td7-aD-5lo">
-                        <items>
-                            <menuItem title="Minimize" keyEquivalent="m" id="OY7-WF-poV">
-                                <connections>
-                                    <action selector="performMiniaturize:" target="-1" id="VwT-WD-YPe"/>
-                                </connections>
-                            </menuItem>
-                            <menuItem title="Zoom" id="R4o-n2-Eq4">
-                                <modifierMask key="keyEquivalentModifierMask"/>
-                                <connections>
-                                    <action selector="performZoom:" target="-1" id="DIl-cC-cCs"/>
-                                </connections>
-                            </menuItem>
-                            <menuItem isSeparatorItem="YES" id="eu3-7i-yIM"/>
-                            <menuItem title="Bring All to Front" id="LE2-aR-0XJ">
-                                <modifierMask key="keyEquivalentModifierMask"/>
-                                <connections>
-                                    <action selector="arrangeInFront:" target="-1" id="DRN-fu-gQh"/>
-                                </connections>
-                            </menuItem>
-                        </items>
-                    </menu>
-                </menuItem>
-                <menuItem title="Help" id="wpr-3q-Mcd">
-                    <modifierMask key="keyEquivalentModifierMask"/>
-                    <menu key="submenu" title="Help" systemMenu="help" id="F2S-fz-NVQ">
-                        <items>
-                            <menuItem title="Sky Help" keyEquivalent="?" id="FKE-Sm-Kum">
-                                <connections>
-                                    <action selector="showHelp:" target="-1" id="y7X-2Q-9no"/>
-                                </connections>
-                            </menuItem>
-                        </items>
-                    </menu>
-                </menuItem>
-            </items>
-        </menu>
-        <window title="Sky" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" releasedWhenClosed="NO" animationBehavior="default" id="QvC-M9-y7g" customClass="SkyWindow">
-            <windowStyleMask key="styleMask" titled="YES" closable="YES" miniaturizable="YES" resizable="YES"/>
-            <windowPositionMask key="initialPositionMask" leftStrut="YES" rightStrut="YES" topStrut="YES" bottomStrut="YES"/>
-            <rect key="contentRect" x="335" y="390" width="480" height="360"/>
-            <rect key="screenRect" x="0.0" y="0.0" width="1920" height="1177"/>
-            <view key="contentView" id="EiT-Mj-1SZ">
-                <rect key="frame" x="0.0" y="0.0" width="480" height="360"/>
-                <autoresizingMask key="autoresizingMask"/>
-                <subviews>
-                    <openGLView autoresizesSubviews="NO" useAuxiliaryDepthBufferStencil="NO" useDoubleBufferingEnabled="YES" allowOffline="YES" translatesAutoresizingMaskIntoConstraints="NO" id="AUD-Hu-um3">
-                        <rect key="frame" x="0.0" y="0.0" width="480" height="360"/>
-                    </openGLView>
-                </subviews>
-                <constraints>
-                    <constraint firstAttribute="trailing" secondItem="AUD-Hu-um3" secondAttribute="trailing" id="9W1-4Z-nsQ"/>
-                    <constraint firstItem="AUD-Hu-um3" firstAttribute="top" secondItem="EiT-Mj-1SZ" secondAttribute="top" id="KpO-qK-Zhv"/>
-                    <constraint firstAttribute="bottom" secondItem="AUD-Hu-um3" secondAttribute="bottom" id="Myy-UN-4eQ"/>
-                    <constraint firstItem="AUD-Hu-um3" firstAttribute="leading" secondItem="EiT-Mj-1SZ" secondAttribute="leading" id="gf3-3r-c0N"/>
-                </constraints>
-            </view>
-            <connections>
-                <outlet property="renderSurface" destination="AUD-Hu-um3" id="0jv-sx-91g"/>
-            </connections>
-            <point key="canvasLocation" x="128" y="455"/>
-        </window>
-    </objects>
-</document>
diff --git a/examples/fitness/pubspec.yaml b/examples/fitness/pubspec.yaml
deleted file mode 100644
index e9c3ad6..0000000
--- a/examples/fitness/pubspec.yaml
+++ /dev/null
@@ -1,12 +0,0 @@
-name: fitness
-dependencies:
-  flutter: 
-    '0.0.16'
-  playfair: ^0.0.10
-  path: ^1.3.6
-  sky_tools: any
-dependency_overrides:
-  material_design_icons:
-    path: ../../sky/packages/material_design_icons
-  flutter:
-    path: ../../sky/packages/sky
diff --git a/examples/game/BUILD.gn b/examples/game/BUILD.gn
deleted file mode 100644
index 780c669..0000000
--- a/examples/game/BUILD.gn
+++ /dev/null
@@ -1,28 +0,0 @@
-# Copyright 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("//sky/build/sky_app.gni")
-
-sky_app("game") {
-  main_dart = "lib/main.dart"
-  manifest = "flutter.yaml"
-
-  if (is_android) {
-    apk_name = "Asteroids"
-
-    deps = [
-      "//examples/game/apk:resources",
-    ]
-  } else if (is_ios) {
-    info_plist = "ios/Info.plist"
-    launcher_resources = [
-      "assets/Icon.png",
-      "assets/Icon@2x.png",
-      "ios/LaunchScreen.storyboardc",
-    ]
-  } else if (is_mac) {
-    info_plist = "mac/Info.plist"
-    xibs = [ "mac/sky_mac.xib" ]
-  }
-}
diff --git a/examples/game/README.md b/examples/game/README.md
deleted file mode 100644
index 3492069..0000000
--- a/examples/game/README.md
+++ /dev/null
@@ -1,4 +0,0 @@
-Assets for this game are from Galactic Guardian:
-https://github.com/slembcke/GalacticGuardian.spritebuilder
-And are used under MIT license:
-https://github.com/slembcke/GalacticGuardian.spritebuilder/pull/2
diff --git a/examples/game/apk/AndroidManifest.xml b/examples/game/apk/AndroidManifest.xml
deleted file mode 100644
index 5514d95..0000000
--- a/examples/game/apk/AndroidManifest.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright 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.
- -->
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="org.domokit.asteroids">
-
-    <uses-sdk android:minSdkVersion="14" android:targetSdkVersion="21" />
-    <uses-permission android:name="android.permission.INTERNET"/>
-
-    <application android:icon="@mipmap/ic_launcher" android:name="org.domokit.sky.shell.SkyApplication" android:label="Asteroids">
-        <activity android:name="org.domokit.sky.shell.SkyActivity"
-                  android:launchMode="singleTask"
-                  android:theme="@android:style/Theme.Black.NoTitleBar"
-                  android:configChanges="orientation|keyboardHidden|keyboard|screenSize"
-                  android:hardwareAccelerated="true">
-            <intent-filter>
-                <action android:name="android.intent.action.MAIN"/>
-                <category android:name="android.intent.category.LAUNCHER"/>
-            </intent-filter>
-        </activity>
-    </application>
- </manifest>
diff --git a/examples/game/apk/BUILD.gn b/examples/game/apk/BUILD.gn
deleted file mode 100644
index 4e64a21..0000000
--- a/examples/game/apk/BUILD.gn
+++ /dev/null
@@ -1,12 +0,0 @@
-# Copyright 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.
-assert(is_android)
-
-import("//build/config/android/config.gni")
-import("//build/config/android/rules.gni")
-
-android_resources("resources") {
-  resource_dirs = [ "res" ]
-  android_manifest = "AndroidManifest.xml"
-}
diff --git a/examples/game/apk/res/mipmap-hdpi/ic_launcher.png b/examples/game/apk/res/mipmap-hdpi/ic_launcher.png
deleted file mode 100644
index b990d91..0000000
--- a/examples/game/apk/res/mipmap-hdpi/ic_launcher.png
+++ /dev/null
Binary files differ
diff --git a/examples/game/apk/res/mipmap-mdpi/ic_launcher.png b/examples/game/apk/res/mipmap-mdpi/ic_launcher.png
deleted file mode 100644
index 7deee57..0000000
--- a/examples/game/apk/res/mipmap-mdpi/ic_launcher.png
+++ /dev/null
Binary files differ
diff --git a/examples/game/apk/res/mipmap-xhdpi/ic_launcher.png b/examples/game/apk/res/mipmap-xhdpi/ic_launcher.png
deleted file mode 100644
index 27117cc..0000000
--- a/examples/game/apk/res/mipmap-xhdpi/ic_launcher.png
+++ /dev/null
Binary files differ
diff --git a/examples/game/apk/res/mipmap-xxhdpi/ic_launcher.png b/examples/game/apk/res/mipmap-xxhdpi/ic_launcher.png
deleted file mode 100644
index 0a64d84..0000000
--- a/examples/game/apk/res/mipmap-xxhdpi/ic_launcher.png
+++ /dev/null
Binary files differ
diff --git a/examples/game/apk/res/mipmap-xxxhdpi/ic_launcher.png b/examples/game/apk/res/mipmap-xxxhdpi/ic_launcher.png
deleted file mode 100644
index c067b7b..0000000
--- a/examples/game/apk/res/mipmap-xxxhdpi/ic_launcher.png
+++ /dev/null
Binary files differ
diff --git a/examples/game/assets/Icon.png b/examples/game/assets/Icon.png
deleted file mode 100644
index 2e9f304..0000000
--- a/examples/game/assets/Icon.png
+++ /dev/null
Binary files differ
diff --git a/examples/game/assets/Icon@2x.png b/examples/game/assets/Icon@2x.png
deleted file mode 100644
index 558e061..0000000
--- a/examples/game/assets/Icon@2x.png
+++ /dev/null
Binary files differ
diff --git a/examples/game/assets/checker.png b/examples/game/assets/checker.png
deleted file mode 100644
index a39686b..0000000
--- a/examples/game/assets/checker.png
+++ /dev/null
Binary files differ
diff --git a/examples/game/assets/explosion.wav b/examples/game/assets/explosion.wav
deleted file mode 100644
index 33dda9e..0000000
--- a/examples/game/assets/explosion.wav
+++ /dev/null
Binary files differ
diff --git a/examples/game/assets/game_ui.json b/examples/game/assets/game_ui.json
deleted file mode 100644
index f8a09f2..0000000
--- a/examples/game/assets/game_ui.json
+++ /dev/null
@@ -1,156 +0,0 @@
-{"frames": [
-
-{
-	"filename": "bar_shield.png",
-	"frame": {"x":2,"y":954,"w":412,"h":100},
-	"rotated": false,
-	"trimmed": false,
-	"spriteSourceSize": {"x":0,"y":0,"w":412,"h":100},
-	"sourceSize": {"w":412,"h":100},
-	"pivot": {"x":0.5,"y":0.5}
-},
-{
-	"filename": "bar_shield_fill.png",
-	"frame": {"x":2,"y":1156,"w":320,"h":72},
-	"rotated": false,
-	"trimmed": false,
-	"spriteSourceSize": {"x":0,"y":0,"w":320,"h":72},
-	"sourceSize": {"w":320,"h":72},
-	"pivot": {"x":0.5,"y":0.5}
-},
-{
-	"filename": "btn_play_down.png",
-	"frame": {"x":2,"y":484,"w":468,"h":468},
-	"rotated": false,
-	"trimmed": true,
-	"spriteSourceSize": {"x":2,"y":16,"w":468,"h":468},
-	"sourceSize": {"w":472,"h":484},
-	"pivot": {"x":0.5,"y":0.5}
-},
-{
-	"filename": "btn_play_up.png",
-	"frame": {"x":2,"y":2,"w":468,"h":480},
-	"rotated": false,
-	"trimmed": true,
-	"spriteSourceSize": {"x":2,"y":4,"w":468,"h":480},
-	"sourceSize": {"w":472,"h":484},
-	"pivot": {"x":0.5,"y":0.5}
-},
-{
-	"filename": "coinboard.png",
-	"frame": {"x":366,"y":1056,"w":261,"h":100},
-	"rotated": true,
-	"trimmed": false,
-	"spriteSourceSize": {"x":0,"y":0,"w":261,"h":100},
-	"sourceSize": {"w":261,"h":100},
-	"pivot": {"x":0.5,"y":0.5}
-},
-{
-	"filename": "number_0.png",
-	"frame": {"x":416,"y":954,"w":38,"h":63},
-	"rotated": false,
-	"trimmed": true,
-	"spriteSourceSize": {"x":23,"y":22,"w":38,"h":63},
-	"sourceSize": {"w":84,"h":107},
-	"pivot": {"x":0.5,"y":0.5}
-},
-{
-	"filename": "number_1.png",
-	"frame": {"x":299,"y":1286,"w":16,"h":57},
-	"rotated": true,
-	"trimmed": true,
-	"spriteSourceSize": {"x":45,"y":25,"w":16,"h":57},
-	"sourceSize": {"w":84,"h":107},
-	"pivot": {"x":0.5,"y":0.5}
-},
-{
-	"filename": "number_2.png",
-	"frame": {"x":324,"y":1156,"w":38,"h":63},
-	"rotated": false,
-	"trimmed": true,
-	"spriteSourceSize": {"x":23,"y":22,"w":38,"h":63},
-	"sourceSize": {"w":84,"h":107},
-	"pivot": {"x":0.5,"y":0.5}
-},
-{
-	"filename": "number_3.png",
-	"frame": {"x":197,"y":1230,"w":35,"h":63},
-	"rotated": true,
-	"trimmed": true,
-	"spriteSourceSize": {"x":26,"y":22,"w":35,"h":63},
-	"sourceSize": {"w":84,"h":107},
-	"pivot": {"x":0.5,"y":0.5}
-},
-{
-	"filename": "number_4.png",
-	"frame": {"x":197,"y":1267,"w":38,"h":57},
-	"rotated": true,
-	"trimmed": true,
-	"spriteSourceSize": {"x":23,"y":25,"w":38,"h":57},
-	"sourceSize": {"w":84,"h":107},
-	"pivot": {"x":0.5,"y":0.5}
-},
-{
-	"filename": "number_5.png",
-	"frame": {"x":324,"y":1221,"w":38,"h":63},
-	"rotated": false,
-	"trimmed": true,
-	"spriteSourceSize": {"x":23,"y":22,"w":38,"h":63},
-	"sourceSize": {"w":84,"h":107},
-	"pivot": {"x":0.5,"y":0.5}
-},
-{
-	"filename": "number_6.png",
-	"frame": {"x":2,"y":1230,"w":38,"h":63},
-	"rotated": true,
-	"trimmed": true,
-	"spriteSourceSize": {"x":23,"y":22,"w":38,"h":63},
-	"sourceSize": {"w":84,"h":107},
-	"pivot": {"x":0.5,"y":0.5}
-},
-{
-	"filename": "number_7.png",
-	"frame": {"x":262,"y":1230,"w":35,"h":60},
-	"rotated": false,
-	"trimmed": true,
-	"spriteSourceSize": {"x":26,"y":22,"w":35,"h":60},
-	"sourceSize": {"w":84,"h":107},
-	"pivot": {"x":0.5,"y":0.5}
-},
-{
-	"filename": "number_8.png",
-	"frame": {"x":67,"y":1230,"w":38,"h":63},
-	"rotated": true,
-	"trimmed": true,
-	"spriteSourceSize": {"x":23,"y":22,"w":38,"h":63},
-	"sourceSize": {"w":84,"h":107},
-	"pivot": {"x":0.5,"y":0.5}
-},
-{
-	"filename": "number_9.png",
-	"frame": {"x":132,"y":1230,"w":38,"h":63},
-	"rotated": true,
-	"trimmed": true,
-	"spriteSourceSize": {"x":23,"y":22,"w":38,"h":63},
-	"sourceSize": {"w":84,"h":107},
-	"pivot": {"x":0.5,"y":0.5}
-},
-{
-	"filename": "scoreboard.png",
-	"frame": {"x":2,"y":1056,"w":362,"h":98},
-	"rotated": false,
-	"trimmed": false,
-	"spriteSourceSize": {"x":0,"y":0,"w":362,"h":98},
-	"sourceSize": {"w":362,"h":98},
-	"pivot": {"x":0.5,"y":0.5}
-}],
-"meta": {
-	"app": "http://www.codeandweb.com/texturepacker",
-	"version": "1.0",
-	"image": "game_ui.png",
-	"format": "RGBA8888",
-	"size": {"w":472,"h":1319},
-	"scale": "1",
-	"smartupdate": "$TexturePacker:SmartUpdate:2fc7dfe766eba152274e2661737d6b51:b44b32d1e0a4146b3591d51b12f2d7ae:10ac111e32c27e51f4e8444dbb39eff6$"
-}
-}
diff --git a/examples/game/assets/game_ui.png b/examples/game/assets/game_ui.png
deleted file mode 100644
index 73359c8..0000000
--- a/examples/game/assets/game_ui.png
+++ /dev/null
Binary files differ
diff --git a/examples/game/assets/laser.wav b/examples/game/assets/laser.wav
deleted file mode 100644
index 8b22973..0000000
--- a/examples/game/assets/laser.wav
+++ /dev/null
Binary files differ
diff --git a/examples/game/assets/levelup.wav b/examples/game/assets/levelup.wav
deleted file mode 100644
index 12ded3e..0000000
--- a/examples/game/assets/levelup.wav
+++ /dev/null
Binary files differ
diff --git a/examples/game/assets/line_effects.png b/examples/game/assets/line_effects.png
deleted file mode 100644
index 198e733..0000000
--- a/examples/game/assets/line_effects.png
+++ /dev/null
Binary files differ
diff --git a/examples/game/assets/nebula.png b/examples/game/assets/nebula.png
deleted file mode 100644
index a4a10ca..0000000
--- a/examples/game/assets/nebula.png
+++ /dev/null
Binary files differ
diff --git a/examples/game/assets/pickup.wav b/examples/game/assets/pickup.wav
deleted file mode 100644
index 1ebf951..0000000
--- a/examples/game/assets/pickup.wav
+++ /dev/null
Binary files differ
diff --git a/examples/game/assets/sprites.json b/examples/game/assets/sprites.json
deleted file mode 100644
index fcde813..0000000
--- a/examples/game/assets/sprites.json
+++ /dev/null
@@ -1,246 +0,0 @@
-{"frames": [
-
-{
-	"filename": "asteroid_big_0.nrm.png",
-	"frame": {"x":2,"y":260,"w":200,"h":188},
-	"rotated": false,
-	"trimmed": false,
-	"spriteSourceSize": {"x":0,"y":0,"w":200,"h":188},
-	"sourceSize": {"w":200,"h":188},
-	"pivot": {"x":0.5,"y":0.5}
-},
-{
-	"filename": "asteroid_big_0.png",
-	"frame": {"x":2,"y":450,"w":200,"h":167},
-	"rotated": false,
-	"trimmed": true,
-	"spriteSourceSize": {"x":0,"y":21,"w":200,"h":167},
-	"sourceSize": {"w":200,"h":188},
-	"pivot": {"x":0.5,"y":0.5}
-},
-{
-	"filename": "asteroid_big_1.nrm.png",
-	"frame": {"x":2,"y":619,"w":204,"h":166},
-	"rotated": false,
-	"trimmed": false,
-	"spriteSourceSize": {"x":0,"y":0,"w":204,"h":166},
-	"sourceSize": {"w":204,"h":166},
-	"pivot": {"x":0.5,"y":0.5}
-},
-{
-	"filename": "asteroid_big_1.png",
-	"frame": {"x":2,"y":787,"w":204,"h":166},
-	"rotated": false,
-	"trimmed": false,
-	"spriteSourceSize": {"x":0,"y":0,"w":204,"h":166},
-	"sourceSize": {"w":204,"h":166},
-	"pivot": {"x":0.5,"y":0.5}
-},
-{
-	"filename": "asteroid_big_2.nrm.png",
-	"frame": {"x":204,"y":335,"w":194,"h":165},
-	"rotated": false,
-	"trimmed": false,
-	"spriteSourceSize": {"x":0,"y":0,"w":194,"h":165},
-	"sourceSize": {"w":194,"h":165},
-	"pivot": {"x":0.5,"y":0.5}
-},
-{
-	"filename": "asteroid_big_2.png",
-	"frame": {"x":208,"y":502,"w":194,"h":165},
-	"rotated": false,
-	"trimmed": true,
-	"spriteSourceSize": {"x":0,"y":2,"w":194,"h":165},
-	"sourceSize": {"w":194,"h":167},
-	"pivot": {"x":0.5,"y":0.5}
-},
-{
-	"filename": "asteroid_small_0.nrm.png",
-	"frame": {"x":347,"y":843,"w":102,"h":84},
-	"rotated": false,
-	"trimmed": false,
-	"spriteSourceSize": {"x":0,"y":0,"w":102,"h":84},
-	"sourceSize": {"w":102,"h":84},
-	"pivot": {"x":0.5,"y":0.5}
-},
-{
-	"filename": "asteroid_small_0.png",
-	"frame": {"x":347,"y":929,"w":102,"h":84},
-	"rotated": false,
-	"trimmed": false,
-	"spriteSourceSize": {"x":0,"y":0,"w":102,"h":84},
-	"sourceSize": {"w":102,"h":84},
-	"pivot": {"x":0.5,"y":0.5}
-},
-{
-	"filename": "asteroid_small_1.nrm.png",
-	"frame": {"x":404,"y":463,"w":96,"h":102},
-	"rotated": false,
-	"trimmed": false,
-	"spriteSourceSize": {"x":0,"y":0,"w":96,"h":102},
-	"sourceSize": {"w":96,"h":102},
-	"pivot": {"x":0.5,"y":0.5}
-},
-{
-	"filename": "asteroid_small_1.png",
-	"frame": {"x":404,"y":567,"w":96,"h":102},
-	"rotated": false,
-	"trimmed": true,
-	"spriteSourceSize": {"x":0,"y":0,"w":96,"h":102},
-	"sourceSize": {"w":96,"h":106},
-	"pivot": {"x":0.5,"y":0.5}
-},
-{
-	"filename": "asteroid_small_2.nrm.png",
-	"frame": {"x":347,"y":671,"w":109,"h":84},
-	"rotated": false,
-	"trimmed": false,
-	"spriteSourceSize": {"x":0,"y":0,"w":109,"h":84},
-	"sourceSize": {"w":109,"h":84},
-	"pivot": {"x":0.5,"y":0.5}
-},
-{
-	"filename": "asteroid_small_2.png",
-	"frame": {"x":347,"y":757,"w":109,"h":84},
-	"rotated": false,
-	"trimmed": false,
-	"spriteSourceSize": {"x":0,"y":0,"w":109,"h":84},
-	"sourceSize": {"w":109,"h":84},
-	"pivot": {"x":0.5,"y":0.5}
-},
-{
-	"filename": "coin.png",
-	"frame": {"x":429,"y":270,"w":42,"h":47},
-	"rotated": false,
-	"trimmed": true,
-	"spriteSourceSize": {"x":6,"y":4,"w":42,"h":47},
-	"sourceSize": {"w":54,"h":56},
-	"pivot": {"x":0.5,"y":0.5}
-},
-{
-	"filename": "enemy_destroyer_1.png",
-	"frame": {"x":260,"y":193,"w":167,"h":140},
-	"rotated": false,
-	"trimmed": true,
-	"spriteSourceSize": {"x":10,"y":31,"w":167,"h":140},
-	"sourceSize": {"w":188,"h":188},
-	"pivot": {"x":0.5,"y":0.5}
-},
-{
-	"filename": "enemy_scout_0.png",
-	"frame": {"x":400,"y":335,"w":107,"h":126},
-	"rotated": false,
-	"trimmed": true,
-	"spriteSourceSize": {"x":11,"y":1,"w":107,"h":126},
-	"sourceSize": {"w":129,"h":129},
-	"pivot": {"x":0.5,"y":0.5}
-},
-{
-	"filename": "explosion_flare.png",
-	"frame": {"x":451,"y":2,"w":56,"h":209},
-	"rotated": false,
-	"trimmed": true,
-	"spriteSourceSize": {"x":4,"y":0,"w":56,"h":209},
-	"sourceSize": {"w":64,"h":256},
-	"pivot": {"x":0.5,"y":0.5}
-},
-{
-	"filename": "explosion_particle.png",
-	"frame": {"x":204,"y":260,"w":36,"h":60},
-	"rotated": false,
-	"trimmed": true,
-	"spriteSourceSize": {"x":14,"y":1,"w":36,"h":60},
-	"sourceSize": {"w":64,"h":64},
-	"pivot": {"x":0.5,"y":0.5}
-},
-{
-	"filename": "explosion_ring.png",
-	"frame": {"x":2,"y":2,"w":256,"h":256},
-	"rotated": false,
-	"trimmed": false,
-	"spriteSourceSize": {"x":0,"y":0,"w":256,"h":256},
-	"sourceSize": {"w":256,"h":256},
-	"pivot": {"x":0.5,"y":0.5}
-},
-{
-	"filename": "fire_particle.png",
-	"frame": {"x":429,"y":213,"w":55,"h":55},
-	"rotated": false,
-	"trimmed": true,
-	"spriteSourceSize": {"x":4,"y":4,"w":55,"h":55},
-	"sourceSize": {"w":64,"h":64},
-	"pivot": {"x":0.5,"y":0.5}
-},
-{
-	"filename": "laser.png",
-	"frame": {"x":458,"y":671,"w":37,"h":76},
-	"rotated": false,
-	"trimmed": false,
-	"spriteSourceSize": {"x":0,"y":0,"w":37,"h":76},
-	"sourceSize": {"w":37,"h":76},
-	"pivot": {"x":0.5,"y":0.5}
-},
-{
-	"filename": "shield.png",
-	"frame": {"x":260,"y":2,"w":189,"h":189},
-	"rotated": false,
-	"trimmed": false,
-	"spriteSourceSize": {"x":0,"y":0,"w":189,"h":189},
-	"sourceSize": {"w":189,"h":189},
-	"pivot": {"x":0.5,"y":0.5}
-},
-{
-	"filename": "ship.nrm.png",
-	"frame": {"x":208,"y":669,"w":137,"h":167},
-	"rotated": false,
-	"trimmed": false,
-	"spriteSourceSize": {"x":0,"y":0,"w":137,"h":167},
-	"sourceSize": {"w":137,"h":167},
-	"pivot": {"x":0.5,"y":0.5}
-},
-{
-	"filename": "ship.png",
-	"frame": {"x":208,"y":838,"w":137,"h":167},
-	"rotated": false,
-	"trimmed": true,
-	"spriteSourceSize": {"x":25,"y":10,"w":137,"h":167},
-	"sourceSize": {"w":188,"h":188},
-	"pivot": {"x":0.5,"y":0.5}
-},
-{
-	"filename": "star_0.png",
-	"frame": {"x":2,"y":955,"w":62,"h":62},
-	"rotated": false,
-	"trimmed": true,
-	"spriteSourceSize": {"x":1,"y":1,"w":62,"h":62},
-	"sourceSize": {"w":64,"h":64},
-	"pivot": {"x":0.5,"y":0.5}
-},
-{
-	"filename": "star_1.png",
-	"frame": {"x":66,"y":955,"w":62,"h":62},
-	"rotated": false,
-	"trimmed": true,
-	"spriteSourceSize": {"x":1,"y":1,"w":62,"h":62},
-	"sourceSize": {"w":64,"h":64},
-	"pivot": {"x":0.5,"y":0.5}
-},
-{
-	"filename": "star_2.png",
-	"frame": {"x":130,"y":955,"w":62,"h":62},
-	"rotated": false,
-	"trimmed": true,
-	"spriteSourceSize": {"x":1,"y":1,"w":62,"h":62},
-	"sourceSize": {"w":64,"h":64},
-	"pivot": {"x":0.5,"y":0.5}
-}],
-"meta": {
-	"app": "http://www.codeandweb.com/texturepacker",
-	"version": "1.0",
-	"image": "sprites.png",
-	"format": "RGBA8888",
-	"size": {"w":509,"h":1019},
-	"scale": "1",
-	"smartupdate": "$TexturePacker:SmartUpdate:2164a72d7de59aa3603277aa505ff73b:f339feca6ccc1f78132ecc733c94dbc5:1eabdf11f75e3a4fe3147baf7b5be24b$"
-}
-}
diff --git a/examples/game/assets/sprites.png b/examples/game/assets/sprites.png
deleted file mode 100644
index 37c5cf6..0000000
--- a/examples/game/assets/sprites.png
+++ /dev/null
Binary files differ
diff --git a/examples/game/assets/starfield.png b/examples/game/assets/starfield.png
deleted file mode 100644
index 5180600..0000000
--- a/examples/game/assets/starfield.png
+++ /dev/null
Binary files differ
diff --git a/examples/game/assets/temp_music.aac b/examples/game/assets/temp_music.aac
deleted file mode 100644
index 934fb54..0000000
--- a/examples/game/assets/temp_music.aac
+++ /dev/null
Binary files differ
diff --git a/examples/game/example_effect_line.dart b/examples/game/example_effect_line.dart
deleted file mode 100644
index c34ebeb..0000000
--- a/examples/game/example_effect_line.dart
+++ /dev/null
@@ -1,179 +0,0 @@
-import 'package:flutter/material.dart';
-import 'package:flutter/rendering.dart';
-import 'package:flutter/services.dart';
-import 'package:flutter/widgets.dart';
-import 'package:flutter_sprites/flutter_sprites.dart';
-
-AssetBundle _initBundle() {
-  if (rootBundle != null)
-    return rootBundle;
-  return new NetworkAssetBundle(Uri.base);
-}
-
-final AssetBundle _bundle = _initBundle();
-
-ImageMap _images;
-SpriteSheet _spriteSheet;
-
-main() async {
-  _images = new ImageMap(_bundle);
-
-  await _images.load(<String>[
-    'assets/checker.png',
-    'assets/line_effects.png'
-  ]);
-
-  assert(_images["assets/checker.png"] != null);
-
-  runApp(new TestApp());
-}
-
-class TestApp extends StatefulComponent {
-  TestAppState createState() => new TestAppState();
-}
-
-final ThemeData _theme = new ThemeData(
-  brightness: ThemeBrightness.light,
-  primarySwatch: Colors.blue
-);
-
-class TestAppState extends State<TestApp> {
-  TestApp() {
-    _testBed = new TestBed(_labelTexts[_selectedLine]);
-  }
-
-  TestBed _testBed;
-  int _selectedLine = 0;
-
-  List<String> _labelTexts = <String>[
-    "Colored",
-    "Smoke",
-    "Electric",
-    "Rocket Trail"
-  ];
-
-  Widget build(BuildContext context) {
-    return new MaterialApp(
-      title: 'EffectLine Demo',
-      theme: _theme,
-      routes: <String, RouteBuilder>{
-        '/': _buildColumn
-      }
-    );
-  }
-
-  Column _buildColumn(RouteArguments args) {
-    return new Column(<Widget>[
-      new Flexible(child: _buildSpriteWidget()),
-      _buildTabBar()
-    ]);
-  }
-
-  TabBar _buildTabBar() {
-    return new TabBar(
-      labels: _buildTabLabels(),
-      selectedIndex: _selectedLine,
-      onChanged: (int selectedLine) {
-        setState(() {
-          _selectedLine = selectedLine;
-        });
-      }
-    );
-  }
-
-  List<TabLabel> _buildTabLabels() {
-    List<TabLabel> labels = <TabLabel>[];
-    for (String text in _labelTexts)
-      labels.add(new TabLabel(text: text));
-    return labels;
-  }
-
-  SpriteWidget _buildSpriteWidget() {
-    _testBed.setupLine(_labelTexts[_selectedLine]);
-
-    return new SpriteWidget(
-      _testBed,
-      SpriteBoxTransformMode.letterbox
-    );
-  }
-}
-
-class TestBed extends NodeWithSize {
-  EffectLine _line;
-
-  TestBed(String lineType) : super(new Size(1024.0, 1024.0)) {
-    userInteractionEnabled = true;
-    setupLine(lineType);
-  }
-
-  void setupLine(String lineType) {
-    if (_line != null) {
-      _line.removeFromParent();
-    }
-
-    if (lineType == "Colored") {
-      // Create a line with no texture and a color sequence
-      _line = new EffectLine(
-        texture: null,
-        colorSequence: new ColorSequence.fromStartAndEndColor(new Color(0xaaffff00), new Color(0xaaff9900)),
-        widthMode: EffectLineWidthMode.barrel,
-        minWidth: 10.0,
-        maxWidth: 15.0,
-        fadeAfterDelay: 1.0,
-        fadeDuration: 1.0
-      );
-    } else if (lineType == "Smoke") {
-      Texture baseTexture = new Texture(_images['assets/line_effects.png']);
-      Texture smokyLineTexture = baseTexture.textureFromRect(new Rect.fromLTRB(0.0, 0.0, 1024.0, 128.0));
-
-      _line = new EffectLine(
-        texture: smokyLineTexture,
-        textureLoopLength: 300.0,
-        colorSequence: new ColorSequence.fromStartAndEndColor(new Color(0xffffffff), new Color(0x00ffffff)),
-        widthMode: EffectLineWidthMode.barrel,
-        minWidth: 20.0,
-        maxWidth: 80.0,
-        animationMode: EffectLineAnimationMode.scroll
-      );
-    } else if (lineType == "Electric") {
-      Texture baseTexture = new Texture(_images['assets/line_effects.png']);
-      Texture electricLineTexture = baseTexture.textureFromRect(new Rect.fromLTRB(0.0, 384.0, 1024.0, 512.0));
-
-      _line = new EffectLine(
-        texture: electricLineTexture,
-        textureLoopLength: 300.0,
-        widthMode: EffectLineWidthMode.barrel,
-        minWidth: 20.0,
-        maxWidth: 100.0,
-        animationMode: EffectLineAnimationMode.random
-      );
-    } else if (lineType == "Rocket Trail") {
-      Texture baseTexture = new Texture(_images['assets/line_effects.png']);
-      Texture trailLineTexture = baseTexture.textureFromRect(new Rect.fromLTRB(0.0, 896.0, 1024.0, 1024.0));
-
-      _line = new EffectLine(
-        texture: trailLineTexture,
-        textureLoopLength: 300.0,
-        widthMode: EffectLineWidthMode.barrel,
-        minWidth: 20.0,
-        maxWidth: 40.0,
-        widthGrowthSpeed: 40.0,
-        fadeAfterDelay: 0.5,
-        fadeDuration: 1.5
-      );
-    }
-
-    addChild(_line);
-  }
-
-  bool handleEvent(SpriteBoxEvent event) {
-    if (event.type == "pointerdown")
-       _line.points = <Point>[];
-
-    if (event.type == "pointerdown" || event.type == "pointermove") {
-      Point pos = convertPointToNodeSpace(event.boxPosition);
-      _line.addPoint(pos);
-    }
-    return true;
-  }
-}
diff --git a/examples/game/flutter.yaml b/examples/game/flutter.yaml
deleted file mode 100644
index df02f36..0000000
--- a/examples/game/flutter.yaml
+++ /dev/null
@@ -1,12 +0,0 @@
-assets:
-  - assets/nebula.png
-  - assets/sprites.json
-  - assets/sprites.png
-  - assets/starfield.png
-  - assets/game_ui.png
-  - assets/game_ui.json
-  - assets/explosion.wav
-  - assets/laser.wav
-  - assets/levelup.wav
-  - assets/pickup.wav
-  - assets/temp_music.aac
diff --git a/examples/game/ios/Info.plist b/examples/game/ios/Info.plist
deleted file mode 100644
index f0a02ce..0000000
--- a/examples/game/ios/Info.plist
+++ /dev/null
@@ -1,58 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
-<plist version="1.0">
-<dict>
-  <key>CFBundleDevelopmentRegion</key>
-  <string>en</string>
-
-  <!--
-    This executable name must match the name of the app provided to the
-    ios_app GN template
-  -->
-  <key>CFBundleExecutable</key>
-  <string>game_app</string>
-
-  <key>CFBundleDisplayName</key>
-  <string>Asteroids</string>
-
-  <key>UILaunchStoryboardName</key>
-  <string>LaunchScreen</string>
-
-  <key>CFBundleIdentifier</key>
-  <string>com.google.sky.game</string>
-  
-  <key>CFBundleInfoDictionaryVersion</key>
-  <string>6.0</string>
-  <key>CFBundleName</key>
-  <string>game_app</string>
-  <key>CFBundlePackageType</key>
-  <string>APPL</string>
-  <key>CFBundleShortVersionString</key>
-  <string>1.0</string>
-  <key>CFBundleVersion</key>
-  <string>1</string>
-  <key>LSRequiresIPhoneOS</key>
-  <true/>
-  <key>UIRequiredDeviceCapabilities</key>
-  <array>
-    <string>armv7</string>
-  </array>
-  <key>DTPlatformName</key>
-  <string>iphonesimulator</string>
-  <key>DTSDKName</key>
-  <string>iphonesimulator8.3</string>
-  <key>LSRequiresIPhoneOS</key>
-  <true/>
-  <key>MinimumOSVersion</key>
-  <string>8.3</string>
-  <key>UIDeviceFamily</key>
-  <array>
-    <integer>1</integer>
-    <integer>2</integer>
-  </array>
-  <key>CFBundleSupportedPlatforms</key>
-  <array>
-    <string>iPhoneSimulator</string>
-  </array>
-</dict>
-</plist>
diff --git a/examples/game/ios/LaunchScreen.storyboardc/01J-lp-oVM-view-Ze5-6b-2t3.nib b/examples/game/ios/LaunchScreen.storyboardc/01J-lp-oVM-view-Ze5-6b-2t3.nib
deleted file mode 100644
index 1aa489d..0000000
--- a/examples/game/ios/LaunchScreen.storyboardc/01J-lp-oVM-view-Ze5-6b-2t3.nib
+++ /dev/null
Binary files differ
diff --git a/examples/game/ios/LaunchScreen.storyboardc/Info.plist b/examples/game/ios/LaunchScreen.storyboardc/Info.plist
deleted file mode 100644
index 32288e8..0000000
--- a/examples/game/ios/LaunchScreen.storyboardc/Info.plist
+++ /dev/null
Binary files differ
diff --git a/examples/game/ios/LaunchScreen.storyboardc/UIViewController-01J-lp-oVM.nib b/examples/game/ios/LaunchScreen.storyboardc/UIViewController-01J-lp-oVM.nib
deleted file mode 100644
index 8de9bed..0000000
--- a/examples/game/ios/LaunchScreen.storyboardc/UIViewController-01J-lp-oVM.nib
+++ /dev/null
Binary files differ
diff --git a/examples/game/lib/custom_actions.dart b/examples/game/lib/custom_actions.dart
deleted file mode 100644
index a7d5f97..0000000
--- a/examples/game/lib/custom_actions.dart
+++ /dev/null
@@ -1,35 +0,0 @@
-part of game;
-
-typedef void PointSetterCallback(Point value);
-
-class ActionCircularMove extends ActionInterval {
-  ActionCircularMove(this.setter, this.center, this.radius, this.startAngle, this.clockWise, double duration) : super (duration);
-
-  final PointSetterCallback setter;
-  final Point center;
-  final double radius;
-  final double startAngle;
-  final bool clockWise;
-
-  void update(double t) {
-    if (!clockWise) t = -t;
-    double rad = radians(startAngle + t * 360.0);
-    Offset offset = new Offset(math.cos(rad) * radius, math.sin(rad) * radius);
-    Point pos = center + offset;
-    setter(pos);
-  }
-}
-
-class ActionOscillate extends ActionInterval {
-  ActionOscillate(this.setter, this.center, this.radius, double duration) : super(duration);
-
-  final PointSetterCallback setter;
-  final Point center;
-  final double radius;
-
-  void update(double t) {
-    double rad = radians(t * 360.0);
-    Offset offset = new Offset(math.sin(rad) * radius, 0.0);
-    setter(center + offset);
-  }
-}
diff --git a/examples/game/lib/explosions.dart b/examples/game/lib/explosions.dart
deleted file mode 100644
index e916deb..0000000
--- a/examples/game/lib/explosions.dart
+++ /dev/null
@@ -1,109 +0,0 @@
-part of game;
-
-class Explosion extends Node {
-  Explosion() {
-    zPosition = 10.0;
-  }
-}
-
-class ExplosionBig extends Explosion {
-  ExplosionBig(SpriteSheet sheet) {
-    // Add particles
-    ParticleSystem particlesDebris = new ParticleSystem(
-      sheet["explosion_particle.png"],
-      rotateToMovement: true,
-      startRotation:90.0,
-      startRotationVar: 0.0,
-      endRotation: 90.0,
-      startSize: 0.3,
-      startSizeVar: 0.1,
-      endSize: 0.3,
-      endSizeVar: 0.1,
-      numParticlesToEmit: 25,
-      emissionRate:1000.0,
-      greenVar: 127,
-      redVar: 127,
-      life: 0.75,
-      lifeVar: 0.5
-    );
-    particlesDebris.zPosition = 1010.0;
-    addChild(particlesDebris);
-
-    ParticleSystem particlesFire = new ParticleSystem(
-      sheet["fire_particle.png"],
-      colorSequence: new ColorSequence(<Color>[new Color(0xffffff33), new Color(0xffff3333), new Color(0x00ff3333)], <double>[0.0, 0.5, 1.0]),
-      numParticlesToEmit: 25,
-      emissionRate: 1000.0,
-      startSize: 0.5,
-      startSizeVar: 0.1,
-      endSize: 0.5,
-      endSizeVar: 0.1,
-      posVar: new Point(10.0, 10.0),
-      speed: 10.0,
-      speedVar: 5.0,
-      life: 0.75,
-      lifeVar: 0.5
-    );
-    particlesFire.zPosition = 1011.0;
-    addChild(particlesFire);
-
-    // Add ring
-    Sprite spriteRing = new Sprite(sheet["explosion_ring.png"]);
-    spriteRing.transferMode = ui.TransferMode.plus;
-    addChild(spriteRing);
-
-    Action scale = new ActionTween((double a) { spriteRing.scale = a; }, 0.2, 1.0, 0.75);
-    Action scaleAndRemove = new ActionSequence(<Action>[scale, new ActionRemoveNode(spriteRing)]);
-    Action fade = new ActionTween((double a) { spriteRing.opacity = a; }, 1.0, 0.0, 0.75);
-    actions.run(scaleAndRemove);
-    actions.run(fade);
-
-    // Add streaks
-    for (int i = 0; i < 5; i++) {
-      Sprite spriteFlare = new Sprite(sheet["explosion_flare.png"]);
-      spriteFlare.pivot = new Point(0.3, 1.0);
-      spriteFlare.scaleX = 0.3;
-      spriteFlare.transferMode = ui.TransferMode.plus;
-      spriteFlare.rotation = randomDouble() * 360.0;
-      addChild(spriteFlare);
-
-      double multiplier = randomDouble() * 0.3 + 1.0;
-
-      Action scale = new ActionTween((double a) { spriteFlare.scaleY = a; }, 0.3 * multiplier, 0.8, 0.75 * multiplier);
-      Action scaleAndRemove = new ActionSequence(<Action>[scale, new ActionRemoveNode(spriteFlare)]);
-      Action fadeIn = new ActionTween((double a) { spriteFlare.opacity = a; }, 0.0, 1.0, 0.25 * multiplier);
-      Action fadeOut = new ActionTween((double a) { spriteFlare.opacity = a; }, 1.0, 0.0, 0.5 * multiplier);
-      Action fadeInOut = new ActionSequence(<Action>[fadeIn, fadeOut]);
-      actions.run(scaleAndRemove);
-      actions.run(fadeInOut);
-    }
-  }
-}
-
-class ExplosionMini extends Explosion {
-  ExplosionMini(SpriteSheet sheet) {
-    for (int i = 0; i < 2; i++) {
-      Sprite star = new Sprite(sheet["star_0.png"]);
-      star.scale = 0.5;
-      star.colorOverlay = new Color(0xff95f4fb);
-      star.transferMode = ui.TransferMode.plus;
-      addChild(star);
-
-      double rotationStart = randomDouble() * 90.0;
-      double rotationEnd = 180.0 + randomDouble() * 90.0;
-      if (i == 0) {
-        rotationStart = -rotationStart;
-        rotationEnd = -rotationEnd;
-      }
-
-      ActionTween rotate = new ActionTween((double a) { star.rotation = a; }, rotationStart, rotationEnd, 0.2);
-      actions.run(rotate);
-
-      ActionTween fade = new ActionTween((double a) { star.opacity = a; }, 1.0, 0.0, 0.2);
-      actions.run(fade);
-    }
-
-    ActionSequence seq = new ActionSequence(<Action>[new ActionDelay(0.2), new ActionRemoveNode(this)]);
-    actions.run(seq);
-  }
-}
diff --git a/examples/game/lib/flash.dart b/examples/game/lib/flash.dart
deleted file mode 100644
index 98a0625..0000000
--- a/examples/game/lib/flash.dart
+++ /dev/null
@@ -1,23 +0,0 @@
-part of game;
-
-class Flash extends NodeWithSize {
-  Flash(Size size, this.duration) : super(size) {
-    ActionTween fade = new ActionTween((double a) { _opacity = a; }, 1.0, 0.0, duration);
-    ActionSequence seq = new ActionSequence(<Action>[fade, new ActionRemoveNode(this)]);
-    actions.run(seq);
-  }
-
-  double duration;
-  double _opacity = 1.0;
-  Paint _cachedPaint = new Paint();
-
-  void paint(PaintingCanvas canvas) {
-    // Update the color
-    _cachedPaint.color = new Color.fromARGB((255.0 * _opacity).toInt(),
-                                            255, 255, 255);
-    // Fill the area
-    applyTransformForPivot(canvas);
-    canvas.drawRect(new Rect.fromLTRB(0.0, 0.0, size.width, size.height),
-      _cachedPaint);
-  }
-}
diff --git a/examples/game/lib/game_demo.dart b/examples/game/lib/game_demo.dart
deleted file mode 100644
index 637423d..0000000
--- a/examples/game/lib/game_demo.dart
+++ /dev/null
@@ -1,20 +0,0 @@
-library game;
-
-import 'dart:async';
-import 'dart:math' as math;
-import 'dart:ui' as ui;
-
-import 'package:flutter/rendering.dart';
-import 'package:flutter_sprites/flutter_sprites.dart';
-import 'package:vector_math/vector_math_64.dart';
-
-part 'custom_actions.dart';
-part 'explosions.dart';
-part 'flash.dart';
-part 'game_demo_node.dart';
-part 'game_objects.dart';
-part 'game_object_factory.dart';
-part 'player_state.dart';
-part 'power_bar.dart';
-part 'repeated_image.dart';
-part 'star_field.dart';
diff --git a/examples/game/lib/game_demo_node.dart b/examples/game/lib/game_demo_node.dart
deleted file mode 100644
index 97df4f0..0000000
--- a/examples/game/lib/game_demo_node.dart
+++ /dev/null
@@ -1,279 +0,0 @@
-part of game;
-
-final double _gameSizeWidth = 320.0;
-double _gameSizeHeight = 320.0;
-
-final double _chunkSpacing = 640.0;
-final int _chunksPerLevel = 9;
-
-final bool _drawDebug = false;
-
-typedef void GameOverCallback(int score);
-
-class GameDemoNode extends NodeWithSize {
-
-  GameDemoNode(
-    this._images,
-    this._spritesGame,
-    this._spritesUI,
-    this._sounds,
-    this._gameOverCallback
-  ): super(new Size(320.0, 320.0)) {
-    // Add background
-    _background = new RepeatedImage(_images["assets/starfield.png"]);
-    addChild(_background);
-
-    // Create starfield
-    _starField = new StarField(_spritesGame, 200);
-    addChild(_starField);
-
-    // Add nebula
-    _nebula = new RepeatedImage(_images["assets/nebula.png"], ui.TransferMode.plus);
-    addChild(_nebula);
-
-    // Setup game screen, it will always be anchored to the bottom of the screen
-    _gameScreen = new Node();
-    addChild(_gameScreen);
-
-    // Setup the level and add it to the screen, the level is the node where
-    // all our game objects live. It is moved to scroll the game
-    _level = new Level();
-    _gameScreen.addChild(_level);
-
-    // Add heads up display
-    _playerState = new PlayerState(_spritesUI, _spritesGame);
-    addChild(_playerState);
-
-    _objectFactory = new GameObjectFactory(_spritesGame, _sounds, _level, _playerState);
-
-    _level.ship = new Ship(_objectFactory);
-    _level.ship.setupActions();
-    _level.addChild(_level.ship);
-
-    // Add the joystick
-    _joystick = new VirtualJoystick();
-    _gameScreen.addChild(_joystick);
-
-    // Add initial game objects
-    addObjects();
-  }
-
-  // Resources
-  ImageMap _images;
-  Map<String, SoundEffect> _sounds;
-  SpriteSheet _spritesGame;
-  SpriteSheet _spritesUI;
-
-  // Sounds
-  SoundEffectPlayer _effectPlayer = SoundEffectPlayer.sharedInstance();
-
-  // Callback
-  GameOverCallback _gameOverCallback;
-
-  // Game screen nodes
-  Node _gameScreen;
-  VirtualJoystick _joystick;
-
-  GameObjectFactory _objectFactory;
-  Level _level;
-  StarField _starField;
-  RepeatedImage _background;
-  RepeatedImage _nebula;
-  PlayerState _playerState;
-
-  // Game properties
-  double _scroll = 0.0;
-
-  int _framesToFire = 0;
-  int _framesBetweenShots = 20;
-
-  bool _gameOver = false;
-
-  void spriteBoxPerformedLayout() {
-    _gameSizeHeight = spriteBox.visibleArea.height;
-    _gameScreen.position = new Point(0.0, _gameSizeHeight);
-  }
-
-  void update(double dt) {
-    // Scroll the level
-    _scroll = _level.scroll(_playerState.scrollSpeed);
-    _starField.move(0.0, _playerState.scrollSpeed);
-
-    _background.move(_playerState.scrollSpeed * 0.1);
-    _nebula.move(_playerState.scrollSpeed);
-
-    // Add objects
-    addObjects();
-
-    // Move the ship
-    if (!_gameOver) {
-      _level.ship.applyThrust(_joystick.value, _scroll);
-    }
-
-    // Add shots
-    if (_framesToFire == 0 && _joystick.isDown && !_gameOver) {
-      fire();
-      _framesToFire = (_playerState.speedLaserActive) ? _framesBetweenShots ~/ 2 : _framesBetweenShots;
-    }
-    if (_framesToFire > 0) _framesToFire--;
-
-    // Move game objects
-    for (Node node in _level.children) {
-      if (node is GameObject) {
-        node.move();
-      }
-    }
-
-    // Remove offscreen game objects
-    for (int i = _level.children.length - 1; i >= 0; i--) {
-      Node node = _level.children[i];
-      if (node is GameObject) {
-        node.removeIfOffscreen(_scroll);
-      }
-    }
-
-    if (_gameOver) return;
-
-    // Check for collisions between lasers and objects that can take damage
-    List<Laser> lasers = <Laser>[];
-    for (Node node in _level.children) {
-      if (node is Laser) lasers.add(node);
-    }
-
-    List<GameObject> damageables = <GameObject>[];
-    for (Node node in _level.children) {
-      if (node is GameObject && node.canBeDamaged) damageables.add(node);
-    }
-
-    for (Laser laser in lasers) {
-      for (GameObject damageable in damageables) {
-        if (laser.collidingWith(damageable)) {
-          // Hit something that can take damage
-          damageable.addDamage(laser.impact);
-          laser.destroy();
-        }
-      }
-    }
-
-    // Check for collsions between ship and objects that can damage the ship
-    List<Node> nodes = new List<Node>.from(_level.children);
-    for (Node node in nodes) {
-      if (node is GameObject && node.canDamageShip) {
-        if (node.collidingWith(_level.ship)) {
-          if (_playerState.shieldActive) {
-            // Hit, but saved by the shield!
-            node.destroy();
-          } else {
-            // The ship was hit :(
-            killShip();
-          }
-        }
-      } else if (node is GameObject && node.canBeCollected) {
-        if (node.collidingWith(_level.ship)) {
-          // The ship ran over something collectable
-          node.collect();
-        }
-      }
-    }
-  }
-
-  int _chunk = 0;
-
-  void addObjects() {
-
-    while (_scroll + _chunkSpacing >= _chunk * _chunkSpacing) {
-      addLevelChunk(
-        _chunk,
-        -_chunk * _chunkSpacing - _chunkSpacing);
-
-      _chunk += 1;
-    }
-  }
-
-  void addLevelChunk(int chunk, double yPos) {
-    int level = chunk ~/ _chunksPerLevel;
-    int part = chunk % _chunksPerLevel;
-
-    if (part == 0) {
-      LevelLabel lbl = new LevelLabel(_objectFactory, level + 1);
-      lbl.position = new Point(0.0, yPos + _chunkSpacing / 2.0 - 150.0);
-      _level.addChild(lbl);
-    } else if (part == 1) {
-      _objectFactory.addAsteroids(10 + level * 2, yPos, 0.0 + (level * 0.2).clamp(0.0, 0.7));
-    } else if (part == 2) {
-      _objectFactory.addEnemyScoutSwarm(4 + level * 2, yPos);
-    } else if (part == 3) {
-      _objectFactory.addAsteroids(10 + level * 2, yPos, 0.0 + (level * 0.2).clamp(0.0, 0.7));
-    } else if (part == 4) {
-      _objectFactory.addEnemyDestroyerSwarm(2 + level, yPos);
-    } else if (part == 5) {
-      _objectFactory.addAsteroids(10 + level * 2, yPos, 0.0 + (level * 0.2).clamp(0.0, 0.7));
-    } else if (part == 6) {
-      _objectFactory.addEnemyScoutSwarm(4 + level * 2, yPos);
-    } else if (part == 7) {
-      _objectFactory.addAsteroids(10 + level * 2, yPos, 0.0 + (level * 0.2).clamp(0.0, 0.7));
-    } else if (part == 8) {
-      _objectFactory.addBossFight(level, yPos);
-    }
-  }
-
-  void fire() {
-    int laserLevel = _objectFactory.playerState.laserLevel;
-
-    Laser shot0 = new Laser(_objectFactory, laserLevel, -90.0);
-    shot0.position = _level.ship.position + new Offset(17.0, -10.0);
-    _level.addChild(shot0);
-
-    Laser shot1 = new Laser(_objectFactory, laserLevel, -90.0);
-    shot1.position = _level.ship.position + new Offset(-17.0, -10.0);
-    _level.addChild(shot1);
-
-    if (_playerState.sideLaserActive) {
-      Laser shot2 = new Laser(_objectFactory, laserLevel, -45.0);
-      shot2.position = _level.ship.position + new Offset(17.0, -10.0);
-      _level.addChild(shot2);
-
-      Laser shot3 = new Laser(_objectFactory, laserLevel, -135.0);
-      shot3.position = _level.ship.position + new Offset(-17.0, -10.0);
-      _level.addChild(shot3);
-    }
-
-    _effectPlayer.play(_sounds["laser"]);
-  }
-
-  void killShip() {
-    // Hide ship
-    _level.ship.visible = false;
-
-    _effectPlayer.play(_sounds["explosion"]);
-
-    // Add explosion
-    ExplosionBig explo = new ExplosionBig(_spritesGame);
-    explo.scale = 1.5;
-    explo.position = _level.ship.position;
-    _level.addChild(explo);
-
-    // Add flash
-    Flash flash = new Flash(size, 1.0);
-    addChild(flash);
-
-    // Set the state to game over
-    _gameOver = true;
-
-    // Return to main scene and report the score back in 2 seconds
-    new Timer(new Duration(seconds: 2), () { _gameOverCallback(_playerState.score); });
-  }
-}
-
-class Level extends Node {
-  Level() {
-    position = new Point(160.0, 0.0);
-  }
-
-  Ship ship;
-
-  double scroll(double scrollSpeed) {
-    position += new Offset(0.0, scrollSpeed);
-    return position.y;
-  }
-}
diff --git a/examples/game/lib/game_object_factory.dart b/examples/game/lib/game_object_factory.dart
deleted file mode 100644
index afe0178..0000000
--- a/examples/game/lib/game_object_factory.dart
+++ /dev/null
@@ -1,74 +0,0 @@
-part of game;
-
-class GameObjectFactory {
-  GameObjectFactory(this.sheet, this.sounds, this.level, this.playerState);
-
-  SpriteSheet sheet;
-  Map<String,SoundEffect> sounds;
-  Level level;
-  PlayerState playerState;
-
-  void addAsteroids(int numAsteroids, double yPos, double distribution) {
-    for (int i = 0; i < numAsteroids; i++) {
-      GameObject obj;
-      if (i == 0)
-        obj = new AsteroidPowerUp(this);
-      else if (randomDouble() < distribution)
-        obj = new AsteroidBig(this);
-      else
-        obj = new AsteroidSmall(this);
-
-      Point pos = new Point(randomSignedDouble() * 160.0,
-                            yPos + _chunkSpacing * randomDouble());
-      addGameObject(obj, pos);
-    }
-  }
-
-  void addEnemyScoutSwarm(int numEnemies, double yPos) {
-    for (int i = 0; i < numEnemies; i++) {
-      double spacing = math.max(_chunkSpacing / (numEnemies + 1.0), 80.0);
-      double y = yPos + _chunkSpacing / 2.0 - (numEnemies - 1) * spacing / 2.0 + i * spacing;
-      addGameObject(new EnemyScout(this), new Point(0.0, y));
-    }
-  }
-
-  void addEnemyDestroyerSwarm(int numEnemies, double yPos) {
-    for (int i = 0; i < numEnemies; i++) {
-      addGameObject(new EnemyDestroyer(this), new Point(randomSignedDouble() * 120.0 , yPos + _chunkSpacing * randomDouble()));
-    }
-  }
-
-  void addGameObject(GameObject obj, Point pos) {
-    obj.position = pos;
-    obj.setupActions();
-
-    level.addChild(obj);
-  }
-
-  void addBossFight(int l, double yPos) {
-    // Add boss
-    EnemyBoss boss = new EnemyBoss(this);
-    Point pos = new Point(0.0, yPos + _chunkSpacing / 2.0);
-
-    addGameObject(boss, pos);
-
-    playerState.boss = boss;
-
-    // Add boss's helpers
-    if (l >= 1) {
-      EnemyDestroyer destroyer0 = new EnemyDestroyer(this);
-      addGameObject(destroyer0, new Point(-80.0, yPos + _chunkSpacing / 2.0 + 70.0));
-
-      EnemyDestroyer destroyer1 = new EnemyDestroyer(this);
-      addGameObject(destroyer1, new Point(80.0, yPos + _chunkSpacing / 2.0 + 70.0));
-
-      if (l >= 2) {
-        EnemyDestroyer destroyer0 = new EnemyDestroyer(this);
-        addGameObject(destroyer0, new Point(-80.0, yPos + _chunkSpacing / 2.0 - 70.0));
-
-        EnemyDestroyer destroyer1 = new EnemyDestroyer(this);
-        addGameObject(destroyer1, new Point(80.0, yPos + _chunkSpacing / 2.0 - 70.0));
-      }
-    }
-  }
-}
diff --git a/examples/game/lib/game_objects.dart b/examples/game/lib/game_objects.dart
deleted file mode 100644
index 9c0d414..0000000
--- a/examples/game/lib/game_objects.dart
+++ /dev/null
@@ -1,596 +0,0 @@
-part of game;
-
-abstract class GameObject extends Node {
-  GameObject(this.f);
-
-  double radius = 0.0;
-  double removeLimit = 1280.0;
-  bool canDamageShip = true;
-  bool canBeDamaged = true;
-  bool canBeCollected = false;
-  double maxDamage = 3.0;
-  double damage = 0.0;
-
-  final GameObjectFactory f;
-
-  Paint _paintDebug = new Paint()
-    ..color=new Color(0xffff0000)
-    ..strokeWidth = 1.0
-    ..style = ui.PaintingStyle.stroke;
-
-  bool collidingWith(GameObject obj) {
-    return (GameMath.distanceBetweenPoints(position, obj.position)
-      < radius + obj.radius);
-  }
-
-  void move() {
-  }
-
-  void removeIfOffscreen(double scroll) {
-    ;
-    if (-position.y > scroll + removeLimit ||
-        -position.y < scroll - 50.0) {
-      removeFromParent();
-    }
-  }
-
-  void destroy() {
-    if (parent != null) {
-      Explosion explo = createExplosion();
-      if (explo != null) {
-        explo.position = position;
-        parent.addChild(explo);
-      }
-
-      Collectable powerUp = createPowerUp();
-      if (powerUp != null) {
-        f.addGameObject(powerUp, position);
-      }
-
-      removeFromParent();
-    }
-  }
-
-  void collect() {
-    removeFromParent();
-  }
-
-  void addDamage(double d) {
-    if (!canBeDamaged) return;
-
-    damage += d;
-    if (damage >= maxDamage) {
-      destroy();
-      f.playerState.score += (maxDamage * 10).ceil();
-    }
-  }
-
-  Explosion createExplosion() {
-    return null;
-  }
-
-  Collectable createPowerUp() {
-    return null;
-  }
-
-  void paint(PaintingCanvas canvas) {
-    if (_drawDebug) {
-      canvas.drawCircle(Point.origin, radius, _paintDebug);
-    }
-    super.paint(canvas);
-  }
-
-  void setupActions() {
-  }
-}
-
-class LevelLabel extends GameObject {
-  LevelLabel(GameObjectFactory f, int level) : super(f) {
-    canDamageShip = false;
-    canBeDamaged = false;
-
-    Label lbl = new Label(
-      "L E V E L $level",
-      new TextStyle(
-        textAlign: TextAlign.center,
-        color:new Color(0xffffffff),
-        fontSize: 24.0,
-        fontWeight: FontWeight.w600
-      ));
-    addChild(lbl);
-  }
-}
-
-class Ship extends GameObject {
-  Ship(GameObjectFactory f) : super(f) {
-    // Add main ship sprite
-    _sprite = new Sprite(f.sheet["ship.png"]);
-    _sprite.scale = 0.3;
-    _sprite.rotation = -90.0;
-    addChild(_sprite);
-
-    _spriteShield = new Sprite(f.sheet["shield.png"]);
-    _spriteShield.scale = 0.35;
-    _spriteShield.transferMode = ui.TransferMode.plus;
-    addChild(_spriteShield);
-
-    radius = 20.0;
-    canBeDamaged = false;
-    canDamageShip = false;
-
-    // Set start position
-    position = new Point(0.0, 50.0);
-  }
-
-  Sprite _sprite;
-  Sprite _spriteShield;
-
-  void applyThrust(Point joystickValue, double scroll) {
-    Point oldPos = position;
-    Point target = new Point(joystickValue.x * 160.0, joystickValue.y * 220.0 - 250.0 - scroll);
-    double filterFactor = 0.2;
-
-    position = new Point(
-      GameMath.filter(oldPos.x, target.x, filterFactor),
-      GameMath.filter(oldPos.y, target.y, filterFactor));
-  }
-
-  void setupActions() {
-    ActionTween rotate = new ActionTween((double a) { _spriteShield.rotation = a; }, 0.0, 360.0, 1.0);
-    _spriteShield.actions.run(new ActionRepeatForever(rotate));
-  }
-
-  void update(double dt) {
-    // Update shield
-    if (f.playerState.shieldActive) {
-      if (f.playerState.shieldDeactivating)
-        _spriteShield.visible = !_spriteShield.visible;
-      else
-        _spriteShield.visible = true;
-    } else {
-      _spriteShield.visible = false;
-    }
-  }
-}
-
-class Laser extends GameObject {
-  double impact = 0.0;
-
-  final List<Color> laserColors = <Color>[
-    new Color(0xff95f4fb),
-    new Color(0xff5bff35),
-    new Color(0xffff886c),
-    new Color(0xffffd012),
-    new Color(0xfffd7fff)
-  ];
-
-  Laser(GameObjectFactory f, int level, double r) : super(f) {
-    // Game object properties
-    radius = 10.0;
-    removeLimit = _gameSizeHeight + radius;
-    canDamageShip = false;
-    canBeDamaged = false;
-    impact = 1.0 + level * 0.5;
-
-    // Offset for movement
-    _offset = new Offset(
-      math.cos(radians(r)) * 8.0,
-      math.sin(radians(r)) * 8.0 - f.playerState.scrollSpeed);
-
-    // Drawing properties
-    rotation = r + 90.0;
-    int numLasers = level % 3 + 1;
-    Color laserColor = laserColors[(level ~/ 3) % laserColors.length];
-
-    // Add sprites
-    List<Sprite> sprites = <Sprite>[];
-    for (int i = 0; i < numLasers; i++) {
-      Sprite sprite = new Sprite(f.sheet["explosion_particle.png"]);
-      sprite.scale = 0.5;
-      sprite.colorOverlay = laserColor;
-      sprite.transferMode = ui.TransferMode.plus;
-      addChild(sprite);
-      sprites.add(sprite);
-    }
-
-    // Position the individual sprites
-    if (numLasers == 2) {
-      sprites[0].position = new Point(-3.0, 0.0);
-      sprites[1].position = new Point(3.0, 0.0);
-    } else if (numLasers == 3) {
-      sprites[0].position = new Point(-4.0, 0.0);
-      sprites[1].position = new Point(4.0, 0.0);
-      sprites[2].position = new Point(0.0, -2.0);
-    }
-  }
-
-  Offset _offset;
-
-  void move() {
-    position += _offset;
-  }
-
-  Explosion createExplosion() {
-    return new ExplosionMini(f.sheet);
-  }
-}
-
-Color colorForDamage(double damage, double maxDamage) {
-  int alpha = ((200.0 * damage) ~/ maxDamage).clamp(0, 200);
-  return new Color.fromARGB(alpha, 255, 3, 86);
-}
-
-abstract class Obstacle extends GameObject {
-
-  Obstacle(GameObjectFactory f) : super(f);
-
-  double explosionScale = 1.0;
-
-  Explosion createExplosion() {
-    SoundEffectPlayer.sharedInstance().play(f.sounds["explosion"]);
-    Explosion explo = new ExplosionBig(f.sheet);
-    explo.scale = explosionScale;
-    return explo;
-  }
-}
-
-abstract class Asteroid extends Obstacle {
-  Asteroid(GameObjectFactory f) : super(f);
-
-  Sprite _sprite;
-
-  void setupActions() {
-    // Rotate obstacle
-    int direction = 1;
-    if (randomBool()) direction = -1;
-    ActionTween rotate = new ActionTween(
-      (double a) { _sprite.rotation = a; },
-      0.0, 360.0 * direction, 5.0 + 5.0 * randomDouble());
-    _sprite.actions.run(new ActionRepeatForever(rotate));
-  }
-
-  set damage(double d) {
-    super.damage = d;
-    _sprite.colorOverlay = colorForDamage(d, maxDamage);
-  }
-
-  Collectable createPowerUp() {
-    return new Coin(f);
-  }
-}
-
-class AsteroidBig extends Asteroid {
-  AsteroidBig(GameObjectFactory f) : super(f) {
-    _sprite = new Sprite(f.sheet["asteroid_big_${randomInt(3)}.png"]);
-    _sprite.scale = 0.3;
-    radius = 25.0;
-    maxDamage = 5.0;
-    addChild(_sprite);
-  }
-}
-
-class AsteroidSmall extends Asteroid {
-  AsteroidSmall(GameObjectFactory f) : super(f) {
-    _sprite = new Sprite(f.sheet["asteroid_small_${randomInt(3)}.png"]);
-    _sprite.scale = 0.3;
-    radius = 12.0;
-    maxDamage = 3.0;
-    addChild(_sprite);
-  }
-}
-
-class AsteroidPowerUp extends AsteroidBig {
-  AsteroidPowerUp(GameObjectFactory f) : super(f);
-
-  Collectable createPowerUp() {
-    return new PowerUp(f, nextPowerUpType());
-  }
-}
-
-class EnemyScout extends Obstacle {
-  EnemyScout(GameObjectFactory f) : super(f) {
-    _sprite = new Sprite(f.sheet["enemy_scout_0.png"]);
-    _sprite.scale = 0.32;
-    radius = 12.0;
-    maxDamage = 1.0;
-    addChild(_sprite);
-
-    constraints = <Constraint>[new ConstraintRotationToMovement(dampening: 0.5)];
-  }
-
-  final double _swirlSpacing = 80.0;
-
-  _addRandomSquare(List<Offset> offsets, double x, double y) {
-    double xMove = (randomBool()) ? _swirlSpacing : -_swirlSpacing;
-    double yMove = (randomBool()) ? _swirlSpacing : -_swirlSpacing;
-
-    if (randomBool()) {
-      offsets.addAll(<Offset>[
-        new Offset(x, y),
-        new Offset(xMove + x, y),
-        new Offset(xMove + x, yMove + y),
-        new Offset(x, yMove + y),
-        new Offset(x, y)
-      ]);
-    } else {
-      offsets.addAll(<Offset>[
-        new Offset(x, y),
-        new Offset(x, y + yMove),
-        new Offset(xMove + x, yMove + y),
-        new Offset(xMove + x, y),
-        new Offset(x, y)
-      ]);
-    }
-  }
-
-  void setupActions() {
-
-    List<Offset> offsets = <Offset>[];
-    _addRandomSquare(offsets, -_swirlSpacing, 0.0);
-    _addRandomSquare(offsets, _swirlSpacing, 0.0);
-    offsets.add(new Offset(-_swirlSpacing, 0.0));
-
-    List<Point> points = <Point>[];
-    for (Offset offset in offsets) {
-      points.add(position + offset);
-    }
-
-    ActionSpline spline = new ActionSpline((Point a) => position = a, points, 6.0);
-    spline.tension = 0.7;
-    actions.run(new ActionRepeatForever(spline));
-  }
-
-  Collectable createPowerUp() {
-    return new Coin(f);
-  }
-
-  Sprite _sprite;
-}
-
-class EnemyDestroyer extends Obstacle {
-  EnemyDestroyer(GameObjectFactory f) : super(f) {
-    _sprite = new Sprite(f.sheet["enemy_destroyer_1.png"]);
-    _sprite.scale = 0.32;
-    radius = 24.0;
-    maxDamage = 4.0;
-    addChild(_sprite);
-
-    constraints = <Constraint>[new ConstraintRotationToNode(f.level.ship, dampening: 0.05)];
-  }
-
-  int _countDown = randomInt(120) + 240;
-
-  void setupActions() {
-    ActionCircularMove circle = new ActionCircularMove(
-      (Point a) { position = a; },
-      position, 40.0,
-      360.0 * randomDouble(),
-      randomBool(),
-      3.0);
-    actions.run(new ActionRepeatForever(circle));
-  }
-
-  Collectable createPowerUp() {
-    return new Coin(f);
-  }
-
-  void update(double dt) {
-    _countDown -= 1;
-    if (_countDown <= 0) {
-      // Shoot at player
-      EnemyLaser laser = new EnemyLaser(f, rotation, 5.0, new Color(0xffffe38e));
-      laser.position = position;
-      f.level.addChild(laser);
-
-      _countDown = 60 + randomInt(120);
-    }
-  }
-
-  set damage(double d) {
-    super.damage = d;
-    _sprite.colorOverlay = colorForDamage(d, maxDamage);
-  }
-
-  Sprite _sprite;
-}
-
-class EnemyLaser extends Obstacle {
-  EnemyLaser(GameObjectFactory f, double rotation, double speed, Color color) : super(f) {
-    _sprite = new Sprite(f.sheet["explosion_particle.png"]);
-    _sprite.scale = 0.5;
-    _sprite.rotation = rotation + 90;
-    _sprite.colorOverlay = color;
-    addChild(_sprite);
-
-    canDamageShip = true;
-    canBeDamaged = false;
-
-    double rad = radians(rotation);
-    _movement = new Offset(math.cos(rad) * speed, math.sin(rad) * speed);
-  }
-
-  Sprite _sprite;
-  Offset _movement;
-
-  void move() {
-    position += _movement;
-  }
-}
-
-class EnemyBoss extends Obstacle {
-  EnemyBoss(GameObjectFactory f) : super(f) {
-    radius = 48.0;
-    _sprite = new Sprite(f.sheet["enemy_destroyer_1.png"]);
-    _sprite.scale = 0.64;
-    addChild(_sprite);
-    maxDamage = 40.0;
-
-    constraints = <Constraint>[new ConstraintRotationToNode(f.level.ship, dampening: 0.05)];
-
-    _powerBar = new PowerBar(new Size(60.0, 10.0));
-    _powerBar.pivot = new Point(0.5, 0.5);
-    f.level.addChild(_powerBar);
-    _powerBar.constraints = <Constraint>[new ConstraintPositionToNode(
-      this,
-      dampening: 0.5,
-      offset: new Offset(0.0, -70.0)
-    )];
-  }
-
-  Sprite _sprite;
-  PowerBar _powerBar;
-
-  int _countDown = randomInt(120) + 240;
-
-  void update(double dt) {
-    _countDown -= 1;
-    if (_countDown <= 0) {
-      // Shoot at player
-      fire(10.0);
-      fire(0.0);
-      fire(-10.0);
-
-      _countDown = 60 + randomInt(120);
-    }
-  }
-
-  void fire(double r) {
-    r += rotation;
-    EnemyLaser laser = new EnemyLaser(f, r, 5.0, new Color(0xffffe38e));
-
-    double rad = radians(r);
-    Offset startOffset = new Offset(math.cos(rad) * 30.0, math.sin(rad) * 30.0);
-
-    laser.position = position + startOffset;
-    f.level.addChild(laser);
-  }
-
-  void setupActions() {
-    ActionOscillate oscillate = new ActionOscillate((Point a) { position = a; }, position, 120.0, 3.0);
-    actions.run(new ActionRepeatForever(oscillate));
-  }
-
-  void destroy() {
-    f.playerState.boss = null;
-    _powerBar.removeFromParent();
-
-    // Flash the screen
-    NodeWithSize screen = f.playerState.parent;
-    screen.addChild(new Flash(screen.size, 1.0));
-    super.destroy();
-
-    // Add coins
-    for (int i = 0; i < 20; i++) {
-      Coin coin = new Coin(f);
-      Point pos = new Point(
-        randomSignedDouble() * 160,
-        position.y + randomSignedDouble() * 160.0);
-      f.addGameObject(coin, pos);
-    }
-  }
-
-  Explosion createExplosion() {
-    ExplosionBig explo = new ExplosionBig(f.sheet);
-    explo.scale = 1.5;
-    return explo;
-  }
-
-  set damage(double d) {
-    super.damage = d;
-    _sprite.actions.stopAll();
-    _sprite.actions.run(new ActionTween(
-      (Color a) { _sprite.colorOverlay = a; },
-      new Color.fromARGB(180, 255, 3, 86),
-      new Color(0x00000000),
-      0.3
-    ));
-
-    _powerBar.power = (1.0 - (damage / maxDamage)).clamp(0.0, 1.0);
-  }
-}
-
-class Collectable extends GameObject {
-  Collectable(GameObjectFactory f) : super(f) {
-    canDamageShip = false;
-    canBeDamaged = false;
-    canBeCollected = true;
-
-    zPosition = 20.0;
-  }
-}
-
-class Coin extends Collectable {
-  Coin(GameObjectFactory f) : super(f) {
-    _sprite = new Sprite(f.sheet["coin.png"]);
-    _sprite.scale = 0.7;
-    addChild(_sprite);
-
-    radius = 7.5;
-  }
-
-  void setupActions() {
-    // Rotate
-    ActionTween rotate = new ActionTween((double a) { _sprite.rotation = a; }, 0.0, 360.0, 1.0);
-    actions.run(new ActionRepeatForever(rotate));
-
-    // Fade in
-    ActionTween fadeIn = new ActionTween((double a) { _sprite.opacity = a; }, 0.0, 1.0, 0.6);
-    actions.run(fadeIn);
-  }
-
-  Sprite _sprite;
-
-  void collect() {
-    f.playerState.addCoin(this);
-    super.collect();
-  }
-}
-
-enum PowerUpType {
-  shield,
-  speedLaser,
-  sideLaser,
-  speedBoost,
-}
-
-List<PowerUpType> _powerUpTypes = new List<PowerUpType>.from(PowerUpType.values);
-int _lastPowerUp = _powerUpTypes.length;
-
-PowerUpType nextPowerUpType() {
-  if (_lastPowerUp >= _powerUpTypes.length) {
-     _powerUpTypes.shuffle();
-     _lastPowerUp = 0;
-  }
-
-  PowerUpType type = _powerUpTypes[_lastPowerUp];
-  _lastPowerUp++;
-
-  return type;
-}
-
-class PowerUp extends Collectable {
-  PowerUp(GameObjectFactory f, this.type) : super(f) {
-    _sprite = new Sprite(f.sheet["coin.png"]);
-    _sprite.scale = 1.2;
-    addChild(_sprite);
-
-    radius = 10.0;
-  }
-
-  Sprite _sprite;
-  PowerUpType type;
-
-  void setupActions() {
-    ActionTween rotate = new ActionTween((double a) { _sprite.rotation = a; }, 0.0, 360.0, 1.0);
-    actions.run(new ActionRepeatForever(rotate));
-
-    // Fade in
-    ActionTween fadeIn = new ActionTween((double a) { _sprite.opacity = a; }, 0.0, 1.0, 0.6);
-    actions.run(fadeIn);
-  }
-
-  void collect() {
-    f.playerState.activatePowerUp(type);
-    super.collect();
-  }
-}
diff --git a/examples/game/lib/main.dart b/examples/game/lib/main.dart
deleted file mode 100644
index c3ac276..0000000
--- a/examples/game/lib/main.dart
+++ /dev/null
@@ -1,260 +0,0 @@
-// Copyright 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 'dart:async';
-
-import 'package:flutter/material.dart';
-import 'package:flutter/painting.dart';
-import 'package:flutter/rendering.dart';
-import 'package:flutter/services.dart';
-import 'package:flutter_sprites/flutter_sprites.dart';
-
-import 'game_demo.dart';
-
-AssetBundle _initBundle() {
-  if (rootBundle != null)
-    return rootBundle;
-  return new NetworkAssetBundle(new Uri.directory(Uri.base.origin));
-}
-
-final AssetBundle _bundle = _initBundle();
-
-ImageMap _imageMap;
-SpriteSheet _spriteSheet;
-SpriteSheet _spriteSheetUI;
-Map<String, SoundEffect> _sounds = <String, SoundEffect>{};
-
-main() async {
-  _imageMap = new ImageMap(_bundle);
-
-  // Use a list to wait on all loads in parallel just before starting the app.
-  List loads = [];
-
-  loads.add(_imageMap.load(<String>[
-    'assets/nebula.png',
-    'assets/sprites.png',
-    'assets/starfield.png',
-    'assets/game_ui.png',
-  ]));
-
-  // TODO(eseidel): SoundEffect doesn't really do anything except hold a future.
-  _sounds['explosion'] = new SoundEffect(_bundle.load('assets/explosion.wav'));
-  _sounds['laser'] = new SoundEffect(_bundle.load('assets/laser.wav'));
-
-  loads.addAll([
-    _sounds['explosion'].load(),
-    _sounds['laser'].load(),
-  ]);
-
-  await Future.wait(loads);
-
-  // TODO(eseidel): These load in serial which is bad for startup!
-  String json = await _bundle.loadString('assets/sprites.json');
-  _spriteSheet = new SpriteSheet(_imageMap['assets/sprites.png'], json);
-
-  json = await _bundle.loadString('assets/game_ui.json');
-  _spriteSheetUI = new SpriteSheet(_imageMap['assets/game_ui.png'], json);
-
-  assert(_spriteSheet.image != null);
-
-  SoundTrackPlayer stPlayer = SoundTrackPlayer.sharedInstance();
-  SoundTrack music = await stPlayer.load(_bundle.load('assets/temp_music.aac'));
-  stPlayer.play(music);
-
-  runApp(new GameDemo());
-}
-
-// TODO(viktork): The task bar purple is the wrong purple, we may need
-// a custom theme swatch to match the purples in the sprites.
-final ThemeData _theme = new ThemeData(
-  brightness: ThemeBrightness.light,
-  primarySwatch: Colors.purple
-);
-
-class GameDemo extends StatefulComponent {
-  GameDemoState createState() => new GameDemoState();
-}
-
-class GameDemoState extends State<GameDemo> {
-  NodeWithSize _game;
-  int _lastScore = 0;
-
-  Widget build(BuildContext context) {
-    return new MaterialApp(
-      title: 'Asteroids',
-      theme: _theme,
-      routes: <String, RouteBuilder>{
-        '/': _buildMainScene,
-        '/game': _buildGameScene
-      }
-    );
-  }
-
-  Widget _buildGameScene(RouteArguments args) {
-    return new SpriteWidget(_game, SpriteBoxTransformMode.fixedWidth);
-  }
-
-  Widget _buildMainScene(RouteArguments args) {
-    NavigatorState navigatorState = Navigator.of(args.context);
-
-    return new Stack(<Widget>[
-      new SpriteWidget(new MainScreenBackground(), SpriteBoxTransformMode.fixedWidth),
-      new Column(<Widget>[
-          new TextureButton(
-            onPressed: () {
-              _game = new GameDemoNode(
-                _imageMap,
-                _spriteSheet,
-                _spriteSheetUI,
-                _sounds,
-                (int lastScore) {
-                  setState(() { _lastScore = lastScore; });
-                  navigatorState.pop();
-                }
-              );
-              navigatorState.pushNamed('/game');
-            },
-            texture: _spriteSheetUI['btn_play_up.png'],
-            textureDown: _spriteSheetUI['btn_play_down.png'],
-            width: 128.0,
-            height: 128.0
-          ),
-          new DefaultTextStyle(
-            child: new Text(
-              "Last Score: $_lastScore"
-            ),
-            style: new TextStyle(fontSize:20.0)
-          )
-        ],
-        justifyContent: FlexJustifyContent.center
-      )
-    ]);
-  }
-}
-
-class TextureButton extends StatefulComponent {
-  TextureButton({
-    Key key,
-    this.onPressed,
-    this.texture,
-    this.textureDown,
-    this.width: 128.0,
-    this.height: 128.0
-  }) : super(key: key);
-
-  final VoidCallback onPressed;
-  final Texture texture;
-  final Texture textureDown;
-  final double width;
-  final double height;
-
-  TextureButtonState createState() => new TextureButtonState();
-}
-
-class TextureButtonState extends State<TextureButton> {
-  bool _highlight = false;
-
-  Widget build(BuildContext context) {
-    return new GestureDetector(
-      child: new Container(
-        width: config.width,
-        height: config.height,
-        child: new CustomPaint(
-          onPaint: paintCallback,
-          token: new _TextureButtonToken(
-            _highlight,
-            config.texture,
-            config.textureDown,
-            config.width,
-            config.height
-          )
-        )
-      ),
-      onTapDown: (_) {
-        setState(() {
-          _highlight = true;
-        });
-      },
-      onTap: () {
-        setState(() {
-          _highlight = false;
-        });
-        if (config.onPressed != null)
-          config.onPressed();
-      },
-      onTapCancel: () {
-        setState(() {
-          _highlight = false;
-        });
-      }
-    );
-  }
-
-  void paintCallback(PaintingCanvas canvas, Size size) {
-    if (config.texture == null)
-      return;
-
-    canvas.save();
-    if (_highlight && config.textureDown != null) {
-      // Draw down state
-      canvas.scale(size.width / config.textureDown.size.width, size.height / config.textureDown.size.height);
-      config.textureDown.drawTexture(canvas, Point.origin, new Paint());
-    } else {
-      // Draw up state
-      canvas.scale(size.width / config.texture.size.width, size.height / config.texture.size.height);
-      config.texture.drawTexture(canvas, Point.origin, new Paint());
-    }
-    canvas.restore();
-  }
-}
-
-class _TextureButtonToken {
-  _TextureButtonToken(
-    this._highlight,
-    this._texture,
-    this._textureDown,
-    this._width,
-    this._height
-  );
-
-  final bool _highlight;
-  final Texture _texture;
-  final Texture _textureDown;
-  final double _width;
-  final double _height;
-
-  bool operator== (other) {
-    return
-      other is _TextureButtonToken &&
-      _highlight == other._highlight &&
-      _texture == other._texture &&
-      _textureDown == other._textureDown &&
-      _width == other._width &&
-      _height == other._height;
-  }
-
-  int get hashCode {
-    int value = 373;
-    value = 37 * value * _highlight.hashCode;
-    value = 37 * value * _texture.hashCode;
-    value = 37 * value * _textureDown.hashCode;
-    value = 37 * value * _width.hashCode;
-    value = 37 * value * _height.hashCode;
-    return value;
-  }
-}
-
-class MainScreenBackground extends NodeWithSize {
-  MainScreenBackground() : super(new Size(320.0, 320.0)) {
-    assert(_spriteSheet.image != null);
-
-    StarField starField = new StarField(_spriteSheet, 200, true);
-    addChild(starField);
-  }
-
-  void paint(PaintingCanvas canvas) {
-    canvas.drawRect(new Rect.fromLTWH(0.0, 0.0, 320.0, 320.0), new Paint()..color=new Color(0xff000000));
-    super.paint(canvas);
-  }
-}
diff --git a/examples/game/lib/player_state.dart b/examples/game/lib/player_state.dart
deleted file mode 100644
index 3dc5bb9..0000000
--- a/examples/game/lib/player_state.dart
+++ /dev/null
@@ -1,180 +0,0 @@
-part of game;
-
-class PlayerState extends Node {
-  PlayerState(this._sheetUI, this._sheetGame) {
-    // Score display
-    _spriteBackgroundScore = new Sprite(_sheetUI["scoreboard.png"]);
-    _spriteBackgroundScore.pivot = new Point(1.0, 0.0);
-    _spriteBackgroundScore.scale = 0.35;
-    _spriteBackgroundScore.position = new Point(240.0, 10.0);
-    addChild(_spriteBackgroundScore);
-
-    _scoreDisplay = new ScoreDisplay(_sheetUI);
-    _scoreDisplay.position = new Point(-13.0, 49.0);
-    _spriteBackgroundScore.addChild(_scoreDisplay);
-
-    // Coin display
-    _spriteBackgroundCoins = new Sprite(_sheetUI["coinboard.png"]);
-    _spriteBackgroundCoins.pivot = new Point(1.0, 0.0);
-    _spriteBackgroundCoins.scale = 0.35;
-    _spriteBackgroundCoins.position = new Point(105.0, 10.0);
-    addChild(_spriteBackgroundCoins);
-
-    _coinDisplay = new ScoreDisplay(_sheetUI);
-    _coinDisplay.position = new Point(-13.0, 49.0);
-    _spriteBackgroundCoins.addChild(_coinDisplay);
-  }
-
-  final SpriteSheet _sheetUI;
-  final SpriteSheet _sheetGame;
-
-  int laserLevel = 0;
-
-  static const double normalScrollSpeed = 2.0;
-
-  double scrollSpeed = normalScrollSpeed;
-
-  double _scrollSpeedTarget = normalScrollSpeed;
-
-  EnemyBoss boss;
-
-  Sprite _spriteBackgroundScore;
-  ScoreDisplay _scoreDisplay;
-  Sprite _spriteBackgroundCoins;
-  ScoreDisplay _coinDisplay;
-
-  int get score => _scoreDisplay.score;
-
-  set score(int score) {
-    _scoreDisplay.score = score;
-    flashBackgroundSprite(_spriteBackgroundScore);
-  }
-
-  int get coins => _coinDisplay.score;
-
-  void addCoin(Coin c) {
-    // Animate coin to the top of the screen
-    Point startPos = convertPointFromNode(Point.origin, c);
-    Point finalPos = new Point(30.0, 30.0);
-    Point middlePos = new Point((startPos.x + finalPos.x) / 2.0 + 50.0,
-      (startPos.y + finalPos.y) / 2.0);
-
-    List<Point> path = <Point>[startPos, middlePos, finalPos];
-
-    Sprite sprite = new Sprite(_sheetGame["coin.png"]);
-    sprite.scale = 0.7;
-
-    ActionSpline spline = new ActionSpline((Point a) { sprite.position = a; }, path, 0.5);
-    spline.tension = 0.25;
-    ActionTween rotate = new ActionTween((double a) { sprite.rotation = a; }, 0.0, 360.0, 0.5);
-    ActionTween scale = new ActionTween((double a) { sprite.scale = a; }, 0.7, 1.2, 0.5);
-    ActionGroup group = new ActionGroup(<Action>[spline, rotate, scale]);
-    sprite.actions.run(new ActionSequence(<Action>[
-      group,
-      new ActionRemoveNode(sprite),
-      new ActionCallFunction(() {
-        _coinDisplay.score += 1;
-        flashBackgroundSprite(_spriteBackgroundCoins);
-      })
-    ]));
-
-    addChild(sprite);
-  }
-
-  void activatePowerUp(PowerUpType type) {
-    if (type == PowerUpType.shield) {
-      _shieldFrames += 300;
-    } else if (type == PowerUpType.sideLaser) {
-      _sideLaserFrames += 300;
-    } else if (type == PowerUpType.speedLaser) {
-      _speedLaserFrames += 300;
-    } else if (type == PowerUpType.speedBoost) {
-      _speedBoostFrames += 150;
-    }
-  }
-
-  int _shieldFrames = 0;
-  bool get shieldActive => _shieldFrames > 0 || _speedBoostFrames > 0;
-  bool get shieldDeactivating =>
-    math.max(_shieldFrames, _speedBoostFrames) > 0 && math.max(_shieldFrames, _speedBoostFrames) < 60;
-
-  int _sideLaserFrames = 0;
-  bool get sideLaserActive => _sideLaserFrames > 0;
-
-  int _speedLaserFrames = 0;
-  bool get speedLaserActive => _speedLaserFrames > 0;
-
-  int _speedBoostFrames = 0;
-  bool get speedBoostActive => _speedBoostFrames > 0;
-
-  void flashBackgroundSprite(Sprite sprite) {
-    sprite.actions.stopAll();
-    ActionTween flash = new ActionTween(
-      (Color a) { sprite.colorOverlay = a; },
-      new Color(0x66ccfff0),
-      new Color(0x00ccfff0),
-      0.3);
-    sprite.actions.run(flash);
-  }
-
-  void update(double dt) {
-    if (_shieldFrames > 0)
-      _shieldFrames--;
-    if (_sideLaserFrames > 0)
-      _sideLaserFrames--;
-    if (_speedLaserFrames > 0)
-      _speedLaserFrames--;
-    if (_speedBoostFrames > 0)
-      _speedBoostFrames--;
-
-    // Update speed
-    if (boss != null) {
-      Point globalBossPos = boss.convertPointToBoxSpace(Point.origin);
-      if (globalBossPos.y > (_gameSizeHeight - 400.0))
-        _scrollSpeedTarget = 0.0;
-      else
-        _scrollSpeedTarget = normalScrollSpeed;
-    } else {
-      if (speedBoostActive)
-        _scrollSpeedTarget = normalScrollSpeed * 6.0;
-      else
-        _scrollSpeedTarget = normalScrollSpeed;
-    }
-
-    scrollSpeed = GameMath.filter(scrollSpeed, _scrollSpeedTarget, 0.1);
-  }
-}
-
-class ScoreDisplay extends Node {
-  ScoreDisplay(this._sheetUI);
-
-  int _score = 0;
-
-  int get score => _score;
-
-  set score(int score) {
-    _score = score;
-    _dirtyScore = true;
-  }
-
-  SpriteSheet _sheetUI;
-
-  bool _dirtyScore = true;
-
-  void update(double dt) {
-    if (_dirtyScore) {
-      removeAllChildren();
-
-      String scoreStr = _score.toString();
-      double xPos = -37.0;
-      for (int i = scoreStr.length - 1; i >= 0; i--) {
-        String numStr = scoreStr.substring(i, i + 1);
-        Sprite numSprite = new Sprite(_sheetUI["number_$numStr.png"]);
-        numSprite.position = new Point(xPos, 0.0);
-        addChild(numSprite);
-        xPos -= 37.0;
-      }
-      _dirtyScore = false;
-    }
-  }
-}
diff --git a/examples/game/lib/power_bar.dart b/examples/game/lib/power_bar.dart
deleted file mode 100644
index 17ee1c4..0000000
--- a/examples/game/lib/power_bar.dart
+++ /dev/null
@@ -1,21 +0,0 @@
-part of game;
-
-class PowerBar extends NodeWithSize {
-  PowerBar(Size size, [this.power = 1.0]) : super(size);
-
-  double power;
-
-  Paint _paintFill = new Paint()
-    ..color = new Color(0xffffffff);
-  Paint _paintOutline = new Paint()
-    ..color = new Color(0xffffffff)
-    ..strokeWidth = 1.0
-    ..style = ui.PaintingStyle.stroke;
-
-  void paint(PaintingCanvas canvas) {
-    applyTransformForPivot(canvas);
-
-    canvas.drawRect(new Rect.fromLTRB(0.0, 0.0, size.width - 0.0, size.height - 0.0), _paintOutline);
-    canvas.drawRect(new Rect.fromLTRB(2.0, 2.0, (size.width - 2.0) * power, size.height - 2.0), _paintFill);
-  }
-}
diff --git a/examples/game/lib/repeated_image.dart b/examples/game/lib/repeated_image.dart
deleted file mode 100644
index 013106c..0000000
--- a/examples/game/lib/repeated_image.dart
+++ /dev/null
@@ -1,29 +0,0 @@
-part of game;
-
-class RepeatedImage extends Node {
-  Sprite _sprite0;
-  Sprite _sprite1;
-
-  RepeatedImage(ui.Image image, [ui.TransferMode mode = null]) {
-    _sprite0 = new Sprite.fromImage(image);
-    _sprite0.size = new Size(1024.0, 1024.0);
-    _sprite0.pivot = Point.origin;
-    _sprite1 = new Sprite.fromImage(image);
-    _sprite1.size = new Size(1024.0, 1024.0);
-    _sprite1.pivot = Point.origin;
-    _sprite1.position = new Point(0.0, -1024.0);
-
-    if (mode != null) {
-      _sprite0.transferMode = mode;
-      _sprite1.transferMode = mode;
-    }
-
-    addChild(_sprite0);
-    addChild(_sprite1);
-  }
-
-  void move(double dy) {
-    double yPos = (position.y + dy) % 1024.0;
-    position = new Point(0.0, yPos);
-  }
-}
diff --git a/examples/game/lib/star_field.dart b/examples/game/lib/star_field.dart
deleted file mode 100644
index 09528b4..0000000
--- a/examples/game/lib/star_field.dart
+++ /dev/null
@@ -1,89 +0,0 @@
-part of game;
-
-class StarField extends NodeWithSize {
-  ui.Image _image;
-  SpriteSheet _spriteSheet;
-  int _numStars;
-  bool _autoScroll;
-
-  List<Point> _starPositions;
-  List<double> _starScales;
-  List<Rect> _rects;
-  List<Color> _colors;
-
-  final double _padding = 50.0;
-  Size _paddedSize = Size.zero;
-
-  Paint _paint = new Paint()
-    ..filterQuality = ui.FilterQuality.low
-    ..isAntiAlias = false
-    ..transferMode = ui.TransferMode.plus;
-
-  StarField(this._spriteSheet, this._numStars, [this._autoScroll = false]) : super(Size.zero) {
-    _image = _spriteSheet.image;
-  }
-
-  void addStars() {
-    _starPositions = <Point>[];
-    _starScales = <double>[];
-    _colors = <Color>[];
-    _rects = <Rect>[];
-
-    size = spriteBox.visibleArea.size;
-    _paddedSize = new Size(size.width + _padding * 2.0,
-                           size.height + _padding * 2.0);
-
-    for (int i  = 0; i < _numStars; i++) {
-      _starPositions.add(new Point(randomDouble() * _paddedSize.width,
-                                   randomDouble() * _paddedSize.height));
-      _starScales.add(randomDouble() * 0.4);
-      _colors.add(new Color.fromARGB((255.0 * (randomDouble() * 0.5 + 0.5)).toInt(), 255, 255, 255));
-      _rects.add(_spriteSheet["star_${randomInt(2)}.png"].frame);
-    }
-  }
-
-  void spriteBoxPerformedLayout() {
-    addStars();
-  }
-
-  void paint(PaintingCanvas canvas) {
-    // Create a transform for each star
-    List<ui.RSTransform> transforms = <ui.RSTransform>[];
-    for (int i = 0; i < _numStars; i++) {
-      ui.RSTransform transform = new ui.RSTransform(
-        _starScales[i],
-        0.0,
-        _starPositions[i].x - _padding,
-        _starPositions[i].y - _padding);
-
-      transforms.add(transform);
-    }
-
-    // Draw the stars
-    canvas.drawAtlas(_image, transforms, _rects, _colors, ui.TransferMode.modulate, null, _paint);
-  }
-
-  void move(double dx, double dy) {
-    for (int i  = 0; i < _numStars; i++) {
-      double xPos = _starPositions[i].x;
-      double yPos = _starPositions[i].y;
-      double scale = _starScales[i];
-
-      xPos += dx * scale;
-      yPos += dy * scale;
-
-      if (xPos >= _paddedSize.width) xPos -= _paddedSize.width;
-      if (xPos < 0) xPos += _paddedSize.width;
-      if (yPos >= _paddedSize.height) yPos -= _paddedSize.height;
-      if (yPos < 0) yPos += _paddedSize.height;
-
-      _starPositions[i] = new Point(xPos, yPos);
-    }
-  }
-
-  void update(double dt) {
-    if (_autoScroll) {
-      move(0.0, dt * 100.0);
-    }
-  }
-}
diff --git a/examples/game/mac/Info.plist b/examples/game/mac/Info.plist
deleted file mode 100644
index f885c99..0000000
--- a/examples/game/mac/Info.plist
+++ /dev/null
@@ -1,34 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
-<plist version="1.0">
-<dict>
-	<key>CFBundleDevelopmentRegion</key>
-	<string>en</string>
-	<key>CFBundleExecutable</key>
-	<string>game_app</string>
-	<key>CFBundleIconFile</key>
-	<string></string>
-	<key>CFBundleIdentifier</key>
-	<string>org.domokit.sky.asteroids</string>
-	<key>CFBundleInfoDictionaryVersion</key>
-	<string>6.0</string>
-	<key>CFBundleName</key>
-	<string>Asteroids</string>
-	<key>CFBundlePackageType</key>
-	<string>APPL</string>
-	<key>CFBundleShortVersionString</key>
-	<string>1.0</string>
-	<key>CFBundleSignature</key>
-	<string>????</string>
-	<key>CFBundleVersion</key>
-	<string>1</string>
-	<key>LSMinimumSystemVersion</key>
-	<string>10.6</string>
-	<key>NSHumanReadableCopyright</key>
-	<string>Copyright © 2015 The Chromium Authors. All rights reserved.</string>
-	<key>NSMainNibFile</key>
-	<string>sky_mac</string>
-	<key>NSPrincipalClass</key>
-	<string>SkyApplication</string>
-</dict>
-</plist>
diff --git a/examples/game/mac/sky_mac.xib b/examples/game/mac/sky_mac.xib
deleted file mode 100644
index 0173ec3..0000000
--- a/examples/game/mac/sky_mac.xib
+++ /dev/null
@@ -1,695 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="7702" systemVersion="14E46" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
-    <dependencies>
-        <plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="7702"/>
-    </dependencies>
-    <objects>
-        <customObject id="-2" userLabel="File's Owner" customClass="SkyApplication">
-            <connections>
-                <outlet property="delegate" destination="Voe-Tx-rLC" id="GzC-gU-4Uq"/>
-            </connections>
-        </customObject>
-        <customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
-        <customObject id="-3" userLabel="Application" customClass="NSObject"/>
-        <customObject id="Voe-Tx-rLC" customClass="SkyAppDelegate">
-            <connections>
-                <outlet property="window" destination="QvC-M9-y7g" id="gIp-Ho-8D9"/>
-            </connections>
-        </customObject>
-        <customObject id="YLy-65-1bz" customClass="NSFontManager"/>
-        <menu title="Main Menu" systemMenu="main" id="AYu-sK-qS6">
-            <items>
-                <menuItem title="Sky" id="1Xt-HY-uBw">
-                    <modifierMask key="keyEquivalentModifierMask"/>
-                    <menu key="submenu" title="Sky" systemMenu="apple" id="uQy-DD-JDr">
-                        <items>
-                            <menuItem title="About Sky" id="5kV-Vb-QxS">
-                                <modifierMask key="keyEquivalentModifierMask"/>
-                                <connections>
-                                    <action selector="orderFrontStandardAboutPanel:" target="-1" id="Exp-CZ-Vem"/>
-                                </connections>
-                            </menuItem>
-                            <menuItem isSeparatorItem="YES" id="VOq-y0-SEH"/>
-                            <menuItem title="Preferences…" keyEquivalent="," id="BOF-NM-1cW"/>
-                            <menuItem isSeparatorItem="YES" id="wFC-TO-SCJ"/>
-                            <menuItem title="Services" id="NMo-om-nkz">
-                                <modifierMask key="keyEquivalentModifierMask"/>
-                                <menu key="submenu" title="Services" systemMenu="services" id="hz9-B4-Xy5"/>
-                            </menuItem>
-                            <menuItem isSeparatorItem="YES" id="4je-JR-u6R"/>
-                            <menuItem title="Hide Sky" keyEquivalent="h" id="Olw-nP-bQN">
-                                <connections>
-                                    <action selector="hide:" target="-1" id="PnN-Uc-m68"/>
-                                </connections>
-                            </menuItem>
-                            <menuItem title="Hide Others" keyEquivalent="h" id="Vdr-fp-XzO">
-                                <modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
-                                <connections>
-                                    <action selector="hideOtherApplications:" target="-1" id="VT4-aY-XCT"/>
-                                </connections>
-                            </menuItem>
-                            <menuItem title="Show All" id="Kd2-mp-pUS">
-                                <modifierMask key="keyEquivalentModifierMask"/>
-                                <connections>
-                                    <action selector="unhideAllApplications:" target="-1" id="Dhg-Le-xox"/>
-                                </connections>
-                            </menuItem>
-                            <menuItem isSeparatorItem="YES" id="kCx-OE-vgT"/>
-                            <menuItem title="Quit Sky" keyEquivalent="q" id="4sb-4s-VLi">
-                                <connections>
-                                    <action selector="terminate:" target="-1" id="Te7-pn-YzF"/>
-                                </connections>
-                            </menuItem>
-                        </items>
-                    </menu>
-                </menuItem>
-                <menuItem title="File" id="dMs-cI-mzQ">
-                    <modifierMask key="keyEquivalentModifierMask"/>
-                    <menu key="submenu" title="File" id="bib-Uj-vzu">
-                        <items>
-                            <menuItem title="New" keyEquivalent="n" id="Was-JA-tGl">
-                                <connections>
-                                    <action selector="newDocument:" target="-1" id="4Si-XN-c54"/>
-                                </connections>
-                            </menuItem>
-                            <menuItem title="Open…" keyEquivalent="o" id="IAo-SY-fd9">
-                                <connections>
-                                    <action selector="openDocument:" target="-1" id="bVn-NM-KNZ"/>
-                                </connections>
-                            </menuItem>
-                            <menuItem title="Open Recent" id="tXI-mr-wws">
-                                <modifierMask key="keyEquivalentModifierMask"/>
-                                <menu key="submenu" title="Open Recent" systemMenu="recentDocuments" id="oas-Oc-fiZ">
-                                    <items>
-                                        <menuItem title="Clear Menu" id="vNY-rz-j42">
-                                            <modifierMask key="keyEquivalentModifierMask"/>
-                                            <connections>
-                                                <action selector="clearRecentDocuments:" target="-1" id="Daa-9d-B3U"/>
-                                            </connections>
-                                        </menuItem>
-                                    </items>
-                                </menu>
-                            </menuItem>
-                            <menuItem isSeparatorItem="YES" id="m54-Is-iLE"/>
-                            <menuItem title="Close" keyEquivalent="w" id="DVo-aG-piG">
-                                <connections>
-                                    <action selector="performClose:" target="-1" id="HmO-Ls-i7Q"/>
-                                </connections>
-                            </menuItem>
-                            <menuItem title="Save…" keyEquivalent="s" id="pxx-59-PXV">
-                                <connections>
-                                    <action selector="saveDocument:" target="-1" id="teZ-XB-qJY"/>
-                                </connections>
-                            </menuItem>
-                            <menuItem title="Save As…" keyEquivalent="S" id="Bw7-FT-i3A">
-                                <connections>
-                                    <action selector="saveDocumentAs:" target="-1" id="mDf-zr-I0C"/>
-                                </connections>
-                            </menuItem>
-                            <menuItem title="Revert to Saved" id="KaW-ft-85H">
-                                <modifierMask key="keyEquivalentModifierMask"/>
-                                <connections>
-                                    <action selector="revertDocumentToSaved:" target="-1" id="iJ3-Pv-kwq"/>
-                                </connections>
-                            </menuItem>
-                            <menuItem isSeparatorItem="YES" id="aJh-i4-bef"/>
-                            <menuItem title="Page Setup…" keyEquivalent="P" id="qIS-W8-SiK">
-                                <modifierMask key="keyEquivalentModifierMask" shift="YES" command="YES"/>
-                                <connections>
-                                    <action selector="runPageLayout:" target="-1" id="Din-rz-gC5"/>
-                                </connections>
-                            </menuItem>
-                            <menuItem title="Print…" keyEquivalent="p" id="aTl-1u-JFS">
-                                <connections>
-                                    <action selector="print:" target="-1" id="qaZ-4w-aoO"/>
-                                </connections>
-                            </menuItem>
-                        </items>
-                    </menu>
-                </menuItem>
-                <menuItem title="Edit" id="5QF-Oa-p0T">
-                    <modifierMask key="keyEquivalentModifierMask"/>
-                    <menu key="submenu" title="Edit" id="W48-6f-4Dl">
-                        <items>
-                            <menuItem title="Undo" keyEquivalent="z" id="dRJ-4n-Yzg">
-                                <connections>
-                                    <action selector="undo:" target="-1" id="M6e-cu-g7V"/>
-                                </connections>
-                            </menuItem>
-                            <menuItem title="Redo" keyEquivalent="Z" id="6dh-zS-Vam">
-                                <connections>
-                                    <action selector="redo:" target="-1" id="oIA-Rs-6OD"/>
-                                </connections>
-                            </menuItem>
-                            <menuItem isSeparatorItem="YES" id="WRV-NI-Exz"/>
-                            <menuItem title="Cut" keyEquivalent="x" id="uRl-iY-unG">
-                                <connections>
-                                    <action selector="cut:" target="-1" id="YJe-68-I9s"/>
-                                </connections>
-                            </menuItem>
-                            <menuItem title="Copy" keyEquivalent="c" id="x3v-GG-iWU">
-                                <connections>
-                                    <action selector="copy:" target="-1" id="G1f-GL-Joy"/>
-                                </connections>
-                            </menuItem>
-                            <menuItem title="Paste" keyEquivalent="v" id="gVA-U4-sdL">
-                                <connections>
-                                    <action selector="paste:" target="-1" id="UvS-8e-Qdg"/>
-                                </connections>
-                            </menuItem>
-                            <menuItem title="Paste and Match Style" keyEquivalent="V" id="WeT-3V-zwk">
-                                <modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
-                                <connections>
-                                    <action selector="pasteAsPlainText:" target="-1" id="cEh-KX-wJQ"/>
-                                </connections>
-                            </menuItem>
-                            <menuItem title="Delete" id="pa3-QI-u2k">
-                                <modifierMask key="keyEquivalentModifierMask"/>
-                                <connections>
-                                    <action selector="delete:" target="-1" id="0Mk-Ml-PaM"/>
-                                </connections>
-                            </menuItem>
-                            <menuItem title="Select All" keyEquivalent="a" id="Ruw-6m-B2m">
-                                <connections>
-                                    <action selector="selectAll:" target="-1" id="VNm-Mi-diN"/>
-                                </connections>
-                            </menuItem>
-                            <menuItem isSeparatorItem="YES" id="uyl-h8-XO2"/>
-                            <menuItem title="Find" id="4EN-yA-p0u">
-                                <modifierMask key="keyEquivalentModifierMask"/>
-                                <menu key="submenu" title="Find" id="1b7-l0-nxx">
-                                    <items>
-                                        <menuItem title="Find…" tag="1" keyEquivalent="f" id="Xz5-n4-O0W">
-                                            <connections>
-                                                <action selector="performFindPanelAction:" target="-1" id="cD7-Qs-BN4"/>
-                                            </connections>
-                                        </menuItem>
-                                        <menuItem title="Find and Replace…" tag="12" keyEquivalent="f" id="YEy-JH-Tfz">
-                                            <modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
-                                            <connections>
-                                                <action selector="performFindPanelAction:" target="-1" id="WD3-Gg-5AJ"/>
-                                            </connections>
-                                        </menuItem>
-                                        <menuItem title="Find Next" tag="2" keyEquivalent="g" id="q09-fT-Sye">
-                                            <connections>
-                                                <action selector="performFindPanelAction:" target="-1" id="NDo-RZ-v9R"/>
-                                            </connections>
-                                        </menuItem>
-                                        <menuItem title="Find Previous" tag="3" keyEquivalent="G" id="OwM-mh-QMV">
-                                            <connections>
-                                                <action selector="performFindPanelAction:" target="-1" id="HOh-sY-3ay"/>
-                                            </connections>
-                                        </menuItem>
-                                        <menuItem title="Use Selection for Find" tag="7" keyEquivalent="e" id="buJ-ug-pKt">
-                                            <connections>
-                                                <action selector="performFindPanelAction:" target="-1" id="U76-nv-p5D"/>
-                                            </connections>
-                                        </menuItem>
-                                        <menuItem title="Jump to Selection" keyEquivalent="j" id="S0p-oC-mLd">
-                                            <connections>
-                                                <action selector="centerSelectionInVisibleArea:" target="-1" id="IOG-6D-g5B"/>
-                                            </connections>
-                                        </menuItem>
-                                    </items>
-                                </menu>
-                            </menuItem>
-                            <menuItem title="Spelling and Grammar" id="Dv1-io-Yv7">
-                                <modifierMask key="keyEquivalentModifierMask"/>
-                                <menu key="submenu" title="Spelling" id="3IN-sU-3Bg">
-                                    <items>
-                                        <menuItem title="Show Spelling and Grammar" keyEquivalent=":" id="HFo-cy-zxI">
-                                            <connections>
-                                                <action selector="showGuessPanel:" target="-1" id="vFj-Ks-hy3"/>
-                                            </connections>
-                                        </menuItem>
-                                        <menuItem title="Check Document Now" keyEquivalent=";" id="hz2-CU-CR7">
-                                            <connections>
-                                                <action selector="checkSpelling:" target="-1" id="fz7-VC-reM"/>
-                                            </connections>
-                                        </menuItem>
-                                        <menuItem isSeparatorItem="YES" id="bNw-od-mp5"/>
-                                        <menuItem title="Check Spelling While Typing" id="rbD-Rh-wIN">
-                                            <modifierMask key="keyEquivalentModifierMask"/>
-                                            <connections>
-                                                <action selector="toggleContinuousSpellChecking:" target="-1" id="7w6-Qz-0kB"/>
-                                            </connections>
-                                        </menuItem>
-                                        <menuItem title="Check Grammar With Spelling" id="mK6-2p-4JG">
-                                            <modifierMask key="keyEquivalentModifierMask"/>
-                                            <connections>
-                                                <action selector="toggleGrammarChecking:" target="-1" id="muD-Qn-j4w"/>
-                                            </connections>
-                                        </menuItem>
-                                        <menuItem title="Correct Spelling Automatically" id="78Y-hA-62v">
-                                            <modifierMask key="keyEquivalentModifierMask"/>
-                                            <connections>
-                                                <action selector="toggleAutomaticSpellingCorrection:" target="-1" id="2lM-Qi-WAP"/>
-                                            </connections>
-                                        </menuItem>
-                                    </items>
-                                </menu>
-                            </menuItem>
-                            <menuItem title="Substitutions" id="9ic-FL-obx">
-                                <modifierMask key="keyEquivalentModifierMask"/>
-                                <menu key="submenu" title="Substitutions" id="FeM-D8-WVr">
-                                    <items>
-                                        <menuItem title="Show Substitutions" id="z6F-FW-3nz">
-                                            <modifierMask key="keyEquivalentModifierMask"/>
-                                            <connections>
-                                                <action selector="orderFrontSubstitutionsPanel:" target="-1" id="oku-mr-iSq"/>
-                                            </connections>
-                                        </menuItem>
-                                        <menuItem isSeparatorItem="YES" id="gPx-C9-uUO"/>
-                                        <menuItem title="Smart Copy/Paste" id="9yt-4B-nSM">
-                                            <modifierMask key="keyEquivalentModifierMask"/>
-                                            <connections>
-                                                <action selector="toggleSmartInsertDelete:" target="-1" id="3IJ-Se-DZD"/>
-                                            </connections>
-                                        </menuItem>
-                                        <menuItem title="Smart Quotes" id="hQb-2v-fYv">
-                                            <modifierMask key="keyEquivalentModifierMask"/>
-                                            <connections>
-                                                <action selector="toggleAutomaticQuoteSubstitution:" target="-1" id="ptq-xd-QOA"/>
-                                            </connections>
-                                        </menuItem>
-                                        <menuItem title="Smart Dashes" id="rgM-f4-ycn">
-                                            <modifierMask key="keyEquivalentModifierMask"/>
-                                            <connections>
-                                                <action selector="toggleAutomaticDashSubstitution:" target="-1" id="oCt-pO-9gS"/>
-                                            </connections>
-                                        </menuItem>
-                                        <menuItem title="Smart Links" id="cwL-P1-jid">
-                                            <modifierMask key="keyEquivalentModifierMask"/>
-                                            <connections>
-                                                <action selector="toggleAutomaticLinkDetection:" target="-1" id="Gip-E3-Fov"/>
-                                            </connections>
-                                        </menuItem>
-                                        <menuItem title="Data Detectors" id="tRr-pd-1PS">
-                                            <modifierMask key="keyEquivalentModifierMask"/>
-                                            <connections>
-                                                <action selector="toggleAutomaticDataDetection:" target="-1" id="R1I-Nq-Kbl"/>
-                                            </connections>
-                                        </menuItem>
-                                        <menuItem title="Text Replacement" id="HFQ-gK-NFA">
-                                            <modifierMask key="keyEquivalentModifierMask"/>
-                                            <connections>
-                                                <action selector="toggleAutomaticTextReplacement:" target="-1" id="DvP-Fe-Py6"/>
-                                            </connections>
-                                        </menuItem>
-                                    </items>
-                                </menu>
-                            </menuItem>
-                            <menuItem title="Transformations" id="2oI-Rn-ZJC">
-                                <modifierMask key="keyEquivalentModifierMask"/>
-                                <menu key="submenu" title="Transformations" id="c8a-y6-VQd">
-                                    <items>
-                                        <menuItem title="Make Upper Case" id="vmV-6d-7jI">
-                                            <modifierMask key="keyEquivalentModifierMask"/>
-                                            <connections>
-                                                <action selector="uppercaseWord:" target="-1" id="sPh-Tk-edu"/>
-                                            </connections>
-                                        </menuItem>
-                                        <menuItem title="Make Lower Case" id="d9M-CD-aMd">
-                                            <modifierMask key="keyEquivalentModifierMask"/>
-                                            <connections>
-                                                <action selector="lowercaseWord:" target="-1" id="iUZ-b5-hil"/>
-                                            </connections>
-                                        </menuItem>
-                                        <menuItem title="Capitalize" id="UEZ-Bs-lqG">
-                                            <modifierMask key="keyEquivalentModifierMask"/>
-                                            <connections>
-                                                <action selector="capitalizeWord:" target="-1" id="26H-TL-nsh"/>
-                                            </connections>
-                                        </menuItem>
-                                    </items>
-                                </menu>
-                            </menuItem>
-                            <menuItem title="Speech" id="xrE-MZ-jX0">
-                                <modifierMask key="keyEquivalentModifierMask"/>
-                                <menu key="submenu" title="Speech" id="3rS-ZA-NoH">
-                                    <items>
-                                        <menuItem title="Start Speaking" id="Ynk-f8-cLZ">
-                                            <modifierMask key="keyEquivalentModifierMask"/>
-                                            <connections>
-                                                <action selector="startSpeaking:" target="-1" id="654-Ng-kyl"/>
-                                            </connections>
-                                        </menuItem>
-                                        <menuItem title="Stop Speaking" id="Oyz-dy-DGm">
-                                            <modifierMask key="keyEquivalentModifierMask"/>
-                                            <connections>
-                                                <action selector="stopSpeaking:" target="-1" id="dX8-6p-jy9"/>
-                                            </connections>
-                                        </menuItem>
-                                    </items>
-                                </menu>
-                            </menuItem>
-                        </items>
-                    </menu>
-                </menuItem>
-                <menuItem title="Format" id="jxT-CU-nIS">
-                    <modifierMask key="keyEquivalentModifierMask"/>
-                    <menu key="submenu" title="Format" id="GEO-Iw-cKr">
-                        <items>
-                            <menuItem title="Font" id="Gi5-1S-RQB">
-                                <modifierMask key="keyEquivalentModifierMask"/>
-                                <menu key="submenu" title="Font" systemMenu="font" id="aXa-aM-Jaq">
-                                    <items>
-                                        <menuItem title="Show Fonts" keyEquivalent="t" id="Q5e-8K-NDq">
-                                            <connections>
-                                                <action selector="orderFrontFontPanel:" target="YLy-65-1bz" id="WHr-nq-2xA"/>
-                                            </connections>
-                                        </menuItem>
-                                        <menuItem title="Bold" tag="2" keyEquivalent="b" id="GB9-OM-e27">
-                                            <connections>
-                                                <action selector="addFontTrait:" target="YLy-65-1bz" id="hqk-hr-sYV"/>
-                                            </connections>
-                                        </menuItem>
-                                        <menuItem title="Italic" tag="1" keyEquivalent="i" id="Vjx-xi-njq">
-                                            <connections>
-                                                <action selector="addFontTrait:" target="YLy-65-1bz" id="IHV-OB-c03"/>
-                                            </connections>
-                                        </menuItem>
-                                        <menuItem title="Underline" keyEquivalent="u" id="WRG-CD-K1S">
-                                            <connections>
-                                                <action selector="underline:" target="-1" id="FYS-2b-JAY"/>
-                                            </connections>
-                                        </menuItem>
-                                        <menuItem isSeparatorItem="YES" id="5gT-KC-WSO"/>
-                                        <menuItem title="Bigger" tag="3" keyEquivalent="+" id="Ptp-SP-VEL">
-                                            <connections>
-                                                <action selector="modifyFont:" target="YLy-65-1bz" id="Uc7-di-UnL"/>
-                                            </connections>
-                                        </menuItem>
-                                        <menuItem title="Smaller" tag="4" keyEquivalent="-" id="i1d-Er-qST">
-                                            <connections>
-                                                <action selector="modifyFont:" target="YLy-65-1bz" id="HcX-Lf-eNd"/>
-                                            </connections>
-                                        </menuItem>
-                                        <menuItem isSeparatorItem="YES" id="kx3-Dk-x3B"/>
-                                        <menuItem title="Kern" id="jBQ-r6-VK2">
-                                            <modifierMask key="keyEquivalentModifierMask"/>
-                                            <menu key="submenu" title="Kern" id="tlD-Oa-oAM">
-                                                <items>
-                                                    <menuItem title="Use Default" id="GUa-eO-cwY">
-                                                        <modifierMask key="keyEquivalentModifierMask"/>
-                                                        <connections>
-                                                            <action selector="useStandardKerning:" target="-1" id="6dk-9l-Ckg"/>
-                                                        </connections>
-                                                    </menuItem>
-                                                    <menuItem title="Use None" id="cDB-IK-hbR">
-                                                        <modifierMask key="keyEquivalentModifierMask"/>
-                                                        <connections>
-                                                            <action selector="turnOffKerning:" target="-1" id="U8a-gz-Maa"/>
-                                                        </connections>
-                                                    </menuItem>
-                                                    <menuItem title="Tighten" id="46P-cB-AYj">
-                                                        <modifierMask key="keyEquivalentModifierMask"/>
-                                                        <connections>
-                                                            <action selector="tightenKerning:" target="-1" id="hr7-Nz-8ro"/>
-                                                        </connections>
-                                                    </menuItem>
-                                                    <menuItem title="Loosen" id="ogc-rX-tC1">
-                                                        <modifierMask key="keyEquivalentModifierMask"/>
-                                                        <connections>
-                                                            <action selector="loosenKerning:" target="-1" id="8i4-f9-FKE"/>
-                                                        </connections>
-                                                    </menuItem>
-                                                </items>
-                                            </menu>
-                                        </menuItem>
-                                        <menuItem title="Ligatures" id="o6e-r0-MWq">
-                                            <modifierMask key="keyEquivalentModifierMask"/>
-                                            <menu key="submenu" title="Ligatures" id="w0m-vy-SC9">
-                                                <items>
-                                                    <menuItem title="Use Default" id="agt-UL-0e3">
-                                                        <modifierMask key="keyEquivalentModifierMask"/>
-                                                        <connections>
-                                                            <action selector="useStandardLigatures:" target="-1" id="7uR-wd-Dx6"/>
-                                                        </connections>
-                                                    </menuItem>
-                                                    <menuItem title="Use None" id="J7y-lM-qPV">
-                                                        <modifierMask key="keyEquivalentModifierMask"/>
-                                                        <connections>
-                                                            <action selector="turnOffLigatures:" target="-1" id="iX2-gA-Ilz"/>
-                                                        </connections>
-                                                    </menuItem>
-                                                    <menuItem title="Use All" id="xQD-1f-W4t">
-                                                        <modifierMask key="keyEquivalentModifierMask"/>
-                                                        <connections>
-                                                            <action selector="useAllLigatures:" target="-1" id="KcB-kA-TuK"/>
-                                                        </connections>
-                                                    </menuItem>
-                                                </items>
-                                            </menu>
-                                        </menuItem>
-                                        <menuItem title="Baseline" id="OaQ-X3-Vso">
-                                            <modifierMask key="keyEquivalentModifierMask"/>
-                                            <menu key="submenu" title="Baseline" id="ijk-EB-dga">
-                                                <items>
-                                                    <menuItem title="Use Default" id="3Om-Ey-2VK">
-                                                        <modifierMask key="keyEquivalentModifierMask"/>
-                                                        <connections>
-                                                            <action selector="unscript:" target="-1" id="0vZ-95-Ywn"/>
-                                                        </connections>
-                                                    </menuItem>
-                                                    <menuItem title="Superscript" id="Rqc-34-cIF">
-                                                        <modifierMask key="keyEquivalentModifierMask"/>
-                                                        <connections>
-                                                            <action selector="superscript:" target="-1" id="3qV-fo-wpU"/>
-                                                        </connections>
-                                                    </menuItem>
-                                                    <menuItem title="Subscript" id="I0S-gh-46l">
-                                                        <modifierMask key="keyEquivalentModifierMask"/>
-                                                        <connections>
-                                                            <action selector="subscript:" target="-1" id="Q6W-4W-IGz"/>
-                                                        </connections>
-                                                    </menuItem>
-                                                    <menuItem title="Raise" id="2h7-ER-AoG">
-                                                        <modifierMask key="keyEquivalentModifierMask"/>
-                                                        <connections>
-                                                            <action selector="raiseBaseline:" target="-1" id="4sk-31-7Q9"/>
-                                                        </connections>
-                                                    </menuItem>
-                                                    <menuItem title="Lower" id="1tx-W0-xDw">
-                                                        <modifierMask key="keyEquivalentModifierMask"/>
-                                                        <connections>
-                                                            <action selector="lowerBaseline:" target="-1" id="OF1-bc-KW4"/>
-                                                        </connections>
-                                                    </menuItem>
-                                                </items>
-                                            </menu>
-                                        </menuItem>
-                                        <menuItem isSeparatorItem="YES" id="Ndw-q3-faq"/>
-                                        <menuItem title="Show Colors" keyEquivalent="C" id="bgn-CT-cEk">
-                                            <connections>
-                                                <action selector="orderFrontColorPanel:" target="-1" id="mSX-Xz-DV3"/>
-                                            </connections>
-                                        </menuItem>
-                                        <menuItem isSeparatorItem="YES" id="iMs-zA-UFJ"/>
-                                        <menuItem title="Copy Style" keyEquivalent="c" id="5Vv-lz-BsD">
-                                            <modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
-                                            <connections>
-                                                <action selector="copyFont:" target="-1" id="GJO-xA-L4q"/>
-                                            </connections>
-                                        </menuItem>
-                                        <menuItem title="Paste Style" keyEquivalent="v" id="vKC-jM-MkH">
-                                            <modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
-                                            <connections>
-                                                <action selector="pasteFont:" target="-1" id="JfD-CL-leO"/>
-                                            </connections>
-                                        </menuItem>
-                                    </items>
-                                </menu>
-                            </menuItem>
-                            <menuItem title="Text" id="Fal-I4-PZk">
-                                <modifierMask key="keyEquivalentModifierMask"/>
-                                <menu key="submenu" title="Text" id="d9c-me-L2H">
-                                    <items>
-                                        <menuItem title="Align Left" keyEquivalent="{" id="ZM1-6Q-yy1">
-                                            <connections>
-                                                <action selector="alignLeft:" target="-1" id="zUv-R1-uAa"/>
-                                            </connections>
-                                        </menuItem>
-                                        <menuItem title="Center" keyEquivalent="|" id="VIY-Ag-zcb">
-                                            <connections>
-                                                <action selector="alignCenter:" target="-1" id="spX-mk-kcS"/>
-                                            </connections>
-                                        </menuItem>
-                                        <menuItem title="Justify" id="J5U-5w-g23">
-                                            <modifierMask key="keyEquivalentModifierMask"/>
-                                            <connections>
-                                                <action selector="alignJustified:" target="-1" id="ljL-7U-jND"/>
-                                            </connections>
-                                        </menuItem>
-                                        <menuItem title="Align Right" keyEquivalent="}" id="wb2-vD-lq4">
-                                            <connections>
-                                                <action selector="alignRight:" target="-1" id="r48-bG-YeY"/>
-                                            </connections>
-                                        </menuItem>
-                                        <menuItem isSeparatorItem="YES" id="4s2-GY-VfK"/>
-                                        <menuItem title="Writing Direction" id="H1b-Si-o9J">
-                                            <modifierMask key="keyEquivalentModifierMask"/>
-                                            <menu key="submenu" title="Writing Direction" id="8mr-sm-Yjd">
-                                                <items>
-                                                    <menuItem title="Paragraph" enabled="NO" id="ZvO-Gk-QUH">
-                                                        <modifierMask key="keyEquivalentModifierMask"/>
-                                                    </menuItem>
-                                                    <menuItem id="YGs-j5-SAR">
-                                                        <string key="title">	Default</string>
-                                                        <modifierMask key="keyEquivalentModifierMask"/>
-                                                        <connections>
-                                                            <action selector="makeBaseWritingDirectionNatural:" target="-1" id="qtV-5e-UBP"/>
-                                                        </connections>
-                                                    </menuItem>
-                                                    <menuItem id="Lbh-J2-qVU">
-                                                        <string key="title">	Left to Right</string>
-                                                        <modifierMask key="keyEquivalentModifierMask"/>
-                                                        <connections>
-                                                            <action selector="makeBaseWritingDirectionLeftToRight:" target="-1" id="S0X-9S-QSf"/>
-                                                        </connections>
-                                                    </menuItem>
-                                                    <menuItem id="jFq-tB-4Kx">
-                                                        <string key="title">	Right to Left</string>
-                                                        <modifierMask key="keyEquivalentModifierMask"/>
-                                                        <connections>
-                                                            <action selector="makeBaseWritingDirectionRightToLeft:" target="-1" id="5fk-qB-AqJ"/>
-                                                        </connections>
-                                                    </menuItem>
-                                                    <menuItem isSeparatorItem="YES" id="swp-gr-a21"/>
-                                                    <menuItem title="Selection" enabled="NO" id="cqv-fj-IhA">
-                                                        <modifierMask key="keyEquivalentModifierMask"/>
-                                                    </menuItem>
-                                                    <menuItem id="Nop-cj-93Q">
-                                                        <string key="title">	Default</string>
-                                                        <modifierMask key="keyEquivalentModifierMask"/>
-                                                        <connections>
-                                                            <action selector="makeTextWritingDirectionNatural:" target="-1" id="lPI-Se-ZHp"/>
-                                                        </connections>
-                                                    </menuItem>
-                                                    <menuItem id="BgM-ve-c93">
-                                                        <string key="title">	Left to Right</string>
-                                                        <modifierMask key="keyEquivalentModifierMask"/>
-                                                        <connections>
-                                                            <action selector="makeTextWritingDirectionLeftToRight:" target="-1" id="caW-Bv-w94"/>
-                                                        </connections>
-                                                    </menuItem>
-                                                    <menuItem id="RB4-Sm-HuC">
-                                                        <string key="title">	Right to Left</string>
-                                                        <modifierMask key="keyEquivalentModifierMask"/>
-                                                        <connections>
-                                                            <action selector="makeTextWritingDirectionRightToLeft:" target="-1" id="EXD-6r-ZUu"/>
-                                                        </connections>
-                                                    </menuItem>
-                                                </items>
-                                            </menu>
-                                        </menuItem>
-                                        <menuItem isSeparatorItem="YES" id="fKy-g9-1gm"/>
-                                        <menuItem title="Show Ruler" id="vLm-3I-IUL">
-                                            <modifierMask key="keyEquivalentModifierMask"/>
-                                            <connections>
-                                                <action selector="toggleRuler:" target="-1" id="FOx-HJ-KwY"/>
-                                            </connections>
-                                        </menuItem>
-                                        <menuItem title="Copy Ruler" keyEquivalent="c" id="MkV-Pr-PK5">
-                                            <modifierMask key="keyEquivalentModifierMask" control="YES" command="YES"/>
-                                            <connections>
-                                                <action selector="copyRuler:" target="-1" id="71i-fW-3W2"/>
-                                            </connections>
-                                        </menuItem>
-                                        <menuItem title="Paste Ruler" keyEquivalent="v" id="LVM-kO-fVI">
-                                            <modifierMask key="keyEquivalentModifierMask" control="YES" command="YES"/>
-                                            <connections>
-                                                <action selector="pasteRuler:" target="-1" id="cSh-wd-qM2"/>
-                                            </connections>
-                                        </menuItem>
-                                    </items>
-                                </menu>
-                            </menuItem>
-                        </items>
-                    </menu>
-                </menuItem>
-                <menuItem title="View" id="H8h-7b-M4v">
-                    <modifierMask key="keyEquivalentModifierMask"/>
-                    <menu key="submenu" title="View" id="HyV-fh-RgO">
-                        <items>
-                            <menuItem title="Show Toolbar" keyEquivalent="t" id="snW-S8-Cw5">
-                                <modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
-                                <connections>
-                                    <action selector="toggleToolbarShown:" target="-1" id="BXY-wc-z0C"/>
-                                </connections>
-                            </menuItem>
-                            <menuItem title="Customize Toolbar…" id="1UK-8n-QPP">
-                                <modifierMask key="keyEquivalentModifierMask"/>
-                                <connections>
-                                    <action selector="runToolbarCustomizationPalette:" target="-1" id="pQI-g3-MTW"/>
-                                </connections>
-                            </menuItem>
-                        </items>
-                    </menu>
-                </menuItem>
-                <menuItem title="Window" id="aUF-d1-5bR">
-                    <modifierMask key="keyEquivalentModifierMask"/>
-                    <menu key="submenu" title="Window" systemMenu="window" id="Td7-aD-5lo">
-                        <items>
-                            <menuItem title="Minimize" keyEquivalent="m" id="OY7-WF-poV">
-                                <connections>
-                                    <action selector="performMiniaturize:" target="-1" id="VwT-WD-YPe"/>
-                                </connections>
-                            </menuItem>
-                            <menuItem title="Zoom" id="R4o-n2-Eq4">
-                                <modifierMask key="keyEquivalentModifierMask"/>
-                                <connections>
-                                    <action selector="performZoom:" target="-1" id="DIl-cC-cCs"/>
-                                </connections>
-                            </menuItem>
-                            <menuItem isSeparatorItem="YES" id="eu3-7i-yIM"/>
-                            <menuItem title="Bring All to Front" id="LE2-aR-0XJ">
-                                <modifierMask key="keyEquivalentModifierMask"/>
-                                <connections>
-                                    <action selector="arrangeInFront:" target="-1" id="DRN-fu-gQh"/>
-                                </connections>
-                            </menuItem>
-                        </items>
-                    </menu>
-                </menuItem>
-                <menuItem title="Help" id="wpr-3q-Mcd">
-                    <modifierMask key="keyEquivalentModifierMask"/>
-                    <menu key="submenu" title="Help" systemMenu="help" id="F2S-fz-NVQ">
-                        <items>
-                            <menuItem title="Sky Help" keyEquivalent="?" id="FKE-Sm-Kum">
-                                <connections>
-                                    <action selector="showHelp:" target="-1" id="y7X-2Q-9no"/>
-                                </connections>
-                            </menuItem>
-                        </items>
-                    </menu>
-                </menuItem>
-            </items>
-        </menu>
-        <window title="Sky" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" releasedWhenClosed="NO" animationBehavior="default" id="QvC-M9-y7g" customClass="SkyWindow">
-            <windowStyleMask key="styleMask" titled="YES" closable="YES" miniaturizable="YES" resizable="YES"/>
-            <windowPositionMask key="initialPositionMask" leftStrut="YES" rightStrut="YES" topStrut="YES" bottomStrut="YES"/>
-            <rect key="contentRect" x="335" y="390" width="480" height="360"/>
-            <rect key="screenRect" x="0.0" y="0.0" width="1920" height="1177"/>
-            <view key="contentView" id="EiT-Mj-1SZ">
-                <rect key="frame" x="0.0" y="0.0" width="480" height="360"/>
-                <autoresizingMask key="autoresizingMask"/>
-                <subviews>
-                    <openGLView autoresizesSubviews="NO" useAuxiliaryDepthBufferStencil="NO" useDoubleBufferingEnabled="YES" allowOffline="YES" translatesAutoresizingMaskIntoConstraints="NO" id="AUD-Hu-um3">
-                        <rect key="frame" x="0.0" y="0.0" width="480" height="360"/>
-                    </openGLView>
-                </subviews>
-                <constraints>
-                    <constraint firstAttribute="trailing" secondItem="AUD-Hu-um3" secondAttribute="trailing" id="9W1-4Z-nsQ"/>
-                    <constraint firstItem="AUD-Hu-um3" firstAttribute="top" secondItem="EiT-Mj-1SZ" secondAttribute="top" id="KpO-qK-Zhv"/>
-                    <constraint firstAttribute="bottom" secondItem="AUD-Hu-um3" secondAttribute="bottom" id="Myy-UN-4eQ"/>
-                    <constraint firstItem="AUD-Hu-um3" firstAttribute="leading" secondItem="EiT-Mj-1SZ" secondAttribute="leading" id="gf3-3r-c0N"/>
-                </constraints>
-            </view>
-            <connections>
-                <outlet property="renderSurface" destination="AUD-Hu-um3" id="0jv-sx-91g"/>
-            </connections>
-            <point key="canvasLocation" x="128" y="455"/>
-        </window>
-    </objects>
-</document>
diff --git a/examples/game/pubspec.yaml b/examples/game/pubspec.yaml
deleted file mode 100644
index dccb772..0000000
--- a/examples/game/pubspec.yaml
+++ /dev/null
@@ -1,15 +0,0 @@
-name: asteroids
-dependencies:
-  flutter: 
-    '0.0.16'
-  sky_tools: any
-  flutter_sprites: 
-    '0.0.13'
-  box2d: any
-dependency_overrides:
-  material_design_icons:
-    path: ../../sky/packages/material_design_icons
-  flutter:
-    path: ../../sky/packages/sky
-  flutter_sprites:
-    path: ../../skysprites
diff --git a/examples/game/test_bed.dart b/examples/game/test_bed.dart
deleted file mode 100644
index b4cabd7..0000000
--- a/examples/game/test_bed.dart
+++ /dev/null
@@ -1,58 +0,0 @@
-import 'dart:ui';
-
-import 'package:flutter/material.dart';
-import 'package:flutter/rendering.dart';
-import 'package:flutter/services.dart';
-import 'package:flutter/widgets.dart';
-import 'package:flutter_sprites/flutter_sprites.dart';
-
-AssetBundle _initBundle() {
-  if (rootBundle != null)
-    return rootBundle;
-  return new NetworkAssetBundle(Uri.base);
-}
-
-final AssetBundle _bundle = _initBundle();
-
-ImageMap _images;
-SpriteSheet _spriteSheet;
-TestBedApp _app;
-
-main() async {
-  _images = new ImageMap(_bundle);
-
-  await _images.load(<String>[
-    'assets/sprites.png'
-  ]);
-
-  String json = await _bundle.loadString('assets/sprites.json');
-  _spriteSheet = new SpriteSheet(_images['assets/sprites.png'], json);
-
-  _app = new TestBedApp();
-  runApp(_app);
-}
-
-class TestBedApp extends MaterialApp {
-
-  Widget build() {
-    ThemeData theme = new ThemeData(
-      brightness: ThemeBrightness.light,
-      primarySwatch: Colors.purple
-    );
-
-    return new Theme(
-      data: theme,
-      child: new Title(
-        title: 'Test Bed',
-        child: new SpriteWidget(
-          new TestBed(),
-          SpriteBoxTransformMode.letterbox
-        )
-      )
-    );
-  }
-}
-
-class TestBed extends NodeWithSize {
-  TestBed() : super(new Size(1024.0, 1024.0));
-}
diff --git a/examples/game/test_drawatlas.dart b/examples/game/test_drawatlas.dart
deleted file mode 100644
index 96812e7..0000000
--- a/examples/game/test_drawatlas.dart
+++ /dev/null
@@ -1,75 +0,0 @@
-import 'dart:ui';
-
-import 'package:flutter/material.dart';
-import 'package:flutter/rendering.dart';
-import 'package:flutter/services.dart';
-import 'package:flutter/widgets.dart';
-import 'package:flutter_sprites/flutter_sprites.dart';
-
-AssetBundle _initBundle() {
-  if (rootBundle != null)
-    return rootBundle;
-  return new NetworkAssetBundle(Uri.base);
-}
-
-final AssetBundle _bundle = _initBundle();
-
-ImageMap _images;
-SpriteSheet _spriteSheet;
-
-final ThemeData _theme = new ThemeData(
-  brightness: ThemeBrightness.light,
-  primarySwatch: Colors.purple
-);
-
-main() async {
-  _images = new ImageMap(_bundle);
-
-  await _images.load(<String>[
-    'assets/sprites.png'
-  ]);
-
-  String json = await _bundle.loadString('assets/sprites.json');
-  _spriteSheet = new SpriteSheet(_images['assets/sprites.png'], json);
-
-  runApp(new MaterialApp(
-    title: 'Test drawAtlas',
-    theme: _theme,
-    routes: <String, RouteBuilder>{
-      '/': (RouteArguments args) {
-        return new SpriteWidget(
-          new TestDrawAtlas(),
-          SpriteBoxTransformMode.fixedWidth
-        );
-      }
-    }
-  ));
-}
-
-class TestDrawAtlas extends NodeWithSize {
-  TestDrawAtlas() : super(new Size(1024.0, 1024.0));
-
-  void paint(PaintingCanvas canvas) {
-    List<RSTransform> transforms = <RSTransform>[
-      new RSTransform(1.0, 0.0, 100.0, 100.0)
-    ];
-    List<Rect> rects = <Rect>[
-      _spriteSheet["ship.png"].frame
-    ];
-    List<Color> colors = <Color>[
-      new Color(0xffffffff)
-    ];
-
-    canvas.drawAtlas(
-      _spriteSheet.image,
-      transforms,
-      rects,
-      colors,
-      TransferMode.src,
-      null,
-      new Paint()
-        ..filterQuality = FilterQuality.low
-        ..isAntiAlias = false
-    );
-  }
-}
diff --git a/examples/game/test_performance.dart b/examples/game/test_performance.dart
deleted file mode 100644
index 50d9bbb..0000000
--- a/examples/game/test_performance.dart
+++ /dev/null
@@ -1,297 +0,0 @@
-import 'dart:ui' as ui;
-import 'dart:math' as math;
-
-import 'package:flutter/material.dart';
-import 'package:flutter/rendering.dart';
-import 'package:flutter/services.dart';
-import 'package:flutter/widgets.dart';
-import 'package:flutter_sprites/flutter_sprites.dart';
-
-AssetBundle _initBundle() {
-  if (rootBundle != null)
-    return rootBundle;
-  return new NetworkAssetBundle(Uri.base);
-}
-
-final AssetBundle _bundle = _initBundle();
-
-ImageMap _images;
-SpriteSheet _spriteSheet;
-
-final ThemeData _theme = new ThemeData(
-  brightness: ThemeBrightness.light,
-  primarySwatch: Colors.purple
-);
-
-main() async {
-  _images = new ImageMap(_bundle);
-
-  await _images.load(<String>[
-    'assets/sprites.png'
-  ]);
-
-  String json = await _bundle.loadString('assets/sprites.json');
-  _spriteSheet = new SpriteSheet(_images['assets/sprites.png'], json);
-
-  runApp(new MaterialApp(
-    title: 'Test Sprite Performance',
-    theme: _theme,
-    routes: <String, RouteBuilder>{
-      '/': (RouteArguments args) => new SpriteWidget(new TestPerformance())
-    }
-  ));
-}
-
-class TestPerformance extends NodeWithSize {
-
-  TestPerformance() : super(new Size(1024.0, 1024.0));
-
-  final int numFramesPerTest = 100;
-  final int numTests = 5;
-
-  int test = 0;
-  int frame = 0;
-  int testStartTime;
-
-  void update(double dt) {
-    if (frame % numFramesPerTest == 0) {
-      if (test > 0 && test <= numTests) {
-        // End last test
-        int currentTime = new DateTime.now().millisecondsSinceEpoch;
-        int totalTestTime = currentTime - testStartTime;
-        double millisPerFrame =
-          totalTestTime.toDouble() / numFramesPerTest.toDouble();
-        print("  - RESULT fps: ${(1.0 / (millisPerFrame / 1000)).toStringAsFixed(1)} millis/frame: ${millisPerFrame.round()}");
-
-        // Clear test
-        removeAllChildren();
-      }
-
-      if (test < numTests) {
-        // Start new test
-        PerformanceTest perfTest = createTest(test);
-        addChild(perfTest);
-
-        print("TEST ${test + 1}/$numTests STARTING: ${perfTest.name}");
-
-        testStartTime = new DateTime.now().millisecondsSinceEpoch;
-      }
-      test++;
-    }
-    frame++;
-  }
-
-  PerformanceTest createTest(int n) {
-    if (test == 0) {
-      // Test atlas performance
-      return new TestPerformanceAtlas();
-    } else if (test == 1) {
-      // Test atlas performance
-      return new TestPerformanceAtlas2();
-    } else if (test == 2) {
-      // Test sprite performance
-      return new TestPerformanceSprites();
-    } else if (test == 3) {
-      // Test sprite performance
-      return new TestPerformanceSprites2();
-    } else if (test == 4) {
-      // Test particle performance
-      return new TestPerformanceParticles();
-    }
-    return null;
-  }
-}
-
-abstract class PerformanceTest extends Node {
-  String get name;
-}
-
-class TestPerformanceParticles extends PerformanceTest {
-  String get name => "64 particle systems";
-
-  final grid = 8;
-  TestPerformanceParticles() {
-    for (int x = 0; x < grid; x++) {
-      for (int y = 0; y < grid; y++) {
-        ParticleSystem particles = new ParticleSystem(
-          _spriteSheet["explosion_particle.png"],
-          rotateToMovement: true,
-          startRotation:90.0,
-          startRotationVar: 0.0,
-          endRotation: 90.0,
-          startSize: 0.3,
-          startSizeVar: 0.1,
-          endSize: 0.3,
-          endSizeVar: 0.1,
-          emissionRate:100.0,
-          greenVar: 127,
-          redVar: 127
-        );
-        particles.position = new Point(x * 1024.0 / (grid - 1), y * 1024.0 / (grid - 1));
-        addChild(particles);
-      }
-    }
-  }
-}
-
-class TestPerformanceSprites extends PerformanceTest {
-  String get name => "1001 sprites (24% offscreen)";
-
-  final int grid = 100;
-
-  TestPerformanceSprites() {
-    for (int x = 0; x < grid; x++) {
-      for (int y = 0; y < grid; y++) {
-        Sprite sprite = new Sprite(_spriteSheet["asteroid_big_1.png"]);
-        sprite.scale = 1.0;
-        sprite.position = new Point(x * 1024.0 / (grid - 1), y * 1024.0 / (grid - 1));
-        addChild(sprite);
-      }
-    }
-
-    Sprite sprite = new Sprite(_spriteSheet["asteroid_big_1.png"]);
-    sprite.position = new Point(512.0, 512.0);
-    addChild(sprite);
-  }
-
-  void update(double dt) {
-    for (Node child in children) {
-      final Sprite sprite = child;
-      sprite.rotation += 1;
-    }
-  }
-}
-
-class TestPerformanceSprites2 extends PerformanceTest {
-  String get name => "1001 sprites (24% offscreen never added)";
-
-  final int grid = 100;
-
-  TestPerformanceSprites2() {
-    for (int x = 12; x < grid - 12; x++) {
-      for (int y = 0; y < grid; y++) {
-        Sprite sprite = new Sprite(_spriteSheet["asteroid_big_1.png"]);
-        sprite.scale = 1.0;
-        sprite.position = new Point(x * 1024.0 / (grid - 1), y * 1024.0 / (grid - 1));
-        addChild(sprite);
-      }
-    }
-
-    Sprite sprite = new Sprite(_spriteSheet["asteroid_big_1.png"]);
-    sprite.position = new Point(512.0, 512.0);
-    addChild(sprite);
-  }
-
-  void update(double dt) {
-    for (Node child in children) {
-      final Sprite sprite = child;
-      sprite.rotation += 1;
-    }
-  }
-}
-
-class TestPerformanceAtlas extends PerformanceTest {
-  String get name => "1001 rects drawAtlas (24% offscreen)";
-
-  final int grid = 100;
-
-  double rotation = 0.0;
-  List<Rect> rects = <Rect>[];
-  Paint cachedPaint = new Paint()
-    ..filterQuality = ui.FilterQuality.low
-    ..isAntiAlias = false;
-
-  TestPerformanceAtlas() {
-    for (int x = 0; x < grid; x++) {
-      for (int y = 0; y < grid; y++) {
-        rects.add(_spriteSheet["asteroid_big_1.png"].frame);
-      }
-    }
-    rects.add(_spriteSheet["asteroid_big_1.png"].frame);
-  }
-
-  void paint(PaintingCanvas canvas) {
-    // Setup transforms
-    List<ui.RSTransform> transforms = <ui.RSTransform>[];
-
-    for (int x = 0; x < grid; x++) {
-      for (int y = 0; y < grid; y++) {
-        double xPos = x * 1024.0 / (grid - 1);
-        double yPos = y * 1024.0 / (grid - 1);
-
-        transforms.add(createTransform(xPos, yPos, rects[0].size.width / 2.0, rects[0].size.height / 2.0, rotation, 1.0));
-      }
-    }
-
-    transforms.add(createTransform(512.0, 512.0, rects[0].size.width / 2.0, rects[0].size.height / 2.0, rotation, 1.0));
-
-    // Draw atlas
-    Rect cullRect = spriteBox.visibleArea;
-    canvas.drawAtlas(_spriteSheet.image, transforms, rects, null, null, cullRect, cachedPaint);
-  }
-
-  void update(double dt) {
-    rotation += 1.0;
-  }
-
-  ui.RSTransform createTransform(double x, double y, double ax, double ay, double rot, double scale) {
-    double scos = math.cos(convertDegrees2Radians(rot)) * scale;
-    double ssin = math.sin(convertDegrees2Radians(rot)) * scale;
-    double tx = x + -scos * ax + ssin * ay;
-    double ty = y + -ssin * ax - scos * ay;
-    return new ui.RSTransform(scos, ssin, tx, ty);
-  }
-}
-
-class TestPerformanceAtlas2 extends PerformanceTest {
-  String get name => "1001 rects drawAtlas (24% offscreen never added)";
-
-  final int grid = 100;
-
-  double rotation = 0.0;
-  List<Rect> rects = <Rect>[];
-  Paint cachedPaint = new Paint()
-    ..filterQuality = ui.FilterQuality.low
-    ..isAntiAlias = false;
-
-  TestPerformanceAtlas2() {
-    for (int x = 12; x < grid - 12; x++) {
-      for (int y = 0; y < grid; y++) {
-        rects.add(_spriteSheet["asteroid_big_1.png"].frame);
-      }
-    }
-    rects.add(_spriteSheet["asteroid_big_1.png"].frame);
-  }
-
-  void paint(PaintingCanvas canvas) {
-    // Setup transforms
-    List<ui.RSTransform> transforms = <ui.RSTransform>[];
-
-    for (int x = 12; x < grid - 12; x++) {
-      for (int y = 0; y < grid; y++) {
-        double xPos = x * 1024.0 / (grid - 1);
-        double yPos = y * 1024.0 / (grid - 1);
-
-        transforms.add(createTransform(xPos, yPos, rects[0].size.width / 2.0, rects[0].size.height / 2.0, rotation, 1.0));
-      }
-    }
-
-    transforms.add(createTransform(512.0, 512.0, rects[0].size.width / 2.0, rects[0].size.height / 2.0, rotation, 1.0));
-
-    // Draw atlas
-    Rect cullRect = spriteBox.visibleArea;
-    canvas.drawAtlas(_spriteSheet.image, transforms, rects, null, null, cullRect, cachedPaint);
-  }
-
-  void update(double dt) {
-    rotation += 1.0;
-  }
-
-  ui.RSTransform createTransform(double x, double y, double ax, double ay, double rot, double scale) {
-    double scos = math.cos(convertDegrees2Radians(rot)) * scale;
-    double ssin = math.sin(convertDegrees2Radians(rot)) * scale;
-    double tx = x + -scos * ax + ssin * ay;
-    double ty = y + -ssin * ax - scos * ay;
-    return new ui.RSTransform(scos, ssin, tx, ty);
-  }
-}
diff --git a/examples/game/test_performance_computation.dart b/examples/game/test_performance_computation.dart
deleted file mode 100644
index 4c42e4e..0000000
--- a/examples/game/test_performance_computation.dart
+++ /dev/null
@@ -1,308 +0,0 @@
-import 'dart:math' as math;
-import 'dart:typed_data';
-
-import 'package:vector_math/vector_math_64.dart';
-
-main() {
-  runTest();
-}
-
-const int numSystems = 1000;
-const int numFrames = 1000;
-
-void runTest() {
-  int timeStart;
-  timeStart = new DateTime.now().millisecondsSinceEpoch;
-
-  // Create systems
-  List<TestParticleSystem> systems = <TestParticleSystem>[];
-  for (int i = 0; i < numSystems; i++)
-    systems.add(new TestParticleSystem());
-
-  int timeAfterCreate = new DateTime.now().millisecondsSinceEpoch;
-  print("TIME creation ${(timeAfterCreate - timeStart) / 1000.0}");
-  timeStart =  new DateTime.now().millisecondsSinceEpoch;
-
-  // Update systems
-  for (int frame = 0; frame < numFrames; frame++) {
-    for (int i = 0; i < numSystems; i++) {
-      systems[i].update(1.0 / 60.0);
-    }
-  }
-
-  int timeAfterUpdates = new DateTime.now().millisecondsSinceEpoch;
-  print("TIME updates ${(timeAfterUpdates - timeStart) / 1000.0}");
-  timeStart =  new DateTime.now().millisecondsSinceEpoch;
-
-  // Calculate matrices
-  for (int frame = 0; frame < numFrames; frame++) {
-    for (int i = 0; i < numSystems; i++) {
-      systems[i].paint();
-    }
-  }
-
-  int timeAfterMatrices = new DateTime.now().millisecondsSinceEpoch;
-  print("TIME matrices ${(timeAfterMatrices - timeStart) / 1000.0}");
-}
-
-class TestParticle {
-  Vector2 pos;
-  Vector2 startPos;
-
-  double colorPos;
-  double deltaColorPos;
-
-  double size;
-  double deltaSize;
-
-  double rotation;
-  double deltaRotation;
-
-  double timeToLive;
-
-  Vector2 dir;
-
-  double radialAccel;
-  double tangentialAccel;
-
-  Float64List simpleColorSequence;
-
-  Matrix4 transform;
-}
-
-class TestParticleSystem {
-  double life;
-  double lifeVar;
-
-  Vector2 posVar;
-
-  double startSize;
-  double startSizeVar;
-
-  double endSize;
-  double endSizeVar;
-
-  double startRotation;
-  double startRotationVar;
-
-  double endRotation;
-  double endRotationVar;
-
-  double direction;
-  double directionVar;
-
-  double speed;
-  double speedVar;
-
-  double radialAcceleration;
-  double radialAccelerationVar;
-
-  double tangentialAcceleration;
-  double tangentialAccelerationVar;
-
-  Vector2 gravity;
-
-  int maxParticles;
-  int numParticlesToEmit;
-  double emissionRate;
-
-  List<TestParticle> _particles;
-
-  double _emitCounter;
-  int _numEmittedParticles = 0;
-
-  TestParticleSystem({this.life: 1.5,
-                  this.lifeVar: 0.0,
-                  this.startSize: 2.5,
-                  this.startSizeVar: 0.5,
-                  this.endSize: 0.0,
-                  this.endSizeVar: 0.0,
-                  this.startRotation: 0.0,
-                  this.startRotationVar: 0.0,
-                  this.endRotation: 0.0,
-                  this.endRotationVar: 0.0,
-                  this.direction: 0.0,
-                  this.directionVar: 360.0,
-                  this.speed: 100.0,
-                  this.speedVar: 50.0,
-                  this.radialAcceleration: 0.0,
-                  this.radialAccelerationVar: 0.0,
-                  this.tangentialAcceleration: 0.0,
-                  this.tangentialAccelerationVar: 0.0,
-                  this.gravity,
-                  this.maxParticles: 100,
-                  this.emissionRate: 50.0,
-                  this.numParticlesToEmit: 0}) {
-    posVar = new Vector2.zero();
-    _particles = new List<TestParticle>();
-    _emitCounter = 0.0;
-    gravity = new Vector2.zero();
-  }
-
-  void update(double dt) {
-    // Create new particles
-    double rate = 1.0 / emissionRate;
-
-    if (_particles.length < maxParticles) {
-      _emitCounter += dt;
-    }
-
-    while(_particles.length < maxParticles
-       && _emitCounter > rate
-       && (numParticlesToEmit == 0 || _numEmittedParticles < numParticlesToEmit)) {
-      // Add a new particle
-      _addParticle();
-      _emitCounter -= rate;
-    }
-
-    // Iterate over all particles
-    for (int i = _particles.length -1; i >= 0; i--) {
-      TestParticle particle = _particles[i];
-
-      // Manage life time
-      particle.timeToLive -= dt;
-      if (particle.timeToLive <= 0) {
-        _particles.removeAt(i);
-        continue;
-      }
-
-      // Update the particle
-
-      // Radial acceleration
-      Vector2 radial;
-      if (particle.pos[0] != 0 || particle.pos[1] != 0) {
-        radial = new Vector2.copy(particle.pos).normalize();
-      } else {
-        radial = new Vector2.zero();
-      }
-      Vector2 tangential = new Vector2.copy(radial);
-      radial.scale(particle.radialAccel);
-
-      // Tangential acceleration
-      double newY = tangential.x;
-      tangential.x = -tangential.y;
-      tangential.y = newY;
-      tangential.scale(particle.tangentialAccel);
-
-      // (gravity + radial + tangential) * dt
-      Vector2 accel = (gravity + radial + tangential).scale(dt);
-      particle.dir += accel;
-
-      // Update particle position
-      particle.pos[0] += particle.dir[0] * dt;
-      particle.pos[1] += particle.dir[1] * dt;
-
-      // Size
-      particle.size = math.max(particle.size + particle.deltaSize * dt, 0.0);
-
-      // Angle
-      particle.rotation += particle.deltaRotation * dt;
-
-      // Color
-      if (particle.simpleColorSequence != null) {
-        for (int i = 0; i < 4; i++) {
-          particle.simpleColorSequence[i] += particle.simpleColorSequence[i + 4] * dt;
-        }
-      } else {
-        particle.colorPos = math.min(particle.colorPos + particle.deltaColorPos * dt, 1.0);
-      }
-    }
-  }
-
-  void _addParticle() {
-
-    TestParticle particle = new TestParticle();
-
-    // Time to live
-    particle.timeToLive = math.max(life + lifeVar * randomSignedDouble(), 0.0);
-
-    // Position
-    Vector2 srcPos = new Vector2.zero();
-    particle.pos = new Vector2(srcPos.x + posVar.x * randomSignedDouble(),
-                               srcPos.y + posVar.y * randomSignedDouble());
-
-    // Size
-    particle.size = math.max(startSize + startSizeVar * randomSignedDouble(), 0.0);
-    double endSizeFinal = math.max(endSize + endSizeVar * randomSignedDouble(), 0.0);
-    particle.deltaSize = (endSizeFinal - particle.size) / particle.timeToLive;
-
-    // Rotation
-    particle.rotation = startRotation + startRotationVar * randomSignedDouble();
-    double endRotationFinal = endRotation + endRotationVar * randomSignedDouble();
-    particle.deltaRotation = (endRotationFinal - particle.rotation) / particle.timeToLive;
-
-    // Direction
-    double dirRadians = radians(direction + directionVar * randomSignedDouble());
-    Vector2 dirVector = new Vector2(math.cos(dirRadians), math.sin(dirRadians));
-    double speedFinal = speed + speedVar * randomSignedDouble();
-    particle.dir = dirVector.scale(speedFinal);
-
-    // Radial acceleration
-    particle.radialAccel = radialAcceleration + radialAccelerationVar * randomSignedDouble();
-
-    // Tangential acceleration
-    particle.tangentialAccel = tangentialAcceleration + tangentialAccelerationVar * randomSignedDouble();
-
-    // Colors
-    particle.simpleColorSequence = new Float64List(8);
-    particle.simpleColorSequence[0] = 255.0;
-    particle.simpleColorSequence[1] = 255.0;
-    particle.simpleColorSequence[2] = 255.0;
-    particle.simpleColorSequence[3] = 255.0;
-
-    particle.simpleColorSequence[4] = 255.0;
-    particle.simpleColorSequence[5] = 0.0;
-    particle.simpleColorSequence[6] = 0.0;
-    particle.simpleColorSequence[7] = 0.0;
-
-    // Transform
-    particle.transform = new Matrix4.identity();
-
-    // Add particle
-    _particles.add(particle);
-    _numEmittedParticles++;
-  }
-
-
-  void paint() {
-
-    if (!printed) {
-      printed = true;
-    }
-
-    for (int i = _particles.length -1; i >= 0; i--) {
-      TestParticle particle = _particles[i];
-      particle.rotation + randomSignedDouble();
-
-      // Transform
-      double c = math.cos(radians(particle.rotation));
-      double s = math.sin(radians(particle.rotation));
-
-      // Create transformation matrix for scale, position and rotation
-      Matrix4 matrix = new Matrix4(c * particle.size, s * particle.size, 0.0, 0.0,
-                 -s * particle.size, c * particle.size, 0.0, 0.0,
-                 0.0, 0.0, 1.0, 0.0,
-                particle.pos.x, particle.pos.y, 0.0, 1.0);
-
-      particle.transform.multiply(matrix);
-    }
-  }
-}
-
-math.Random _random = new math.Random();
-
-bool printed = false;
-
-// Random methods
-
-double randomDouble() {
-  return _random.nextDouble();
-}
-
-double randomSignedDouble() {
-  return _random.nextDouble() * 2.0 - 1.0;
-}
-
-int randomInt(int max) {
-  return _random.nextInt(max);
-}
diff --git a/examples/game/test_physics.dart b/examples/game/test_physics.dart
deleted file mode 100644
index 3252c1d..0000000
--- a/examples/game/test_physics.dart
+++ /dev/null
@@ -1,125 +0,0 @@
-import 'dart:ui';
-
-import 'package:flutter/animation.dart';
-import 'package:flutter/material.dart';
-import 'package:flutter/rendering.dart';
-import 'package:flutter/services.dart';
-import 'package:flutter/widgets.dart';
-import 'package:flutter_sprites/flutter_sprites.dart';
-
-AssetBundle _initBundle() {
-  if (rootBundle != null)
-    return rootBundle;
-  return new NetworkAssetBundle(Uri.base);
-}
-
-final AssetBundle _bundle = _initBundle();
-
-ImageMap _images;
-SpriteSheet _spriteSheet;
-
-main() async {
-  _images = new ImageMap(_bundle);
-
-  await _images.load(<String>[
-    'assets/sprites.png'
-  ]);
-
-  String json = await _bundle.loadString('assets/sprites.json');
-  _spriteSheet = new SpriteSheet(_images['assets/sprites.png'], json);
-
-  runApp(new MaterialApp(
-    title: 'Test Physics',
-    theme: new ThemeData(
-      brightness: ThemeBrightness.light,
-      primarySwatch: Colors.purple
-    ),
-    routes: <String, RouteBuilder>{
-      '/': (RouteArguments args) {
-        return new SpriteWidget(
-          new TestBed(),
-          SpriteBoxTransformMode.letterbox
-        );
-      }
-    }
-  ));
-}
-
-class TestBed extends NodeWithSize {
-  Sprite _obstacle;
-  PhysicsWorld _world;
-  PhysicsGroup _group;
-  PhysicsGroup _group2;
-
-  TestBed() : super(new Size(1024.0, 1024.0)) {
-    _world = new PhysicsWorld(new Offset(0.0, 100.0));
-    _world.drawDebug = true;
-    _group = new PhysicsGroup();
-    _group2 = new PhysicsGroup();
-    _group2.position = new Point(50.0, 50.0);
-    _world.addChild(_group);
-    _world.addChild(_group2);
-
-    _obstacle = new Sprite(_spriteSheet["ship.png"]);
-    _obstacle.position = new Point(512.0, 800.0);
-    _obstacle.size = new Size(64.0, 64.0);
-    _obstacle.scale = 2.0;
-    _obstacle.physicsBody = new PhysicsBody(
-      new PhysicsShapeCircle(Point.origin, 32.0),
-      type: PhysicsBodyType.static,
-      friction: 0.5,
-      tag: "obstacle"
-    );
-    _group.addChild(_obstacle);
-    _world.addContactCallback(myCallback, "obstacle", "ship", PhysicsContactType.begin);
-
-    // Animate group
-    ActionSequence seq = new ActionSequence(<Action>[
-      new ActionTween((Point a) { _group.position = a; }, new Point(-256.0, 0.0), new Point(256.0, 0.0), 1.0, Curves.easeInOut),
-      new ActionTween((Point a) { _group.position = a; }, new Point(256.0, 0.0), new Point(-256.0, 0.0), 1.0, Curves.easeInOut)
-    ]);
-    _group.actions.run(new ActionRepeatForever(seq));
-
-    addChild(_world);
-
-    userInteractionEnabled = true;
-  }
-
-  void myCallback(PhysicsContactType type, PhysicsContact contact) {
-  }
-
-  bool handleEvent(SpriteBoxEvent event) {
-    if (event.type == "pointerdown") {
-      Point pos = convertPointToNodeSpace(event.boxPosition);
-
-      PhysicsGroup group = new PhysicsGroup();
-      group.position = pos;
-      _world.addChild(group);
-
-      Sprite shipA;
-      shipA = new Sprite(_spriteSheet["ship.png"]);
-      shipA.opacity = 0.3;
-      shipA.position = new Point(-40.0, 0.0);
-      shipA.size = new Size(64.0, 64.0);
-      shipA.physicsBody = new PhysicsBody(new PhysicsShapeCircle(Point.origin, 32.0),
-        friction: 0.5,
-        restitution: 0.5,
-        tag: "ship"
-      );
-      group.addChild(shipA);
-
-      Sprite shipB;
-      shipB = new Sprite(_spriteSheet["ship.png"]);
-      shipB.opacity = 0.3;
-      shipB.position = new Point(40.0, 0.0);
-      shipB.size = new Size(64.0, 64.0);
-      shipB.physicsBody = new PhysicsBody(new PhysicsShapePolygon(<Point>[new Point(-25.0, -25.0), new Point(25.0, -25.0), new Point(25.0, 25.0), new Point(-25.0, 25.0)]),
-        friction: 0.5,
-        restitution: 0.5,
-        tag: "ship"
-      );
-      group.addChild(shipB);
-    }
-    return true;
-  }
-}
diff --git a/examples/hello_world/lib/main.dart b/examples/hello_world/lib/main.dart
deleted file mode 100644
index fc37338..0000000
--- a/examples/hello_world/lib/main.dart
+++ /dev/null
@@ -1,7 +0,0 @@
-// Copyright 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:flutter/widgets.dart';
-
-void main() => runApp(new Center(child: new Text('Hello, world!')));
diff --git a/examples/hello_world/pubspec.yaml b/examples/hello_world/pubspec.yaml
deleted file mode 100644
index f823464..0000000
--- a/examples/hello_world/pubspec.yaml
+++ /dev/null
@@ -1,10 +0,0 @@
-name: hello_world
-dependencies:
-  flutter: 
-    '0.0.16'
-  sky_tools: any
-dependency_overrides:
-  material_design_icons:
-    path: ../../sky/packages/material_design_icons
-  flutter:
-    path: ../../sky/packages/sky
diff --git a/examples/mine_digger/BUILD.gn b/examples/mine_digger/BUILD.gn
deleted file mode 100644
index ec5218b..0000000
--- a/examples/mine_digger/BUILD.gn
+++ /dev/null
@@ -1,13 +0,0 @@
-# Copyright 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("//sky/build/sky_app.gni")
-
-sky_app("mine_digger") {
-  main_dart = "lib/main.dart"
-
-  if (is_android) {
-    apk_name = "MineDigger"
-  }
-}
diff --git a/examples/mine_digger/apk/AndroidManifest.xml b/examples/mine_digger/apk/AndroidManifest.xml
deleted file mode 100644
index dbd3bc2..0000000
--- a/examples/mine_digger/apk/AndroidManifest.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright 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.
- -->
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="org.domokit.mine_digger">
-
-    <uses-sdk android:minSdkVersion="14" android:targetSdkVersion="21" />
-    <uses-permission android:name="android.permission.INTERNET"/>
-
-    <application android:name="org.domokit.sky.shell.SkyApplication" android:label="Mine Digger">
-        <activity android:name="org.domokit.sky.shell.SkyActivity"
-                  android:launchMode="singleTask"
-                  android:theme="@android:style/Theme.Black.NoTitleBar"
-                  android:configChanges="orientation|keyboardHidden|keyboard|screenSize"
-                  android:hardwareAccelerated="true">
-            <intent-filter>
-                <action android:name="android.intent.action.MAIN"/>
-                <category android:name="android.intent.category.LAUNCHER"/>
-            </intent-filter>
-        </activity>
-    </application>
- </manifest>
diff --git a/examples/mine_digger/lib/main.dart b/examples/mine_digger/lib/main.dart
deleted file mode 100644
index 6e04a8d..0000000
--- a/examples/mine_digger/lib/main.dart
+++ /dev/null
@@ -1,337 +0,0 @@
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-import 'dart:math';
-
-import 'package:flutter/gestures.dart';
-import 'package:flutter/material.dart';
-import 'package:flutter/painting.dart';
-import 'package:flutter/rendering.dart';
-import 'package:flutter/services.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. MineDiggerApp, which is
-// contains all the logic and two classes that describe the mines:
-// CoveredMineNode and ExposedMineNode, none of them holding state.
-
-// Colors for each mine count (0-8):
-const List<Color> textColors = const <Color>[
-  const Color(0xFF555555),
-  const Color(0xFF0094FF), // blue
-  const Color(0xFF13A023), // green
-  const Color(0xFFDA1414), // red
-  const Color(0xFF1E2347), // black
-  const Color(0xFF7F0037), // dark red
-  const Color(0xFF000000),
-  const Color(0xFF000000),
-  const Color(0xFF000000),
-];
-
-final List<TextStyle> textStyles = textColors.map((Color color) {
-  return new TextStyle(color: color, fontWeight: bold, textAlign: TextAlign.center);
-}).toList();
-
-enum CellState { covered, exploded, cleared, flagged, shown }
-
-class MineDigger extends StatefulComponent {
-  MineDiggerState createState() => new MineDiggerState();
-}
-
-class MineDiggerState extends State<MineDigger> {
-  static const int rows = 9;
-  static const int cols = 9;
-  static const int totalMineCount = 11;
-
-  bool alive;
-  bool hasWon;
-  int detectedCount;
-
-  // |cells| keeps track of the positions of the mines.
-  List<List<bool>> cells;
-  // |uiState| keeps track of the visible player progess.
-  List<List<CellState>> uiState;
-
-  void initState() {
-    super.initState();
-    resetGame();
-  }
-
-  void resetGame() {
-    alive = true;
-    hasWon = false;
-    detectedCount = 0;
-    // Initialize matrices.
-    cells = new List<List<bool>>.generate(rows, (int row) {
-      return new List<bool>.filled(cols, false);
-    });
-    uiState = new List<List<CellState>>.generate(rows, (int row) {
-      return new List<CellState>.filled(cols, CellState.covered);
-    });
-    // Place the mines.
-    Random random = new Random();
-    int minesRemaining = totalMineCount;
-    while (minesRemaining > 0) {
-      int pos = random.nextInt(rows * cols);
-      int row = pos ~/ rows;
-      int col = pos % cols;
-      if (!cells[row][col]) {
-        cells[row][col] = true;
-        minesRemaining--;
-      }
-    }
-  }
-
-  PointerEventListener _pointerDownHandlerFor(int posX, int posY) {
-    return (PointerInputEvent event) {
-      if (event.buttons == 1) {
-        probe(posX, posY);
-      } else if (event.buttons == 2) {
-        flag(posX, posY);
-      }
-    };
-  }
-
-  Widget buildBoard() {
-    bool hasCoveredCell = false;
-    List<Row> flexRows = <Row>[];
-    for (int iy = 0; iy < rows; iy++) {
-      List<Widget> row = <Widget>[];
-      for (int ix = 0; ix < cols; ix++) {
-        CellState state = uiState[iy][ix];
-        int count = mineCount(ix, iy);
-        if (!alive) {
-          if (state != CellState.exploded)
-            state = cells[iy][ix] ? CellState.shown : state;
-        }
-        if (state == CellState.covered || state == CellState.flagged) {
-          row.add(new GestureDetector(
-            onTap: () {
-              if (state == CellState.covered)
-                probe(ix, iy);
-            },
-            onLongPress: () {
-              userFeedback.performHapticFeedback(HapticFeedbackType.LONG_PRESS);
-              flag(ix, iy);
-            },
-            child: new Listener(
-              onPointerDown: _pointerDownHandlerFor(ix, iy),
-              child: new CoveredMineNode(
-                flagged: state == CellState.flagged,
-                posX: ix,
-                posY: iy
-              )
-            )
-          ));
-          if (state == CellState.covered) {
-            // Mutating |hasCoveredCell| here is hacky, but convenient, same
-            // goes for mutating |hasWon| below.
-            hasCoveredCell = true;
-          }
-        } else {
-          row.add(new ExposedMineNode(
-            state: state,
-            count: count
-          ));
-        }
-      }
-      flexRows.add(
-        new Row(
-          row,
-          justifyContent: FlexJustifyContent.center,
-          key: new ValueKey<int>(iy)
-        )
-      );
-    }
-
-    if (!hasCoveredCell) {
-      // all cells uncovered. Are all mines flagged?
-      if ((detectedCount == totalMineCount) && alive) {
-        hasWon = true;
-      }
-    }
-
-    return new Container(
-      padding: new EdgeDims.all(10.0),
-      margin: new EdgeDims.all(10.0),
-      decoration: new BoxDecoration(backgroundColor: const Color(0xFF6B6B6B)),
-      child: new Column(flexRows)
-    );
-  }
-
-  Widget buildToolBar(BuildContext context) {
-    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(context).text.title)
-      )
-    );
-  }
-
-  Widget build(BuildContext context) {
-    // We build the board before we build the toolbar because we compute the win state during build step.
-    Widget board = buildBoard();
-    return new Title(
-      title: 'Mine Digger',
-      child: new Scaffold(
-        toolBar: buildToolBar(context),
-        body: new Container(
-          child: new Center(child: board),
-          decoration: new BoxDecoration(backgroundColor: Colors.grey[50])
-        )
-      )
-    );
-  }
-
-  void handleToolbarPointerDown(PointerInputEvent event) {
-    setState(() {
-      resetGame();
-    });
-  }
-
-  // User action. The user uncovers the cell which can cause losing the game.
-  void probe(int x, int y) {
-    if (!alive)
-      return;
-    if (uiState[y][x] == CellState.flagged)
-      return;
-    setState(() {
-      // Allowed to probe.
-      if (cells[y][x]) {
-        // Probed on a mine --> dead!!
-        uiState[y][x] = CellState.exploded;
-        alive = false;
-      } else {
-        // No mine, uncover nearby if possible.
-        cull(x, y);
-      }
-    });
-  }
-
-  // User action. The user is sure a mine is at this location.
-  void flag(int x, int y) {
-    setState(() {
-      if (uiState[y][x] == CellState.flagged) {
-        uiState[y][x] = CellState.covered;
-        --detectedCount;
-      } else {
-        uiState[y][x] = CellState.flagged;
-        ++detectedCount;
-      }
-    });
-  }
-
-  // Recursively uncovers cells whose totalMineCount is zero.
-  void cull(int x, int y) {
-    if (!inBoard(x, y))
-      return;
-    if (uiState[y][x] == CellState.cleared)
-      return;
-    uiState[y][x] = CellState.cleared;
-
-    if (mineCount(x, y) > 0)
-      return;
-
-    cull(x - 1, y);
-    cull(x + 1, y);
-    cull(x, y - 1);
-    cull(x, y + 1 );
-    cull(x - 1, y - 1);
-    cull(x + 1, y + 1);
-    cull(x + 1, y - 1);
-    cull(x - 1, y + 1);
-  }
-
-  int mineCount(int x, int y) {
-    int count = 0;
-    count += bombs(x - 1, y);
-    count += bombs(x + 1, y);
-    count += bombs(x, y - 1);
-    count += bombs(x, y + 1 );
-    count += bombs(x - 1, y - 1);
-    count += bombs(x + 1, y + 1);
-    count += bombs(x + 1, y - 1);
-    count += bombs(x - 1, y + 1);
-    return count;
-  }
-
-  int bombs(int x, int y) => inBoard(x, y) && cells[y][x] ? 1 : 0;
-
-  bool inBoard(int x, int y) => x >= 0 && x < cols && y >= 0 && y < rows;
-}
-
-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: 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: child
-  );
-}
-
-class CoveredMineNode extends StatelessComponent {
-
-  CoveredMineNode({ this.flagged, this.posX, this.posY });
-
-  final bool flagged;
-  final int posX;
-  final int posY;
-
-  Widget build(BuildContext context) {
-    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 buildCell(inner);
-  }
-}
-
-class ExposedMineNode extends StatelessComponent {
-
-  ExposedMineNode({ this.state, this.count });
-
-  final CellState state;
-  final int count;
-
-  Widget build(BuildContext context) {
-    StyledText text;
-    if (state == CellState.cleared) {
-      // Uncovered cell with nearby mine count.
-      if (count != 0)
-        text = new StyledText(elements : [textStyles[count], '$count']);
-    } else {
-      // Exploded mine or shown mine for 'game over'.
-      int color = state == CellState.exploded ? 3 : 0;
-      text = new StyledText(elements : [textStyles[color], '\u2600']);
-    }
-    return buildCell(buildInnerCell(text));
-  }
-}
-
-void main() {
-  runApp(new MineDigger());
-}
diff --git a/examples/mine_digger/pubspec.yaml b/examples/mine_digger/pubspec.yaml
deleted file mode 100644
index 6f5d79a..0000000
--- a/examples/mine_digger/pubspec.yaml
+++ /dev/null
@@ -1,10 +0,0 @@
-name: mine_digger
-dependencies:
-  flutter: 
-    '0.0.16'
-  sky_tools: any
-dependency_overrides:
-  material_design_icons:
-    path: ../../sky/packages/material_design_icons
-  flutter:
-    path: ../../sky/packages/sky
diff --git a/examples/raw/hello_world.dart b/examples/raw/hello_world.dart
deleted file mode 100644
index a8faa38..0000000
--- a/examples/raw/hello_world.dart
+++ /dev/null
@@ -1,72 +0,0 @@
-// Copyright 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 'dart:ui' as ui;
-import 'dart:typed_data';
-
-ui.Color color;
-
-ui.Picture paint(ui.Rect paintBounds) {
-  ui.PictureRecorder recorder = new ui.PictureRecorder();
-  ui.Canvas canvas = new ui.Canvas(recorder, paintBounds);
-  ui.Size size = paintBounds.size;
-
-  double radius = size.shortestSide * 0.45;
-  ui.Paint paint = new ui.Paint()
-    ..color = color;
-  canvas.drawCircle(size.center(ui.Point.origin), radius, paint);
-
-  return recorder.endRecording();
-}
-
-ui.Scene composite(ui.Picture picture, ui.Rect paintBounds) {
-  final double devicePixelRatio = ui.window.devicePixelRatio;
-  ui.Rect sceneBounds = new ui.Rect.fromLTWH(0.0, 0.0, ui.window.size.width * devicePixelRatio, ui.window.size.height * devicePixelRatio);
-  Float64List deviceTransform = new Float64List(16)
-    ..[0] = devicePixelRatio
-    ..[5] = devicePixelRatio
-    ..[10] = 1.0
-    ..[15] = 1.0;
-  ui.SceneBuilder sceneBuilder = new ui.SceneBuilder(sceneBounds)
-    ..pushTransform(deviceTransform)
-    ..addPicture(ui.Offset.zero, picture, paintBounds)
-    ..pop();
-  return sceneBuilder.build();
-}
-
-void beginFrame(Duration timeStamp) {
-  ui.Rect paintBounds = ui.Point.origin & ui.window.size;
-  ui.Picture picture = paint(paintBounds);
-  ui.Scene scene = composite(picture, paintBounds);
-  ui.window.render(scene);
-}
-
-bool handleEvent(ui.Event event) {
-  if (event.type == 'pointerdown') {
-    color = new ui.Color.fromARGB(255, 0, 0, 255);
-    ui.window.scheduleFrame();
-    return true;
-  }
-
-  if (event.type == 'pointerup') {
-    color = new ui.Color.fromARGB(255, 0, 255, 0);
-    ui.window.scheduleFrame();
-    return true;
-  }
-
-  if (event.type == 'back') {
-    print('Pressed back button.');
-    return true;
-  }
-
-  return false;
-}
-
-void main() {
-  print('Hello, world');
-  color = new ui.Color.fromARGB(255, 0, 255, 0);
-  ui.window.onBeginFrame = beginFrame;
-  ui.window.onEvent = handleEvent;
-  ui.window.scheduleFrame();
-}
diff --git a/examples/raw/painting.dart b/examples/raw/painting.dart
deleted file mode 100644
index 292d7b1..0000000
--- a/examples/raw/painting.dart
+++ /dev/null
@@ -1,121 +0,0 @@
-// Copyright 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 'dart:ui' as ui;
-import 'dart:math' as math;
-import 'dart:typed_data';
-
-ui.Picture paint(ui.Rect paintBounds) {
-  ui.PictureRecorder recorder = new ui.PictureRecorder();
-  ui.Canvas canvas = new ui.Canvas(recorder, paintBounds);
-  ui.Size size = paintBounds.size;
-
-  ui.Paint paint = new ui.Paint();
-  ui.Point mid = size.center(ui.Point.origin);
-  double radius = size.shortestSide / 2.0;
-  canvas.drawPaint(new ui.Paint()..color = const ui.Color(0xFFFFFFFF));
-
-  canvas.save();
-  canvas.translate(-mid.x/2.0, ui.window.size.height*2.0);
-  canvas.clipRect(
-      new ui.Rect.fromLTRB(0.0, -ui.window.size.height, ui.window.size.width, radius));
-
-  canvas.translate(mid.x, mid.y);
-  paint.color = const ui.Color.fromARGB(128, 255, 0, 255);
-  canvas.rotate(math.PI/4.0);
-
-  ui.Gradient yellowBlue = new ui.Gradient.linear(
-    <ui.Point>[new ui.Point(-radius, -radius), new ui.Point(0.0, 0.0)],
-    <ui.Color>[const ui.Color(0xFFFFFF00), const ui.Color(0xFF0000FF)]
-  );
-  canvas.drawRect(new ui.Rect.fromLTRB(-radius, -radius, radius, radius),
-                  new ui.Paint()..shader = yellowBlue);
-
-  // Scale x and y by 0.5.
-  Float64List scaleMatrix = new Float64List.fromList(<double>[
-      0.5, 0.0, 0.0, 0.0,
-      0.0, 0.5, 0.0, 0.0,
-      0.0, 0.0, 1.0, 0.0,
-      0.0, 0.0, 0.0, 1.0,
-  ]);
-  canvas.concat(scaleMatrix);
-  paint.color = const ui.Color.fromARGB(128, 0, 255, 0);
-  canvas.drawCircle(ui.Point.origin, radius, paint);
-
-  canvas.restore();
-
-  canvas.translate(0.0, 50.0);
-  ui.LayerDrawLooperBuilder builder = new ui.LayerDrawLooperBuilder()
-    ..addLayerOnTop(
-        new ui.DrawLooperLayerInfo()
-          ..setOffset(const ui.Offset(150.0, 0.0))
-          ..setColorMode(ui.TransferMode.src)
-          ..setPaintBits(ui.PaintBits.all),
-        new ui.Paint()
-          ..color = const ui.Color.fromARGB(128, 255, 255, 0)
-          ..colorFilter = new ui.ColorFilter.mode(
-              const ui.Color.fromARGB(128, 0, 0, 255),
-              ui.TransferMode.srcIn
-            )
-          ..maskFilter = new ui.MaskFilter.blur(
-              ui.BlurStyle.normal, 3.0, highQuality: true
-            )
-      )
-    ..addLayerOnTop(
-        new ui.DrawLooperLayerInfo()
-          ..setOffset(const ui.Offset(75.0, 75.0))
-          ..setColorMode(ui.TransferMode.src)
-          ..setPaintBits(ui.PaintBits.shader),
-        new ui.Paint()
-          ..shader = new ui.Gradient.radial(
-              new ui.Point(0.0, 0.0), radius/3.0,
-              <ui.Color>[
-                const ui.Color(0xFFFFFF00),
-                const ui.Color(0xFFFF0000)
-              ],
-              null,
-              ui.TileMode.mirror
-            )
-          // Since we're don't set ui.PaintBits.maskFilter, this has no effect.
-          ..maskFilter = new ui.MaskFilter.blur(
-              ui.BlurStyle.normal, 50.0, highQuality: true
-            )
-      )
-    ..addLayerOnTop(
-        new ui.DrawLooperLayerInfo()..setOffset(const ui.Offset(225.0, 75.0)),
-        // Since this layer uses a DST color mode, this has no effect.
-        new ui.Paint()..color = const ui.Color.fromARGB(128, 255, 0, 0)
-      );
-  paint.drawLooper = builder.build();
-  canvas.drawCircle(ui.Point.origin, radius, paint);
-
-  return recorder.endRecording();
-}
-
-ui.Scene composite(ui.Picture picture, ui.Rect paintBounds) {
-  final double devicePixelRatio = ui.window.devicePixelRatio;
-  ui.Rect sceneBounds = new ui.Rect.fromLTWH(0.0, 0.0, ui.window.size.width * devicePixelRatio, ui.window.size.height * devicePixelRatio);
-  Float64List deviceTransform = new Float64List(16)
-    ..[0] = devicePixelRatio
-    ..[5] = devicePixelRatio
-    ..[10] = 1.0
-    ..[15] = 1.0;
-  ui.SceneBuilder sceneBuilder = new ui.SceneBuilder(sceneBounds)
-    ..pushTransform(deviceTransform)
-    ..addPicture(ui.Offset.zero, picture, paintBounds)
-    ..pop();
-  return sceneBuilder.build();
-}
-
-void beginFrame(Duration timeStamp) {
-  ui.Rect paintBounds = ui.Point.origin & ui.window.size;
-  ui.Picture picture = paint(paintBounds);
-  ui.Scene scene = composite(picture, paintBounds);
-  ui.window.render(scene);
-}
-
-void main() {
-  ui.window.onBeginFrame = beginFrame;
-  ui.window.scheduleFrame();
-}
diff --git a/examples/raw/pubspec.yaml b/examples/raw/pubspec.yaml
deleted file mode 100644
index a7b21bc..0000000
--- a/examples/raw/pubspec.yaml
+++ /dev/null
@@ -1,10 +0,0 @@
-name: sky_raw_examples
-dependencies:
-  flutter: 
-    '0.0.16'
-  sky_tools: any
-dependency_overrides:
-  material_design_icons:
-    path: ../../sky/packages/material_design_icons
-  flutter:
-    path: ../../sky/packages/sky
diff --git a/examples/raw/shadow.dart b/examples/raw/shadow.dart
deleted file mode 100644
index f53e01e..0000000
--- a/examples/raw/shadow.dart
+++ /dev/null
@@ -1,64 +0,0 @@
-// Copyright 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 'dart:ui' as ui;
-import 'dart:typed_data';
-
-ui.Picture paint(ui.Rect paintBounds) {
-  ui.PictureRecorder recorder = new ui.PictureRecorder();
-  ui.Canvas canvas = new ui.Canvas(recorder, paintBounds);
-
-  double size = 100.0;
-  canvas.translate(size + 10.0, size + 10.0);
-
-  ui.Paint paint = new ui.Paint();
-  paint.color = const ui.Color.fromARGB(255, 0, 255, 0);
-  var builder = new ui.LayerDrawLooperBuilder()
-    // Shadow layer.
-    ..addLayerOnTop(
-        new ui.DrawLooperLayerInfo()
-          ..setPaintBits(ui.PaintBits.all)
-          ..setOffset(const ui.Offset(5.0, 5.0))
-          ..setColorMode(ui.TransferMode.src),
-        new ui.Paint()
-          ..color = const ui.Color.fromARGB(128, 55, 55, 55)
-          ..maskFilter = new ui.MaskFilter.blur(ui.BlurStyle.normal, 5.0)
-    )
-    // Main layer.
-    ..addLayerOnTop(new ui.DrawLooperLayerInfo(), new ui.Paint());
-  paint.drawLooper = builder.build();
-
-  canvas.drawPaint(
-      new ui.Paint()..color = const ui.Color.fromARGB(255, 255, 255, 255));
-  canvas.drawRect(new ui.Rect.fromLTRB(-size, -size, size, size), paint);
-
-  return recorder.endRecording();
-}
-
-ui.Scene composite(ui.Picture picture, ui.Rect paintBounds) {
-  final double devicePixelRatio = ui.window.devicePixelRatio;
-  ui.Rect sceneBounds = new ui.Rect.fromLTWH(0.0, 0.0, ui.window.size.width * devicePixelRatio, ui.window.size.height * devicePixelRatio);
-  Float64List deviceTransform = new Float64List(16)
-    ..[0] = devicePixelRatio
-    ..[5] = devicePixelRatio
-    ..[10] = 1.0
-    ..[15] = 1.0;
-  ui.SceneBuilder sceneBuilder = new ui.SceneBuilder(sceneBounds)
-    ..pushTransform(deviceTransform)
-    ..addPicture(ui.Offset.zero, picture, paintBounds)
-    ..pop();
-  return sceneBuilder.build();
-}
-
-void beginFrame(Duration timeStamp) {
-  ui.Rect paintBounds = ui.Point.origin & ui.window.size;
-  ui.Picture picture = paint(paintBounds);
-  ui.Scene scene = composite(picture, paintBounds);
-  ui.window.render(scene);
-}
-
-void main() {
-  ui.window.onBeginFrame = beginFrame;
-  ui.window.scheduleFrame();
-}
diff --git a/examples/raw/spinning_arabic.dart b/examples/raw/spinning_arabic.dart
deleted file mode 100644
index 6811664..0000000
--- a/examples/raw/spinning_arabic.dart
+++ /dev/null
@@ -1,68 +0,0 @@
-// Copyright 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 'dart:math' as math;
-import 'dart:ui' as ui;
-import 'dart:typed_data';
-
-Duration timeBase = null;
-ui.Paragraph paragraph;
-
-ui.Picture paint(ui.Rect paintBounds, double delta) {
-  ui.PictureRecorder recorder = new ui.PictureRecorder();
-  ui.Canvas canvas = new ui.Canvas(recorder, paintBounds);
-
-  canvas.translate(ui.window.size.width / 2.0, ui.window.size.height / 2.0);
-  canvas.rotate(math.PI * delta / 1800);
-  canvas.drawRect(new ui.Rect.fromLTRB(-100.0, -100.0, 100.0, 100.0),
-                  new ui.Paint()..color = const ui.Color.fromARGB(255, 0, 255, 0));
-
-  double sin = math.sin(delta / 200);
-  paragraph.maxWidth = 150.0 + (50 * sin);
-  paragraph.layout();
-
-  canvas.translate(paragraph.maxWidth / -2.0, (paragraph.maxWidth / 2.0) - 125);
-  paragraph.paint(canvas, ui.Offset.zero);
-
-  return recorder.endRecording();
-}
-
-ui.Scene composite(ui.Picture picture, ui.Rect paintBounds) {
-  final double devicePixelRatio = ui.window.devicePixelRatio;
-  ui.Rect sceneBounds = new ui.Rect.fromLTWH(0.0, 0.0, ui.window.size.width * devicePixelRatio, ui.window.size.height * devicePixelRatio);
-  Float64List deviceTransform = new Float64List(16)
-    ..[0] = devicePixelRatio
-    ..[5] = devicePixelRatio
-    ..[10] = 1.0
-    ..[15] = 1.0;
-  ui.SceneBuilder sceneBuilder = new ui.SceneBuilder(sceneBounds)
-    ..pushTransform(deviceTransform)
-    ..addPicture(ui.Offset.zero, picture, paintBounds)
-    ..pop();
-  return sceneBuilder.build();
-}
-
-void beginFrame(Duration timeStamp) {
-  if (timeBase == null)
-    timeBase = timeStamp;
-  double delta = (timeStamp - timeBase).inMicroseconds / Duration.MICROSECONDS_PER_MILLISECOND;
-  ui.Rect paintBounds = ui.Point.origin & ui.window.size;
-  ui.Picture picture = paint(paintBounds, delta);
-  ui.Scene scene = composite(picture, paintBounds);
-  ui.window.render(scene);
-  ui.window.scheduleFrame();
-}
-
-void main() {
-  // TODO(abarth): We're missing some bidi style information:
-  //   block.style['direction'] = 'rtl';
-  //   block.style['unicode-bidi'] = 'plaintext';
-  ui.ParagraphBuilder builder = new ui.ParagraphBuilder();
-  builder.addText("هذا هو قليلا طويلة من النص الذي يجب التفاف .");
-  builder.addText(" و أكثر قليلا لجعله أطول. ");
-  paragraph = builder.build(new ui.ParagraphStyle());
-
-  ui.window.onBeginFrame = beginFrame;
-  ui.window.scheduleFrame();
-}
diff --git a/examples/raw/spinning_image.dart b/examples/raw/spinning_image.dart
deleted file mode 100644
index 0afb14f..0000000
--- a/examples/raw/spinning_image.dart
+++ /dev/null
@@ -1,98 +0,0 @@
-// Copyright 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 'dart:math' as math;
-import 'dart:ui' as ui;
-import 'dart:typed_data';
-
-import 'package:flutter/services.dart';
-
-Duration timeBase = null;
-
-ui.Image image = null;
-String url1 = "https://raw.githubusercontent.com/dart-lang/logos/master/logos_and_wordmarks/dart-logo.png";
-String url2 = "http://i2.kym-cdn.com/photos/images/facebook/000/581/296/c09.jpg";
-
-ui.Picture paint(ui.Rect paintBounds, double delta) {
-  ui.PictureRecorder recorder = new ui.PictureRecorder();
-  ui.Canvas canvas = new ui.Canvas(recorder, paintBounds);
-
-  canvas.translate(paintBounds.width / 2.0, paintBounds.height / 2.0);
-  canvas.rotate(math.PI * delta / 1800);
-  canvas.scale(0.2, 0.2);
-  ui.Paint paint = new ui.Paint()..color = const ui.Color.fromARGB(255, 0, 255, 0);
-
-  // Draw image
-  if (image != null)
-    canvas.drawImage(image, new ui.Point(-image.width / 2.0, -image.height / 2.0), paint);
-
-  // Draw cut out of image
-  canvas.rotate(math.PI * delta / 1800);
-  if (image != null) {
-    var w = image.width.toDouble();
-    var h = image.width.toDouble();
-    canvas.drawImageRect(image,
-      new ui.Rect.fromLTRB(w * 0.25, h * 0.25, w * 0.75, h * 0.75),
-      new ui.Rect.fromLTRB(-w / 4.0, -h / 4.0, w / 4.0, h / 4.0),
-      paint);
-  }
-
-  return recorder.endRecording();
-}
-
-ui.Scene composite(ui.Picture picture, ui.Rect paintBounds) {
-  final double devicePixelRatio = ui.window.devicePixelRatio;
-  ui.Rect sceneBounds = new ui.Rect.fromLTWH(0.0, 0.0, ui.window.size.width * devicePixelRatio, ui.window.size.height * devicePixelRatio);
-  Float64List deviceTransform = new Float64List(16)
-    ..[0] = devicePixelRatio
-    ..[5] = devicePixelRatio
-    ..[10] = 1.0
-    ..[15] = 1.0;
-  ui.SceneBuilder sceneBuilder = new ui.SceneBuilder(sceneBounds)
-    ..pushTransform(deviceTransform)
-    ..addPicture(ui.Offset.zero, picture, paintBounds)
-    ..pop();
-  return sceneBuilder.build();
-}
-
-void beginFrame(Duration timeStamp) {
-  if (timeBase == null)
-    timeBase = timeStamp;
-  double delta = (timeStamp - timeBase).inMicroseconds / Duration.MICROSECONDS_PER_MILLISECOND;
-  ui.Rect paintBounds = ui.Point.origin & ui.window.size;
-  ui.Picture picture = paint(paintBounds, delta);
-  ui.Scene scene = composite(picture, paintBounds);
-  ui.window.render(scene);
-  ui.window.scheduleFrame();
-}
-
-
-void handleImageLoad(result) {
-  if (result != image) {
-    print("${result.width}x${result.width} image loaded!");
-    image = result;
-    ui.window.scheduleFrame();
-  } else {
-    print("Existing image was loaded again");
-  }
-}
-
-bool handleEvent(ui.Event event) {
-  if (event.type == "pointerdown") {
-    return true;
-  }
-
-  if (event.type == "pointerup") {
-    imageCache.load(url2).first.then(handleImageLoad);
-    return true;
-  }
-
-  return false;
-}
-
-void main() {
-  imageCache.load(url1).first.then(handleImageLoad);
-  ui.window.onEvent = handleEvent;
-  ui.window.onBeginFrame = beginFrame;
-}
diff --git a/examples/raw/spinning_square.dart b/examples/raw/spinning_square.dart
deleted file mode 100644
index 82bb32c..0000000
--- a/examples/raw/spinning_square.dart
+++ /dev/null
@@ -1,48 +0,0 @@
-// Copyright 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 'dart:math' as math;
-import 'dart:ui' as ui;
-import 'dart:typed_data';
-
-Duration timeBase = null;
-
-void beginFrame(Duration timeStamp) {
-  ui.tracing.begin('beginFrame');
-  if (timeBase == null)
-    timeBase = timeStamp;
-  double delta = (timeStamp - timeBase).inMicroseconds / Duration.MICROSECONDS_PER_MILLISECOND;
-
-  // paint
-  ui.Rect paintBounds = ui.Point.origin & ui.window.size;
-  ui.PictureRecorder recorder = new ui.PictureRecorder();
-  ui.Canvas canvas = new ui.Canvas(recorder, paintBounds);
-  canvas.translate(paintBounds.width / 2.0, paintBounds.height / 2.0);
-  canvas.rotate(math.PI * delta / 1800);
-  canvas.drawRect(new ui.Rect.fromLTRB(-100.0, -100.0, 100.0, 100.0),
-                  new ui.Paint()..color = const ui.Color.fromARGB(255, 0, 255, 0));
-  ui.Picture picture = recorder.endRecording();
-
-  // composite
-  final double devicePixelRatio = ui.window.devicePixelRatio;
-  ui.Rect sceneBounds = new ui.Rect.fromLTWH(0.0, 0.0, ui.window.size.width * devicePixelRatio, ui.window.size.height * devicePixelRatio);
-  Float64List deviceTransform = new Float64List(16)
-    ..[0] = devicePixelRatio
-    ..[5] = devicePixelRatio
-    ..[10] = 1.0
-    ..[15] = 1.0;
-  ui.SceneBuilder sceneBuilder = new ui.SceneBuilder(sceneBounds)
-    ..pushTransform(deviceTransform)
-    ..addPicture(ui.Offset.zero, picture, paintBounds)
-    ..pop();
-  ui.window.render(sceneBuilder.build());
-
-  ui.tracing.end('beginFrame');
-  ui.window.scheduleFrame();
-}
-
-void main() {
-  ui.window.onBeginFrame = beginFrame;
-  ui.window.scheduleFrame();
-}
diff --git a/examples/rendering/align_items.dart b/examples/rendering/align_items.dart
deleted file mode 100644
index 9497f68..0000000
--- a/examples/rendering/align_items.dart
+++ /dev/null
@@ -1,46 +0,0 @@
-// Copyright 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:flutter/rendering.dart';
-
-import 'lib/solid_color_box.dart';
-
-void main() {
-  RenderFlex table = new RenderFlex(direction: FlexDirection.vertical);
-
-  for (FlexAlignItems alignItems in FlexAlignItems.values) {
-    TextStyle style = const TextStyle(color: const Color(0xFF000000));
-    RenderParagraph paragraph = new RenderParagraph(new StyledTextSpan(style, <TextSpan>[new PlainTextSpan("$alignItems")]));
-    table.add(new RenderPadding(child: paragraph, padding: new EdgeDims.only(top: 20.0)));
-    RenderFlex row = new RenderFlex(alignItems: alignItems, textBaseline: TextBaseline.alphabetic);
-    style = new TextStyle(fontSize: 15.0, color: const Color(0xFF000000));
-    row.add(new RenderDecoratedBox(
-      decoration: new BoxDecoration(backgroundColor: const Color(0x7FFFCCCC)),
-      child: new RenderParagraph(new StyledTextSpan(style, <TextSpan>[new PlainTextSpan('foo foo foo')]))
-    ));
-    style = new TextStyle(fontSize: 10.0, color: const Color(0xFF000000));
-    row.add(new RenderDecoratedBox(
-      decoration: new BoxDecoration(backgroundColor: const Color(0x7FCCFFCC)),
-      child: new RenderParagraph(new StyledTextSpan(style, <TextSpan>[new PlainTextSpan('foo foo foo')]))
-    ));
-    RenderFlex subrow = new RenderFlex(alignItems: alignItems, textBaseline: TextBaseline.alphabetic);
-    style = new TextStyle(fontSize: 25.0, color: const Color(0xFF000000));
-    subrow.add(new RenderDecoratedBox(
-      decoration: new BoxDecoration(backgroundColor: const Color(0x7FCCCCFF)),
-      child: new RenderParagraph(new StyledTextSpan(style, <TextSpan>[new PlainTextSpan('foo foo foo foo')]))
-    ));
-    subrow.add(new RenderSolidColorBox(const Color(0x7FCCFFFF), desiredSize: new Size(30.0, 40.0)));
-    row.add(subrow);
-    table.add(row);
-    final FlexParentData rowParentData = row.parentData;
-    rowParentData.flex = 1;
-  }
-
-  RenderDecoratedBox root = new RenderDecoratedBox(
-    decoration: new BoxDecoration(backgroundColor: const Color(0xFFFFFFFF)),
-    child: new RenderPadding(child: table, padding: new EdgeDims.symmetric(vertical: 50.0))
-  );
-
-  new FlutterBinding(root: root);
-}
diff --git a/examples/rendering/baseline.dart b/examples/rendering/baseline.dart
deleted file mode 100644
index 85e337c..0000000
--- a/examples/rendering/baseline.dart
+++ /dev/null
@@ -1,76 +0,0 @@
-// Copyright 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 'dart:ui' as ui;
-
-import 'package:flutter/rendering.dart';
-
-RenderBox getBox(double lh) {
-  RenderParagraph paragraph = new RenderParagraph(
-    new StyledTextSpan(
-      new TextStyle(
-        color: const Color(0xFF0000A0)
-      ),
-      <TextSpan>[
-        new PlainTextSpan('test'),
-        new StyledTextSpan(
-          new TextStyle(
-            fontFamily: 'serif',
-            fontSize: 50.0,
-            height: lh
-          ),
-          <TextSpan>[new PlainTextSpan('مرحبا Hello')]
-        )
-      ]
-    )
-  );
-  return new RenderPadding(
-    padding: new EdgeDims.all(10.0),
-    child: new RenderConstrainedBox(
-      additionalConstraints: new BoxConstraints.tightFor(height: 200.0),
-      child: new RenderDecoratedBox(
-        decoration: new BoxDecoration(
-          backgroundColor: const Color(0xFFFFFFFF)
-        ),
-        child: new RenderPadding(
-          padding: new EdgeDims.all(10.0),
-          child: new RenderCustomPaint(
-            child: paragraph,
-            onPaint: (PaintingCanvas canvas, Size size) {
-              double baseline = paragraph.getDistanceToBaseline(TextBaseline.alphabetic);
-              double w = paragraph.getMaxIntrinsicWidth(new BoxConstraints.loose(size));
-              double h = paragraph.getMaxIntrinsicHeight(new BoxConstraints.loose(size));
-              Path path = new Path();
-              path.moveTo(0.0, 0.0);
-              path.lineTo(w, 0.0);
-              path.moveTo(0.0, baseline);
-              path.lineTo(w, baseline);
-              path.moveTo(0.0, h);
-              path.lineTo(w, h);
-              Paint paint = new Paint()
-               ..color = const Color(0xFFFF9000)
-               ..style = ui.PaintingStyle.stroke
-               ..strokeWidth = 3.0;
-              canvas.drawPath(path, paint);
-            }
-          )
-        )
-      )
-    )
-  );
-}
-
-void main() {
-  RenderBox root = new RenderFlex(children: <RenderBox>[
-      new RenderConstrainedBox(
-        additionalConstraints: new BoxConstraints.tightFor(height: 50.0)
-      ),
-      getBox(1.0),
-      getBox(null),
-    ],
-    direction: FlexDirection.vertical,
-    alignItems: FlexAlignItems.stretch
-  );
-  new FlutterBinding(root: root);
-}
diff --git a/examples/rendering/borders.dart b/examples/rendering/borders.dart
deleted file mode 100644
index 5db29ca..0000000
--- a/examples/rendering/borders.dart
+++ /dev/null
@@ -1,77 +0,0 @@
-// Copyright 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 'dart:ui' as ui;
-
-import 'package:flutter/rendering.dart';
-
-void main() {
-  RenderFlex root = new RenderFlex(
-    children: <RenderBox>[
-      new RenderPadding(
-        padding: new EdgeDims.all(10.0),
-        child: new RenderConstrainedBox(
-          additionalConstraints: new BoxConstraints.tightFor(height: 100.0),
-          child: new RenderDecoratedBox(
-            decoration: new BoxDecoration(
-              backgroundColor: new ui.Color(0xFFFFFF00)
-            )
-          )
-        )
-      ),
-      new RenderPadding(
-        padding: new EdgeDims.all(10.0),
-        child: new RenderConstrainedBox(
-          additionalConstraints: new BoxConstraints.tightFor(height: 100.0),
-          child: new RenderDecoratedBox(
-            decoration: new BoxDecoration(
-              border: new Border(
-                top: new BorderSide(color: new ui.Color(0xFFF00000), width: 5.0),
-                right: new BorderSide(color: new ui.Color(0xFFFF9000), width: 10.0),
-                bottom: new BorderSide(color: new ui.Color(0xFFFFF000), width: 15.0),
-                left: new BorderSide(color: new ui.Color(0xFF00FF00), width: 20.0)
-              ),
-              backgroundColor: new ui.Color(0xFFDDDDDD)
-            )
-          )
-        )
-      ),
-      new RenderPadding(
-        padding: new EdgeDims.all(10.0),
-        child: new RenderConstrainedBox(
-          additionalConstraints: new BoxConstraints.tightFor(height: 100.0),
-          child: new RenderDecoratedBox(
-            decoration: new BoxDecoration(
-              backgroundColor: new ui.Color(0xFFFFFF00)
-            )
-          )
-        )
-      ),
-      new RenderPadding(
-        padding: new EdgeDims.all(10.0),
-        child: new RenderConstrainedBox(
-          additionalConstraints: new BoxConstraints.tightFor(height: 100.0),
-          child: new RenderDecoratedBox(
-            decoration: new BoxDecoration(
-              backgroundColor: new ui.Color(0xFFFFFF00)
-            )
-          )
-        )
-      ),
-      new RenderPadding(
-        padding: new EdgeDims.all(10.0),
-        child: new RenderConstrainedBox(
-          additionalConstraints: new BoxConstraints.tightFor(height: 100.0),
-          child: new RenderDecoratedBox(
-            decoration: new BoxDecoration(
-              backgroundColor: new ui.Color(0xFFFFFF00)
-            )
-          )
-        )
-      ),
-    ],
-    direction: FlexDirection.vertical
-  );
-  new FlutterBinding(root: root);
-}
diff --git a/examples/rendering/flex.dart b/examples/rendering/flex.dart
deleted file mode 100644
index 3fd3d5d..0000000
--- a/examples/rendering/flex.dart
+++ /dev/null
@@ -1,57 +0,0 @@
-// Copyright 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 'dart:ui' as ui;
-
-import 'package:flutter/rendering.dart';
-import 'lib/solid_color_box.dart';
-
-RenderBox buildFlexExample() {
-  RenderFlex flexRoot = new RenderFlex(direction: FlexDirection.vertical);
-
-  RenderDecoratedBox root = new RenderDecoratedBox(
-    decoration: new BoxDecoration(backgroundColor: const ui.Color(0xFF000000)),
-    child: flexRoot
-  );
-
-  void addFlexChildSolidColor(RenderFlex parent, ui.Color backgroundColor, { int flex: 0 }) {
-    RenderSolidColorBox child = new RenderSolidColorBox(backgroundColor);
-    parent.add(child);
-    final FlexParentData childParentData = child.parentData;
-    childParentData.flex = flex;
-  }
-
-  // Yellow bar at top
-  addFlexChildSolidColor(flexRoot, const ui.Color(0xFFFFFF00), flex: 1);
-
-  // Turquoise box
-  flexRoot.add(new RenderSolidColorBox(const ui.Color(0x7700FFFF), desiredSize: new ui.Size(100.0, 100.0)));
-
-  var renderDecoratedBlock = new RenderDecoratedBox(
-    decoration: new BoxDecoration(backgroundColor: const ui.Color(0xFFFFFFFF))
-  );
-
-  flexRoot.add(new RenderPadding(padding: const EdgeDims.all(10.0), child: renderDecoratedBlock));
-
-  var row = new RenderFlex(direction: FlexDirection.horizontal);
-
-  // Purple and blue cells
-  addFlexChildSolidColor(row, const ui.Color(0x77FF00FF), flex: 1);
-  addFlexChildSolidColor(row, const ui.Color(0xFF0000FF), flex: 2);
-
-  var decoratedRow = new RenderDecoratedBox(
-    decoration: new BoxDecoration(backgroundColor: const ui.Color(0xFF333333)),
-    child: row
-  );
-
-  flexRoot.add(decoratedRow);
-  final FlexParentData decoratedRowParentData = decoratedRow.parentData;
-  decoratedRowParentData.flex = 3;
-
-  return root;
-}
-
-void main() {
-  new FlutterBinding(root: buildFlexExample());
-}
diff --git a/examples/rendering/interactive_flex.dart b/examples/rendering/interactive_flex.dart
deleted file mode 100644
index c42b285..0000000
--- a/examples/rendering/interactive_flex.dart
+++ /dev/null
@@ -1,105 +0,0 @@
-// Copyright 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 'dart:ui' as ui;
-import 'dart:math' as math;
-
-import 'package:flutter/services.dart';
-import 'package:flutter/rendering.dart';
-
-import 'lib/solid_color_box.dart';
-
-class Touch {
-  final double x;
-  final double y;
-  const Touch(this.x, this.y);
-}
-
-class RenderImageGrow extends RenderImage {
-  final Size _startingSize;
-
-  RenderImageGrow(ui.Image image, Size size)
-    : _startingSize = size, super(image: image, width: size.width, height: size.height);
-
-  double _growth = 0.0;
-  double get growth => _growth;
-  void set growth(double value) {
-    _growth = value;
-    width = _startingSize.width == null ? null : _startingSize.width + growth;
-    height = _startingSize.height == null ? null : _startingSize.height + growth;
-  }
-}
-
-RenderImageGrow image;
-
-final Map<int, Touch> touches = <int, Touch>{};
-void handleEvent(event) {
-  if (event is ui.PointerEvent) {
-    if (event.type == 'pointermove')
-      image.growth = math.max(0.0, image.growth + event.x - touches[event.pointer].x);
-    touches[event.pointer] = new Touch(event.x, event.y);
-  }
-  if (event.type == "back") {
-    activity.finishCurrentActivity();
-  }
-}
-
-void main() {
-  void addFlexChildSolidColor(RenderFlex parent, Color backgroundColor, { int flex: 0 }) {
-    RenderSolidColorBox child = new RenderSolidColorBox(backgroundColor);
-    parent.add(child);
-    final FlexParentData childParentData = child.parentData;
-    childParentData.flex = flex;
-  }
-
-  var row = new RenderFlex(direction: FlexDirection.horizontal);
-
-  // Left cell
-  addFlexChildSolidColor(row, const Color(0xFF00D2B8), flex: 1);
-
-  // Resizeable image
-  image = new RenderImageGrow(null, new Size(100.0, null));
-  imageCache.load("https://www.dartlang.org/logos/dart-logo.png").first.then((ui.Image dartLogo) {
-    image.image = dartLogo;
-  });
-
-  row.add(new RenderPadding(padding: const EdgeDims.all(10.0), child: image));
-
-  RenderFlex column = new RenderFlex(direction: FlexDirection.vertical);
-
-  // Top cell
-  final Color topColor = const Color(0xFF55DDCA);
-  addFlexChildSolidColor(column, topColor, flex: 1);
-
-  // The internet is a beautiful place.  https://baconipsum.com/
-  String meatyString = """Bacon ipsum dolor amet ham fatback tri-tip, prosciutto
-porchetta bacon kevin meatball meatloaf pig beef ribs chicken. Brisket ribeye
-andouille leberkas capicola meatloaf. Chicken pig ball tip pork picanha bresaola
-alcatra. Pork pork belly alcatra, flank chuck drumstick biltong doner jowl.
-Pancetta meatball tongue tenderloin rump tail jowl boudin.""";
-  TextSpan text = new StyledTextSpan(
-    new TextStyle(color:  const Color(0xFF009900)),
-    <TextSpan>[new PlainTextSpan(meatyString)]
-  );
-  column.add(new RenderPadding(
-    padding: const EdgeDims.all(10.0),
-    child: new RenderParagraph(text)
-  ));
-
-  // Bottom cell
-  addFlexChildSolidColor(column, const Color(0xFF0081C6), flex: 2);
-
-  row.add(column);
-  final FlexParentData childParentData = column.parentData;
-  childParentData.flex = 8;
-
-  RenderDecoratedBox root = new RenderDecoratedBox(
-    decoration: new BoxDecoration(backgroundColor: const Color(0xFFFFFFFF)),
-    child: row
-  );
-
-  updateTaskDescription('Interactive Flex', topColor);
-  new FlutterBinding(root: root);
-  ui.window.onEvent = handleEvent;
-}
diff --git a/examples/rendering/justify_content.dart b/examples/rendering/justify_content.dart
deleted file mode 100644
index f6fc12d..0000000
--- a/examples/rendering/justify_content.dart
+++ /dev/null
@@ -1,41 +0,0 @@
-// Copyright 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:flutter/rendering.dart';
-
-import 'lib/solid_color_box.dart';
-
-const TextStyle style = const TextStyle(color: const Color(0xFF000000));
-
-// Attempts to draw
-// http://www.w3.org/TR/2015/WD-css-flexbox-1-20150514/images/flex-pack.svg
-void main() {
-  var table = new RenderFlex(direction: FlexDirection.vertical);
-
-  void addRow(FlexJustifyContent justify) {
-    RenderParagraph paragraph = new RenderParagraph(new StyledTextSpan(style, <TextSpan>[new PlainTextSpan("$justify")]));
-    table.add(new RenderPadding(child: paragraph, padding: new EdgeDims.only(top: 20.0)));
-    RenderFlex row = new RenderFlex(direction: FlexDirection.horizontal);
-    row.add(new RenderSolidColorBox(const Color(0xFFFFCCCC), desiredSize: new Size(80.0, 60.0)));
-    row.add(new RenderSolidColorBox(const Color(0xFFCCFFCC), desiredSize: new Size(64.0, 60.0)));
-    row.add(new RenderSolidColorBox(const Color(0xFFCCCCFF), desiredSize: new Size(160.0, 60.0)));
-    row.justifyContent = justify;
-    table.add(row);
-    final FlexParentData rowParentData = row.parentData;
-    rowParentData.flex = 1;
-  }
-
-  addRow(FlexJustifyContent.start);
-  addRow(FlexJustifyContent.end);
-  addRow(FlexJustifyContent.center);
-  addRow(FlexJustifyContent.spaceBetween);
-  addRow(FlexJustifyContent.spaceAround);
-
-  RenderDecoratedBox root = new RenderDecoratedBox(
-    decoration: new BoxDecoration(backgroundColor: const Color(0xFFFFFFFF)),
-    child: new RenderPadding(child: table, padding: new EdgeDims.symmetric(vertical: 50.0))
-  );
-
-  new FlutterBinding(root: root);
-}
diff --git a/examples/rendering/lib/sector_layout.dart b/examples/rendering/lib/sector_layout.dart
deleted file mode 100644
index 90a20bf..0000000
--- a/examples/rendering/lib/sector_layout.dart
+++ /dev/null
@@ -1,527 +0,0 @@
-// Copyright 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 'dart:math' as math;
-
-import 'package:flutter/rendering.dart';
-import 'package:flutter/gestures.dart';
-
-const double kTwoPi = 2 * math.PI;
-
-class SectorConstraints extends Constraints {
-  const SectorConstraints({
-    this.minDeltaRadius: 0.0,
-    this.maxDeltaRadius: double.INFINITY,
-    this.minDeltaTheta: 0.0,
-    this.maxDeltaTheta: kTwoPi
-  });
-
-  const SectorConstraints.tight({ double deltaRadius: 0.0, double deltaTheta: 0.0 })
-    : minDeltaRadius = deltaRadius,
-      maxDeltaRadius = deltaRadius,
-      minDeltaTheta = deltaTheta,
-      maxDeltaTheta = deltaTheta;
-
-  final double minDeltaRadius;
-  final double maxDeltaRadius;
-  final double minDeltaTheta;
-  final double maxDeltaTheta;
-
-  double constrainDeltaRadius(double deltaRadius) {
-    return clamp(min: minDeltaRadius, max: maxDeltaRadius, value: deltaRadius);
-  }
-
-  double constrainDeltaTheta(double deltaTheta) {
-    return clamp(min: minDeltaTheta, max: maxDeltaTheta, value: deltaTheta);
-  }
-
-  bool get isTight => minDeltaTheta >= maxDeltaTheta && minDeltaTheta >= maxDeltaTheta;
-}
-
-class SectorDimensions {
-  const SectorDimensions({ this.deltaRadius: 0.0, this.deltaTheta: 0.0 });
-
-  factory SectorDimensions.withConstraints(
-    SectorConstraints constraints,
-    { double deltaRadius: 0.0, double deltaTheta: 0.0 }
-  ) {
-    return new SectorDimensions(
-      deltaRadius: constraints.constrainDeltaRadius(deltaRadius),
-      deltaTheta: constraints.constrainDeltaTheta(deltaTheta)
-    );
-  }
-
-  final double deltaRadius;
-  final double deltaTheta;
-}
-
-class SectorParentData extends ParentData {
-  double radius = 0.0;
-  double theta = 0.0;
-}
-
-abstract class RenderSector extends RenderObject {
-
-  void setupParentData(RenderObject child) {
-    if (child.parentData is! SectorParentData)
-      child.parentData = new SectorParentData();
-  }
-
-  // RenderSectors always use SectorParentData subclasses, as they need to be
-  // able to read their position information for painting and hit testing.
-  SectorParentData get parentData => super.parentData;
-
-  SectorDimensions getIntrinsicDimensions(SectorConstraints constraints, double radius) {
-    return new SectorDimensions.withConstraints(constraints);
-  }
-
-  SectorConstraints get constraints => super.constraints;
-  bool debugDoesMeetConstraints() {
-    assert(constraints != null);
-    assert(deltaRadius != null);
-    assert(deltaRadius < double.INFINITY);
-    assert(deltaTheta != null);
-    assert(deltaTheta < double.INFINITY);
-    return constraints.minDeltaRadius <= deltaRadius &&
-           deltaRadius <= math.max(constraints.minDeltaRadius, constraints.maxDeltaRadius) &&
-           constraints.minDeltaTheta <= deltaTheta &&
-           deltaTheta <= math.max(constraints.minDeltaTheta, constraints.maxDeltaTheta);
-  }
-  void performResize() {
-    // default behaviour for subclasses that have sizedByParent = true
-    deltaRadius = constraints.constrainDeltaRadius(0.0);
-    deltaTheta = constraints.constrainDeltaTheta(0.0);
-  }
-  void performLayout() {
-    // descendants have to either override performLayout() to set both
-    // the dimensions and lay out children, or, set sizedByParent to
-    // true so that performResize()'s logic above does its thing.
-    assert(sizedByParent);
-  }
-
-  Rect get paintBounds => new Rect.fromLTWH(0.0, 0.0, 2.0 * deltaRadius, 2.0 * deltaRadius);
-
-  bool hitTest(HitTestResult result, { double radius, double theta }) {
-    if (radius < parentData.radius || radius >= parentData.radius + deltaRadius ||
-        theta < parentData.theta || theta >= parentData.theta + deltaTheta)
-      return false;
-    hitTestChildren(result, radius: radius, theta: theta);
-    result.add(new HitTestEntry(this));
-    return true;
-  }
-  void hitTestChildren(HitTestResult result, { double radius, double theta }) { }
-
-  double deltaRadius;
-  double deltaTheta;
-}
-
-abstract class RenderDecoratedSector extends RenderSector {
-
-  RenderDecoratedSector(BoxDecoration decoration) : _decoration = decoration;
-
-  BoxDecoration _decoration;
-  BoxDecoration get decoration => _decoration;
-  void set decoration (BoxDecoration value) {
-    if (value == _decoration)
-      return;
-    _decoration = value;
-    markNeedsPaint();
-  }
-
-  // offset must point to the center of the circle
-  void paint(PaintingContext context, Offset offset) {
-    assert(deltaRadius != null);
-    assert(deltaTheta != null);
-    assert(parentData is SectorParentData);
-
-    if (_decoration == null)
-      return;
-
-    if (_decoration.backgroundColor != null) {
-      final PaintingCanvas canvas = context.canvas;
-      Paint paint = new Paint()..color = _decoration.backgroundColor;
-      Path path = new Path();
-      double outerRadius = (parentData.radius + deltaRadius);
-      Rect outerBounds = new Rect.fromLTRB(offset.dx-outerRadius, offset.dy-outerRadius, offset.dx+outerRadius, offset.dy+outerRadius);
-      path.arcTo(outerBounds, parentData.theta, deltaTheta, true);
-      double innerRadius = parentData.radius;
-      Rect innerBounds = new Rect.fromLTRB(offset.dx-innerRadius, offset.dy-innerRadius, offset.dx+innerRadius, offset.dy+innerRadius);
-      path.arcTo(innerBounds, parentData.theta + deltaTheta, -deltaTheta, false);
-      path.close();
-      canvas.drawPath(path, paint);
-    }
-  }
-
-}
-
-class SectorChildListParentData extends SectorParentData with ContainerParentDataMixin<RenderSector> { }
-
-class RenderSectorWithChildren extends RenderDecoratedSector with ContainerRenderObjectMixin<RenderSector, SectorChildListParentData> {
-  RenderSectorWithChildren(BoxDecoration decoration) : super(decoration);
-
-  void hitTestChildren(HitTestResult result, { double radius, double theta }) {
-    RenderSector child = lastChild;
-    while (child != null) {
-      if (child.hitTest(result, radius: radius, theta: theta))
-        return;
-      final SectorChildListParentData childParentData = child.parentData;
-      child = childParentData.previousSibling;
-    }
-  }
-
-  void visitChildren(RenderObjectVisitor visitor) {
-    RenderSector child = lastChild;
-    while (child != null) {
-      visitor(child);
-      final SectorChildListParentData childParentData = child.parentData;
-      child = childParentData.previousSibling;
-    }
-  }
-}
-
-class RenderSectorRing extends RenderSectorWithChildren {
-  // lays out RenderSector children in a ring
-
-  RenderSectorRing({
-    BoxDecoration decoration,
-    double deltaRadius: double.INFINITY,
-    double padding: 0.0
-  }) : _padding = padding, _desiredDeltaRadius = deltaRadius, super(decoration);
-
-  double _desiredDeltaRadius;
-  double get desiredDeltaRadius => _desiredDeltaRadius;
-  void set desiredDeltaRadius(double value) {
-    assert(value != null);
-    if (_desiredDeltaRadius != value) {
-      _desiredDeltaRadius = value;
-      markNeedsLayout();
-    }
-  }
-
-  double _padding;
-  double get padding => _padding;
-  void set padding(double value) {
-    // TODO(ianh): avoid code duplication
-    assert(value != null);
-    if (_padding != value) {
-      _padding = value;
-      markNeedsLayout();
-    }
-  }
-
-  void setupParentData(RenderObject child) {
-    // TODO(ianh): avoid code duplication
-    if (child.parentData is! SectorChildListParentData)
-      child.parentData = new SectorChildListParentData();
-  }
-
-  SectorDimensions getIntrinsicDimensions(SectorConstraints constraints, double radius) {
-    double outerDeltaRadius = constraints.constrainDeltaRadius(desiredDeltaRadius);
-    double innerDeltaRadius = outerDeltaRadius - padding * 2.0;
-    double childRadius = radius + padding;
-    double paddingTheta = math.atan(padding / (radius + outerDeltaRadius));
-    double innerTheta = paddingTheta; // increments with each child
-    double remainingDeltaTheta = constraints.maxDeltaTheta - (innerTheta + paddingTheta);
-    RenderSector child = firstChild;
-    while (child != null) {
-      SectorConstraints innerConstraints = new SectorConstraints(
-        maxDeltaRadius: innerDeltaRadius,
-        maxDeltaTheta: remainingDeltaTheta
-      );
-      SectorDimensions childDimensions = child.getIntrinsicDimensions(innerConstraints, childRadius);
-      innerTheta += childDimensions.deltaTheta;
-      remainingDeltaTheta -= childDimensions.deltaTheta;
-      final SectorChildListParentData childParentData = child.parentData;
-      child = childParentData.nextSibling;
-      if (child != null) {
-        innerTheta += paddingTheta;
-        remainingDeltaTheta -= paddingTheta;
-      }
-    }
-    return new SectorDimensions.withConstraints(constraints,
-                                                deltaRadius: outerDeltaRadius,
-                                                deltaTheta: innerTheta);
-  }
-
-  void performLayout() {
-    assert(this.parentData is SectorParentData);
-    deltaRadius = constraints.constrainDeltaRadius(desiredDeltaRadius);
-    assert(deltaRadius < double.INFINITY);
-    double innerDeltaRadius = deltaRadius - padding * 2.0;
-    double childRadius = this.parentData.radius + padding;
-    double paddingTheta = math.atan(padding / (this.parentData.radius + deltaRadius));
-    double innerTheta = paddingTheta; // increments with each child
-    double remainingDeltaTheta = constraints.maxDeltaTheta - (innerTheta + paddingTheta);
-    RenderSector child = firstChild;
-    while (child != null) {
-      SectorConstraints innerConstraints = new SectorConstraints(
-        maxDeltaRadius: innerDeltaRadius,
-        maxDeltaTheta: remainingDeltaTheta
-      );
-      assert(child.parentData is SectorParentData);
-      child.parentData.theta = innerTheta;
-      child.parentData.radius = childRadius;
-      child.layout(innerConstraints, parentUsesSize: true);
-      innerTheta += child.deltaTheta;
-      remainingDeltaTheta -= child.deltaTheta;
-      final SectorChildListParentData childParentData = child.parentData;
-      child = childParentData.nextSibling;
-      if (child != null) {
-        innerTheta += paddingTheta;
-        remainingDeltaTheta -= paddingTheta;
-      }
-    }
-    deltaTheta = innerTheta;
-  }
-
-  // offset must point to the center of our circle
-  // each sector then knows how to paint itself at its location
-  void paint(PaintingContext context, Offset offset) {
-    // TODO(ianh): avoid code duplication
-    super.paint(context, offset);
-    RenderSector child = firstChild;
-    while (child != null) {
-      context.paintChild(child, offset.toPoint());
-      final SectorChildListParentData childParentData = child.parentData;
-      child = childParentData.nextSibling;
-    }
-  }
-
-}
-
-class RenderSectorSlice extends RenderSectorWithChildren {
-  // lays out RenderSector children in a stack
-
-  RenderSectorSlice({
-    BoxDecoration decoration,
-    double deltaTheta: kTwoPi,
-    double padding: 0.0
-  }) : _padding = padding, _desiredDeltaTheta = deltaTheta, super(decoration);
-
-  double _desiredDeltaTheta;
-  double get desiredDeltaTheta => _desiredDeltaTheta;
-  void set desiredDeltaTheta(double value) {
-    assert(value != null);
-    if (_desiredDeltaTheta != value) {
-      _desiredDeltaTheta = value;
-      markNeedsLayout();
-    }
-  }
-
-  double _padding;
-  double get padding => _padding;
-  void set padding(double value) {
-    // TODO(ianh): avoid code duplication
-    assert(value != null);
-    if (_padding != value) {
-      _padding = value;
-      markNeedsLayout();
-    }
-  }
-
-  void setupParentData(RenderObject child) {
-    // TODO(ianh): avoid code duplication
-    if (child.parentData is! SectorChildListParentData)
-      child.parentData = new SectorChildListParentData();
-  }
-
-  SectorDimensions getIntrinsicDimensions(SectorConstraints constraints, double radius) {
-    assert(this.parentData is SectorParentData);
-    double paddingTheta = math.atan(padding / this.parentData.radius);
-    double outerDeltaTheta = constraints.constrainDeltaTheta(desiredDeltaTheta);
-    double innerDeltaTheta = outerDeltaTheta - paddingTheta * 2.0;
-    double childRadius = this.parentData.radius + padding;
-    double remainingDeltaRadius = constraints.maxDeltaRadius - (padding * 2.0);
-    RenderSector child = firstChild;
-    while (child != null) {
-      SectorConstraints innerConstraints = new SectorConstraints(
-        maxDeltaRadius: remainingDeltaRadius,
-        maxDeltaTheta: innerDeltaTheta
-      );
-      SectorDimensions childDimensions = child.getIntrinsicDimensions(innerConstraints, childRadius);
-      childRadius += childDimensions.deltaRadius;
-      remainingDeltaRadius -= childDimensions.deltaRadius;
-      final SectorChildListParentData childParentData = child.parentData;
-      child = childParentData.nextSibling;
-      childRadius += padding;
-      remainingDeltaRadius -= padding;
-    }
-    return new SectorDimensions.withConstraints(constraints,
-                                                deltaRadius: childRadius - this.parentData.radius,
-                                                deltaTheta: outerDeltaTheta);
-  }
-
-  void performLayout() {
-    assert(this.parentData is SectorParentData);
-    deltaTheta = constraints.constrainDeltaTheta(desiredDeltaTheta);
-    assert(deltaTheta <= kTwoPi);
-    double paddingTheta = math.atan(padding / this.parentData.radius);
-    double innerTheta = this.parentData.theta + paddingTheta;
-    double innerDeltaTheta = deltaTheta - paddingTheta * 2.0;
-    double childRadius = this.parentData.radius + padding;
-    double remainingDeltaRadius = constraints.maxDeltaRadius - (padding * 2.0);
-    RenderSector child = firstChild;
-    while (child != null) {
-      SectorConstraints innerConstraints = new SectorConstraints(
-        maxDeltaRadius: remainingDeltaRadius,
-        maxDeltaTheta: innerDeltaTheta
-      );
-      child.parentData.theta = innerTheta;
-      child.parentData.radius = childRadius;
-      child.layout(innerConstraints, parentUsesSize: true);
-      childRadius += child.deltaRadius;
-      remainingDeltaRadius -= child.deltaRadius;
-      final SectorChildListParentData childParentData = child.parentData;
-      child = childParentData.nextSibling;
-      childRadius += padding;
-      remainingDeltaRadius -= padding;
-    }
-    deltaRadius = childRadius - this.parentData.radius;
-  }
-
-  // offset must point to the center of our circle
-  // each sector then knows how to paint itself at its location
-  void paint(PaintingContext context, Offset offset) {
-    // TODO(ianh): avoid code duplication
-    super.paint(context, offset);
-    RenderSector child = firstChild;
-    while (child != null) {
-      assert(child.parentData is SectorChildListParentData);
-      context.paintChild(child, offset.toPoint());
-      final SectorChildListParentData childParentData = child.parentData;
-      child = childParentData.nextSibling;
-    }
-  }
-
-}
-
-class RenderBoxToRenderSectorAdapter extends RenderBox with RenderObjectWithChildMixin<RenderSector> {
-
-  RenderBoxToRenderSectorAdapter({ double innerRadius: 0.0, RenderSector child }) :
-    _innerRadius = innerRadius {
-    this.child = child;
-  }
-
-  double _innerRadius;
-  double get innerRadius => _innerRadius;
-  void set innerRadius(double value) {
-    _innerRadius = value;
-    markNeedsLayout();
-  }
-
-  void setupParentData(RenderObject child) {
-    if (child.parentData is! SectorParentData)
-      child.parentData = new SectorParentData();
-  }
-
-  double getMinIntrinsicWidth(BoxConstraints constraints) {
-    if (child == null)
-      return super.getMinIntrinsicWidth(constraints);
-    return getIntrinsicDimensions(constraints).width;
-  }
-
-  double getMaxIntrinsicWidth(BoxConstraints constraints) {
-    if (child == null)
-      return super.getMaxIntrinsicWidth(constraints);
-    return getIntrinsicDimensions(constraints).width;
-  }
-
-  double getMinIntrinsicHeight(BoxConstraints constraints) {
-    if (child == null)
-      return super.getMinIntrinsicHeight(constraints);
-    return getIntrinsicDimensions(constraints).height;
-  }
-
-  double getMaxIntrinsicHeight(BoxConstraints constraints) {
-    if (child == null)
-      return super.getMaxIntrinsicHeight(constraints);
-    return getIntrinsicDimensions(constraints).height;
-  }
-
-  Size getIntrinsicDimensions(BoxConstraints constraints) {
-    assert(child is RenderSector);
-    assert(child.parentData is SectorParentData);
-    assert(constraints.maxWidth < double.INFINITY || constraints.maxHeight < double.INFINITY);
-    double maxChildDeltaRadius = math.min(constraints.maxWidth, constraints.maxHeight) / 2.0 - innerRadius;
-    SectorDimensions childDimensions = child.getIntrinsicDimensions(new SectorConstraints(maxDeltaRadius: maxChildDeltaRadius), innerRadius);
-    double dimension = (innerRadius + childDimensions.deltaRadius) * 2.0;
-    return constraints.constrain(new Size(dimension, dimension));
-  }
-
-  void performLayout() {
-    if (child == null) {
-      size = constraints.constrain(Size.zero);
-    } else {
-      assert(child is RenderSector);
-      assert(constraints.maxWidth < double.INFINITY || constraints.maxHeight < double.INFINITY);
-      double maxChildDeltaRadius = math.min(constraints.maxWidth, constraints.maxHeight) / 2.0 - innerRadius;
-      assert(child.parentData is SectorParentData);
-      child.parentData.radius = innerRadius;
-      child.parentData.theta = 0.0;
-      child.layout(new SectorConstraints(maxDeltaRadius: maxChildDeltaRadius), parentUsesSize: true);
-      double dimension = (innerRadius + child.deltaRadius) * 2.0;
-      size = constraints.constrain(new Size(dimension, dimension));
-    }
-  }
-
-  void paint(PaintingContext context, Offset offset) {
-    super.paint(context, offset);
-    if (child != null) {
-      Rect bounds = offset & size;
-      // we move the offset to the center of the circle for the RenderSectors
-      context.paintChild(child, bounds.center);
-    }
-  }
-
-  bool hitTest(HitTestResult result, { Point position }) {
-    if (child == null)
-      return false;
-    double x = position.x;
-    double y = position.y;
-    // translate to our origin
-    x -= size.width/2.0;
-    y -= size.height/2.0;
-    // convert to radius/theta
-    double radius = math.sqrt(x*x+y*y);
-    double theta = (math.atan2(x, -y) - math.PI/2.0) % kTwoPi;
-    if (radius < innerRadius)
-      return false;
-    if (radius >= innerRadius + child.deltaRadius)
-      return false;
-    if (theta > child.deltaTheta)
-      return false;
-    child.hitTest(result, radius: radius, theta: theta);
-    result.add(new BoxHitTestEntry(this, position));
-    return true;
-  }
-
-}
-
-class RenderSolidColor extends RenderDecoratedSector {
-  RenderSolidColor(Color backgroundColor, {
-    this.desiredDeltaRadius: double.INFINITY,
-    this.desiredDeltaTheta: kTwoPi
-  }) : this.backgroundColor = backgroundColor,
-       super(new BoxDecoration(backgroundColor: backgroundColor));
-
-  double desiredDeltaRadius;
-  double desiredDeltaTheta;
-  final Color backgroundColor;
-
-  SectorDimensions getIntrinsicDimensions(SectorConstraints constraints, double radius) {
-    return new SectorDimensions.withConstraints(constraints, deltaTheta: desiredDeltaTheta);
-  }
-
-  void performLayout() {
-    deltaRadius = constraints.constrainDeltaRadius(desiredDeltaRadius);
-    deltaTheta = constraints.constrainDeltaTheta(desiredDeltaTheta);
-  }
-
-  void handleEvent(InputEvent event, HitTestEntry entry) {
-    if (event.type == 'pointerdown')
-      decoration = new BoxDecoration(backgroundColor: const Color(0xFFFF0000));
-    else if (event.type == 'pointerup')
-      decoration = new BoxDecoration(backgroundColor: backgroundColor);
-  }
-}
diff --git a/examples/rendering/lib/solid_color_box.dart b/examples/rendering/lib/solid_color_box.dart
deleted file mode 100644
index 31928d8..0000000
--- a/examples/rendering/lib/solid_color_box.dart
+++ /dev/null
@@ -1,50 +0,0 @@
-// Copyright 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:flutter/rendering.dart';
-import 'package:flutter/gestures.dart';
-
-class RenderSolidColorBox extends RenderDecoratedBox {
-  final Size desiredSize;
-  final Color backgroundColor;
-
-  RenderSolidColorBox(Color backgroundColor, { this.desiredSize: Size.infinite })
-      : backgroundColor = backgroundColor,
-        super(decoration: new BoxDecoration(backgroundColor: backgroundColor));
-
-  double getMinIntrinsicWidth(BoxConstraints constraints) {
-    return constraints.constrainHeight(
-      this.desiredSize == Size.infinite ? 0.0 : desiredSize.width
-    );
-  }
-
-  double getMaxIntrinsicWidth(BoxConstraints constraints) {
-    return constraints.constrainWidth(
-      this.desiredSize == Size.infinite ? 0.0 : desiredSize.width
-    );
-  }
-
-  double getMinIntrinsicHeight(BoxConstraints constraints) {
-    return constraints.constrainHeight(
-      this.desiredSize == Size.infinite ? 0.0 : desiredSize.height
-    );
-  }
-
-  double getMaxIntrinsicHeight(BoxConstraints constraints) {
-    return constraints.constrainHeight(
-      this.desiredSize == Size.infinite ? 0.0 : desiredSize.height
-    );
-  }
-
-  void performLayout() {
-    size = constraints.constrain(desiredSize);
-  }
-
-  void handleEvent(InputEvent event, BoxHitTestEntry entry) {
-    if (event.type == 'pointerdown')
-      decoration = new BoxDecoration(backgroundColor: const Color(0xFFFF0000));
-    else if (event.type == 'pointerup')
-      decoration = new BoxDecoration(backgroundColor: backgroundColor);
-  }
-}
diff --git a/examples/rendering/pubspec.yaml b/examples/rendering/pubspec.yaml
deleted file mode 100644
index b16bbd4..0000000
--- a/examples/rendering/pubspec.yaml
+++ /dev/null
@@ -1,10 +0,0 @@
-name: flutter_rendering_examples
-dependencies:
-  flutter: 
-    '0.0.16'
-  sky_tools: any
-dependency_overrides:
-  material_design_icons:
-    path: ../../sky/packages/material_design_icons
-  flutter:
-    path: ../../sky/packages/sky
diff --git a/examples/rendering/render_grid.dart b/examples/rendering/render_grid.dart
deleted file mode 100644
index 0140311..0000000
--- a/examples/rendering/render_grid.dart
+++ /dev/null
@@ -1,26 +0,0 @@
-// Copyright 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 'dart:math' as math;
-
-import 'package:flutter/material.dart';
-import 'package:flutter/rendering.dart';
-
-import 'lib/solid_color_box.dart';
-
-Color randomColor() {
-  final List<Color> allColors = [
-    Colors.blue,
-    Colors.indigo
-  ].map((p) => p.values).fold([], (a, b) => a..addAll(b));
-  final random = new math.Random();
-  return allColors[random.nextInt(allColors.length)];
-}
-
-RenderBox buildGridExample() {
-  List<RenderBox> children = new List<RenderBox>.generate(30, (_) => new RenderSolidColorBox(randomColor()));
-  return new RenderGrid(children: children, maxChildExtent: 100.0);
-}
-
-main() => new FlutterBinding(root: buildGridExample());
diff --git a/examples/rendering/render_paragraph.dart b/examples/rendering/render_paragraph.dart
deleted file mode 100644
index 8eca023..0000000
--- a/examples/rendering/render_paragraph.dart
+++ /dev/null
@@ -1,44 +0,0 @@
-// Copyright 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:flutter/rendering.dart';
-
-import 'lib/solid_color_box.dart';
-
-void main() {
-  RenderFlex flexRoot = new RenderFlex(direction: FlexDirection.vertical);
-
-  RenderObject root = new RenderDecoratedBox(
-    decoration: new BoxDecoration(backgroundColor: const Color(0xFF606060)),
-    child: flexRoot
-  );
-
-  FlexParentData childParentData;
-
-  RenderObject child = new RenderSolidColorBox(const Color(0xFFFFFF00));
-  flexRoot.add(child);
-  childParentData = child.parentData;
-  childParentData.flex = 2;
-
-  // The internet is a beautiful place.  https://baconipsum.com/
-  String meatyString = """Bacon ipsum dolor amet ham fatback tri-tip, prosciutto
-porchetta bacon kevin meatball meatloaf pig beef ribs chicken. Brisket ribeye
-andouille leberkas capicola meatloaf. Chicken pig ball tip pork picanha bresaola
-alcatra. Pork pork belly alcatra, flank chuck drumstick biltong doner jowl.
-Pancetta meatball tongue tenderloin rump tail jowl boudin.""";
-
-  StyledTextSpan text = new StyledTextSpan(
-    new TextStyle(color: const Color(0xFF009900)),
-    <TextSpan>[new PlainTextSpan(meatyString)]
-  );
-  child = new RenderDecoratedBox(
-    decoration: new BoxDecoration(backgroundColor: const Color(0xFFFFFFFF)),
-    child: new RenderParagraph(text)
-  );
-  flexRoot.add(child);
-  childParentData = child.parentData;
-  childParentData.flex = 1;
-
-  new FlutterBinding(root: root);
-}
diff --git a/examples/rendering/sector_layout.dart b/examples/rendering/sector_layout.dart
deleted file mode 100644
index a6fc547..0000000
--- a/examples/rendering/sector_layout.dart
+++ /dev/null
@@ -1,22 +0,0 @@
-// Copyright 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:flutter/rendering.dart';
-import 'lib/sector_layout.dart';
-
-RenderBox buildSectorExample() {
-  RenderSectorRing rootCircle = new RenderSectorRing(padding: 20.0);
-  rootCircle.add(new RenderSolidColor(const Color(0xFF00FFFF), desiredDeltaTheta: kTwoPi * 0.15));
-  rootCircle.add(new RenderSolidColor(const Color(0xFF0000FF), desiredDeltaTheta: kTwoPi * 0.4));
-  RenderSectorSlice stack = new RenderSectorSlice(padding: 2.0);
-  stack.add(new RenderSolidColor(const Color(0xFFFFFF00), desiredDeltaRadius: 20.0));
-  stack.add(new RenderSolidColor(const Color(0xFFFF9000), desiredDeltaRadius: 20.0));
-  stack.add(new RenderSolidColor(const Color(0xFF00FF00)));
-  rootCircle.add(stack);
-  return new RenderBoxToRenderSectorAdapter(innerRadius: 50.0, child: rootCircle);
-}
-
-void main() {
-  new FlutterBinding(root: buildSectorExample());
-}
diff --git a/examples/rendering/shadowed_box.dart b/examples/rendering/shadowed_box.dart
deleted file mode 100644
index c2030fc..0000000
--- a/examples/rendering/shadowed_box.dart
+++ /dev/null
@@ -1,27 +0,0 @@
-// Copyright 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 'dart:ui';
-
-import 'package:flutter/rendering.dart';
-import 'package:flutter/material.dart';
-
-void main() {
-  var coloredBox = new RenderDecoratedBox(
-    decoration: new BoxDecoration(
-      gradient: new RadialGradient(
-        center: Point.origin, radius: 500.0,
-        colors: <Color>[Colors.yellow[500], Colors.blue[500]]),
-      boxShadow: shadows[3])
-  );
-  var paddedBox = new RenderPadding(
-    padding: const EdgeDims.all(50.0),
-    child: coloredBox);
-  new FlutterBinding(root: new RenderDecoratedBox(
-    decoration: const BoxDecoration(
-      backgroundColor: const Color(0xFFFFFFFF)
-    ),
-    child: paddedBox
-  ));
-}
diff --git a/examples/rendering/simple_autolayout.dart b/examples/rendering/simple_autolayout.dart
deleted file mode 100644
index 8adbb4a..0000000
--- a/examples/rendering/simple_autolayout.dart
+++ /dev/null
@@ -1,63 +0,0 @@
-// Copyright 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 'dart:ui';
-
-import 'package:cassowary/cassowary.dart' as al;
-import 'package:flutter/rendering.dart';
-
-void main() {
-  RenderDecoratedBox c1 = new RenderDecoratedBox(
-    decoration: new BoxDecoration(backgroundColor: const Color(0xFFFF0000))
-  );
-
-  RenderDecoratedBox c2 = new RenderDecoratedBox(
-    decoration: new BoxDecoration(backgroundColor: const Color(0xFF00FF00))
-  );
-
-  RenderDecoratedBox c3 = new RenderDecoratedBox(
-    decoration: new BoxDecoration(backgroundColor: const Color(0xFF0000FF))
-  );
-
-  RenderDecoratedBox c4 = new RenderDecoratedBox(
-    decoration: new BoxDecoration(backgroundColor: const Color(0xFFFFFFFF))
-  );
-
-  RenderAutoLayout root = new RenderAutoLayout(children: <RenderBox>[c1, c2, c3, c4]);
-
-  AutoLayoutParentData p1 = c1.parentData;
-  AutoLayoutParentData p2 = c2.parentData;
-  AutoLayoutParentData p3 = c3.parentData;
-  AutoLayoutParentData p4 = c4.parentData;
-
-  root.addConstraints(<al.Constraint>[
-    // Sum of widths of each box must be equal to that of the container
-    (p1.width + p2.width + p3.width == root.width) as al.Constraint,
-
-    // The boxes must be stacked left to right
-    p1.rightEdge <= p2.leftEdge,
-    p2.rightEdge <= p3.leftEdge,
-
-    // The widths of the first and the third boxes should be equal
-    (p1.width == p3.width) as al.Constraint,
-
-    // The width of the second box should be twice as much as that of the first
-    // and third
-    (p2.width * al.cm(2.0) == p1.width) as al.Constraint,
-
-    // The height of the three boxes should be equal to that of the container
-    (p1.height == p2.height) as al.Constraint,
-    (p2.height == p3.height) as al.Constraint,
-    (p3.height == root.height) as al.Constraint,
-
-    // The fourth box should be half as wide as the second and must be attached
-    // to the right edge of the same (by its center)
-    (p4.width == p2.width / al.cm(2.0)) as al.Constraint,
-    (p4.height == al.cm(50.0)) as al.Constraint,
-    (p4.horizontalCenter == p2.rightEdge) as al.Constraint,
-    (p4.verticalCenter == p2.height / al.cm(2.0)) as al.Constraint,
-  ]);
-
-  new FlutterBinding(root: root);
-}
diff --git a/examples/rendering/spinning_flex.dart b/examples/rendering/spinning_flex.dart
deleted file mode 100644
index 23dcbde..0000000
--- a/examples/rendering/spinning_flex.dart
+++ /dev/null
@@ -1,47 +0,0 @@
-// Copyright 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 'dart:ui' as ui;
-
-import 'package:flutter/animation.dart';
-import 'package:flutter/rendering.dart';
-
-import 'lib/solid_color_box.dart';
-
-Duration timeBase;
-RenderTransform transformBox;
-
-void main() {
-  RenderFlex flexRoot = new RenderFlex(direction: FlexDirection.vertical);
-
-  void addFlexChildSolidColor(RenderFlex parent, ui.Color backgroundColor, { int flex: 0 }) {
-    RenderSolidColorBox child = new RenderSolidColorBox(backgroundColor);
-    parent.add(child);
-    final FlexParentData childParentData = child.parentData;
-    childParentData.flex = flex;
-  }
-
-  addFlexChildSolidColor(flexRoot, const ui.Color(0xFFFF00FF), flex: 1);
-  addFlexChildSolidColor(flexRoot, const ui.Color(0xFFFFFF00), flex: 2);
-  addFlexChildSolidColor(flexRoot, const ui.Color(0xFF00FFFF), flex: 1);
-
-  transformBox = new RenderTransform(child: flexRoot, transform: new Matrix4.identity());
-
-  RenderPadding root = new RenderPadding(padding: new EdgeDims.all(20.0), child: transformBox);
-
-  new FlutterBinding(root: root);
-
-  scheduler.addPersistentFrameCallback(rotate);
-}
-
-void rotate(Duration timeStamp) {
-  if (timeBase == null)
-    timeBase = timeStamp;
-  double delta = (timeStamp - timeBase).inMicroseconds.toDouble() / Duration.MICROSECONDS_PER_SECOND; // radians
-
-  transformBox.setIdentity();
-  transformBox.translate(transformBox.size.width / 2.0, transformBox.size.height / 2.0);
-  transformBox.rotateZ(delta);
-  transformBox.translate(-transformBox.size.width / 2.0, -transformBox.size.height / 2.0);
-}
diff --git a/examples/rendering/touch_demo.dart b/examples/rendering/touch_demo.dart
deleted file mode 100644
index ec2a108..0000000
--- a/examples/rendering/touch_demo.dart
+++ /dev/null
@@ -1,86 +0,0 @@
-// Copyright 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:flutter/material.dart';
-import 'package:flutter/rendering.dart';
-import 'package:flutter/gestures.dart';
-
-// Material design colors. :p
-List<Color> kColors = <Color>[
-  Colors.teal[500],
-  Colors.amber[500],
-  Colors.purple[500],
-  Colors.lightBlue[500],
-  Colors.deepPurple[500],
-  Colors.lime[500],
-];
-
-class Dot {
-  final Paint _paint;
-  Point position = Point.origin;
-  double radius = 0.0;
-
-  Dot({ Color color }) : _paint = new Paint()..color = color;
-
-  void update(PointerInputEvent event) {
-    position = new Point(event.x, event.y);
-    radius = 5 + (95 * event.pressure);
-  }
-
-  void paint(PaintingContext context, Offset offset) {
-    context.canvas.drawCircle(position + offset, radius, _paint);
-  }
-}
-
-class RenderTouchDemo extends RenderBox {
-  final Map<int, Dot> dots = <int, Dot>{};
-
-  void handleEvent(InputEvent event, BoxHitTestEntry entry) {
-    if (event is PointerInputEvent) {
-      switch (event.type) {
-        case 'pointerdown':
-          Color color = kColors[event.pointer.remainder(kColors.length)];
-          dots[event.pointer] = new Dot(color: color)..update(event);
-          break;
-        case 'pointerup':
-          dots.remove(event.pointer);
-          break;
-        case 'pointercancel':
-          dots.clear();
-          break;
-        case 'pointermove':
-          dots[event.pointer].update(event);
-          break;
-      }
-      markNeedsPaint();
-    }
-  }
-
-  void performLayout() {
-    size = constraints.biggest;
-  }
-
-  void paint(PaintingContext context, Offset offset) {
-    final PaintingCanvas canvas = context.canvas;
-    Paint white = new Paint()
-        ..color = const Color(0xFFFFFFFF);
-    canvas.drawRect(offset & size, white);
-    for (Dot dot in dots.values)
-      dot.paint(context, offset);
-  }
-}
-
-void main() {
-  RenderParagraph paragraph = new RenderParagraph(new PlainTextSpan("Touch me!"));
-  RenderStack stack = new RenderStack(children: <RenderBox>[
-    new RenderTouchDemo(),
-    paragraph,
-  ]);
-  // Prevent the RenderParagraph from filling the whole screen so
-  // that it doesn't eat events.
-  final StackParentData paragraphParentData = paragraph.parentData;
-  paragraphParentData..top = 40.0
-                     ..left = 20.0;
-  new FlutterBinding(root: stack);
-}
diff --git a/examples/rendering/transform.dart b/examples/rendering/transform.dart
deleted file mode 100644
index 664b032..0000000
--- a/examples/rendering/transform.dart
+++ /dev/null
@@ -1,28 +0,0 @@
-// Copyright 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 'dart:ui' as ui;
-
-import 'package:flutter/rendering.dart';
-
-void main() {
-  RenderDecoratedBox green = new RenderDecoratedBox(
-    decoration: new BoxDecoration(backgroundColor: const ui.Color(0xFF00FF00))
-  );
-  RenderConstrainedBox box = new RenderConstrainedBox(
-    additionalConstraints: new BoxConstraints.tight(const ui.Size(200.0, 200.0)),
-    child: green
-  );
-
-  Matrix4 transform = new Matrix4.identity();
-  RenderTransform spin = new RenderTransform(
-    transform: transform,
-    child: box
-  );
-  spin.rotateZ(1.0);
-
-  RenderFlex flex = new RenderFlex();
-  flex.add(spin);
-  new FlutterBinding(root: flex);
-}
diff --git a/examples/stocks/BUILD.gn b/examples/stocks/BUILD.gn
deleted file mode 100644
index d50651d..0000000
--- a/examples/stocks/BUILD.gn
+++ /dev/null
@@ -1,19 +0,0 @@
-# Copyright 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("//sky/build/sky_app.gni")
-
-sky_app("stocks") {
-  main_dart = "lib/main.dart"
-  manifest = "flutter.yaml"
-
-  if (is_android) {
-    apk_name = "Stocks"
-  } else if (is_ios) {
-    info_plist = "ios/Info.plist"
-    launcher_resources = [
-      "ios/LaunchScreen.storyboardc",
-    ]
-  }
-}
diff --git a/examples/stocks/apk/AndroidManifest.xml b/examples/stocks/apk/AndroidManifest.xml
deleted file mode 100644
index 579c98d..0000000
--- a/examples/stocks/apk/AndroidManifest.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright 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.
- -->
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="org.domokit.stocks" android:versionCode="1" android:versionName="0.0.1">
-
-    <uses-sdk android:minSdkVersion="14" android:targetSdkVersion="21" />
-    <uses-permission android:name="android.permission.INTERNET"/>
-
-    <application android:name="org.domokit.sky.shell.SkyApplication" android:label="Stocks">
-        <activity android:name="org.domokit.sky.shell.SkyActivity"
-                  android:launchMode="singleTask"
-                  android:theme="@android:style/Theme.Black.NoTitleBar"
-                  android:configChanges="orientation|keyboardHidden|keyboard|screenSize"
-                  android:hardwareAccelerated="true">
-            <intent-filter>
-                <action android:name="android.intent.action.MAIN"/>
-                <category android:name="android.intent.category.LAUNCHER"/>
-            </intent-filter>
-        </activity>
-    </application>
- </manifest>
diff --git a/examples/stocks/data/stock_data_0.json b/examples/stocks/data/stock_data_0.json
deleted file mode 100644
index c634894..0000000
--- a/examples/stocks/data/stock_data_0.json
+++ /dev/null
@@ -1,1002 +0,0 @@
-[
-  [
-    "AAIT", 
-    "iShares MSCI All Country Asia Information Technology Index Fun", 
-    "35.05", 
-    "$7.01M", 
-    "n/a", 
-    "n/a", 
-    "n/a", 
-    "http://www.nasdaq.com/symbol/aait"
-  ], 
-  [
-    "AAL", 
-    "American Airlines Group, Inc.", 
-    "51.02", 
-    "$36.59B", 
-    "n/a", 
-    "Transportation", 
-    "Air Freight/Delivery Services", 
-    "http://www.nasdaq.com/symbol/aal"
-  ], 
-  [
-    "AAME", 
-    "Atlantic American Corporation", 
-    "3.99", 
-    "$82.28M", 
-    "n/a", 
-    "Finance", 
-    "Life Insurance", 
-    "http://www.nasdaq.com/symbol/aame"
-  ], 
-  [
-    "AAOI", 
-    "Applied Optoelectronics, Inc.", 
-    "10.22", 
-    "$151.42M", 
-    "2013", 
-    "Technology", 
-    "Semiconductors", 
-    "http://www.nasdaq.com/symbol/aaoi"
-  ], 
-  [
-    "AAON", 
-    "AAON, Inc.", 
-    "23.74", 
-    "$1.29B", 
-    "n/a", 
-    "Capital Goods", 
-    "Industrial Machinery/Components", 
-    "http://www.nasdaq.com/symbol/aaon"
-  ], 
-  [
-    "AAPL", 
-    "Apple Inc.", 
-    "129.495", 
-    "$754.28B", 
-    "1980", 
-    "Technology", 
-    "Computer Manufacturing", 
-    "http://www.nasdaq.com/symbol/aapl"
-  ], 
-  [
-    "AAVL", 
-    "Avalanche Biotechnologies, Inc.", 
-    "40.06", 
-    "$995.08M", 
-    "2014", 
-    "Health Care", 
-    "Biotechnology: Biological Products (No Diagnostic Substances)", 
-    "http://www.nasdaq.com/symbol/aavl"
-  ], 
-  [
-    "AAWW", 
-    "Atlas Air Worldwide Holdings", 
-    "47.23", 
-    "$1.17B", 
-    "n/a", 
-    "Transportation", 
-    "Transportation Services", 
-    "http://www.nasdaq.com/symbol/aaww"
-  ], 
-  [
-    "AAXJ", 
-    "iShares MSCI All Country Asia ex Japan Index Fund", 
-    "63.66", 
-    "$3.67B", 
-    "n/a", 
-    "n/a", 
-    "n/a", 
-    "http://www.nasdaq.com/symbol/aaxj"
-  ], 
-  [
-    "ABAC", 
-    "Aoxin Tianli Group, Inc.", 
-    "1.61", 
-    "$44.7M", 
-    "n/a", 
-    "Consumer Non-Durables", 
-    "Farming/Seeds/Milling", 
-    "http://www.nasdaq.com/symbol/abac"
-  ], 
-  [
-    "ABAX", 
-    "ABAXIS, Inc.", 
-    "60.17", 
-    "$1.36B", 
-    "1992", 
-    "Capital Goods", 
-    "Industrial Machinery/Components", 
-    "http://www.nasdaq.com/symbol/abax"
-  ], 
-  [
-    "ABCB", 
-    "Ameris Bancorp", 
-    "26", 
-    "$732.18M", 
-    "1994", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/abcb"
-  ], 
-  [
-    "ABCD", 
-    "Cambium Learning Group, Inc.", 
-    "2.66", 
-    "$119.48M", 
-    "n/a", 
-    "Consumer Services", 
-    "Publishing", 
-    "http://www.nasdaq.com/symbol/abcd"
-  ], 
-  [
-    "ABCO", 
-    "The Advisory Board Company", 
-    "53.5", 
-    "$2.06B", 
-    "2001", 
-    "Consumer Services", 
-    "Other Consumer Services", 
-    "http://www.nasdaq.com/symbol/abco"
-  ], 
-  [
-    "ABCW", 
-    "Anchor BanCorp Wisconsin Inc.", 
-    "34.63", 
-    "$320.16M", 
-    "2014", 
-    "Finance", 
-    "Banks", 
-    "http://www.nasdaq.com/symbol/abcw"
-  ], 
-  [
-    "ABDC", 
-    "Alcentra Capital Corp.", 
-    "13.59", 
-    "$183.69M", 
-    "2014", 
-    "n/a", 
-    "n/a", 
-    "http://www.nasdaq.com/symbol/abdc"
-  ], 
-  [
-    "ABGB", 
-    "Abengoa, S.A.", 
-    "17.53", 
-    "$2.94B", 
-    "2013", 
-    "Consumer Services", 
-    "Military/Government/Technical", 
-    "http://www.nasdaq.com/symbol/abgb"
-  ], 
-  [
-    "ABIO", 
-    "ARCA biopharma, Inc.", 
-    "0.6975", 
-    "$14.75M", 
-    "n/a", 
-    "Health Care", 
-    "Biotechnology: In Vitro & In Vivo Diagnostic Substances", 
-    "http://www.nasdaq.com/symbol/abio"
-  ], 
-  [
-    "ABMD", 
-    "ABIOMED, Inc.", 
-    "60.35", 
-    "$2.48B", 
-    "n/a", 
-    "Health Care", 
-    "Medical/Dental Instruments", 
-    "http://www.nasdaq.com/symbol/abmd"
-  ], 
-  [
-    "ABTL", 
-    "Autobytel Inc.", 
-    "10", 
-    "$90.29M", 
-    "1999", 
-    "Technology", 
-    "Computer Software: Programming, Data Processing", 
-    "http://www.nasdaq.com/symbol/abtl"
-  ], 
-  [
-    "ABY", 
-    "Abengoa Yield plc", 
-    "34.73", 
-    "$2.78B", 
-    "2014", 
-    "Public Utilities", 
-    "Electric Utilities: Central", 
-    "http://www.nasdaq.com/symbol/aby"
-  ], 
-  [
-    "ACAD", 
-    "ACADIA Pharmaceuticals Inc.", 
-    "37.45", 
-    "$3.74B", 
-    "1985", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/acad"
-  ], 
-  [
-    "ACAS", 
-    "American Capital, Ltd.", 
-    "14.75", 
-    "$3.98B", 
-    "1997", 
-    "n/a", 
-    "n/a", 
-    "http://www.nasdaq.com/symbol/acas"
-  ], 
-  [
-    "ACAT", 
-    "Arctic Cat Inc.", 
-    "36.36", 
-    "$470.75M", 
-    "1990", 
-    "Capital Goods", 
-    "Industrial Specialties", 
-    "http://www.nasdaq.com/symbol/acat"
-  ], 
-  [
-    "ACET", 
-    "Aceto Corporation", 
-    "20.95", 
-    "$609.83M", 
-    "n/a", 
-    "Health Care", 
-    "Other Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/acet"
-  ], 
-  [
-    "ACFC", 
-    "Atlantic Coast Financial Corporation", 
-    "3.88", 
-    "$60.18M", 
-    "n/a", 
-    "Finance", 
-    "Savings Institutions", 
-    "http://www.nasdaq.com/symbol/acfc"
-  ], 
-  [
-    "ACFN", 
-    "Acorn Energy, Inc.", 
-    "0.6124", 
-    "$16.21M", 
-    "n/a", 
-    "Consumer Services", 
-    "Military/Government/Technical", 
-    "http://www.nasdaq.com/symbol/acfn"
-  ], 
-  [
-    "ACGL", 
-    "Arch Capital Group Ltd.", 
-    "60.04", 
-    "$7.75B", 
-    "n/a", 
-    "Finance", 
-    "Property-Casualty Insurers", 
-    "http://www.nasdaq.com/symbol/acgl"
-  ], 
-  [
-    "ACHC", 
-    "Acadia Healthcare Company, Inc.", 
-    "63.795", 
-    "$4.21B", 
-    "n/a", 
-    "Health Care", 
-    "Medical Specialities", 
-    "http://www.nasdaq.com/symbol/achc"
-  ], 
-  [
-    "ACHN", 
-    "Achillion Pharmaceuticals, Inc.", 
-    "12.16", 
-    "$1.39B", 
-    "2006", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/achn"
-  ], 
-  [
-    "ACIW", 
-    "ACI Worldwide, Inc.", 
-    "20.46", 
-    "$2.35B", 
-    "n/a", 
-    "Technology", 
-    "Computer Software: Prepackaged Software", 
-    "http://www.nasdaq.com/symbol/aciw"
-  ], 
-  [
-    "ACLS", 
-    "Axcelis Technologies, Inc.", 
-    "2.7", 
-    "$302.41M", 
-    "2000", 
-    "Technology", 
-    "Industrial Machinery/Components", 
-    "http://www.nasdaq.com/symbol/acls"
-  ], 
-  [
-    "ACNB", 
-    "ACNB Corporation", 
-    "20.25", 
-    "$121.73M", 
-    "n/a", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/acnb"
-  ], 
-  [
-    "ACOR", 
-    "Acorda Therapeutics, Inc.", 
-    "37.41", 
-    "$1.57B", 
-    "2006", 
-    "Health Care", 
-    "Biotechnology: Biological Products (No Diagnostic Substances)", 
-    "http://www.nasdaq.com/symbol/acor"
-  ], 
-  [
-    "ACPW", 
-    "Active Power, Inc.", 
-    "1.83", 
-    "$42.26M", 
-    "2000", 
-    "Public Utilities", 
-    "Electric Utilities: Central", 
-    "http://www.nasdaq.com/symbol/acpw"
-  ], 
-  [
-    "ACRX", 
-    "AcelRx Pharmaceuticals, Inc.", 
-    "8.13", 
-    "$355.34M", 
-    "2011", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/acrx"
-  ], 
-  [
-    "ACSF", 
-    "American Capital Senior Floating, Ltd.", 
-    "12.9", 
-    "$129M", 
-    "2014", 
-    "n/a", 
-    "n/a", 
-    "http://www.nasdaq.com/symbol/acsf"
-  ], 
-  [
-    "ACST", 
-    "Acasti Pharma, Inc.", 
-    "0.5592", 
-    "$59.52M", 
-    "n/a", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/acst"
-  ], 
-  [
-    "ACTA", 
-    "Actua Corporation", 
-    "15.37", 
-    "$623.74M", 
-    "n/a", 
-    "Technology", 
-    "EDP Services", 
-    "http://www.nasdaq.com/symbol/acta"
-  ], 
-  [
-    "ACTG", 
-    "Acacia Research Corporation", 
-    "12.83", 
-    "$643.05M", 
-    "n/a", 
-    "Miscellaneous", 
-    "Multi-Sector Companies", 
-    "http://www.nasdaq.com/symbol/actg"
-  ], 
-  [
-    "ACTS", 
-    "Actions Semiconductor Co., Ltd.", 
-    "1.59", 
-    "$136.74M", 
-    "2005", 
-    "Technology", 
-    "Semiconductors", 
-    "http://www.nasdaq.com/symbol/acts"
-  ], 
-  [
-    "ACUR", 
-    "Acura Pharmaceuticals, Inc.", 
-    "0.63", 
-    "$29.51M", 
-    "n/a", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/acur"
-  ], 
-  [
-    "ACWI", 
-    "iShares MSCI ACWI Index Fund", 
-    "61.01", 
-    "$6.59B", 
-    "n/a", 
-    "n/a", 
-    "n/a", 
-    "http://www.nasdaq.com/symbol/acwi"
-  ], 
-  [
-    "ACWX", 
-    "iShares MSCI ACWI ex US Index Fund", 
-    "45.21", 
-    "$1.84B", 
-    "n/a", 
-    "n/a", 
-    "n/a", 
-    "http://www.nasdaq.com/symbol/acwx"
-  ], 
-  [
-    "ACXM", 
-    "Acxiom Corporation", 
-    "19.66", 
-    "$1.52B", 
-    "n/a", 
-    "Technology", 
-    "EDP Services", 
-    "http://www.nasdaq.com/symbol/acxm"
-  ], 
-  [
-    "ADAT", 
-    "Authentidate Holding Corp.", 
-    "0.82", 
-    "$34.25M", 
-    "n/a", 
-    "Technology", 
-    "EDP Services", 
-    "http://www.nasdaq.com/symbol/adat"
-  ], 
-  [
-    "ADBE", 
-    "Adobe Systems Incorporated", 
-    "78.55", 
-    "$39.14B", 
-    "1986", 
-    "Technology", 
-    "Computer Software: Prepackaged Software", 
-    "http://www.nasdaq.com/symbol/adbe"
-  ], 
-  [
-    "ADEP", 
-    "Adept Technology, Inc.", 
-    "6.5", 
-    "$85.17M", 
-    "n/a", 
-    "Technology", 
-    "Industrial Machinery/Components", 
-    "http://www.nasdaq.com/symbol/adep"
-  ], 
-  [
-    "ADHD", 
-    "Alcobra Ltd.", 
-    "7.43", 
-    "$157.35M", 
-    "2013", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/adhd"
-  ], 
-  [
-    "ADI", 
-    "Analog Devices, Inc.", 
-    "59.13", 
-    "$18.43B", 
-    "n/a", 
-    "Technology", 
-    "Semiconductors", 
-    "http://www.nasdaq.com/symbol/adi"
-  ], 
-  [
-    "ADMA", 
-    "ADMA Biologics Inc", 
-    "10.48", 
-    "$97.38M", 
-    "n/a", 
-    "Health Care", 
-    "Biotechnology: Biological Products (No Diagnostic Substances)", 
-    "http://www.nasdaq.com/symbol/adma"
-  ], 
-  [
-    "ADMP", 
-    "Adamis Pharmaceuticals Corporation", 
-    "6.51", 
-    "$84.32M", 
-    "n/a", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/admp"
-  ], 
-  [
-    "ADMS", 
-    "Adamas Pharmaceuticals, Inc.", 
-    "17.28", 
-    "$295.93M", 
-    "2014", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/adms"
-  ], 
-  [
-    "ADNC", 
-    "Audience, Inc.", 
-    "4.67", 
-    "$107.3M", 
-    "2012", 
-    "Technology", 
-    "Semiconductors", 
-    "http://www.nasdaq.com/symbol/adnc"
-  ], 
-  [
-    "ADP", 
-    "Automatic Data Processing, Inc.", 
-    "88.685", 
-    "$42.14B", 
-    "n/a", 
-    "Technology", 
-    "EDP Services", 
-    "http://www.nasdaq.com/symbol/adp"
-  ], 
-  [
-    "ADRA", 
-    "BLDRS Asia 50 ADR Index Fund", 
-    "30.7699", 
-    "$27.69M", 
-    "n/a", 
-    "n/a", 
-    "n/a", 
-    "http://www.nasdaq.com/symbol/adra"
-  ], 
-  [
-    "ADRD", 
-    "BLDRS Developed Markets 100 ADR Index Fund", 
-    "23.87", 
-    "$54.9M", 
-    "n/a", 
-    "n/a", 
-    "n/a", 
-    "http://www.nasdaq.com/symbol/adrd"
-  ], 
-  [
-    "ADRE", 
-    "BLDRS Emerging Markets 50 ADR Index Fund", 
-    "36.68", 
-    "$185.23M", 
-    "n/a", 
-    "n/a", 
-    "n/a", 
-    "http://www.nasdaq.com/symbol/adre"
-  ], 
-  [
-    "ADRU", 
-    "BLDRS Europe 100 ADR Index Fund", 
-    "23.5754", 
-    "$17.68M", 
-    "n/a", 
-    "n/a", 
-    "n/a", 
-    "http://www.nasdaq.com/symbol/adru"
-  ], 
-  [
-    "ADSK", 
-    "Autodesk, Inc.", 
-    "62.37", 
-    "$14.19B", 
-    "n/a", 
-    "Technology", 
-    "Computer Software: Prepackaged Software", 
-    "http://www.nasdaq.com/symbol/adsk"
-  ], 
-  [
-    "ADTN", 
-    "ADTRAN, Inc.", 
-    "23", 
-    "$1.25B", 
-    "1994", 
-    "Public Utilities", 
-    "Telecommunications Equipment", 
-    "http://www.nasdaq.com/symbol/adtn"
-  ], 
-  [
-    "ADUS", 
-    "Addus HomeCare Corporation", 
-    "21.4", 
-    "$235.18M", 
-    "2009", 
-    "Health Care", 
-    "Medical/Nursing Services", 
-    "http://www.nasdaq.com/symbol/adus"
-  ], 
-  [
-    "ADVS", 
-    "Advent Software, Inc.", 
-    "44.17", 
-    "$2.31B", 
-    "1995", 
-    "Technology", 
-    "EDP Services", 
-    "http://www.nasdaq.com/symbol/advs"
-  ], 
-  [
-    "ADXS", 
-    "Advaxis, Inc.", 
-    "8.22", 
-    "$194.36M", 
-    "n/a", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/adxs"
-  ], 
-  [
-    "ADXSW", 
-    "Advaxis, Inc.", 
-    "5.2", 
-    "n/a", 
-    "n/a", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/adxsw"
-  ], 
-  [
-    "AEGN", 
-    "Aegion Corp", 
-    "16.66", 
-    "$622.78M", 
-    "n/a", 
-    "Basic Industries", 
-    "Water Supply", 
-    "http://www.nasdaq.com/symbol/aegn"
-  ], 
-  [
-    "AEGR", 
-    "Aegerion Pharmaceuticals, Inc.", 
-    "26.49", 
-    "$753.27M", 
-    "2010", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/aegr"
-  ], 
-  [
-    "AEHR", 
-    "Aehr Test Systems", 
-    "2.39", 
-    "$30.67M", 
-    "1997", 
-    "Capital Goods", 
-    "Electrical Products", 
-    "http://www.nasdaq.com/symbol/aehr"
-  ], 
-  [
-    "AEIS", 
-    "Advanced Energy Industries, Inc.", 
-    "26.53", 
-    "$1.06B", 
-    "1995", 
-    "Capital Goods", 
-    "Industrial Machinery/Components", 
-    "http://www.nasdaq.com/symbol/aeis"
-  ], 
-  [
-    "AEPI", 
-    "AEP Industries Inc.", 
-    "51.32", 
-    "$260.74M", 
-    "1986", 
-    "Capital Goods", 
-    "Specialty Chemicals", 
-    "http://www.nasdaq.com/symbol/aepi"
-  ], 
-  [
-    "AERI", 
-    "Aerie Pharmaceuticals, Inc.", 
-    "27.71", 
-    "$664.61M", 
-    "2013", 
-    "Health Care", 
-    "Biotechnology: Biological Products (No Diagnostic Substances)", 
-    "http://www.nasdaq.com/symbol/aeri"
-  ], 
-  [
-    "AETI", 
-    "American Electric Technologies, Inc.", 
-    "4.14", 
-    "$33.89M", 
-    "n/a", 
-    "Energy", 
-    "Industrial Machinery/Components", 
-    "http://www.nasdaq.com/symbol/aeti"
-  ], 
-  [
-    "AEY", 
-    "ADDvantage Technologies Group, Inc.", 
-    "2.4568", 
-    "$24.67M", 
-    "n/a", 
-    "Consumer Services", 
-    "Office Equipment/Supplies/Services", 
-    "http://www.nasdaq.com/symbol/aey"
-  ], 
-  [
-    "AEZS", 
-    "AEterna Zentaris Inc.", 
-    "0.601", 
-    "$39.37M", 
-    "n/a", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/aezs"
-  ], 
-  [
-    "AFAM", 
-    "Almost Family Inc", 
-    "29.46", 
-    "$279.16M", 
-    "n/a", 
-    "Health Care", 
-    "Medical/Nursing Services", 
-    "http://www.nasdaq.com/symbol/afam"
-  ], 
-  [
-    "AFCB", 
-    "Athens Bancshares Corporation", 
-    "25.45", 
-    "$45.85M", 
-    "2010", 
-    "Finance", 
-    "Savings Institutions", 
-    "http://www.nasdaq.com/symbol/afcb"
-  ], 
-  [
-    "AFFX", 
-    "Affymetrix, Inc.", 
-    "11.84", 
-    "$884.63M", 
-    "1996", 
-    "Capital Goods", 
-    "Biotechnology: Laboratory Analytical Instruments", 
-    "http://www.nasdaq.com/symbol/affx"
-  ], 
-  [
-    "AFH", 
-    "Atlas Financial Holdings, Inc.", 
-    "17.65", 
-    "$207.77M", 
-    "2013", 
-    "Finance", 
-    "Property-Casualty Insurers", 
-    "http://www.nasdaq.com/symbol/afh"
-  ], 
-  [
-    "AFMD", 
-    "Affimed N.V.", 
-    "5.43", 
-    "$130.23M", 
-    "2014", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/afmd"
-  ], 
-  [
-    "AFOP", 
-    "Alliance Fiber Optic Products, Inc.", 
-    "16.98", 
-    "$316.72M", 
-    "2000", 
-    "Technology", 
-    "Semiconductors", 
-    "http://www.nasdaq.com/symbol/afop"
-  ], 
-  [
-    "AFSI", 
-    "AmTrust Financial Services, Inc.", 
-    "55.76", 
-    "$4.4B", 
-    "n/a", 
-    "Finance", 
-    "Property-Casualty Insurers", 
-    "http://www.nasdaq.com/symbol/afsi"
-  ], 
-  [
-    "AGEN", 
-    "Agenus Inc.", 
-    "5.2", 
-    "$325.96M", 
-    "2000", 
-    "Health Care", 
-    "Biotechnology: Biological Products (No Diagnostic Substances)", 
-    "http://www.nasdaq.com/symbol/agen"
-  ], 
-  [
-    "AGII", 
-    "Argo Group International Holdings, Ltd.", 
-    "52.39", 
-    "$1.35B", 
-    "n/a", 
-    "Finance", 
-    "Specialty Insurers", 
-    "http://www.nasdaq.com/symbol/agii"
-  ], 
-  [
-    "AGIIL", 
-    "Argo Group International Holdings, Ltd.", 
-    "25.181", 
-    "n/a", 
-    "n/a", 
-    "Finance", 
-    "Specialty Insurers", 
-    "http://www.nasdaq.com/symbol/agiil"
-  ], 
-  [
-    "AGIO", 
-    "Agios Pharmaceuticals, Inc.", 
-    "106.3", 
-    "$3.93B", 
-    "2013", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/agio"
-  ], 
-  [
-    "AGNC", 
-    "American Capital Agency Corp.", 
-    "21.94", 
-    "$7.74B", 
-    "2008", 
-    "Consumer Services", 
-    "Real Estate Investment Trusts", 
-    "http://www.nasdaq.com/symbol/agnc"
-  ], 
-  [
-    "AGNCB", 
-    "American Capital Agency Corp.", 
-    "25.1199", 
-    "$8.86B", 
-    "n/a", 
-    "Consumer Services", 
-    "Real Estate Investment Trusts", 
-    "http://www.nasdaq.com/symbol/agncb"
-  ], 
-  [
-    "AGNCP", 
-    "American Capital Agency Corp.", 
-    "26.6399", 
-    "n/a", 
-    "n/a", 
-    "Consumer Services", 
-    "Real Estate Investment Trusts", 
-    "http://www.nasdaq.com/symbol/agncp"
-  ], 
-  [
-    "AGND", 
-    "WisdomTree Barclays U.S. Aggregate Bond Negative Duration Fund", 
-    "45.173", 
-    "$13.55M", 
-    "n/a", 
-    "n/a", 
-    "n/a", 
-    "http://www.nasdaq.com/symbol/agnd"
-  ], 
-  [
-    "AGRX", 
-    "Agile Therapeutics, Inc.", 
-    "9.47", 
-    "$189.51M", 
-    "2014", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/agrx"
-  ], 
-  [
-    "AGTC", 
-    "Applied Genetic Technologies Corporation", 
-    "22.73", 
-    "$373.72M", 
-    "2014", 
-    "Health Care", 
-    "Biotechnology: Biological Products (No Diagnostic Substances)", 
-    "http://www.nasdaq.com/symbol/agtc"
-  ], 
-  [
-    "AGYS", 
-    "Agilysys, Inc.", 
-    "9.87", 
-    "$225.26M", 
-    "n/a", 
-    "Technology", 
-    "EDP Services", 
-    "http://www.nasdaq.com/symbol/agys"
-  ], 
-  [
-    "AGZD", 
-    "WisdomTree Barclays U.S. Aggregate Bond Zero Duration Fund", 
-    "49.15", 
-    "$58.98M", 
-    "n/a", 
-    "n/a", 
-    "n/a", 
-    "http://www.nasdaq.com/symbol/agzd"
-  ], 
-  [
-    "AHGP", 
-    "Alliance Holdings GP, L.P.", 
-    "52.57", 
-    "$3.15B", 
-    "2006", 
-    "Energy", 
-    "Coal Mining", 
-    "http://www.nasdaq.com/symbol/ahgp"
-  ], 
-  [
-    "AHPI", 
-    "Allied Healthcare Products, Inc.", 
-    "1.71", 
-    "$13.73M", 
-    "1992", 
-    "Health Care", 
-    "Industrial Specialties", 
-    "http://www.nasdaq.com/symbol/ahpi"
-  ], 
-  [
-    "AIMC", 
-    "Altra Industrial Motion Corp.", 
-    "26.26", 
-    "$699.44M", 
-    "2006", 
-    "Capital Goods", 
-    "Industrial Machinery/Components", 
-    "http://www.nasdaq.com/symbol/aimc"
-  ], 
-  [
-    "AINV", 
-    "Apollo Investment Corporation", 
-    "7.81", 
-    "$1.85B", 
-    "2004", 
-    "n/a", 
-    "n/a", 
-    "http://www.nasdaq.com/symbol/ainv"
-  ], 
-  [
-    "AIQ", 
-    "Alliance HealthCare Services, Inc.", 
-    "25.08", 
-    "$269.22M", 
-    "2001", 
-    "Health Care", 
-    "Medical Specialities", 
-    "http://www.nasdaq.com/symbol/aiq"
-  ], 
-  [
-    "AIRM", 
-    "Air Methods Corporation", 
-    "45.6", 
-    "$1.79B", 
-    "n/a", 
-    "Transportation", 
-    "Transportation Services", 
-    "http://www.nasdaq.com/symbol/airm"
-  ], 
-  [
-    "AIRR", 
-    "First Trust RBA American Industrial Renaissance ETF", 
-    "18.1247", 
-    "$76.12M", 
-    "n/a", 
-    "n/a", 
-    "n/a", 
-    "http://www.nasdaq.com/symbol/airr"
-  ]
-]
\ No newline at end of file
diff --git a/examples/stocks/data/stock_data_1.json b/examples/stocks/data/stock_data_1.json
deleted file mode 100644
index 7fd39e9..0000000
--- a/examples/stocks/data/stock_data_1.json
+++ /dev/null
@@ -1,1002 +0,0 @@
-[
-  [
-    "AIRT", 
-    "Air T, Inc.", 
-    "19.81", 
-    "$46.95M", 
-    "n/a", 
-    "Transportation", 
-    "Air Freight/Delivery Services", 
-    "http://www.nasdaq.com/symbol/airt"
-  ], 
-  [
-    "AIXG", 
-    "Aixtron SE", 
-    "8.13", 
-    "$906.84M", 
-    "n/a", 
-    "Technology", 
-    "Industrial Machinery/Components", 
-    "http://www.nasdaq.com/symbol/aixg"
-  ], 
-  [
-    "AKAM", 
-    "Akamai Technologies, Inc.", 
-    "71.62", 
-    "$12.75B", 
-    "1999", 
-    "Miscellaneous", 
-    "Business Services", 
-    "http://www.nasdaq.com/symbol/akam"
-  ], 
-  [
-    "AKAO", 
-    "Achaogen, Inc.", 
-    "11.47", 
-    "$203.68M", 
-    "2014", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/akao"
-  ], 
-  [
-    "AKBA", 
-    "Akebia Therapeutics, Inc.", 
-    "10.14", 
-    "$206.26M", 
-    "2014", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/akba"
-  ], 
-  [
-    "AKER", 
-    "Akers Biosciences Inc", 
-    "3.7365", 
-    "$18.51M", 
-    "2014", 
-    "Health Care", 
-    "Biotechnology: In Vitro & In Vivo Diagnostic Substances", 
-    "http://www.nasdaq.com/symbol/aker"
-  ], 
-  [
-    "AKRX", 
-    "Akorn, Inc.", 
-    "48.02", 
-    "$5.18B", 
-    "n/a", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/akrx"
-  ], 
-  [
-    "ALCO", 
-    "Alico, Inc.", 
-    "48.01", 
-    "$353.87M", 
-    "n/a", 
-    "Consumer Non-Durables", 
-    "Farming/Seeds/Milling", 
-    "http://www.nasdaq.com/symbol/alco"
-  ], 
-  [
-    "ALDR", 
-    "Alder BioPharmaceuticals, Inc.", 
-    "27.41", 
-    "$1.03B", 
-    "2014", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/aldr"
-  ], 
-  [
-    "ALDX", 
-    "Aldeyra Therapeutics, Inc.", 
-    "10.5", 
-    "$58.44M", 
-    "2014", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/aldx"
-  ], 
-  [
-    "ALGN", 
-    "Align Technology, Inc.", 
-    "56.81", 
-    "$4.56B", 
-    "2001", 
-    "Health Care", 
-    "Industrial Specialties", 
-    "http://www.nasdaq.com/symbol/algn"
-  ], 
-  [
-    "ALGT", 
-    "Allegiant Travel Company", 
-    "184.79", 
-    "$3.23B", 
-    "2006", 
-    "Transportation", 
-    "Air Freight/Delivery Services", 
-    "http://www.nasdaq.com/symbol/algt"
-  ], 
-  [
-    "ALIM", 
-    "Alimera Sciences, Inc.", 
-    "5.32", 
-    "$235.66M", 
-    "2010", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/alim"
-  ], 
-  [
-    "ALKS", 
-    "Alkermes plc", 
-    "73.24", 
-    "$10.71B", 
-    "1991", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/alks"
-  ], 
-  [
-    "ALLB", 
-    "Alliance Bancorp, Inc. of Pennsylvania", 
-    "16.93", 
-    "$68.18M", 
-    "n/a", 
-    "Finance", 
-    "Savings Institutions", 
-    "http://www.nasdaq.com/symbol/allb"
-  ], 
-  [
-    "ALLT", 
-    "Allot Communications Ltd.", 
-    "9.3", 
-    "$309.2M", 
-    "2006", 
-    "Technology", 
-    "Computer Communications Equipment", 
-    "http://www.nasdaq.com/symbol/allt"
-  ], 
-  [
-    "ALNY", 
-    "Alnylam Pharmaceuticals, Inc.", 
-    "102.39", 
-    "$8.58B", 
-    "2004", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/alny"
-  ], 
-  [
-    "ALOG", 
-    "Analogic Corporation", 
-    "84.98", 
-    "$1.05B", 
-    "1972", 
-    "Capital Goods", 
-    "Electrical Products", 
-    "http://www.nasdaq.com/symbol/alog"
-  ], 
-  [
-    "ALOT", 
-    "Astro-Med, Inc.", 
-    "14.78", 
-    "$107M", 
-    "1983", 
-    "Technology", 
-    "Computer peripheral equipment", 
-    "http://www.nasdaq.com/symbol/alot"
-  ], 
-  [
-    "ALQA", 
-    "Alliqua BioMedical, Inc.", 
-    "6", 
-    "$97.04M", 
-    "n/a", 
-    "Health Care", 
-    "Medical/Dental Instruments", 
-    "http://www.nasdaq.com/symbol/alqa"
-  ], 
-  [
-    "ALSK", 
-    "Alaska Communications Systems Group, Inc.", 
-    "1.71", 
-    "$84.71M", 
-    "1999", 
-    "Public Utilities", 
-    "Telecommunications Equipment", 
-    "http://www.nasdaq.com/symbol/alsk"
-  ], 
-  [
-    "ALTR", 
-    "Altera Corporation", 
-    "36.14", 
-    "$10.87B", 
-    "1988", 
-    "Technology", 
-    "Semiconductors", 
-    "http://www.nasdaq.com/symbol/altr"
-  ], 
-  [
-    "ALXA", 
-    "Alexza Pharmaceuticals, Inc.", 
-    "2.18", 
-    "$42.3M", 
-    "2006", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/alxa"
-  ], 
-  [
-    "ALXN", 
-    "Alexion Pharmaceuticals, Inc.", 
-    "186.02", 
-    "$37.6B", 
-    "1996", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/alxn"
-  ], 
-  [
-    "AMAG", 
-    "AMAG Pharmaceuticals, Inc.", 
-    "43.04", 
-    "$1.1B", 
-    "n/a", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/amag"
-  ], 
-  [
-    "AMAT", 
-    "Applied Materials, Inc.", 
-    "25.13", 
-    "$30.88B", 
-    "1972", 
-    "Technology", 
-    "Semiconductors", 
-    "http://www.nasdaq.com/symbol/amat"
-  ], 
-  [
-    "AMBA", 
-    "Ambarella, Inc.", 
-    "51.75", 
-    "$1.57B", 
-    "2012", 
-    "Technology", 
-    "Semiconductors", 
-    "http://www.nasdaq.com/symbol/amba"
-  ], 
-  [
-    "AMBC", 
-    "Ambac Financial Group, Inc.", 
-    "25.42", 
-    "$1.14B", 
-    "n/a", 
-    "Finance", 
-    "Property-Casualty Insurers", 
-    "http://www.nasdaq.com/symbol/ambc"
-  ], 
-  [
-    "AMBCW", 
-    "Ambac Financial Group, Inc.", 
-    "13.71", 
-    "n/a", 
-    "n/a", 
-    "Finance", 
-    "Property-Casualty Insurers", 
-    "http://www.nasdaq.com/symbol/ambcw"
-  ], 
-  [
-    "AMCC", 
-    "Applied Micro Circuits Corporation", 
-    "4.84", 
-    "$383.04M", 
-    "1997", 
-    "Technology", 
-    "Semiconductors", 
-    "http://www.nasdaq.com/symbol/amcc"
-  ], 
-  [
-    "AMCF", 
-    "Andatee China Marine Fuel Services Corporation", 
-    "1.51", 
-    "$15.49M", 
-    "2010", 
-    "Energy", 
-    "Oil Refining/Marketing", 
-    "http://www.nasdaq.com/symbol/amcf"
-  ], 
-  [
-    "AMCN", 
-    "AirMedia Group Inc", 
-    "2.19", 
-    "$130.45M", 
-    "2007", 
-    "Technology", 
-    "Advertising", 
-    "http://www.nasdaq.com/symbol/amcn"
-  ], 
-  [
-    "AMCX", 
-    "AMC Networks Inc.", 
-    "69.34", 
-    "$5B", 
-    "n/a", 
-    "Consumer Services", 
-    "Television Services", 
-    "http://www.nasdaq.com/symbol/amcx"
-  ], 
-  [
-    "AMD", 
-    "Advanced Micro Devices, Inc.", 
-    "3.06", 
-    "$2.38B", 
-    "n/a", 
-    "Technology", 
-    "Semiconductors", 
-    "http://www.nasdaq.com/symbol/amd"
-  ], 
-  [
-    "AMDA", 
-    "Amedica Corporation", 
-    "0.8", 
-    "$11.04M", 
-    "2014", 
-    "Health Care", 
-    "Medical/Dental Instruments", 
-    "http://www.nasdaq.com/symbol/amda"
-  ], 
-  [
-    "AMED", 
-    "Amedisys Inc", 
-    "28.69", 
-    "$957.68M", 
-    "n/a", 
-    "Health Care", 
-    "Medical/Nursing Services", 
-    "http://www.nasdaq.com/symbol/amed"
-  ], 
-  [
-    "AMGN", 
-    "Amgen Inc.", 
-    "157.66", 
-    "$119.64B", 
-    "1983", 
-    "Health Care", 
-    "Biotechnology: Biological Products (No Diagnostic Substances)", 
-    "http://www.nasdaq.com/symbol/amgn"
-  ], 
-  [
-    "AMIC", 
-    "American Independence Corp.", 
-    "10.61", 
-    "$85.72M", 
-    "n/a", 
-    "Finance", 
-    "Accident &Health Insurance", 
-    "http://www.nasdaq.com/symbol/amic"
-  ], 
-  [
-    "AMKR", 
-    "Amkor Technology, Inc.", 
-    "9.16", 
-    "$2.17B", 
-    "1998", 
-    "Technology", 
-    "Semiconductors", 
-    "http://www.nasdaq.com/symbol/amkr"
-  ], 
-  [
-    "AMNB", 
-    "American National Bankshares, Inc.", 
-    "22.1", 
-    "$173.41M", 
-    "n/a", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/amnb"
-  ], 
-  [
-    "AMOT", 
-    "Allied Motion Technologies, Inc.", 
-    "26.89", 
-    "$248.06M", 
-    "n/a", 
-    "Capital Goods", 
-    "Electrical Products", 
-    "http://www.nasdaq.com/symbol/amot"
-  ], 
-  [
-    "AMOV", 
-    "America Movil, S.A.B. de C.V.", 
-    "21.58", 
-    "$74.86B", 
-    "n/a", 
-    "Public Utilities", 
-    "Telecommunications Equipment", 
-    "http://www.nasdaq.com/symbol/amov"
-  ], 
-  [
-    "AMPH", 
-    "Amphastar Pharmaceuticals, Inc.", 
-    "12.85", 
-    "$573.74M", 
-    "2014", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/amph"
-  ], 
-  [
-    "AMRB", 
-    "American River Bankshares", 
-    "9.72", 
-    "$78.63M", 
-    "n/a", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/amrb"
-  ], 
-  [
-    "AMRI", 
-    "Albany Molecular Research, Inc.", 
-    "16.27", 
-    "$530.51M", 
-    "1999", 
-    "Health Care", 
-    "Biotechnology: Commercial Physical & Biological Resarch", 
-    "http://www.nasdaq.com/symbol/amri"
-  ], 
-  [
-    "AMRK", 
-    "A-Mark Precious Metals, Inc.", 
-    "10.1399", 
-    "$70.6M", 
-    "n/a", 
-    "Basic Industries", 
-    "Other Specialty Stores", 
-    "http://www.nasdaq.com/symbol/amrk"
-  ], 
-  [
-    "AMRN", 
-    "Amarin Corporation PLC", 
-    "1.33", 
-    "$232.23M", 
-    "n/a", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/amrn"
-  ], 
-  [
-    "AMRS", 
-    "Amyris, Inc.", 
-    "2", 
-    "$158.15M", 
-    "2010", 
-    "Basic Industries", 
-    "Major Chemicals", 
-    "http://www.nasdaq.com/symbol/amrs"
-  ], 
-  [
-    "AMSC", 
-    "American Superconductor Corporation", 
-    "0.77", 
-    "$73.71M", 
-    "1991", 
-    "Consumer Durables", 
-    "Metal Fabrications", 
-    "http://www.nasdaq.com/symbol/amsc"
-  ], 
-  [
-    "AMSF", 
-    "AMERISAFE, Inc.", 
-    "42.94", 
-    "$808.25M", 
-    "2005", 
-    "Finance", 
-    "Property-Casualty Insurers", 
-    "http://www.nasdaq.com/symbol/amsf"
-  ], 
-  [
-    "AMSG", 
-    "Amsurg Corp.", 
-    "55.96", 
-    "$2.69B", 
-    "n/a", 
-    "Health Care", 
-    "Medical/Nursing Services", 
-    "http://www.nasdaq.com/symbol/amsg"
-  ], 
-  [
-    "AMSGP", 
-    "Amsurg Corp.", 
-    "116.19", 
-    "$200.43M", 
-    "n/a", 
-    "Health Care", 
-    "Medical/Nursing Services", 
-    "http://www.nasdaq.com/symbol/amsgp"
-  ], 
-  [
-    "AMSWA", 
-    "American Software, Inc.", 
-    "9.12", 
-    "$257.55M", 
-    "n/a", 
-    "Technology", 
-    "Computer Software: Prepackaged Software", 
-    "http://www.nasdaq.com/symbol/amswa"
-  ], 
-  [
-    "AMTX", 
-    "Aemetis, Inc", 
-    "4.42", 
-    "$91.11M", 
-    "n/a", 
-    "Basic Industries", 
-    "Major Chemicals", 
-    "http://www.nasdaq.com/symbol/amtx"
-  ], 
-  [
-    "AMWD", 
-    "American Woodmark Corporation", 
-    "44.12", 
-    "$698.38M", 
-    "1986", 
-    "Basic Industries", 
-    "Forest Products", 
-    "http://www.nasdaq.com/symbol/amwd"
-  ], 
-  [
-    "AMZN", 
-    "Amazon.com, Inc.", 
-    "383.66", 
-    "$178.17B", 
-    "1997", 
-    "Consumer Services", 
-    "Catalog/Specialty Distribution", 
-    "http://www.nasdaq.com/symbol/amzn"
-  ], 
-  [
-    "ANAC", 
-    "Anacor Pharmaceuticals, Inc.", 
-    "43.49", 
-    "$1.87B", 
-    "2010", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/anac"
-  ], 
-  [
-    "ANAD", 
-    "ANADIGICS, Inc.", 
-    "1.24", 
-    "$107.36M", 
-    "1995", 
-    "Technology", 
-    "Semiconductors", 
-    "http://www.nasdaq.com/symbol/anad"
-  ], 
-  [
-    "ANAT", 
-    "American National Insurance Company", 
-    "105.61", 
-    "$2.84B", 
-    "n/a", 
-    "Finance", 
-    "Life Insurance", 
-    "http://www.nasdaq.com/symbol/anat"
-  ], 
-  [
-    "ANCB", 
-    "Anchor Bancorp", 
-    "21.6101", 
-    "$55.11M", 
-    "2011", 
-    "Finance", 
-    "Banks", 
-    "http://www.nasdaq.com/symbol/ancb"
-  ], 
-  [
-    "ANCI", 
-    "American Caresource Holdings Inc", 
-    "2.89", 
-    "$19.4M", 
-    "n/a", 
-    "Health Care", 
-    "Hospital/Nursing Management", 
-    "http://www.nasdaq.com/symbol/anci"
-  ], 
-  [
-    "ANCX", 
-    "Access National Corporation", 
-    "17.98", 
-    "$187.93M", 
-    "n/a", 
-    "Finance", 
-    "Savings Institutions", 
-    "http://www.nasdaq.com/symbol/ancx"
-  ], 
-  [
-    "ANDE", 
-    "The Andersons, Inc.", 
-    "44.84", 
-    "$1.3B", 
-    "n/a", 
-    "Consumer Services", 
-    "Farming/Seeds/Milling", 
-    "http://www.nasdaq.com/symbol/ande"
-  ], 
-  [
-    "ANGI", 
-    "Angie&#39;s List, Inc.", 
-    "6.73", 
-    "$393.82M", 
-    "2011", 
-    "Consumer Services", 
-    "Advertising", 
-    "http://www.nasdaq.com/symbol/angi"
-  ], 
-  [
-    "ANGO", 
-    "AngioDynamics, Inc.", 
-    "19.03", 
-    "$681.68M", 
-    "2004", 
-    "Health Care", 
-    "Medical/Dental Instruments", 
-    "http://www.nasdaq.com/symbol/ango"
-  ], 
-  [
-    "ANIK", 
-    "Anika Therapeutics Inc.", 
-    "44.05", 
-    "$638.9M", 
-    "n/a", 
-    "Health Care", 
-    "Medical/Dental Instruments", 
-    "http://www.nasdaq.com/symbol/anik"
-  ], 
-  [
-    "ANIP", 
-    "ANI Pharmaceuticals, Inc.", 
-    "68.66", 
-    "$777.88M", 
-    "n/a", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/anip"
-  ], 
-  [
-    "ANSS", 
-    "ANSYS, Inc.", 
-    "87.25", 
-    "$8.02B", 
-    "1996", 
-    "Technology", 
-    "Computer Software: Prepackaged Software", 
-    "http://www.nasdaq.com/symbol/anss"
-  ], 
-  [
-    "ANTH", 
-    "Anthera Pharmaceuticals, Inc.", 
-    "4.58", 
-    "$105.06M", 
-    "2010", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/anth"
-  ], 
-  [
-    "ANY", 
-    "Sphere 3D Corp", 
-    "4.31", 
-    "$113.68M", 
-    "n/a", 
-    "Technology", 
-    "EDP Services", 
-    "http://www.nasdaq.com/symbol/any"
-  ], 
-  [
-    "AOSL", 
-    "Alpha and Omega Semiconductor Limited", 
-    "8.79", 
-    "$234.31M", 
-    "2010", 
-    "Technology", 
-    "Semiconductors", 
-    "http://www.nasdaq.com/symbol/aosl"
-  ], 
-  [
-    "APDN", 
-    "Applied DNA Sciences Inc", 
-    "3.73", 
-    "$64.76M", 
-    "n/a", 
-    "Consumer Services", 
-    "Other Consumer Services", 
-    "http://www.nasdaq.com/symbol/apdn"
-  ], 
-  [
-    "APDNW", 
-    "Applied DNA Sciences Inc", 
-    "1.44", 
-    "n/a", 
-    "n/a", 
-    "Consumer Services", 
-    "Other Consumer Services", 
-    "http://www.nasdaq.com/symbol/apdnw"
-  ], 
-  [
-    "APEI", 
-    "American Public Education, Inc.", 
-    "34.08", 
-    "$588.38M", 
-    "2007", 
-    "Consumer Services", 
-    "Other Consumer Services", 
-    "http://www.nasdaq.com/symbol/apei"
-  ], 
-  [
-    "APOG", 
-    "Apogee Enterprises, Inc.", 
-    "45.21", 
-    "$1.31B", 
-    "n/a", 
-    "Capital Goods", 
-    "Auto Parts:O.E.M.", 
-    "http://www.nasdaq.com/symbol/apog"
-  ], 
-  [
-    "APOL", 
-    "Apollo Education Group, Inc.", 
-    "26.755", 
-    "$2.9B", 
-    "1994", 
-    "Consumer Services", 
-    "Other Consumer Services", 
-    "http://www.nasdaq.com/symbol/apol"
-  ], 
-  [
-    "APPS", 
-    "Digital Turbine, Inc.", 
-    "3.32", 
-    "$125.58M", 
-    "n/a", 
-    "Miscellaneous", 
-    "Multi-Sector Companies", 
-    "http://www.nasdaq.com/symbol/apps"
-  ], 
-  [
-    "APPY", 
-    "Venaxis, Inc.", 
-    "0.459", 
-    "$14.22M", 
-    "n/a", 
-    "Health Care", 
-    "Biotechnology: In Vitro & In Vivo Diagnostic Substances", 
-    "http://www.nasdaq.com/symbol/appy"
-  ], 
-  [
-    "APRI", 
-    "Apricus Biosciences, Inc", 
-    "1.94", 
-    "$86M", 
-    "n/a", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/apri"
-  ], 
-  [
-    "APTO", 
-    "Aptose Biosciences, Inc.", 
-    "4.6241", 
-    "$54.1M", 
-    "n/a", 
-    "Health Care", 
-    "Biotechnology: Biological Products (No Diagnostic Substances)", 
-    "http://www.nasdaq.com/symbol/apto"
-  ], 
-  [
-    "APWC", 
-    "Asia Pacific Wire & Cable Corporation Limited", 
-    "2.5", 
-    "$34.5M", 
-    "n/a", 
-    "Basic Industries", 
-    "Telecommunications Equipment", 
-    "http://www.nasdaq.com/symbol/apwc"
-  ], 
-  [
-    "AQXP", 
-    "Aquinox Pharmaceuticals, Inc.", 
-    "10.45", 
-    "$111.76M", 
-    "2014", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/aqxp"
-  ], 
-  [
-    "ARAY", 
-    "Accuray Incorporated", 
-    "8.04", 
-    "$631.05M", 
-    "2007", 
-    "Health Care", 
-    "Medical/Dental Instruments", 
-    "http://www.nasdaq.com/symbol/aray"
-  ], 
-  [
-    "ARCB", 
-    "ArcBest Corporation", 
-    "41.38", 
-    "$1.08B", 
-    "n/a", 
-    "Transportation", 
-    "Trucking Freight/Courier Services", 
-    "http://www.nasdaq.com/symbol/arcb"
-  ], 
-  [
-    "ARCC", 
-    "Ares Capital Corporation", 
-    "16.92", 
-    "$5.31B", 
-    "2004", 
-    "n/a", 
-    "n/a", 
-    "http://www.nasdaq.com/symbol/arcc"
-  ], 
-  [
-    "ARCI", 
-    "Appliance Recycling Centers of America, Inc.", 
-    "2.82", 
-    "$16.32M", 
-    "n/a", 
-    "Consumer Services", 
-    "Home Furnishings", 
-    "http://www.nasdaq.com/symbol/arci"
-  ], 
-  [
-    "ARCP", 
-    "American Realty Capital Properties, Inc.", 
-    "9.44", 
-    "$8.57B", 
-    "2011", 
-    "Consumer Services", 
-    "Real Estate Investment Trusts", 
-    "http://www.nasdaq.com/symbol/arcp"
-  ], 
-  [
-    "ARCPP", 
-    "American Realty Capital Properties, Inc.", 
-    "23.24", 
-    "$999.32M", 
-    "n/a", 
-    "Consumer Services", 
-    "Real Estate Investment Trusts", 
-    "http://www.nasdaq.com/symbol/arcpp"
-  ], 
-  [
-    "ARCW", 
-    "ARC Group Worldwide, Inc.", 
-    "6.27", 
-    "$94.55M", 
-    "n/a", 
-    "Capital Goods", 
-    "Metal Fabrications", 
-    "http://www.nasdaq.com/symbol/arcw"
-  ], 
-  [
-    "ARDM", 
-    "Aradigm Corporation", 
-    "7.261", 
-    "$106.93M", 
-    "1996", 
-    "Health Care", 
-    "Biotechnology: Electromedical & Electrotherapeutic Apparatus", 
-    "http://www.nasdaq.com/symbol/ardm"
-  ], 
-  [
-    "ARDX", 
-    "Ardelyx, Inc.", 
-    "17.18", 
-    "$318.52M", 
-    "2014", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/ardx"
-  ], 
-  [
-    "AREX", 
-    "Approach Resources Inc.", 
-    "7.2", 
-    "$284.8M", 
-    "2007", 
-    "Energy", 
-    "Oil & Gas Production", 
-    "http://www.nasdaq.com/symbol/arex"
-  ], 
-  [
-    "ARGS", 
-    "Argos Therapeutics, Inc.", 
-    "9.19", 
-    "$180.64M", 
-    "2014", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/args"
-  ], 
-  [
-    "ARIA", 
-    "ARIAD Pharmaceuticals, Inc.", 
-    "8.06", 
-    "$1.51B", 
-    "1994", 
-    "Health Care", 
-    "Biotechnology: Biological Products (No Diagnostic Substances)", 
-    "http://www.nasdaq.com/symbol/aria"
-  ], 
-  [
-    "ARII", 
-    "American Railcar Industries, Inc.", 
-    "56.08", 
-    "$1.2B", 
-    "2006", 
-    "Capital Goods", 
-    "Railroads", 
-    "http://www.nasdaq.com/symbol/arii"
-  ], 
-  [
-    "ARIS", 
-    "ARI Network Services, Inc.", 
-    "3.61", 
-    "$51.37M", 
-    "1991", 
-    "Technology", 
-    "Computer Software: Programming, Data Processing", 
-    "http://www.nasdaq.com/symbol/aris"
-  ], 
-  [
-    "ARKR", 
-    "Ark Restaurants Corp.", 
-    "24.45", 
-    "$82.76M", 
-    "n/a", 
-    "Consumer Services", 
-    "Restaurants", 
-    "http://www.nasdaq.com/symbol/arkr"
-  ], 
-  [
-    "ARLP", 
-    "Alliance Resource Partners, L.P.", 
-    "40.41", 
-    "$2.99B", 
-    "1999", 
-    "Energy", 
-    "Coal Mining", 
-    "http://www.nasdaq.com/symbol/arlp"
-  ], 
-  [
-    "ARMH", 
-    "ARM Holdings plc", 
-    "51.68", 
-    "$24.33B", 
-    "n/a", 
-    "Technology", 
-    "Semiconductors", 
-    "http://www.nasdaq.com/symbol/armh"
-  ], 
-  [
-    "ARNA", 
-    "Arena Pharmaceuticals, Inc.", 
-    "4.65", 
-    "$1.02B", 
-    "2000", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/arna"
-  ]
-]
\ No newline at end of file
diff --git a/examples/stocks/data/stock_data_10.json b/examples/stocks/data/stock_data_10.json
deleted file mode 100644
index 9673d83..0000000
--- a/examples/stocks/data/stock_data_10.json
+++ /dev/null
@@ -1,1002 +0,0 @@
-[
-  [
-    "FGEN", 
-    "FibroGen, Inc", 
-    "30.16", 
-    "$1.71B", 
-    "2014", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/fgen"
-  ], 
-  [
-    "FHCO", 
-    "Female Health Company (The)", 
-    "3.71", 
-    "$106.9M", 
-    "n/a", 
-    "Basic Industries", 
-    "Specialty Chemicals", 
-    "http://www.nasdaq.com/symbol/fhco"
-  ], 
-  [
-    "FIBK", 
-    "First Interstate BancSystem, Inc.", 
-    "26.63", 
-    "$583.97M", 
-    "2010", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/fibk"
-  ], 
-  [
-    "FINL", 
-    "The Finish Line, Inc.", 
-    "24.36", 
-    "$1.14B", 
-    "1992", 
-    "Consumer Services", 
-    "Clothing/Shoe/Accessory Stores", 
-    "http://www.nasdaq.com/symbol/finl"
-  ], 
-  [
-    "FISH", 
-    "Marlin Midstream Partners, LP", 
-    "23.67", 
-    "$419.05M", 
-    "1992", 
-    "Public Utilities", 
-    "Natural Gas Distribution", 
-    "http://www.nasdaq.com/symbol/fish"
-  ], 
-  [
-    "FISI", 
-    "Financial Institutions, Inc.", 
-    "22.75", 
-    "$320.73M", 
-    "1999", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/fisi"
-  ], 
-  [
-    "FISV", 
-    "Fiserv, Inc.", 
-    "79.05", 
-    "$19.29B", 
-    "1986", 
-    "Technology", 
-    "EDP Services", 
-    "http://www.nasdaq.com/symbol/fisv"
-  ], 
-  [
-    "FITB", 
-    "Fifth Third Bancorp", 
-    "19.39", 
-    "$15.98B", 
-    "n/a", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/fitb"
-  ], 
-  [
-    "FITBI", 
-    "Fifth Third Bancorp", 
-    "27.42", 
-    "$493.56M", 
-    "n/a", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/fitbi"
-  ], 
-  [
-    "FIVE", 
-    "Five Below, Inc.", 
-    "32.22", 
-    "$1.75B", 
-    "2012", 
-    "Consumer Services", 
-    "Department/Specialty Retail Stores", 
-    "http://www.nasdaq.com/symbol/five"
-  ], 
-  [
-    "FIVN", 
-    "Five9, Inc.", 
-    "3.8", 
-    "$185.74M", 
-    "2014", 
-    "Technology", 
-    "EDP Services", 
-    "http://www.nasdaq.com/symbol/fivn"
-  ], 
-  [
-    "FIZZ", 
-    "National Beverage Corp.", 
-    "22.5", 
-    "$1.04B", 
-    "n/a", 
-    "Consumer Non-Durables", 
-    "Beverages (Production/Distribution)", 
-    "http://www.nasdaq.com/symbol/fizz"
-  ], 
-  [
-    "FLAT", 
-    "iPath US Treasury Flattener ETN", 
-    "60.948", 
-    "$5.06M", 
-    "n/a", 
-    "Finance", 
-    "Commercial Banks", 
-    "http://www.nasdaq.com/symbol/flat"
-  ], 
-  [
-    "FLDM", 
-    "Fluidigm Corporation", 
-    "38.97", 
-    "$1.1B", 
-    "2011", 
-    "Capital Goods", 
-    "Biotechnology: Laboratory Analytical Instruments", 
-    "http://www.nasdaq.com/symbol/fldm"
-  ], 
-  [
-    "FLEX", 
-    "Flextronics International Ltd.", 
-    "12.23", 
-    "$7B", 
-    "1994", 
-    "Technology", 
-    "Electrical Products", 
-    "http://www.nasdaq.com/symbol/flex"
-  ], 
-  [
-    "FLIC", 
-    "The First of Long Island Corporation", 
-    "24.9", 
-    "$345.13M", 
-    "n/a", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/flic"
-  ], 
-  [
-    "FLIR", 
-    "FLIR Systems, Inc.", 
-    "32.12", 
-    "$4.53B", 
-    "1993", 
-    "Capital Goods", 
-    "Industrial Machinery/Components", 
-    "http://www.nasdaq.com/symbol/flir"
-  ], 
-  [
-    "FLKS", 
-    "Flex Pharma, Inc.", 
-    "14.71", 
-    "$261.92M", 
-    "2015", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/flks"
-  ], 
-  [
-    "FLL", 
-    "Full House Resorts, Inc.", 
-    "1.52", 
-    "$28.69M", 
-    "n/a", 
-    "Consumer Services", 
-    "Hotels/Resorts", 
-    "http://www.nasdaq.com/symbol/fll"
-  ], 
-  [
-    "FLML", 
-    "Flamel Technologies S.A.", 
-    "14.62", 
-    "$569.25M", 
-    "1996", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/flml"
-  ], 
-  [
-    "FLWS", 
-    "1-800 FLOWERS.COM, Inc.", 
-    "10.32", 
-    "$667.78M", 
-    "1999", 
-    "Consumer Services", 
-    "Other Specialty Stores", 
-    "http://www.nasdaq.com/symbol/flws"
-  ], 
-  [
-    "FLXN", 
-    "Flexion Therapeutics, Inc.", 
-    "22.5", 
-    "$482.02M", 
-    "2014", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/flxn"
-  ], 
-  [
-    "FLXS", 
-    "Flexsteel Industries, Inc.", 
-    "31.02", 
-    "$230.67M", 
-    "n/a", 
-    "Consumer Durables", 
-    "Home Furnishings", 
-    "http://www.nasdaq.com/symbol/flxs"
-  ], 
-  [
-    "FMB", 
-    "First Trust Managed Municipal ETF", 
-    "51.77", 
-    "$20.71M", 
-    "n/a", 
-    "n/a", 
-    "n/a", 
-    "http://www.nasdaq.com/symbol/fmb"
-  ], 
-  [
-    "FMBH", 
-    "First Mid-Illinois Bancshares, Inc.", 
-    "19.96", 
-    "$117.26M", 
-    "n/a", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/fmbh"
-  ], 
-  [
-    "FMBI", 
-    "First Midwest Bancorp, Inc.", 
-    "16.82", 
-    "$1.27B", 
-    "n/a", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/fmbi"
-  ], 
-  [
-    "FMER", 
-    "FirstMerit Corporation", 
-    "18.29", 
-    "$3.03B", 
-    "n/a", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/fmer"
-  ], 
-  [
-    "FMI", 
-    "Foundation Medicine, Inc.", 
-    "48.48", 
-    "$1.38B", 
-    "2013", 
-    "Health Care", 
-    "Medical Specialities", 
-    "http://www.nasdaq.com/symbol/fmi"
-  ], 
-  [
-    "FMNB", 
-    "Farmers National Banc Corp.", 
-    "7.98", 
-    "$146.9M", 
-    "n/a", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/fmnb"
-  ], 
-  [
-    "FNBC", 
-    "First NBC Bank Holding Company", 
-    "32.5", 
-    "$603.69M", 
-    "2013", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/fnbc"
-  ], 
-  [
-    "FNFG", 
-    "First Niagara Financial Group Inc.", 
-    "8.85", 
-    "$3.14B", 
-    "n/a", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/fnfg"
-  ], 
-  [
-    "FNGN", 
-    "Financial Engines, Inc.", 
-    "38.32", 
-    "$1.99B", 
-    "2010", 
-    "Finance", 
-    "Investment Managers", 
-    "http://www.nasdaq.com/symbol/fngn"
-  ], 
-  [
-    "FNHC", 
-    "Federated National Holding Company", 
-    "28.42", 
-    "$398.13M", 
-    "n/a", 
-    "Finance", 
-    "Property-Casualty Insurers", 
-    "http://www.nasdaq.com/symbol/fnhc"
-  ], 
-  [
-    "FNJN", 
-    "Finjan Holdings, Inc.", 
-    "2.75", 
-    "$61.72M", 
-    "n/a", 
-    "Miscellaneous", 
-    "Multi-Sector Companies", 
-    "http://www.nasdaq.com/symbol/fnjn"
-  ], 
-  [
-    "FNLC", 
-    "First Bancorp, Inc (ME)", 
-    "16.92", 
-    "$181.41M", 
-    "n/a", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/fnlc"
-  ], 
-  [
-    "FNRG", 
-    "ForceField Energy Inc.", 
-    "7.44", 
-    "$134.72M", 
-    "n/a", 
-    "Basic Industries", 
-    "Major Chemicals", 
-    "http://www.nasdaq.com/symbol/fnrg"
-  ], 
-  [
-    "FNSR", 
-    "Finisar Corporation", 
-    "21.45", 
-    "$2.22B", 
-    "1999", 
-    "Technology", 
-    "Semiconductors", 
-    "http://www.nasdaq.com/symbol/fnsr"
-  ], 
-  [
-    "FNTCU", 
-    "FinTech Acquisition Corp.", 
-    "10", 
-    "n/a", 
-    "2015", 
-    "Finance", 
-    "Business Services", 
-    "http://www.nasdaq.com/symbol/fntcu"
-  ], 
-  [
-    "FNWB", 
-    "First Northwest Bancorp", 
-    "12.52", 
-    "$164.02M", 
-    "2015", 
-    "Finance", 
-    "Banks", 
-    "http://www.nasdaq.com/symbol/fnwb"
-  ], 
-  [
-    "FOLD", 
-    "Amicus Therapeutics, Inc.", 
-    "8.7", 
-    "$828.67M", 
-    "2007", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/fold"
-  ], 
-  [
-    "FOMX", 
-    "Foamix Pharmaceuticals Ltd.", 
-    "9.18", 
-    "$197.15M", 
-    "2014", 
-    "Consumer Durables", 
-    "Specialty Chemicals", 
-    "http://www.nasdaq.com/symbol/fomx"
-  ], 
-  [
-    "FONE", 
-    "First Trust NASDAQ CEA Smartphone Index Fund", 
-    "40.287", 
-    "$12.09M", 
-    "n/a", 
-    "n/a", 
-    "n/a", 
-    "http://www.nasdaq.com/symbol/fone"
-  ], 
-  [
-    "FONR", 
-    "Fonar Corporation", 
-    "12.68", 
-    "$81.58M", 
-    "1981", 
-    "Health Care", 
-    "Biotechnology: Electromedical & Electrotherapeutic Apparatus", 
-    "http://www.nasdaq.com/symbol/fonr"
-  ], 
-  [
-    "FORD", 
-    "Forward Industries, Inc.", 
-    "0.93", 
-    "$7.79M", 
-    "n/a", 
-    "Consumer Non-Durables", 
-    "Plastic Products", 
-    "http://www.nasdaq.com/symbol/ford"
-  ], 
-  [
-    "FORM", 
-    "FormFactor, Inc.", 
-    "9.14", 
-    "$515.6M", 
-    "2003", 
-    "Technology", 
-    "Semiconductors", 
-    "http://www.nasdaq.com/symbol/form"
-  ], 
-  [
-    "FORR", 
-    "Forrester Research, Inc.", 
-    "38.3", 
-    "$697.25M", 
-    "1996", 
-    "Consumer Services", 
-    "Diversified Commercial Services", 
-    "http://www.nasdaq.com/symbol/forr"
-  ], 
-  [
-    "FORTY", 
-    "Formula Systems (1985) Ltd.", 
-    "23.7", 
-    "$348.84M", 
-    "n/a", 
-    "Technology", 
-    "EDP Services", 
-    "http://www.nasdaq.com/symbol/forty"
-  ], 
-  [
-    "FOSL", 
-    "Fossil Group, Inc.", 
-    "85.14", 
-    "$4.35B", 
-    "1993", 
-    "Consumer Non-Durables", 
-    "Consumer Specialties", 
-    "http://www.nasdaq.com/symbol/fosl"
-  ], 
-  [
-    "FOX", 
-    "Twenty-First Century Fox, Inc.", 
-    "34.275", 
-    "$72.87B", 
-    "n/a", 
-    "Consumer Services", 
-    "Television Services", 
-    "http://www.nasdaq.com/symbol/fox"
-  ], 
-  [
-    "FOXA", 
-    "Twenty-First Century Fox, Inc.", 
-    "35.3", 
-    "$46.86B", 
-    "n/a", 
-    "Consumer Services", 
-    "Television Services", 
-    "http://www.nasdaq.com/symbol/foxa"
-  ], 
-  [
-    "FOXF", 
-    "Fox Factory Holding Corp.", 
-    "15.79", 
-    "$585.14M", 
-    "2013", 
-    "Consumer Non-Durables", 
-    "Motor Vehicles", 
-    "http://www.nasdaq.com/symbol/foxf"
-  ], 
-  [
-    "FPRX", 
-    "Five Prime Therapeutics, Inc.", 
-    "26.27", 
-    "$668.91M", 
-    "2013", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/fprx"
-  ], 
-  [
-    "FPXI", 
-    "First Trust International IPO ETF", 
-    "28.96", 
-    "n/a", 
-    "n/a", 
-    "n/a", 
-    "n/a", 
-    "http://www.nasdaq.com/symbol/fpxi"
-  ], 
-  [
-    "FRAN", 
-    "Francesca&#39;s Holdings Corporation", 
-    "15.12", 
-    "$639.54M", 
-    "2011", 
-    "Consumer Services", 
-    "Clothing/Shoe/Accessory Stores", 
-    "http://www.nasdaq.com/symbol/fran"
-  ], 
-  [
-    "FRBA", 
-    "First Bank", 
-    "6", 
-    "$47.32M", 
-    "2013", 
-    "n/a", 
-    "n/a", 
-    "http://www.nasdaq.com/symbol/frba"
-  ], 
-  [
-    "FRBK", 
-    "Republic First Bancorp, Inc.", 
-    "3.45", 
-    "$130.46M", 
-    "n/a", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/frbk"
-  ], 
-  [
-    "FRED", 
-    "Fred&#39;s, Inc.", 
-    "19.02", 
-    "$702.13M", 
-    "1992", 
-    "Consumer Services", 
-    "Department/Specialty Retail Stores", 
-    "http://www.nasdaq.com/symbol/fred"
-  ], 
-  [
-    "FREE", 
-    "FreeSeas Inc.", 
-    "0.09", 
-    "$10.39M", 
-    "n/a", 
-    "Transportation", 
-    "Marine Transportation", 
-    "http://www.nasdaq.com/symbol/free"
-  ], 
-  [
-    "FRGI", 
-    "Fiesta Restaurant Group, Inc.", 
-    "64.96", 
-    "$1.74B", 
-    "n/a", 
-    "Consumer Services", 
-    "Restaurants", 
-    "http://www.nasdaq.com/symbol/frgi"
-  ], 
-  [
-    "FRME", 
-    "First Merchants Corporation", 
-    "22.94", 
-    "$827.55M", 
-    "n/a", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/frme"
-  ], 
-  [
-    "FRP", 
-    "FairPoint Communications, Inc.", 
-    "17.65", 
-    "$471.41M", 
-    "n/a", 
-    "Public Utilities", 
-    "Telecommunications Equipment", 
-    "http://www.nasdaq.com/symbol/frp"
-  ], 
-  [
-    "FRPH", 
-    "FRP Holdings, Inc.", 
-    "30.02", 
-    "$291.75M", 
-    "n/a", 
-    "Transportation", 
-    "Trucking Freight/Courier Services", 
-    "http://www.nasdaq.com/symbol/frph"
-  ], 
-  [
-    "FRPT", 
-    "Freshpet, Inc.", 
-    "16.15", 
-    "$540.5M", 
-    "2014", 
-    "Consumer Non-Durables", 
-    "Packaged Foods", 
-    "http://www.nasdaq.com/symbol/frpt"
-  ], 
-  [
-    "FRSH", 
-    "Papa Murphy&#39;s Holdings, Inc.", 
-    "13.63", 
-    "$230.91M", 
-    "2014", 
-    "Consumer Services", 
-    "Restaurants", 
-    "http://www.nasdaq.com/symbol/frsh"
-  ], 
-  [
-    "FSAM", 
-    "Fifth Street Asset Management Inc.", 
-    "12.57", 
-    "$614.13M", 
-    "2014", 
-    "Finance", 
-    "Investment Managers", 
-    "http://www.nasdaq.com/symbol/fsam"
-  ], 
-  [
-    "FSBK", 
-    "First South Bancorp Inc", 
-    "8.11", 
-    "$77.84M", 
-    "n/a", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/fsbk"
-  ], 
-  [
-    "FSBW", 
-    "FS Bancorp, Inc.", 
-    "19.4499", 
-    "$62.93M", 
-    "2012", 
-    "Finance", 
-    "Banks", 
-    "http://www.nasdaq.com/symbol/fsbw"
-  ], 
-  [
-    "FSC", 
-    "Fifth Street Finance Corp.", 
-    "7.21", 
-    "$1.11B", 
-    "2008", 
-    "n/a", 
-    "n/a", 
-    "http://www.nasdaq.com/symbol/fsc"
-  ], 
-  [
-    "FSCFL", 
-    "Fifth Street Finance Corp.", 
-    "24.0592", 
-    "n/a", 
-    "n/a", 
-    "n/a", 
-    "n/a", 
-    "http://www.nasdaq.com/symbol/fscfl"
-  ], 
-  [
-    "FSFG", 
-    "First Savings Financial Group, Inc.", 
-    "26.8899", 
-    "$58.83M", 
-    "n/a", 
-    "Finance", 
-    "Savings Institutions", 
-    "http://www.nasdaq.com/symbol/fsfg"
-  ], 
-  [
-    "FSFR", 
-    "Fifth Street Senior Floating Rate Corp.", 
-    "10.92", 
-    "$321.78M", 
-    "2013", 
-    "n/a", 
-    "n/a", 
-    "http://www.nasdaq.com/symbol/fsfr"
-  ], 
-  [
-    "FSGI", 
-    "First Security Group, Inc.", 
-    "2.24", 
-    "$149.69M", 
-    "2005", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/fsgi"
-  ], 
-  [
-    "FSLR", 
-    "First Solar, Inc.", 
-    "49.02", 
-    "$4.91B", 
-    "2006", 
-    "Technology", 
-    "Semiconductors", 
-    "http://www.nasdaq.com/symbol/fslr"
-  ], 
-  [
-    "FSNN", 
-    "Fusion Telecommunications International, Inc.", 
-    "3.611", 
-    "$23.45M", 
-    "n/a", 
-    "Public Utilities", 
-    "Telecommunications Equipment", 
-    "http://www.nasdaq.com/symbol/fsnn"
-  ], 
-  [
-    "FSRV", 
-    "FirstService Corporation", 
-    "60.5", 
-    "$2.09B", 
-    "n/a", 
-    "Finance", 
-    "Real Estate", 
-    "http://www.nasdaq.com/symbol/fsrv"
-  ], 
-  [
-    "FSTR", 
-    "L.B. Foster Company", 
-    "49.23", 
-    "$509.6M", 
-    "n/a", 
-    "Basic Industries", 
-    "Metal Fabrications", 
-    "http://www.nasdaq.com/symbol/fstr"
-  ], 
-  [
-    "FSYS", 
-    "Fuel Systems Solutions, Inc.", 
-    "10.98", 
-    "$220.76M", 
-    "n/a", 
-    "Capital Goods", 
-    "Auto Parts:O.E.M.", 
-    "http://www.nasdaq.com/symbol/fsys"
-  ], 
-  [
-    "FTCS", 
-    "First Trust Capital Strength ETF", 
-    "39.2693", 
-    "$86.39M", 
-    "n/a", 
-    "n/a", 
-    "n/a", 
-    "http://www.nasdaq.com/symbol/ftcs"
-  ], 
-  [
-    "FTD", 
-    "FTD Companies, Inc.", 
-    "34.27", 
-    "$650.72M", 
-    "n/a", 
-    "Consumer Services", 
-    "Other Consumer Services", 
-    "http://www.nasdaq.com/symbol/ftd"
-  ], 
-  [
-    "FTEK", 
-    "Fuel Tech, Inc.", 
-    "3.2", 
-    "$73.07M", 
-    "n/a", 
-    "Capital Goods", 
-    "Pollution Control Equipment", 
-    "http://www.nasdaq.com/symbol/ftek"
-  ], 
-  [
-    "FTGC", 
-    "First Trust Global Tactical Commodity Strategy Fund", 
-    "25.1", 
-    "$229.75M", 
-    "n/a", 
-    "n/a", 
-    "n/a", 
-    "http://www.nasdaq.com/symbol/ftgc"
-  ], 
-  [
-    "FTHI", 
-    "First Trust High Income ETF", 
-    "20.89", 
-    "$3.13M", 
-    "n/a", 
-    "n/a", 
-    "n/a", 
-    "http://www.nasdaq.com/symbol/fthi"
-  ], 
-  [
-    "FTLB", 
-    "First Trust Low Beta Income ETF", 
-    "20.796", 
-    "$2.08M", 
-    "n/a", 
-    "n/a", 
-    "n/a", 
-    "http://www.nasdaq.com/symbol/ftlb"
-  ], 
-  [
-    "FTNT", 
-    "Fortinet, Inc.", 
-    "33.84", 
-    "$5.58B", 
-    "2009", 
-    "Technology", 
-    "Computer peripheral equipment", 
-    "http://www.nasdaq.com/symbol/ftnt"
-  ], 
-  [
-    "FTR", 
-    "Frontier Communications Corporation", 
-    "8.3", 
-    "$8.32B", 
-    "n/a", 
-    "Public Utilities", 
-    "Telecommunications Equipment", 
-    "http://www.nasdaq.com/symbol/ftr"
-  ], 
-  [
-    "FTSL", 
-    "First Trust Senior Loan ETF", 
-    "49.1365", 
-    "$201.46M", 
-    "n/a", 
-    "n/a", 
-    "n/a", 
-    "http://www.nasdaq.com/symbol/ftsl"
-  ], 
-  [
-    "FTSM", 
-    "First Trust Enhanced Short Maturity ETF", 
-    "59.97", 
-    "$3M", 
-    "n/a", 
-    "n/a", 
-    "n/a", 
-    "http://www.nasdaq.com/symbol/ftsm"
-  ], 
-  [
-    "FUEL", 
-    "Rocket Fuel Inc.", 
-    "10.82", 
-    "$446.81M", 
-    "2013", 
-    "Technology", 
-    "Computer Software: Programming, Data Processing", 
-    "http://www.nasdaq.com/symbol/fuel"
-  ], 
-  [
-    "FULL", 
-    "Full Circle Capital Corporation", 
-    "4.66", 
-    "$55.68M", 
-    "2010", 
-    "n/a", 
-    "n/a", 
-    "http://www.nasdaq.com/symbol/full"
-  ], 
-  [
-    "FULLL", 
-    "Full Circle Capital Corporation", 
-    "25.8499", 
-    "n/a", 
-    "n/a", 
-    "n/a", 
-    "n/a", 
-    "http://www.nasdaq.com/symbol/fulll"
-  ], 
-  [
-    "FULT", 
-    "Fulton Financial Corporation", 
-    "12.17", 
-    "$2.25B", 
-    "n/a", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/fult"
-  ], 
-  [
-    "FUNC", 
-    "First United Corporation", 
-    "9.26", 
-    "$57.67M", 
-    "n/a", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/func"
-  ], 
-  [
-    "FUND", 
-    "Royce Focus Trust, Inc.", 
-    "7.44", 
-    "$166.34M", 
-    "n/a", 
-    "n/a", 
-    "n/a", 
-    "http://www.nasdaq.com/symbol/fund"
-  ], 
-  [
-    "FV", 
-    "First Trust Dorsey Wright Focus", 
-    "23.6", 
-    "$1.98B", 
-    "n/a", 
-    "n/a", 
-    "n/a", 
-    "http://www.nasdaq.com/symbol/fv"
-  ], 
-  [
-    "FWM", 
-    "Fairway Group Holdings Corp.", 
-    "5.63", 
-    "$245.4M", 
-    "2013", 
-    "Consumer Services", 
-    "Food Chains", 
-    "http://www.nasdaq.com/symbol/fwm"
-  ], 
-  [
-    "FWP", 
-    "Forward Pharma A/S", 
-    "23.59", 
-    "$1.08B", 
-    "2014", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/fwp"
-  ], 
-  [
-    "FWRD", 
-    "Forward Air Corporation", 
-    "53.76", 
-    "$1.64B", 
-    "n/a", 
-    "Transportation", 
-    "Oil Refining/Marketing", 
-    "http://www.nasdaq.com/symbol/fwrd"
-  ], 
-  [
-    "FXCB", 
-    "Fox Chase Bancorp, Inc.", 
-    "16.28", 
-    "$195.55M", 
-    "n/a", 
-    "Finance", 
-    "Savings Institutions", 
-    "http://www.nasdaq.com/symbol/fxcb"
-  ], 
-  [
-    "FXEN", 
-    "FX Energy, Inc.", 
-    "2.26", 
-    "$122.21M", 
-    "n/a", 
-    "Energy", 
-    "Oil & Gas Production", 
-    "http://www.nasdaq.com/symbol/fxen"
-  ], 
-  [
-    "FXENP", 
-    "FX Energy, Inc.", 
-    "20", 
-    "$16M", 
-    "n/a", 
-    "Energy", 
-    "Oil & Gas Production", 
-    "http://www.nasdaq.com/symbol/fxenp"
-  ]
-]
\ No newline at end of file
diff --git a/examples/stocks/data/stock_data_11.json b/examples/stocks/data/stock_data_11.json
deleted file mode 100644
index 4df9797..0000000
--- a/examples/stocks/data/stock_data_11.json
+++ /dev/null
@@ -1,1002 +0,0 @@
-[
-  [
-    "GABC", 
-    "German American Bancorp, Inc.", 
-    "29.18", 
-    "$385.48M", 
-    "n/a", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/gabc"
-  ], 
-  [
-    "GAI", 
-    "Global-Tech Advanced Innovations Inc.", 
-    "3.9", 
-    "$11.87M", 
-    "n/a", 
-    "Consumer Durables", 
-    "Home Furnishings", 
-    "http://www.nasdaq.com/symbol/gai"
-  ], 
-  [
-    "GAIA", 
-    "Gaiam, Inc.", 
-    "6.64", 
-    "$162.45M", 
-    "1999", 
-    "Consumer Services", 
-    "Movies/Entertainment", 
-    "http://www.nasdaq.com/symbol/gaia"
-  ], 
-  [
-    "GAIN", 
-    "Gladstone Investment Corporation", 
-    "7.8", 
-    "$206.51M", 
-    "2005", 
-    "n/a", 
-    "n/a", 
-    "http://www.nasdaq.com/symbol/gain"
-  ], 
-  [
-    "GAINO", 
-    "Gladstone Investment Corporation", 
-    "25.3799", 
-    "n/a", 
-    "n/a", 
-    "n/a", 
-    "n/a", 
-    "http://www.nasdaq.com/symbol/gaino"
-  ], 
-  [
-    "GAINP", 
-    "Gladstone Investment Corporation", 
-    "25.8", 
-    "n/a", 
-    "n/a", 
-    "n/a", 
-    "n/a", 
-    "http://www.nasdaq.com/symbol/gainp"
-  ], 
-  [
-    "GALE", 
-    "Galena Biopharma, Inc.", 
-    "1.84", 
-    "$223.48M", 
-    "n/a", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/gale"
-  ], 
-  [
-    "GALT", 
-    "Galectin Therapeutics Inc.", 
-    "4.04", 
-    "$89.38M", 
-    "n/a", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/galt"
-  ], 
-  [
-    "GALTU", 
-    "Galectin Therapeutics Inc.", 
-    "7.7", 
-    "n/a", 
-    "n/a", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/galtu"
-  ], 
-  [
-    "GALTW", 
-    "Galectin Therapeutics Inc.", 
-    "1.9732", 
-    "n/a", 
-    "n/a", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/galtw"
-  ], 
-  [
-    "GAME", 
-    "Shanda Games Limited", 
-    "5.58", 
-    "$1.5B", 
-    "n/a", 
-    "Miscellaneous", 
-    "Business Services", 
-    "http://www.nasdaq.com/symbol/game"
-  ], 
-  [
-    "GARS", 
-    "Garrison Capital Inc.", 
-    "14.83", 
-    "$248.53M", 
-    "2013", 
-    "n/a", 
-    "n/a", 
-    "http://www.nasdaq.com/symbol/gars"
-  ], 
-  [
-    "GASS", 
-    "StealthGas, Inc.", 
-    "6.14", 
-    "$245.61M", 
-    "2005", 
-    "Transportation", 
-    "Marine Transportation", 
-    "http://www.nasdaq.com/symbol/gass"
-  ], 
-  [
-    "GBCI", 
-    "Glacier Bancorp, Inc.", 
-    "24.79", 
-    "$1.86B", 
-    "n/a", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/gbci"
-  ], 
-  [
-    "GBDC", 
-    "Golub Capital BDC, Inc.", 
-    "17.58", 
-    "$829.28M", 
-    "2010", 
-    "n/a", 
-    "n/a", 
-    "http://www.nasdaq.com/symbol/gbdc"
-  ], 
-  [
-    "GBIM", 
-    "GlobeImmune, Inc.", 
-    "7.61", 
-    "$43.75M", 
-    "2014", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/gbim"
-  ], 
-  [
-    "GBLI", 
-    "Global Indemnity plc", 
-    "26.71", 
-    "$676.28M", 
-    "n/a", 
-    "Finance", 
-    "Property-Casualty Insurers", 
-    "http://www.nasdaq.com/symbol/gbli"
-  ], 
-  [
-    "GBNK", 
-    "Guaranty Bancorp", 
-    "15.1", 
-    "$328.38M", 
-    "n/a", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/gbnk"
-  ], 
-  [
-    "GBSN", 
-    "Great Basin Scientific, Inc.", 
-    "1.8", 
-    "$9.16M", 
-    "2014", 
-    "Health Care", 
-    "Medical/Dental Instruments", 
-    "http://www.nasdaq.com/symbol/gbsn"
-  ], 
-  [
-    "GCBC", 
-    "Greene County Bancorp, Inc.", 
-    "27.9748", 
-    "$118.12M", 
-    "n/a", 
-    "Finance", 
-    "Banks", 
-    "http://www.nasdaq.com/symbol/gcbc"
-  ], 
-  [
-    "GCVRZ", 
-    "Sanofi", 
-    "0.62", 
-    "n/a", 
-    "n/a", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/gcvrz"
-  ], 
-  [
-    "GDEF", 
-    "Global Defense & National Security Systems, Inc.", 
-    "10.3", 
-    "$99.13M", 
-    "2013", 
-    "Finance", 
-    "Business Services", 
-    "http://www.nasdaq.com/symbol/gdef"
-  ], 
-  [
-    "GENC", 
-    "Gencor Industries Inc.", 
-    "9.66", 
-    "$91.96M", 
-    "n/a", 
-    "Capital Goods", 
-    "Construction/Ag Equipment/Trucks", 
-    "http://www.nasdaq.com/symbol/genc"
-  ], 
-  [
-    "GENE", 
-    "Genetic Technologies Ltd", 
-    "6.46", 
-    "$26.44M", 
-    "n/a", 
-    "Health Care", 
-    "Biotechnology: Biological Products (No Diagnostic Substances)", 
-    "http://www.nasdaq.com/symbol/gene"
-  ], 
-  [
-    "GEOS", 
-    "Geospace Technologies Corporation", 
-    "18.31", 
-    "$240.71M", 
-    "n/a", 
-    "Capital Goods", 
-    "Industrial Machinery/Components", 
-    "http://www.nasdaq.com/symbol/geos"
-  ], 
-  [
-    "GERN", 
-    "Geron Corporation", 
-    "3.16", 
-    "$496.79M", 
-    "1996", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/gern"
-  ], 
-  [
-    "GEVA", 
-    "Synageva BioPharma Corp.", 
-    "102.45", 
-    "$3.77B", 
-    "n/a", 
-    "Health Care", 
-    "Biotechnology: Biological Products (No Diagnostic Substances)", 
-    "http://www.nasdaq.com/symbol/geva"
-  ], 
-  [
-    "GEVO", 
-    "Gevo, Inc.", 
-    "0.27", 
-    "$26.9M", 
-    "2011", 
-    "Basic Industries", 
-    "Major Chemicals", 
-    "http://www.nasdaq.com/symbol/gevo"
-  ], 
-  [
-    "GFED", 
-    "Guaranty Federal Bancshares, Inc.", 
-    "14.53", 
-    "$62.48M", 
-    "n/a", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/gfed"
-  ], 
-  [
-    "GFN", 
-    "General Finance Corporation", 
-    "8.9", 
-    "$230.06M", 
-    "n/a", 
-    "Consumer Services", 
-    "Other Specialty Stores", 
-    "http://www.nasdaq.com/symbol/gfn"
-  ], 
-  [
-    "GFNCP", 
-    "General Finance Corporation", 
-    "110", 
-    "n/a", 
-    "n/a", 
-    "Consumer Services", 
-    "Other Specialty Stores", 
-    "http://www.nasdaq.com/symbol/gfncp"
-  ], 
-  [
-    "GFNSL", 
-    "General Finance Corporation", 
-    "25.85", 
-    "n/a", 
-    "n/a", 
-    "Consumer Services", 
-    "Other Specialty Stores", 
-    "http://www.nasdaq.com/symbol/gfnsl"
-  ], 
-  [
-    "GGAC", 
-    "Garnero Group Acquisition Company", 
-    "9.52", 
-    "$177.1M", 
-    "2014", 
-    "Finance", 
-    "Business Services", 
-    "http://www.nasdaq.com/symbol/ggac"
-  ], 
-  [
-    "GGACR", 
-    "Garnero Group Acquisition Company", 
-    "0.16", 
-    "n/a", 
-    "2014", 
-    "Finance", 
-    "Business Services", 
-    "http://www.nasdaq.com/symbol/ggacr"
-  ], 
-  [
-    "GGACU", 
-    "Garnero Group Acquisition Company", 
-    "9.9", 
-    "$129.33M", 
-    "2014", 
-    "Finance", 
-    "Business Services", 
-    "http://www.nasdaq.com/symbol/ggacu"
-  ], 
-  [
-    "GGACW", 
-    "Garnero Group Acquisition Company", 
-    "0.11", 
-    "n/a", 
-    "2014", 
-    "Finance", 
-    "Business Services", 
-    "http://www.nasdaq.com/symbol/ggacw"
-  ], 
-  [
-    "GGAL", 
-    "Grupo Financiero Galicia S.A.", 
-    "20.505", 
-    "$2.67B", 
-    "n/a", 
-    "Finance", 
-    "Commercial Banks", 
-    "http://www.nasdaq.com/symbol/ggal"
-  ], 
-  [
-    "GHDX", 
-    "Genomic Health, Inc.", 
-    "31", 
-    "$983.37M", 
-    "2005", 
-    "Health Care", 
-    "Medical Specialities", 
-    "http://www.nasdaq.com/symbol/ghdx"
-  ], 
-  [
-    "GIFI", 
-    "Gulf Island Fabrication, Inc.", 
-    "16.86", 
-    "$244.67M", 
-    "1997", 
-    "Capital Goods", 
-    "Metal Fabrications", 
-    "http://www.nasdaq.com/symbol/gifi"
-  ], 
-  [
-    "GIGA", 
-    "Giga-tronics Incorporated", 
-    "1.76", 
-    "$9.58M", 
-    "1983", 
-    "Capital Goods", 
-    "Electrical Products", 
-    "http://www.nasdaq.com/symbol/giga"
-  ], 
-  [
-    "GIGM", 
-    "GigaMedia Limited", 
-    "0.772", 
-    "$39.25M", 
-    "n/a", 
-    "Technology", 
-    "Computer Software: Programming, Data Processing", 
-    "http://www.nasdaq.com/symbol/gigm"
-  ], 
-  [
-    "GIII", 
-    "G-III Apparel Group, LTD.", 
-    "105.53", 
-    "$2.37B", 
-    "1989", 
-    "Consumer Non-Durables", 
-    "Apparel", 
-    "http://www.nasdaq.com/symbol/giii"
-  ], 
-  [
-    "GILD", 
-    "Gilead Sciences, Inc.", 
-    "102.61", 
-    "$154.8B", 
-    "1992", 
-    "Health Care", 
-    "Biotechnology: Biological Products (No Diagnostic Substances)", 
-    "http://www.nasdaq.com/symbol/gild"
-  ], 
-  [
-    "GILT", 
-    "Gilat Satellite Networks Ltd.", 
-    "4.83", 
-    "$205.84M", 
-    "n/a", 
-    "Technology", 
-    "Radio And Television Broadcasting And Communications Equipment", 
-    "http://www.nasdaq.com/symbol/gilt"
-  ], 
-  [
-    "GK", 
-    "G&K Services, Inc.", 
-    "72.46", 
-    "$1.44B", 
-    "n/a", 
-    "Consumer Services", 
-    "Other Consumer Services", 
-    "http://www.nasdaq.com/symbol/gk"
-  ], 
-  [
-    "GKNT", 
-    "Geeknet, Inc.", 
-    "7.87", 
-    "$52.88M", 
-    "n/a", 
-    "Consumer Services", 
-    "Other Specialty Stores", 
-    "http://www.nasdaq.com/symbol/gknt"
-  ], 
-  [
-    "GLAD", 
-    "Gladstone Capital Corporation", 
-    "8.41", 
-    "$176.61M", 
-    "2001", 
-    "n/a", 
-    "n/a", 
-    "http://www.nasdaq.com/symbol/glad"
-  ], 
-  [
-    "GLADO", 
-    "Gladstone Capital Corporation", 
-    "25.3352", 
-    "$55.74M", 
-    "n/a", 
-    "n/a", 
-    "n/a", 
-    "http://www.nasdaq.com/symbol/glado"
-  ], 
-  [
-    "GLBS", 
-    "Globus Maritime Limited", 
-    "1.647", 
-    "$16.86M", 
-    "n/a", 
-    "Transportation", 
-    "Marine Transportation", 
-    "http://www.nasdaq.com/symbol/glbs"
-  ], 
-  [
-    "GLBZ", 
-    "Glen Burnie Bancorp", 
-    "12.23", 
-    "$33.77M", 
-    "n/a", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/glbz"
-  ], 
-  [
-    "GLDC", 
-    "Golden Enterprises, Inc.", 
-    "3.97", 
-    "$46.58M", 
-    "n/a", 
-    "Consumer Non-Durables", 
-    "Packaged Foods", 
-    "http://www.nasdaq.com/symbol/gldc"
-  ], 
-  [
-    "GLDD", 
-    "Great Lakes Dredge & Dock Corporation", 
-    "7.42", 
-    "$446.21M", 
-    "n/a", 
-    "Basic Industries", 
-    "Military/Government/Technical", 
-    "http://www.nasdaq.com/symbol/gldd"
-  ], 
-  [
-    "GLDI", 
-    "Credit Suisse AG", 
-    "12", 
-    "$162.3M", 
-    "n/a", 
-    "Finance", 
-    "Investment Bankers/Brokers/Service", 
-    "http://www.nasdaq.com/symbol/gldi"
-  ], 
-  [
-    "GLMD", 
-    "Galmed Pharmaceuticals Ltd.", 
-    "8.04", 
-    "$89.25M", 
-    "2014", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/glmd"
-  ], 
-  [
-    "GLNG", 
-    "Golar LNG Limited", 
-    "31.32", 
-    "$2.92B", 
-    "n/a", 
-    "Consumer Services", 
-    "Marine Transportation", 
-    "http://www.nasdaq.com/symbol/glng"
-  ], 
-  [
-    "GLPI", 
-    "Gaming and Leisure Properties, Inc.", 
-    "33.79", 
-    "$3.8B", 
-    "n/a", 
-    "Consumer Services", 
-    "Real Estate Investment Trusts", 
-    "http://www.nasdaq.com/symbol/glpi"
-  ], 
-  [
-    "GLRE", 
-    "Greenlight Reinsurance, Ltd.", 
-    "31.95", 
-    "$1.2B", 
-    "2007", 
-    "Finance", 
-    "Property-Casualty Insurers", 
-    "http://www.nasdaq.com/symbol/glre"
-  ], 
-  [
-    "GLRI", 
-    "Glori Energy Inc", 
-    "3.175", 
-    "$100.01M", 
-    "n/a", 
-    "Energy", 
-    "Oil & Gas Production", 
-    "http://www.nasdaq.com/symbol/glri"
-  ], 
-  [
-    "GLUU", 
-    "Glu Mobile Inc.", 
-    "5.11", 
-    "$546.51M", 
-    "2007", 
-    "Technology", 
-    "EDP Services", 
-    "http://www.nasdaq.com/symbol/gluu"
-  ], 
-  [
-    "GLYC", 
-    "GlycoMimetics, Inc.", 
-    "8.12", 
-    "$153.43M", 
-    "2014", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/glyc"
-  ], 
-  [
-    "GMAN", 
-    "Gordmans Stores, Inc.", 
-    "3.95", 
-    "$77.33M", 
-    "2010", 
-    "Consumer Services", 
-    "Clothing/Shoe/Accessory Stores", 
-    "http://www.nasdaq.com/symbol/gman"
-  ], 
-  [
-    "GMCR", 
-    "Keurig Green Mountain, Inc.", 
-    "122.87", 
-    "$19.87B", 
-    "1993", 
-    "Consumer Non-Durables", 
-    "Packaged Foods", 
-    "http://www.nasdaq.com/symbol/gmcr"
-  ], 
-  [
-    "GMLP", 
-    "Golar LNG Partners LP", 
-    "27.76", 
-    "$1.71B", 
-    "2011", 
-    "Consumer Services", 
-    "Marine Transportation", 
-    "http://www.nasdaq.com/symbol/gmlp"
-  ], 
-  [
-    "GNBC", 
-    "Green Bancorp, Inc.", 
-    "11.35", 
-    "$297.04M", 
-    "2014", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/gnbc"
-  ], 
-  [
-    "GNCA", 
-    "Genocea Biosciences, Inc.", 
-    "9", 
-    "$158.49M", 
-    "2014", 
-    "Health Care", 
-    "Biotechnology: Biological Products (No Diagnostic Substances)", 
-    "http://www.nasdaq.com/symbol/gnca"
-  ], 
-  [
-    "GNCMA", 
-    "General Communication, Inc.", 
-    "14.43", 
-    "$594.69M", 
-    "n/a", 
-    "Public Utilities", 
-    "Telecommunications Equipment", 
-    "http://www.nasdaq.com/symbol/gncma"
-  ], 
-  [
-    "GNMA", 
-    "iShares GNMA Bond ETF", 
-    "50.2932", 
-    "$40.23M", 
-    "n/a", 
-    "n/a", 
-    "n/a", 
-    "http://www.nasdaq.com/symbol/gnma"
-  ], 
-  [
-    "GNMK", 
-    "GenMark Diagnostics, Inc.", 
-    "13.22", 
-    "$551.73M", 
-    "2010", 
-    "Health Care", 
-    "Medical/Dental Instruments", 
-    "http://www.nasdaq.com/symbol/gnmk"
-  ], 
-  [
-    "GNTX", 
-    "Gentex Corporation", 
-    "17.875", 
-    "$5.23B", 
-    "n/a", 
-    "Capital Goods", 
-    "Auto Parts:O.E.M.", 
-    "http://www.nasdaq.com/symbol/gntx"
-  ], 
-  [
-    "GNVC", 
-    "GenVec, Inc.", 
-    "3.37", 
-    "$58.2M", 
-    "2000", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/gnvc"
-  ], 
-  [
-    "GOGO", 
-    "Gogo Inc.", 
-    "16.22", 
-    "$1.38B", 
-    "2013", 
-    "Consumer Services", 
-    "Telecommunications Equipment", 
-    "http://www.nasdaq.com/symbol/gogo"
-  ], 
-  [
-    "GOLD", 
-    "Randgold Resources Limited", 
-    "76.11", 
-    "$7.06B", 
-    "n/a", 
-    "Basic Industries", 
-    "Precious Metals", 
-    "http://www.nasdaq.com/symbol/gold"
-  ], 
-  [
-    "GOMO", 
-    "Sungy Mobile Limited", 
-    "4.99", 
-    "$167.08M", 
-    "2013", 
-    "Technology", 
-    "Computer Software: Prepackaged Software", 
-    "http://www.nasdaq.com/symbol/gomo"
-  ], 
-  [
-    "GOOD", 
-    "Gladstone Commercial Corporation", 
-    "17.6", 
-    "$372.57M", 
-    "2003", 
-    "Consumer Services", 
-    "Real Estate", 
-    "http://www.nasdaq.com/symbol/good"
-  ], 
-  [
-    "GOODN", 
-    "Gladstone Commercial Corporation", 
-    "25.6101", 
-    "n/a", 
-    "n/a", 
-    "Consumer Services", 
-    "Real Estate", 
-    "http://www.nasdaq.com/symbol/goodn"
-  ], 
-  [
-    "GOODO", 
-    "Gladstone Commercial Corporation", 
-    "25.4301", 
-    "$29.24M", 
-    "n/a", 
-    "Consumer Services", 
-    "Real Estate", 
-    "http://www.nasdaq.com/symbol/goodo"
-  ], 
-  [
-    "GOODP", 
-    "Gladstone Commercial Corporation", 
-    "25.6", 
-    "$25.6M", 
-    "n/a", 
-    "Consumer Services", 
-    "Real Estate", 
-    "http://www.nasdaq.com/symbol/goodp"
-  ], 
-  [
-    "GOOG", 
-    "Google Inc.", 
-    "538.95", 
-    "$366.82B", 
-    "2004", 
-    "Technology", 
-    "Computer Software: Programming, Data Processing", 
-    "http://www.nasdaq.com/symbol/goog"
-  ], 
-  [
-    "GOOGL", 
-    "Google Inc.", 
-    "541.8", 
-    "$368.76B", 
-    "n/a", 
-    "Technology", 
-    "Computer Software: Programming, Data Processing", 
-    "http://www.nasdaq.com/symbol/googl"
-  ], 
-  [
-    "GPIC", 
-    "Gaming Partners International Corporation", 
-    "8.265", 
-    "$65.43M", 
-    "n/a", 
-    "Consumer Non-Durables", 
-    "Recreational Products/Toys", 
-    "http://www.nasdaq.com/symbol/gpic"
-  ], 
-  [
-    "GPOR", 
-    "Gulfport Energy Corporation", 
-    "43.01", 
-    "$3.68B", 
-    "n/a", 
-    "Energy", 
-    "Oil & Gas Production", 
-    "http://www.nasdaq.com/symbol/gpor"
-  ], 
-  [
-    "GPRE", 
-    "Green Plains, Inc.", 
-    "25.01", 
-    "$940.6M", 
-    "n/a", 
-    "Basic Industries", 
-    "Major Chemicals", 
-    "http://www.nasdaq.com/symbol/gpre"
-  ], 
-  [
-    "GPRO", 
-    "GoPro, Inc.", 
-    "45.07", 
-    "$5.67B", 
-    "2014", 
-    "Miscellaneous", 
-    "Industrial Machinery/Components", 
-    "http://www.nasdaq.com/symbol/gpro"
-  ], 
-  [
-    "GRBK", 
-    "Green Brick Partners, Inc.", 
-    "8.2", 
-    "$51.15M", 
-    "n/a", 
-    "Capital Goods", 
-    "Homebuilding", 
-    "http://www.nasdaq.com/symbol/grbk"
-  ], 
-  [
-    "GRFS", 
-    "Grifols, S.A.", 
-    "35.2", 
-    "$12.1B", 
-    "n/a", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/grfs"
-  ], 
-  [
-    "GRID", 
-    "First Trust NASDAQ Clean Edge Smart Grid Infrastructure Index ", 
-    "35.9316", 
-    "$12.58M", 
-    "n/a", 
-    "n/a", 
-    "n/a", 
-    "http://www.nasdaq.com/symbol/grid"
-  ], 
-  [
-    "GRIF", 
-    "Griffin Land & Nurseries, Inc.", 
-    "31.38", 
-    "$161.59M", 
-    "n/a", 
-    "Finance", 
-    "Real Estate", 
-    "http://www.nasdaq.com/symbol/grif"
-  ], 
-  [
-    "GRMN", 
-    "Garmin Ltd.", 
-    "49.42", 
-    "$9.48B", 
-    "2000", 
-    "Capital Goods", 
-    "Industrial Machinery/Components", 
-    "http://www.nasdaq.com/symbol/grmn"
-  ], 
-  [
-    "GROW", 
-    "U.S. Global Investors, Inc.", 
-    "3.345", 
-    "$51.46M", 
-    "n/a", 
-    "Finance", 
-    "Investment Managers", 
-    "http://www.nasdaq.com/symbol/grow"
-  ], 
-  [
-    "GRPN", 
-    "Groupon, Inc.", 
-    "8.15", 
-    "$5.5B", 
-    "2011", 
-    "Technology", 
-    "Advertising", 
-    "http://www.nasdaq.com/symbol/grpn"
-  ], 
-  [
-    "GRVY", 
-    "GRAVITY Co., Ltd.", 
-    "0.519", 
-    "$14.43M", 
-    "2005", 
-    "Miscellaneous", 
-    "Business Services", 
-    "http://www.nasdaq.com/symbol/grvy"
-  ], 
-  [
-    "GSBC", 
-    "Great Southern Bancorp, Inc.", 
-    "36.93", 
-    "$506.96M", 
-    "1989", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/gsbc"
-  ], 
-  [
-    "GSIG", 
-    "GSI Group, Inc.", 
-    "13.62", 
-    "$465.96M", 
-    "n/a", 
-    "Miscellaneous", 
-    "Industrial Machinery/Components", 
-    "http://www.nasdaq.com/symbol/gsig"
-  ], 
-  [
-    "GSIT", 
-    "GSI Technology, Inc.", 
-    "5.7275", 
-    "$133.95M", 
-    "2007", 
-    "Technology", 
-    "Semiconductors", 
-    "http://www.nasdaq.com/symbol/gsit"
-  ], 
-  [
-    "GSM", 
-    "Globe Specialty Metals Inc.", 
-    "15.37", 
-    "$1.13B", 
-    "2009", 
-    "Capital Goods", 
-    "Metal Fabrications", 
-    "http://www.nasdaq.com/symbol/gsm"
-  ], 
-  [
-    "GSOL", 
-    "Global Sources Ltd.", 
-    "5.56", 
-    "$165.79M", 
-    "n/a", 
-    "Consumer Services", 
-    "Advertising", 
-    "http://www.nasdaq.com/symbol/gsol"
-  ], 
-  [
-    "GSVC", 
-    "GSV Capital Corp", 
-    "9.97", 
-    "$192.62M", 
-    "2011", 
-    "n/a", 
-    "n/a", 
-    "http://www.nasdaq.com/symbol/gsvc"
-  ], 
-  [
-    "GT", 
-    "The Goodyear Tire & Rubber Company", 
-    "27.69", 
-    "$7.46B", 
-    "n/a", 
-    "Consumer Durables", 
-    "Automotive Aftermarket", 
-    "http://www.nasdaq.com/symbol/gt"
-  ], 
-  [
-    "GTIM", 
-    "Good Times Restaurants Inc.", 
-    "8.29", 
-    "$78.33M", 
-    "n/a", 
-    "Consumer Services", 
-    "Restaurants", 
-    "http://www.nasdaq.com/symbol/gtim"
-  ], 
-  [
-    "GTLS", 
-    "Chart Industries, Inc.", 
-    "31.07", 
-    "$947.05M", 
-    "2006", 
-    "Capital Goods", 
-    "Metal Fabrications", 
-    "http://www.nasdaq.com/symbol/gtls"
-  ]
-]
\ No newline at end of file
diff --git a/examples/stocks/data/stock_data_12.json b/examples/stocks/data/stock_data_12.json
deleted file mode 100644
index 51fd8da..0000000
--- a/examples/stocks/data/stock_data_12.json
+++ /dev/null
@@ -1,1002 +0,0 @@
-[
-  [
-    "GTWN", 
-    "Georgetown Bancorp, Inc.", 
-    "17.5501", 
-    "$32.08M", 
-    "n/a", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/gtwn"
-  ], 
-  [
-    "GTXI", 
-    "GTx, Inc.", 
-    "0.7", 
-    "$98.23M", 
-    "2004", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/gtxi"
-  ], 
-  [
-    "GUID", 
-    "Guidance Software, Inc.", 
-    "5.99", 
-    "$176.55M", 
-    "2006", 
-    "Technology", 
-    "Computer Software: Prepackaged Software", 
-    "http://www.nasdaq.com/symbol/guid"
-  ], 
-  [
-    "GULF", 
-    "WisdomTree Middle East Dividend Fund", 
-    "21.14", 
-    "$50.74M", 
-    "n/a", 
-    "n/a", 
-    "n/a", 
-    "http://www.nasdaq.com/symbol/gulf"
-  ], 
-  [
-    "GULTU", 
-    "Gulf Coast Ultra Deep Royalty Trust", 
-    "1", 
-    "$230.17M", 
-    "n/a", 
-    "Energy", 
-    "Oil & Gas Production", 
-    "http://www.nasdaq.com/symbol/gultu"
-  ], 
-  [
-    "GURE", 
-    "Gulf Resources, Inc.", 
-    "1.58", 
-    "$61.19M", 
-    "n/a", 
-    "Basic Industries", 
-    "Major Chemicals", 
-    "http://www.nasdaq.com/symbol/gure"
-  ], 
-  [
-    "GWGH", 
-    "GWG Holdings, Inc", 
-    "8.405", 
-    "$49.34M", 
-    "2014", 
-    "Finance", 
-    "Life Insurance", 
-    "http://www.nasdaq.com/symbol/gwgh"
-  ], 
-  [
-    "GWPH", 
-    "GW Pharmaceuticals Plc", 
-    "84.89", 
-    "$1.67B", 
-    "2013", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/gwph"
-  ], 
-  [
-    "GYRO", 
-    "Gyrodyne Company of America, Inc.", 
-    "3.944", 
-    "$5.85M", 
-    "n/a", 
-    "Consumer Services", 
-    "Building operators", 
-    "http://www.nasdaq.com/symbol/gyro"
-  ], 
-  [
-    "HA", 
-    "Hawaiian Holdings, Inc.", 
-    "18.745", 
-    "$1.02B", 
-    "n/a", 
-    "Transportation", 
-    "Air Freight/Delivery Services", 
-    "http://www.nasdaq.com/symbol/ha"
-  ], 
-  [
-    "HABT", 
-    "The Habit Restaurants, Inc.", 
-    "32.26", 
-    "$814.65M", 
-    "2014", 
-    "Consumer Services", 
-    "Restaurants", 
-    "http://www.nasdaq.com/symbol/habt"
-  ], 
-  [
-    "HAFC", 
-    "Hanmi Financial Corporation", 
-    "20.05", 
-    "$639.68M", 
-    "n/a", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/hafc"
-  ], 
-  [
-    "HAIN", 
-    "The Hain Celestial Group, Inc.", 
-    "62.12", 
-    "$6.32B", 
-    "n/a", 
-    "Consumer Non-Durables", 
-    "Packaged Foods", 
-    "http://www.nasdaq.com/symbol/hain"
-  ], 
-  [
-    "HALL", 
-    "Hallmark Financial Services, Inc.", 
-    "10.87", 
-    "$207.45M", 
-    "n/a", 
-    "Finance", 
-    "Property-Casualty Insurers", 
-    "http://www.nasdaq.com/symbol/hall"
-  ], 
-  [
-    "HALO", 
-    "Halozyme Therapeutics, Inc.", 
-    "15.365", 
-    "$1.93B", 
-    "n/a", 
-    "Health Care", 
-    "Biotechnology: Biological Products (No Diagnostic Substances)", 
-    "http://www.nasdaq.com/symbol/halo"
-  ], 
-  [
-    "HART          ", 
-    "Harvard Apparatus Regenerative Technology, Inc.", 
-    "3.32", 
-    "$26.08M", 
-    "n/a", 
-    "Health Care", 
-    "Medical/Dental Instruments", 
-    "http://www.nasdaq.com/symbol/hart          "
-  ], 
-  [
-    "HAS", 
-    "Hasbro, Inc.", 
-    "61.83", 
-    "$7.77B", 
-    "n/a", 
-    "Consumer Non-Durables", 
-    "Recreational Products/Toys", 
-    "http://www.nasdaq.com/symbol/has"
-  ], 
-  [
-    "HAWK", 
-    "Blackhawk Network Holdings, Inc.", 
-    "38.15", 
-    "$2.02B", 
-    "2013", 
-    "Finance", 
-    "Finance: Consumer Services", 
-    "http://www.nasdaq.com/symbol/hawk"
-  ], 
-  [
-    "HAWKB", 
-    "Blackhawk Network Holdings, Inc.", 
-    "37.71", 
-    "$2B", 
-    "n/a", 
-    "Finance", 
-    "Finance: Consumer Services", 
-    "http://www.nasdaq.com/symbol/hawkb"
-  ], 
-  [
-    "HAYN", 
-    "Haynes International, Inc.", 
-    "41.54", 
-    "$517.02M", 
-    "2007", 
-    "Capital Goods", 
-    "Steel/Iron Ore", 
-    "http://www.nasdaq.com/symbol/hayn"
-  ], 
-  [
-    "HBAN", 
-    "Huntington Bancshares Incorporated", 
-    "10.72", 
-    "$8.68B", 
-    "n/a", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/hban"
-  ], 
-  [
-    "HBANP", 
-    "Huntington Bancshares Incorporated", 
-    "1335", 
-    "n/a", 
-    "n/a", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/hbanp"
-  ], 
-  [
-    "HBCP", 
-    "Home Bancorp, Inc.", 
-    "21.06", 
-    "$149.83M", 
-    "n/a", 
-    "Finance", 
-    "Banks", 
-    "http://www.nasdaq.com/symbol/hbcp"
-  ], 
-  [
-    "HBHC", 
-    "Hancock Holding Company", 
-    "29.4", 
-    "$2.4B", 
-    "n/a", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/hbhc"
-  ], 
-  [
-    "HBIO", 
-    "Harvard Bioscience, Inc.", 
-    "5.45", 
-    "$176.69M", 
-    "2000", 
-    "n/a", 
-    "n/a", 
-    "http://www.nasdaq.com/symbol/hbio"
-  ], 
-  [
-    "HBK", 
-    "Hamilton Bancorp, Inc.", 
-    "12.99", 
-    "$44.4M", 
-    "2012", 
-    "Finance", 
-    "Savings Institutions", 
-    "http://www.nasdaq.com/symbol/hbk"
-  ], 
-  [
-    "HBMD", 
-    "Howard Bancorp, Inc.", 
-    "13.24", 
-    "$54.82M", 
-    "n/a", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/hbmd"
-  ], 
-  [
-    "HBNC", 
-    "Horizon Bancorp (IN)", 
-    "22.44", 
-    "$206.69M", 
-    "n/a", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/hbnc"
-  ], 
-  [
-    "HBNK", 
-    "Hampden Bancorp, Inc.", 
-    "20.9001", 
-    "$116.09M", 
-    "n/a", 
-    "Finance", 
-    "Banks", 
-    "http://www.nasdaq.com/symbol/hbnk"
-  ], 
-  [
-    "HBOS", 
-    "Heritage Financial Group", 
-    "25.11", 
-    "$230.71M", 
-    "n/a", 
-    "Finance", 
-    "Savings Institutions", 
-    "http://www.nasdaq.com/symbol/hbos"
-  ], 
-  [
-    "HBP", 
-    "Huttig Building Products, Inc.", 
-    "3.1", 
-    "$76.17M", 
-    "n/a", 
-    "Consumer Services", 
-    "RETAIL: Building Materials", 
-    "http://www.nasdaq.com/symbol/hbp"
-  ], 
-  [
-    "HCAC", 
-    "Hennessy Capital Acquisition Corp.", 
-    "10.04", 
-    "$144.33M", 
-    "2014", 
-    "Capital Goods", 
-    "Construction/Ag Equipment/Trucks", 
-    "http://www.nasdaq.com/symbol/hcac"
-  ], 
-  [
-    "HCACU", 
-    "Hennessy Capital Acquisition Corp.", 
-    "11.64", 
-    "$116.4M", 
-    "2014", 
-    "Finance", 
-    "Investment Managers", 
-    "http://www.nasdaq.com/symbol/hcacu"
-  ], 
-  [
-    "HCACW", 
-    "Hennessy Capital Acquisition Corp.", 
-    "0.71", 
-    "n/a", 
-    "2014", 
-    "Capital Goods", 
-    "Construction/Ag Equipment/Trucks", 
-    "http://www.nasdaq.com/symbol/hcacw"
-  ], 
-  [
-    "HCAP", 
-    "Harvest Capital Credit Corporation", 
-    "12.38", 
-    "$76.9M", 
-    "2013", 
-    "n/a", 
-    "n/a", 
-    "http://www.nasdaq.com/symbol/hcap"
-  ], 
-  [
-    "HCAPL", 
-    "Harvest Capital Credit Corporation", 
-    "25.6759", 
-    "n/a", 
-    "n/a", 
-    "n/a", 
-    "n/a", 
-    "http://www.nasdaq.com/symbol/hcapl"
-  ], 
-  [
-    "HCBK", 
-    "Hudson City Bancorp, Inc.", 
-    "9.67", 
-    "$5.11B", 
-    "n/a", 
-    "Finance", 
-    "Banks", 
-    "http://www.nasdaq.com/symbol/hcbk"
-  ], 
-  [
-    "HCCI", 
-    "Heritage-Crystal Clean, Inc.", 
-    "12.5", 
-    "$275.83M", 
-    "2008", 
-    "Basic Industries", 
-    "Miscellaneous", 
-    "http://www.nasdaq.com/symbol/hcci"
-  ], 
-  [
-    "HCKT", 
-    "The Hackett Group, Inc.", 
-    "7.93", 
-    "$231.55M", 
-    "n/a", 
-    "Consumer Services", 
-    "Professional Services", 
-    "http://www.nasdaq.com/symbol/hckt"
-  ], 
-  [
-    "HCOM", 
-    "Hawaiian Telcom Holdco, Inc.", 
-    "26.44", 
-    "$282.2M", 
-    "n/a", 
-    "Consumer Services", 
-    "Telecommunications Equipment", 
-    "http://www.nasdaq.com/symbol/hcom"
-  ], 
-  [
-    "HCSG", 
-    "Healthcare Services Group, Inc.", 
-    "32.69", 
-    "$2.33B", 
-    "1983", 
-    "Health Care", 
-    "Hospital/Nursing Management", 
-    "http://www.nasdaq.com/symbol/hcsg"
-  ], 
-  [
-    "HDNG", 
-    "Hardinge, Inc.", 
-    "11.44", 
-    "$146.68M", 
-    "1995", 
-    "Capital Goods", 
-    "Industrial Machinery/Components", 
-    "http://www.nasdaq.com/symbol/hdng"
-  ], 
-  [
-    "HDP", 
-    "Hortonworks, Inc.", 
-    "24.47", 
-    "$1.02B", 
-    "2014", 
-    "Technology", 
-    "Computer Software: Prepackaged Software", 
-    "http://www.nasdaq.com/symbol/hdp"
-  ], 
-  [
-    "HDRA", 
-    "Hydra Industries Acquisition Corp.", 
-    "9.5", 
-    "$97.85M", 
-    "2014", 
-    "Finance", 
-    "Business Services", 
-    "http://www.nasdaq.com/symbol/hdra"
-  ], 
-  [
-    "HDRAR", 
-    "Hydra Industries Acquisition Corp.", 
-    "0.2792", 
-    "n/a", 
-    "2014", 
-    "Finance", 
-    "Business Services", 
-    "http://www.nasdaq.com/symbol/hdrar"
-  ], 
-  [
-    "HDRAU", 
-    "Hydra Industries Acquisition Corp.", 
-    "9.86", 
-    "n/a", 
-    "2014", 
-    "Finance", 
-    "Business Services", 
-    "http://www.nasdaq.com/symbol/hdrau"
-  ], 
-  [
-    "HDRAW", 
-    "Hydra Industries Acquisition Corp.", 
-    "0.19", 
-    "n/a", 
-    "2014", 
-    "Finance", 
-    "Business Services", 
-    "http://www.nasdaq.com/symbol/hdraw"
-  ], 
-  [
-    "HDS", 
-    "HD Supply Holdings, Inc.", 
-    "29.62", 
-    "$5.81B", 
-    "2013", 
-    "Consumer Services", 
-    "Office Equipment/Supplies/Services", 
-    "http://www.nasdaq.com/symbol/hds"
-  ], 
-  [
-    "HDSN", 
-    "Hudson Technologies, Inc.", 
-    "3.87", 
-    "$123.96M", 
-    "n/a", 
-    "Consumer Durables", 
-    "Industrial Specialties", 
-    "http://www.nasdaq.com/symbol/hdsn"
-  ], 
-  [
-    "HEAR", 
-    "Turtle Beach Corporation", 
-    "2.57", 
-    "$108.01M", 
-    "n/a", 
-    "Consumer Durables", 
-    "Telecommunications Equipment", 
-    "http://www.nasdaq.com/symbol/hear"
-  ], 
-  [
-    "HEES", 
-    "H&E Equipment Services, Inc.", 
-    "22.2", 
-    "$782.18M", 
-    "2006", 
-    "n/a", 
-    "n/a", 
-    "http://www.nasdaq.com/symbol/hees"
-  ], 
-  [
-    "HELE", 
-    "Helen of Troy Limited", 
-    "77.56", 
-    "$2.2B", 
-    "n/a", 
-    "Consumer Durables", 
-    "Home Furnishings", 
-    "http://www.nasdaq.com/symbol/hele"
-  ], 
-  [
-    "HEOP", 
-    "Heritage Oaks Bancorp", 
-    "7.87", 
-    "$260.46M", 
-    "n/a", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/heop"
-  ], 
-  [
-    "HERO", 
-    "Hercules Offshore, Inc.", 
-    "0.8601", 
-    "$138.32M", 
-    "2005", 
-    "Energy", 
-    "Oil & Gas Production", 
-    "http://www.nasdaq.com/symbol/hero"
-  ], 
-  [
-    "HFBC", 
-    "HopFed Bancorp, Inc.", 
-    "13.07", 
-    "$94.24M", 
-    "n/a", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/hfbc"
-  ], 
-  [
-    "HFBL", 
-    "Home Federal Bancorp, Inc. of Louisiana", 
-    "19.69", 
-    "$42.66M", 
-    "n/a", 
-    "Finance", 
-    "Savings Institutions", 
-    "http://www.nasdaq.com/symbol/hfbl"
-  ], 
-  [
-    "HFFC", 
-    "HF Financial Corp.", 
-    "14.84", 
-    "$104.68M", 
-    "n/a", 
-    "Finance", 
-    "Savings Institutions", 
-    "http://www.nasdaq.com/symbol/hffc"
-  ], 
-  [
-    "HFWA", 
-    "Heritage Financial Corporation", 
-    "16.29", 
-    "$492.87M", 
-    "n/a", 
-    "Finance", 
-    "Banks", 
-    "http://www.nasdaq.com/symbol/hfwa"
-  ], 
-  [
-    "HGSH", 
-    "China HGS Real Estate, Inc.", 
-    "3.2", 
-    "$144.16M", 
-    "n/a", 
-    "Finance", 
-    "Real Estate", 
-    "http://www.nasdaq.com/symbol/hgsh"
-  ], 
-  [
-    "HIBB", 
-    "Hibbett Sports, Inc.", 
-    "49.06", 
-    "$1.23B", 
-    "1996", 
-    "Consumer Services", 
-    "Other Specialty Stores", 
-    "http://www.nasdaq.com/symbol/hibb"
-  ], 
-  [
-    "HIFS", 
-    "Hingham Institution for Savings", 
-    "100.75", 
-    "$214.47M", 
-    "n/a", 
-    "n/a", 
-    "n/a", 
-    "http://www.nasdaq.com/symbol/hifs"
-  ], 
-  [
-    "HIHO", 
-    "Highway Holdings Limited", 
-    "3.463", 
-    "$13.1M", 
-    "n/a", 
-    "Capital Goods", 
-    "Metal Fabrications", 
-    "http://www.nasdaq.com/symbol/hiho"
-  ], 
-  [
-    "HIIQ", 
-    "Health Insurance Innovations, Inc.", 
-    "7.77", 
-    "$114.13M", 
-    "2013", 
-    "Finance", 
-    "Specialty Insurers", 
-    "http://www.nasdaq.com/symbol/hiiq"
-  ], 
-  [
-    "HILL", 
-    "Dot Hill Systems Corporation", 
-    "4.38", 
-    "$265.11M", 
-    "n/a", 
-    "Technology", 
-    "Electronic Components", 
-    "http://www.nasdaq.com/symbol/hill"
-  ], 
-  [
-    "HIMX", 
-    "Himax Technologies, Inc.", 
-    "7.75", 
-    "$1.33B", 
-    "2006", 
-    "Technology", 
-    "Semiconductors", 
-    "http://www.nasdaq.com/symbol/himx"
-  ], 
-  [
-    "HKTV", 
-    "Hong Kong Television Network Limited", 
-    "8.01", 
-    "$324.01M", 
-    "n/a", 
-    "Public Utilities", 
-    "Telecommunications Equipment", 
-    "http://www.nasdaq.com/symbol/hktv"
-  ], 
-  [
-    "HLIT", 
-    "Harmonic Inc.", 
-    "7.9", 
-    "$695.67M", 
-    "1995", 
-    "Technology", 
-    "Radio And Television Broadcasting And Communications Equipment", 
-    "http://www.nasdaq.com/symbol/hlit"
-  ], 
-  [
-    "HLSS", 
-    "Home Loan Servicing Solutions, Ltd.", 
-    "16.76", 
-    "$1.19B", 
-    "2012", 
-    "Finance", 
-    "Finance: Consumer Services", 
-    "http://www.nasdaq.com/symbol/hlss"
-  ], 
-  [
-    "HMHC", 
-    "Houghton Mifflin Harcourt Company", 
-    "20.07", 
-    "$2.84B", 
-    "2013", 
-    "Consumer Services", 
-    "Books", 
-    "http://www.nasdaq.com/symbol/hmhc"
-  ], 
-  [
-    "HMIN", 
-    "Homeinns Hotel Group", 
-    "29", 
-    "$1.39B", 
-    "n/a", 
-    "Consumer Services", 
-    "Hotels/Resorts", 
-    "http://www.nasdaq.com/symbol/hmin"
-  ], 
-  [
-    "HMNF", 
-    "HMN Financial, Inc.", 
-    "12.0286", 
-    "$53.77M", 
-    "n/a", 
-    "Finance", 
-    "Savings Institutions", 
-    "http://www.nasdaq.com/symbol/hmnf"
-  ], 
-  [
-    "HMNY", 
-    "Helios and Matheson Analytics Inc", 
-    "1.7856", 
-    "$4.16M", 
-    "n/a", 
-    "Consumer Services", 
-    "Other Consumer Services", 
-    "http://www.nasdaq.com/symbol/hmny"
-  ], 
-  [
-    "HMPR", 
-    "Hampton Roads Bankshares Inc", 
-    "1.63", 
-    "$277.58M", 
-    "n/a", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/hmpr"
-  ], 
-  [
-    "HMST", 
-    "HomeStreet, Inc.", 
-    "17.2", 
-    "$255.53M", 
-    "2012", 
-    "Finance", 
-    "Banks", 
-    "http://www.nasdaq.com/symbol/hmst"
-  ], 
-  [
-    "HMSY", 
-    "HMS Holdings Corp", 
-    "19.1", 
-    "$1.68B", 
-    "1992", 
-    "Miscellaneous", 
-    "Business Services", 
-    "http://www.nasdaq.com/symbol/hmsy"
-  ], 
-  [
-    "HMTV", 
-    "Hemisphere Media Group, Inc.", 
-    "12.67", 
-    "$571.75M", 
-    "n/a", 
-    "Consumer Services", 
-    "Television Services", 
-    "http://www.nasdaq.com/symbol/hmtv"
-  ], 
-  [
-    "HNH", 
-    "Handy & Harman Ltd.", 
-    "46.66", 
-    "$503.01M", 
-    "n/a", 
-    "Capital Goods", 
-    "Industrial Specialties", 
-    "http://www.nasdaq.com/symbol/hnh"
-  ], 
-  [
-    "HNNA", 
-    "Hennessy Advisors, Inc.", 
-    "22.6505", 
-    "$136.46M", 
-    "n/a", 
-    "Finance", 
-    "Investment Managers", 
-    "http://www.nasdaq.com/symbol/hnna"
-  ], 
-  [
-    "HNRG", 
-    "Hallador Energy Company", 
-    "11.44", 
-    "$329.22M", 
-    "n/a", 
-    "Energy", 
-    "Coal Mining", 
-    "http://www.nasdaq.com/symbol/hnrg"
-  ], 
-  [
-    "HNSN", 
-    "Hansen Medical, Inc.", 
-    "1.09", 
-    "$144.44M", 
-    "2006", 
-    "Health Care", 
-    "Industrial Specialties", 
-    "http://www.nasdaq.com/symbol/hnsn"
-  ], 
-  [
-    "HOFT", 
-    "Hooker Furniture Corporation", 
-    "18.5", 
-    "$199.31M", 
-    "n/a", 
-    "Consumer Durables", 
-    "Home Furnishings", 
-    "http://www.nasdaq.com/symbol/hoft"
-  ], 
-  [
-    "HOLI", 
-    "Hollysys Automation Technologies, Ltd.", 
-    "18.93", 
-    "$1.1B", 
-    "n/a", 
-    "Energy", 
-    "Industrial Machinery/Components", 
-    "http://www.nasdaq.com/symbol/holi"
-  ], 
-  [
-    "HOLX", 
-    "Hologic, Inc.", 
-    "31.735", 
-    "$8.88B", 
-    "1990", 
-    "Health Care", 
-    "Medical Electronics", 
-    "http://www.nasdaq.com/symbol/holx"
-  ], 
-  [
-    "HOMB", 
-    "Home BancShares, Inc.", 
-    "31.57", 
-    "$2.13B", 
-    "2006", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/homb"
-  ], 
-  [
-    "HOTR", 
-    "Chanticleer Holdings, Inc.", 
-    "2.7", 
-    "$19.55M", 
-    "n/a", 
-    "Consumer Services", 
-    "Restaurants", 
-    "http://www.nasdaq.com/symbol/hotr"
-  ], 
-  [
-    "HOTRW", 
-    "Chanticleer Holdings, Inc.", 
-    "0.2999", 
-    "n/a", 
-    "n/a", 
-    "Consumer Services", 
-    "Restaurants", 
-    "http://www.nasdaq.com/symbol/hotrw"
-  ], 
-  [
-    "HOVNP", 
-    "Hovnanian Enterprises Inc", 
-    "14.94", 
-    "$74.7M", 
-    "n/a", 
-    "Capital Goods", 
-    "Homebuilding", 
-    "http://www.nasdaq.com/symbol/hovnp"
-  ], 
-  [
-    "HPJ", 
-    "Highpower International Inc", 
-    "5.38", 
-    "$80.98M", 
-    "n/a", 
-    "Miscellaneous", 
-    "Industrial Machinery/Components", 
-    "http://www.nasdaq.com/symbol/hpj"
-  ], 
-  [
-    "HPTX", 
-    "Hyperion Therapeutics, Inc.", 
-    "27.42", 
-    "$568.24M", 
-    "2012", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/hptx"
-  ], 
-  [
-    "HQCL", 
-    "Hanwha Q CELLS Co., Ltd. ", 
-    "1.1784", 
-    "$989.68M", 
-    "n/a", 
-    "Technology", 
-    "Semiconductors", 
-    "http://www.nasdaq.com/symbol/hqcl"
-  ], 
-  [
-    "HQY", 
-    "HealthEquity, Inc.", 
-    "19.42", 
-    "$1.06B", 
-    "2014", 
-    "Miscellaneous", 
-    "Business Services", 
-    "http://www.nasdaq.com/symbol/hqy"
-  ], 
-  [
-    "HRTX", 
-    "Heron Therapeutics, Inc.  ", 
-    "11.07", 
-    "$323.02M", 
-    "n/a", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/hrtx"
-  ], 
-  [
-    "HRZN", 
-    "Horizon Technology Finance Corporation", 
-    "14.03", 
-    "$135.06M", 
-    "2010", 
-    "n/a", 
-    "n/a", 
-    "http://www.nasdaq.com/symbol/hrzn"
-  ], 
-  [
-    "HSGX", 
-    "Histogenics Corporation", 
-    "9.6", 
-    "$122.47M", 
-    "2014", 
-    "Health Care", 
-    "Industrial Specialties", 
-    "http://www.nasdaq.com/symbol/hsgx"
-  ], 
-  [
-    "HSIC", 
-    "Henry Schein, Inc.", 
-    "142.55", 
-    "$11.95B", 
-    "1995", 
-    "Health Care", 
-    "Medical Specialities", 
-    "http://www.nasdaq.com/symbol/hsic"
-  ], 
-  [
-    "HSII", 
-    "Heidrick & Struggles International, Inc.", 
-    "23.21", 
-    "$423.45M", 
-    "1999", 
-    "Technology", 
-    "Diversified Commercial Services", 
-    "http://www.nasdaq.com/symbol/hsii"
-  ], 
-  [
-    "HSKA", 
-    "Heska Corporation", 
-    "21.14", 
-    "$133.6M", 
-    "1997", 
-    "Health Care", 
-    "Biotechnology: Biological Products (No Diagnostic Substances)", 
-    "http://www.nasdaq.com/symbol/hska"
-  ], 
-  [
-    "HSNI", 
-    "HSN, Inc.", 
-    "68.11", 
-    "$3.57B", 
-    "n/a", 
-    "Consumer Services", 
-    "Other Specialty Stores", 
-    "http://www.nasdaq.com/symbol/hsni"
-  ], 
-  [
-    "HSON", 
-    "Hudson Global, Inc.", 
-    "2.58", 
-    "$85.43M", 
-    "n/a", 
-    "Technology", 
-    "Professional Services", 
-    "http://www.nasdaq.com/symbol/hson"
-  ], 
-  [
-    "HSTM", 
-    "HealthStream, Inc.", 
-    "26.46", 
-    "$731.21M", 
-    "2000", 
-    "Technology", 
-    "Computer Software: Programming, Data Processing", 
-    "http://www.nasdaq.com/symbol/hstm"
-  ]
-]
\ No newline at end of file
diff --git a/examples/stocks/data/stock_data_13.json b/examples/stocks/data/stock_data_13.json
deleted file mode 100644
index a907431..0000000
--- a/examples/stocks/data/stock_data_13.json
+++ /dev/null
@@ -1,1002 +0,0 @@
-[
-  [
-    "HTBI", 
-    "HomeTrust Bancshares, Inc.", 
-    "16.01", 
-    "$326.58M", 
-    "2012", 
-    "Finance", 
-    "Savings Institutions", 
-    "http://www.nasdaq.com/symbol/htbi"
-  ], 
-  [
-    "HTBK", 
-    "Heritage Commerce Corp", 
-    "8.64", 
-    "$228.28M", 
-    "n/a", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/htbk"
-  ], 
-  [
-    "HTBX", 
-    "Heat Biologics, Inc.", 
-    "6.83", 
-    "$44.27M", 
-    "2013", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/htbx"
-  ], 
-  [
-    "HTCH", 
-    "Hutchinson Technology Incorporated", 
-    "3.66", 
-    "$122.46M", 
-    "1985", 
-    "Capital Goods", 
-    "Industrial Machinery/Components", 
-    "http://www.nasdaq.com/symbol/htch"
-  ], 
-  [
-    "HTHT", 
-    "China Lodging Group, Limited", 
-    "22.07", 
-    "$1.37B", 
-    "2010", 
-    "Consumer Services", 
-    "Hotels/Resorts", 
-    "http://www.nasdaq.com/symbol/htht"
-  ], 
-  [
-    "HTLD", 
-    "Heartland Express, Inc.", 
-    "25.49", 
-    "$2.24B", 
-    "1986", 
-    "Transportation", 
-    "Trucking Freight/Courier Services", 
-    "http://www.nasdaq.com/symbol/htld"
-  ], 
-  [
-    "HTLF", 
-    "Heartland Financial USA, Inc.", 
-    "29.45", 
-    "$544.23M", 
-    "n/a", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/htlf"
-  ], 
-  [
-    "HTWO", 
-    "HF2 Financial Management Inc.", 
-    "10.2", 
-    "$242.68M", 
-    "2013", 
-    "Finance", 
-    "Investment Managers", 
-    "http://www.nasdaq.com/symbol/htwo"
-  ], 
-  [
-    "HTWR", 
-    "Heartware International, Inc.", 
-    "89.49", 
-    "$1.52B", 
-    "n/a", 
-    "Health Care", 
-    "Medical/Dental Instruments", 
-    "http://www.nasdaq.com/symbol/htwr"
-  ], 
-  [
-    "HUBG", 
-    "Hub Group, Inc.", 
-    "38.77", 
-    "$1.45B", 
-    "1996", 
-    "Transportation", 
-    "Oil Refining/Marketing", 
-    "http://www.nasdaq.com/symbol/hubg"
-  ], 
-  [
-    "HURC", 
-    "Hurco Companies, Inc.", 
-    "35.25", 
-    "$230.29M", 
-    "n/a", 
-    "Capital Goods", 
-    "Industrial Machinery/Components", 
-    "http://www.nasdaq.com/symbol/hurc"
-  ], 
-  [
-    "HURN", 
-    "Huron Consulting Group Inc.", 
-    "77.8", 
-    "$1.78B", 
-    "2004", 
-    "Consumer Services", 
-    "Professional Services", 
-    "http://www.nasdaq.com/symbol/hurn"
-  ], 
-  [
-    "HWAY", 
-    "Healthways, Inc.", 
-    "21.15", 
-    "$748.49M", 
-    "n/a", 
-    "Health Care", 
-    "Hospital/Nursing Management", 
-    "http://www.nasdaq.com/symbol/hway"
-  ], 
-  [
-    "HWBK", 
-    "Hawthorn Bancshares, Inc.", 
-    "15", 
-    "$78.51M", 
-    "n/a", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/hwbk"
-  ], 
-  [
-    "HWCC", 
-    "Houston Wire & Cable Company", 
-    "10.6", 
-    "$185.73M", 
-    "2006", 
-    "Consumer Non-Durables", 
-    "Telecommunications Equipment", 
-    "http://www.nasdaq.com/symbol/hwcc"
-  ], 
-  [
-    "HWKN", 
-    "Hawkins, Inc.", 
-    "38.61", 
-    "$411.01M", 
-    "n/a", 
-    "Consumer Durables", 
-    "Specialty Chemicals", 
-    "http://www.nasdaq.com/symbol/hwkn"
-  ], 
-  [
-    "HYGS", 
-    "Hydrogenics Corporation", 
-    "13.83", 
-    "$139.54M", 
-    "n/a", 
-    "Basic Industries", 
-    "Major Chemicals", 
-    "http://www.nasdaq.com/symbol/hygs"
-  ], 
-  [
-    "HYLS", 
-    "First Trust High Yield Long/Short ETF", 
-    "50.43", 
-    "$186.59M", 
-    "n/a", 
-    "n/a", 
-    "n/a", 
-    "http://www.nasdaq.com/symbol/hyls"
-  ], 
-  [
-    "HYND", 
-    "WisdomTree BofA Merrill Lynch High Yield Bond Negative Duratio", 
-    "21.75", 
-    "$8.7M", 
-    "n/a", 
-    "n/a", 
-    "n/a", 
-    "http://www.nasdaq.com/symbol/hynd"
-  ], 
-  [
-    "HYZD", 
-    "WisdomTree BofA Merrill Lynch High Yield Bond Zero Duration Fu", 
-    "24.24", 
-    "$21.82M", 
-    "n/a", 
-    "n/a", 
-    "n/a", 
-    "http://www.nasdaq.com/symbol/hyzd"
-  ], 
-  [
-    "HZNP", 
-    "Horizon Pharma plc", 
-    "18.53", 
-    "$2.2B", 
-    "2011", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/hznp"
-  ], 
-  [
-    "IACI", 
-    "IAC/InterActiveCorp", 
-    "67.06", 
-    "$5.62B", 
-    "n/a", 
-    "Consumer Services", 
-    "Other Specialty Stores", 
-    "http://www.nasdaq.com/symbol/iaci"
-  ], 
-  [
-    "IART", 
-    "Integra LifeSciences Holdings Corporation", 
-    "56.99", 
-    "$1.87B", 
-    "n/a", 
-    "Capital Goods", 
-    "Biotechnology: Laboratory Analytical Instruments", 
-    "http://www.nasdaq.com/symbol/iart"
-  ], 
-  [
-    "IBB", 
-    "iShares Nasdaq Biotechnology Index Fund", 
-    "336.43", 
-    "$7.75B", 
-    "n/a", 
-    "n/a", 
-    "n/a", 
-    "http://www.nasdaq.com/symbol/ibb"
-  ], 
-  [
-    "IBCP", 
-    "Independent Bank Corporation", 
-    "12.55", 
-    "$288.05M", 
-    "n/a", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/ibcp"
-  ], 
-  [
-    "IBKC", 
-    "IBERIABANK Corporation", 
-    "62.57", 
-    "$2.09B", 
-    "n/a", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/ibkc"
-  ], 
-  [
-    "IBKR", 
-    "Interactive Brokers Group, Inc.", 
-    "32.53", 
-    "$1.9B", 
-    "n/a", 
-    "Finance", 
-    "Investment Bankers/Brokers/Service", 
-    "http://www.nasdaq.com/symbol/ibkr"
-  ], 
-  [
-    "IBOC", 
-    "International Bancshares Corporation", 
-    "24.65", 
-    "$1.64B", 
-    "n/a", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/iboc"
-  ], 
-  [
-    "IBTX", 
-    "Independent Bank Group, Inc", 
-    "36.95", 
-    "$628.78M", 
-    "2013", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/ibtx"
-  ], 
-  [
-    "ICAD", 
-    "icad inc.", 
-    "10.85", 
-    "$168.64M", 
-    "n/a", 
-    "Health Care", 
-    "Medical/Dental Instruments", 
-    "http://www.nasdaq.com/symbol/icad"
-  ], 
-  [
-    "ICBK", 
-    "County Bancorp, Inc.", 
-    "20.2108", 
-    "$111.11M", 
-    "2015", 
-    "n/a", 
-    "n/a", 
-    "http://www.nasdaq.com/symbol/icbk"
-  ], 
-  [
-    "ICCC", 
-    "ImmuCell Corporation", 
-    "6.6999", 
-    "$20.28M", 
-    "1987", 
-    "Health Care", 
-    "Biotechnology: In Vitro & In Vivo Diagnostic Substances", 
-    "http://www.nasdaq.com/symbol/iccc"
-  ], 
-  [
-    "ICEL", 
-    "Cellular Dynamics International, Inc.", 
-    "5.36", 
-    "$84.76M", 
-    "2013", 
-    "Health Care", 
-    "Biotechnology: Biological Products (No Diagnostic Substances)", 
-    "http://www.nasdaq.com/symbol/icel"
-  ], 
-  [
-    "ICFI", 
-    "ICF International, Inc.", 
-    "39.56", 
-    "$767.41M", 
-    "2006", 
-    "Consumer Services", 
-    "Professional Services", 
-    "http://www.nasdaq.com/symbol/icfi"
-  ], 
-  [
-    "ICLD", 
-    "InterCloud Systems, Inc", 
-    "2.71", 
-    "$46.2M", 
-    "n/a", 
-    "Miscellaneous", 
-    "Business Services", 
-    "http://www.nasdaq.com/symbol/icld"
-  ], 
-  [
-    "ICLDW", 
-    "InterCloud Systems, Inc", 
-    "1.575", 
-    "n/a", 
-    "n/a", 
-    "Miscellaneous", 
-    "Business Services", 
-    "http://www.nasdaq.com/symbol/icldw"
-  ], 
-  [
-    "ICLN", 
-    "iShares S&P Global Clean Energy Index Fund", 
-    "10.6101", 
-    "$68.97M", 
-    "n/a", 
-    "n/a", 
-    "n/a", 
-    "http://www.nasdaq.com/symbol/icln"
-  ], 
-  [
-    "ICLR", 
-    "ICON plc", 
-    "60.31", 
-    "$3.71B", 
-    "1998", 
-    "Health Care", 
-    "Biotechnology: Commercial Physical & Biological Resarch", 
-    "http://www.nasdaq.com/symbol/iclr"
-  ], 
-  [
-    "ICON", 
-    "Iconix Brand Group, Inc.", 
-    "34.96", 
-    "$1.68B", 
-    "n/a", 
-    "Consumer Non-Durables", 
-    "Shoe Manufacturing", 
-    "http://www.nasdaq.com/symbol/icon"
-  ], 
-  [
-    "ICPT", 
-    "Intercept Pharmaceuticals, Inc.", 
-    "218.89", 
-    "$4.94B", 
-    "2012", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/icpt"
-  ], 
-  [
-    "ICUI", 
-    "ICU Medical, Inc.", 
-    "87.85", 
-    "$1.35B", 
-    "1992", 
-    "Health Care", 
-    "Medical/Dental Instruments", 
-    "http://www.nasdaq.com/symbol/icui"
-  ], 
-  [
-    "IDCC", 
-    "InterDigital, Inc.", 
-    "51.66", 
-    "$1.92B", 
-    "n/a", 
-    "Miscellaneous", 
-    "Multi-Sector Companies", 
-    "http://www.nasdaq.com/symbol/idcc"
-  ], 
-  [
-    "IDRA", 
-    "Idera Pharmaceuticals, Inc.", 
-    "4.66", 
-    "$549.08M", 
-    "n/a", 
-    "Health Care", 
-    "Biotechnology: Biological Products (No Diagnostic Substances)", 
-    "http://www.nasdaq.com/symbol/idra"
-  ], 
-  [
-    "IDSA", 
-    "Industrial Services of America, Inc.", 
-    "5.7499", 
-    "$45.75M", 
-    "n/a", 
-    "Basic Industries", 
-    "Miscellaneous", 
-    "http://www.nasdaq.com/symbol/idsa"
-  ], 
-  [
-    "IDSY", 
-    "I.D. Systems, Inc.", 
-    "6.73", 
-    "$86.19M", 
-    "1999", 
-    "Consumer Durables", 
-    "Telecommunications Equipment", 
-    "http://www.nasdaq.com/symbol/idsy"
-  ], 
-  [
-    "IDTI", 
-    "Integrated Device Technology, Inc.", 
-    "20.84", 
-    "$3.09B", 
-    "1984", 
-    "Technology", 
-    "Semiconductors", 
-    "http://www.nasdaq.com/symbol/idti"
-  ], 
-  [
-    "IDXX", 
-    "IDEXX Laboratories, Inc.", 
-    "158.15", 
-    "$7.45B", 
-    "1991", 
-    "Health Care", 
-    "Biotechnology: In Vitro & In Vivo Diagnostic Substances", 
-    "http://www.nasdaq.com/symbol/idxx"
-  ], 
-  [
-    "IEP", 
-    "Icahn Enterprises L.P.", 
-    "98.95", 
-    "$12.02B", 
-    "n/a", 
-    "Energy", 
-    "Integrated oil Companies", 
-    "http://www.nasdaq.com/symbol/iep"
-  ], 
-  [
-    "IESC", 
-    "Integrated Electrical Services, Inc.", 
-    "7.96", 
-    "$173.21M", 
-    "n/a", 
-    "Capital Goods", 
-    "Engineering & Construction", 
-    "http://www.nasdaq.com/symbol/iesc"
-  ], 
-  [
-    "IEUS", 
-    "iShares MSCI Europe Small-Cap ETF", 
-    "44.83", 
-    "$38.11M", 
-    "n/a", 
-    "n/a", 
-    "n/a", 
-    "http://www.nasdaq.com/symbol/ieus"
-  ], 
-  [
-    "IFAS", 
-    "iShares FTSE EPRA/NAREIT Asia Index Fund", 
-    "32.16", 
-    "$19.3M", 
-    "n/a", 
-    "n/a", 
-    "n/a", 
-    "http://www.nasdaq.com/symbol/ifas"
-  ], 
-  [
-    "IFEU", 
-    "iShares FTSE EPRA/NAREIT Europe Index Fund", 
-    "40.49", 
-    "$48.59M", 
-    "n/a", 
-    "n/a", 
-    "n/a", 
-    "http://www.nasdaq.com/symbol/ifeu"
-  ], 
-  [
-    "IFGL", 
-    "iShares FTSE EPRA/NAREIT Global Real Estate ex-US Index Fund", 
-    "32.07", 
-    "$997.38M", 
-    "n/a", 
-    "n/a", 
-    "n/a", 
-    "http://www.nasdaq.com/symbol/ifgl"
-  ], 
-  [
-    "IFNA", 
-    "iShares FTSE EPRA/NAREIT North America Index Fund", 
-    "59.748", 
-    "$23.9M", 
-    "n/a", 
-    "n/a", 
-    "n/a", 
-    "http://www.nasdaq.com/symbol/ifna"
-  ], 
-  [
-    "IFON", 
-    "InfoSonics Corp", 
-    "1.78", 
-    "$25.56M", 
-    "n/a", 
-    "Consumer Non-Durables", 
-    "Electronic Components", 
-    "http://www.nasdaq.com/symbol/ifon"
-  ], 
-  [
-    "IFV", 
-    "First Trust Dorsey Wright International Focus 5 ETF", 
-    "19.51", 
-    "$26.34M", 
-    "n/a", 
-    "n/a", 
-    "n/a", 
-    "http://www.nasdaq.com/symbol/ifv"
-  ], 
-  [
-    "IGLD", 
-    "Internet Gold Golden Lines Ltd.", 
-    "4.38", 
-    "$84.11M", 
-    "1999", 
-    "Public Utilities", 
-    "Telecommunications Equipment", 
-    "http://www.nasdaq.com/symbol/igld"
-  ], 
-  [
-    "IGOV", 
-    "iShares S&P/Citigroup International Treasury Bond Fund", 
-    "93.86", 
-    "$483.38M", 
-    "n/a", 
-    "n/a", 
-    "n/a", 
-    "http://www.nasdaq.com/symbol/igov"
-  ], 
-  [
-    "IGTE", 
-    "iGATE Corporation", 
-    "39.32", 
-    "$3.18B", 
-    "n/a", 
-    "Technology", 
-    "EDP Services", 
-    "http://www.nasdaq.com/symbol/igte"
-  ], 
-  [
-    "III", 
-    "Information Services Group, Inc.", 
-    "4.22", 
-    "$154.9M", 
-    "n/a", 
-    "Consumer Services", 
-    "Professional Services", 
-    "http://www.nasdaq.com/symbol/iii"
-  ], 
-  [
-    "IIIN", 
-    "Insteel Industries, Inc.", 
-    "21.5", 
-    "$395.11M", 
-    "n/a", 
-    "Capital Goods", 
-    "Steel/Iron Ore", 
-    "http://www.nasdaq.com/symbol/iiin"
-  ], 
-  [
-    "IIJI", 
-    "Internet Initiative Japan, Inc.", 
-    "9.75", 
-    "$895.87M", 
-    "n/a", 
-    "Technology", 
-    "Computer Software: Programming, Data Processing", 
-    "http://www.nasdaq.com/symbol/iiji"
-  ], 
-  [
-    "IILG", 
-    "Interval Leisure Group, Inc.", 
-    "25.84", 
-    "$1.48B", 
-    "n/a", 
-    "Finance", 
-    "Real Estate", 
-    "http://www.nasdaq.com/symbol/iilg"
-  ], 
-  [
-    "IIN", 
-    "IntriCon Corporation", 
-    "7.85", 
-    "$45.74M", 
-    "n/a", 
-    "Capital Goods", 
-    "Electrical Products", 
-    "http://www.nasdaq.com/symbol/iin"
-  ], 
-  [
-    "IIVI", 
-    "II-VI Incorporated", 
-    "17.54", 
-    "$1.07B", 
-    "1987", 
-    "Capital Goods", 
-    "Electronic Components", 
-    "http://www.nasdaq.com/symbol/iivi"
-  ], 
-  [
-    "IKAN", 
-    "Ikanos Communications, Inc.", 
-    "3.35", 
-    "$46.69M", 
-    "2005", 
-    "Public Utilities", 
-    "Telecommunications Equipment", 
-    "http://www.nasdaq.com/symbol/ikan"
-  ], 
-  [
-    "IKGH", 
-    "Iao Kun Group Holding Company Limited", 
-    "1.39", 
-    "$84.03M", 
-    "n/a", 
-    "Consumer Services", 
-    "Services-Misc. Amusement & Recreation", 
-    "http://www.nasdaq.com/symbol/ikgh"
-  ], 
-  [
-    "IKNX", 
-    "Ikonics Corporation", 
-    "18.15", 
-    "$36.63M", 
-    "n/a", 
-    "Miscellaneous", 
-    "Industrial Machinery/Components", 
-    "http://www.nasdaq.com/symbol/iknx"
-  ], 
-  [
-    "ILMN", 
-    "Illumina, Inc.", 
-    "203.135", 
-    "$29.21B", 
-    "2000", 
-    "Capital Goods", 
-    "Biotechnology: Laboratory Analytical Instruments", 
-    "http://www.nasdaq.com/symbol/ilmn"
-  ], 
-  [
-    "IMDZ", 
-    "Immune Design Corp.", 
-    "24.18", 
-    "$408.13M", 
-    "2014", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/imdz"
-  ], 
-  [
-    "IMGN", 
-    "ImmunoGen, Inc.", 
-    "7.62", 
-    "$656.14M", 
-    "1989", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/imgn"
-  ], 
-  [
-    "IMI", 
-    "Intermolecular, Inc.", 
-    "1.73", 
-    "$82.34M", 
-    "2011", 
-    "Technology", 
-    "Semiconductors", 
-    "http://www.nasdaq.com/symbol/imi"
-  ], 
-  [
-    "IMKTA", 
-    "Ingles Markets, Incorporated", 
-    "42.91", 
-    "$869.35M", 
-    "1987", 
-    "Consumer Services", 
-    "Food Chains", 
-    "http://www.nasdaq.com/symbol/imkta"
-  ], 
-  [
-    "IMMR", 
-    "Immersion Corporation", 
-    "8.8", 
-    "$243.57M", 
-    "1999", 
-    "Technology", 
-    "Computer peripheral equipment", 
-    "http://www.nasdaq.com/symbol/immr"
-  ], 
-  [
-    "IMMU", 
-    "Immunomedics, Inc.", 
-    "3.99", 
-    "$372.61M", 
-    "n/a", 
-    "Health Care", 
-    "Biotechnology: In Vitro & In Vivo Diagnostic Substances", 
-    "http://www.nasdaq.com/symbol/immu"
-  ], 
-  [
-    "IMMY", 
-    "Imprimis Pharmaceuticals, Inc.", 
-    "7.68", 
-    "$71.08M", 
-    "n/a", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/immy"
-  ], 
-  [
-    "IMNP          ", 
-    "Immune Pharmaceuticals Inc.", 
-    "1.81", 
-    "$34.75M", 
-    "n/a", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/imnp          "
-  ], 
-  [
-    "IMOS", 
-    "ChipMOS TECHNOLOGIES (Bermuda) LTD.", 
-    "23.65", 
-    "$699.69M", 
-    "n/a", 
-    "Technology", 
-    "Semiconductors", 
-    "http://www.nasdaq.com/symbol/imos"
-  ], 
-  [
-    "IMRS", 
-    "Imris Inc", 
-    "0.8546", 
-    "$53.49M", 
-    "n/a", 
-    "Health Care", 
-    "Biotechnology: Electromedical & Electrotherapeutic Apparatus", 
-    "http://www.nasdaq.com/symbol/imrs"
-  ], 
-  [
-    "INAP", 
-    "Internap Corporation", 
-    "9.04", 
-    "$386.44M", 
-    "1999", 
-    "Technology", 
-    "Computer Software: Programming, Data Processing", 
-    "http://www.nasdaq.com/symbol/inap"
-  ], 
-  [
-    "INBK", 
-    "First Internet Bancorp", 
-    "16.278", 
-    "$72.27M", 
-    "n/a", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/inbk"
-  ], 
-  [
-    "INCR", 
-    "INC Research Holdings, Inc.", 
-    "25.61", 
-    "$1.57B", 
-    "2014", 
-    "Health Care", 
-    "Biotechnology: Commercial Physical & Biological Resarch", 
-    "http://www.nasdaq.com/symbol/incr"
-  ], 
-  [
-    "INCY", 
-    "Incyte Corporation", 
-    "82.49", 
-    "$14.17B", 
-    "n/a", 
-    "Health Care", 
-    "Biotechnology: Commercial Physical & Biological Resarch", 
-    "http://www.nasdaq.com/symbol/incy"
-  ], 
-  [
-    "INDB", 
-    "Independent Bank Corp.", 
-    "41.81", 
-    "$1B", 
-    "n/a", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/indb"
-  ], 
-  [
-    "INDY", 
-    "iShares S&P India Nifty 50 Index Fund", 
-    "32.8", 
-    "$941.36M", 
-    "n/a", 
-    "n/a", 
-    "n/a", 
-    "http://www.nasdaq.com/symbol/indy"
-  ], 
-  [
-    "INFA", 
-    "Informatica Corporation", 
-    "43.9", 
-    "$4.77B", 
-    "1999", 
-    "Technology", 
-    "Computer Software: Prepackaged Software", 
-    "http://www.nasdaq.com/symbol/infa"
-  ], 
-  [
-    "INFI", 
-    "Infinity Pharmaceuticals, Inc.", 
-    "15.69", 
-    "$765.15M", 
-    "n/a", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/infi"
-  ], 
-  [
-    "INFN", 
-    "Infinera Corporation", 
-    "17.65", 
-    "$2.26B", 
-    "2007", 
-    "Public Utilities", 
-    "Telecommunications Equipment", 
-    "http://www.nasdaq.com/symbol/infn"
-  ], 
-  [
-    "INGN", 
-    "Inogen, Inc", 
-    "33.34", 
-    "$621.09M", 
-    "2014", 
-    "Health Care", 
-    "Industrial Specialties", 
-    "http://www.nasdaq.com/symbol/ingn"
-  ], 
-  [
-    "ININ", 
-    "Interactive Intelligence Group, Inc.", 
-    "42.53", 
-    "$896.87M", 
-    "1999", 
-    "Technology", 
-    "Computer Software: Prepackaged Software", 
-    "http://www.nasdaq.com/symbol/inin"
-  ], 
-  [
-    "INNL", 
-    "Innocoll AG", 
-    "8.01", 
-    "$158.62M", 
-    "2014", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/innl"
-  ], 
-  [
-    "INO", 
-    "Inovio Pharmaceuticals, Inc.", 
-    "6.88", 
-    "$416.87M", 
-    "n/a", 
-    "Health Care", 
-    "Medical/Dental Instruments", 
-    "http://www.nasdaq.com/symbol/ino"
-  ], 
-  [
-    "INOD", 
-    "Innodata Inc.", 
-    "2.7", 
-    "$68.41M", 
-    "1993", 
-    "Technology", 
-    "EDP Services", 
-    "http://www.nasdaq.com/symbol/inod"
-  ], 
-  [
-    "INOV", 
-    "Inovalon Holdings, Inc.", 
-    "29.84", 
-    "$4.31B", 
-    "2015", 
-    "Technology", 
-    "EDP Services", 
-    "http://www.nasdaq.com/symbol/inov"
-  ], 
-  [
-    "INPH", 
-    "Interphase Corporation", 
-    "2.17", 
-    "$18.18M", 
-    "1984", 
-    "Technology", 
-    "Computer Communications Equipment", 
-    "http://www.nasdaq.com/symbol/inph"
-  ], 
-  [
-    "INSM", 
-    "Insmed, Inc.", 
-    "17.58", 
-    "$873.11M", 
-    "n/a", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/insm"
-  ], 
-  [
-    "INSY", 
-    "Insys Therapeutics, Inc.", 
-    "52.42", 
-    "$1.83B", 
-    "2013", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/insy"
-  ], 
-  [
-    "INTC", 
-    "Intel Corporation", 
-    "34.41", 
-    "$162.97B", 
-    "n/a", 
-    "Technology", 
-    "Semiconductors", 
-    "http://www.nasdaq.com/symbol/intc"
-  ], 
-  [
-    "INTG", 
-    "The Intergroup Corporation", 
-    "19.6", 
-    "$46.71M", 
-    "n/a", 
-    "Consumer Services", 
-    "Building operators", 
-    "http://www.nasdaq.com/symbol/intg"
-  ], 
-  [
-    "INTL", 
-    "INTL FCStone Inc.", 
-    "25.2", 
-    "$475.43M", 
-    "n/a", 
-    "Finance", 
-    "Investment Bankers/Brokers/Service", 
-    "http://www.nasdaq.com/symbol/intl"
-  ]
-]
\ No newline at end of file
diff --git a/examples/stocks/data/stock_data_14.json b/examples/stocks/data/stock_data_14.json
deleted file mode 100644
index 6514c95..0000000
--- a/examples/stocks/data/stock_data_14.json
+++ /dev/null
@@ -1,1002 +0,0 @@
-[
-  [
-    "INTLL", 
-    "INTL FCStone Inc.", 
-    "25.76", 
-    "n/a", 
-    "n/a", 
-    "Finance", 
-    "Investment Bankers/Brokers/Service", 
-    "http://www.nasdaq.com/symbol/intll"
-  ], 
-  [
-    "INTU", 
-    "Intuit Inc.", 
-    "96.72", 
-    "$26.76B", 
-    "1993", 
-    "Technology", 
-    "Computer Software: Prepackaged Software", 
-    "http://www.nasdaq.com/symbol/intu"
-  ], 
-  [
-    "INTX", 
-    "Intersections, Inc.", 
-    "3.76", 
-    "$69.68M", 
-    "2004", 
-    "Technology", 
-    "EDP Services", 
-    "http://www.nasdaq.com/symbol/intx"
-  ], 
-  [
-    "INVE", 
-    "Identiv, Inc.", 
-    "11.35", 
-    "$120.79M", 
-    "n/a", 
-    "Technology", 
-    "Computer peripheral equipment", 
-    "http://www.nasdaq.com/symbol/inve"
-  ], 
-  [
-    "INVT", 
-    "Inventergy Global, Inc.", 
-    "0.51", 
-    "$13.66M", 
-    "n/a", 
-    "Public Utilities", 
-    "Telecommunications Equipment", 
-    "http://www.nasdaq.com/symbol/invt"
-  ], 
-  [
-    "INWK", 
-    "InnerWorkings, Inc.", 
-    "6.43", 
-    "$346.48M", 
-    "2006", 
-    "Consumer Durables", 
-    "Containers/Packaging", 
-    "http://www.nasdaq.com/symbol/inwk"
-  ], 
-  [
-    "IOSP", 
-    "Innospec Inc.", 
-    "43.95", 
-    "$1.07B", 
-    "n/a", 
-    "Basic Industries", 
-    "Major Chemicals", 
-    "http://www.nasdaq.com/symbol/iosp"
-  ], 
-  [
-    "IPAR", 
-    "Inter Parfums, Inc.", 
-    "27.31", 
-    "$845.05M", 
-    "n/a", 
-    "Consumer Non-Durables", 
-    "Package Goods/Cosmetics", 
-    "http://www.nasdaq.com/symbol/ipar"
-  ], 
-  [
-    "IPAS", 
-    "iPass Inc.", 
-    "0.9", 
-    "$58.17M", 
-    "2003", 
-    "Technology", 
-    "EDP Services", 
-    "http://www.nasdaq.com/symbol/ipas"
-  ], 
-  [
-    "IPCC", 
-    "Infinity Property and Casualty Corporation", 
-    "75.47", 
-    "$867.55M", 
-    "2003", 
-    "Finance", 
-    "Property-Casualty Insurers", 
-    "http://www.nasdaq.com/symbol/ipcc"
-  ], 
-  [
-    "IPCI", 
-    "Intellipharmaceutics International Inc.", 
-    "2.48", 
-    "$58.17M", 
-    "n/a", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/ipci"
-  ], 
-  [
-    "IPCM", 
-    "IPC Healthcare, Inc.", 
-    "41.71", 
-    "$718.35M", 
-    "2008", 
-    "Health Care", 
-    "Hospital/Nursing Management", 
-    "http://www.nasdaq.com/symbol/ipcm"
-  ], 
-  [
-    "IPDN", 
-    "Professional Diversity Network, Inc.", 
-    "4.88", 
-    "$61.58M", 
-    "2013", 
-    "Technology", 
-    "Computer Software: Programming, Data Processing", 
-    "http://www.nasdaq.com/symbol/ipdn"
-  ], 
-  [
-    "IPGP", 
-    "IPG Photonics Corporation", 
-    "93.28", 
-    "$4.87B", 
-    "2006", 
-    "Technology", 
-    "Semiconductors", 
-    "http://www.nasdaq.com/symbol/ipgp"
-  ], 
-  [
-    "IPHS", 
-    "Innophos Holdings, Inc.", 
-    "56.92", 
-    "$1.21B", 
-    "2006", 
-    "Consumer Durables", 
-    "Specialty Chemicals", 
-    "http://www.nasdaq.com/symbol/iphs"
-  ], 
-  [
-    "IPKW", 
-    "PowerShares International BuyBack Achievers Portfolio", 
-    "26.0535", 
-    "$18.24M", 
-    "n/a", 
-    "n/a", 
-    "n/a", 
-    "http://www.nasdaq.com/symbol/ipkw"
-  ], 
-  [
-    "IPWR", 
-    "Ideal Power Inc.", 
-    "7.82", 
-    "$55.12M", 
-    "2013", 
-    "Energy", 
-    "Industrial Machinery/Components", 
-    "http://www.nasdaq.com/symbol/ipwr"
-  ], 
-  [
-    "IPXL", 
-    "Impax Laboratories, Inc.", 
-    "40.35", 
-    "$2.87B", 
-    "n/a", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/ipxl"
-  ], 
-  [
-    "IQNT", 
-    "Inteliquent, Inc.", 
-    "17.94", 
-    "$594.08M", 
-    "n/a", 
-    "Public Utilities", 
-    "Telecommunications Equipment", 
-    "http://www.nasdaq.com/symbol/iqnt"
-  ], 
-  [
-    "IRBT", 
-    "iRobot Corporation", 
-    "31.46", 
-    "$933.49M", 
-    "2005", 
-    "Consumer Durables", 
-    "Consumer Electronics/Appliances", 
-    "http://www.nasdaq.com/symbol/irbt"
-  ], 
-  [
-    "IRCP", 
-    "IRSA Propiedades Comerciales S.A.", 
-    "23.01", 
-    "$724.9M", 
-    "n/a", 
-    "Consumer Services", 
-    "Building operators", 
-    "http://www.nasdaq.com/symbol/ircp"
-  ], 
-  [
-    "IRDM", 
-    "Iridium Communications Inc", 
-    "9.58", 
-    "$898.05M", 
-    "n/a", 
-    "Consumer Durables", 
-    "Telecommunications Equipment", 
-    "http://www.nasdaq.com/symbol/irdm"
-  ], 
-  [
-    "IRDMB", 
-    "Iridium Communications Inc", 
-    "357.9", 
-    "$178.95M", 
-    "n/a", 
-    "Consumer Durables", 
-    "Telecommunications Equipment", 
-    "http://www.nasdaq.com/symbol/irdmb"
-  ], 
-  [
-    "IRG", 
-    "Ignite Restaurant Group, Inc.", 
-    "7.15", 
-    "$187.34M", 
-    "2012", 
-    "Consumer Services", 
-    "Restaurants", 
-    "http://www.nasdaq.com/symbol/irg"
-  ], 
-  [
-    "IRIX", 
-    "IRIDEX Corporation", 
-    "9.83", 
-    "$96.74M", 
-    "1996", 
-    "Health Care", 
-    "Biotechnology: Electromedical & Electrotherapeutic Apparatus", 
-    "http://www.nasdaq.com/symbol/irix"
-  ], 
-  [
-    "IRMD", 
-    "iRadimed Corporation", 
-    "14.7305", 
-    "$159.31M", 
-    "2014", 
-    "n/a", 
-    "n/a", 
-    "http://www.nasdaq.com/symbol/irmd"
-  ], 
-  [
-    "IROQ", 
-    "IF Bancorp, Inc.", 
-    "16.75", 
-    "$72.68M", 
-    "2011", 
-    "Finance", 
-    "Savings Institutions", 
-    "http://www.nasdaq.com/symbol/iroq"
-  ], 
-  [
-    "IRWD", 
-    "Ironwood Pharmaceuticals, Inc.", 
-    "15.65", 
-    "$2.21B", 
-    "2010", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/irwd"
-  ], 
-  [
-    "ISBC", 
-    "Investors Bancorp, Inc.", 
-    "11.68", 
-    "$4.18B", 
-    "n/a", 
-    "Finance", 
-    "Savings Institutions", 
-    "http://www.nasdaq.com/symbol/isbc"
-  ], 
-  [
-    "ISCA", 
-    "International Speedway Corporation", 
-    "31.98", 
-    "$1.49B", 
-    "1996", 
-    "Consumer Services", 
-    "Services-Misc. Amusement & Recreation", 
-    "http://www.nasdaq.com/symbol/isca"
-  ], 
-  [
-    "ISHG", 
-    "iShares 1-3 Year International Treasury Bond ETF", 
-    "81.41", 
-    "$154.68M", 
-    "n/a", 
-    "n/a", 
-    "n/a", 
-    "http://www.nasdaq.com/symbol/ishg"
-  ], 
-  [
-    "ISIG", 
-    "Insignia Systems, Inc.", 
-    "3.09", 
-    "$37.99M", 
-    "1991", 
-    "Consumer Services", 
-    "Advertising", 
-    "http://www.nasdaq.com/symbol/isig"
-  ], 
-  [
-    "ISIL", 
-    "Intersil Corporation", 
-    "15.36", 
-    "$2B", 
-    "2000", 
-    "Technology", 
-    "Semiconductors", 
-    "http://www.nasdaq.com/symbol/isil"
-  ], 
-  [
-    "ISIS", 
-    "Isis Pharmaceuticals, Inc.", 
-    "67.01", 
-    "$7.92B", 
-    "1991", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/isis"
-  ], 
-  [
-    "ISLE", 
-    "Isle of Capri Casinos, Inc.", 
-    "10.44", 
-    "$417.89M", 
-    "n/a", 
-    "Consumer Services", 
-    "Hotels/Resorts", 
-    "http://www.nasdaq.com/symbol/isle"
-  ], 
-  [
-    "ISM", 
-    "SLM Corporation", 
-    "24.01", 
-    "n/a", 
-    "n/a", 
-    "Finance", 
-    "Finance: Consumer Services", 
-    "http://www.nasdaq.com/symbol/ism"
-  ], 
-  [
-    "ISNS", 
-    "Image Sensing Systems, Inc.", 
-    "2.43", 
-    "$12.12M", 
-    "1995", 
-    "Capital Goods", 
-    "Industrial Machinery/Components", 
-    "http://www.nasdaq.com/symbol/isns"
-  ], 
-  [
-    "ISRG", 
-    "Intuitive Surgical, Inc.", 
-    "513.31", 
-    "$18.79B", 
-    "2000", 
-    "Health Care", 
-    "Industrial Specialties", 
-    "http://www.nasdaq.com/symbol/isrg"
-  ], 
-  [
-    "ISRL", 
-    "Isramco, Inc.", 
-    "123", 
-    "$334.28M", 
-    "1983", 
-    "Energy", 
-    "Oil & Gas Production", 
-    "http://www.nasdaq.com/symbol/isrl"
-  ], 
-  [
-    "ISSC", 
-    "Innovative Solutions and Support, Inc.", 
-    "4.4", 
-    "$74.31M", 
-    "2000", 
-    "Technology", 
-    "EDP Services", 
-    "http://www.nasdaq.com/symbol/issc"
-  ], 
-  [
-    "ISSI", 
-    "Integrated Silicon Solution, Inc.", 
-    "16.4", 
-    "$516.64M", 
-    "1995", 
-    "Technology", 
-    "Semiconductors", 
-    "http://www.nasdaq.com/symbol/issi"
-  ], 
-  [
-    "ISTR", 
-    "Investar Holding Corporation", 
-    "14.6", 
-    "$105.91M", 
-    "2014", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/istr"
-  ], 
-  [
-    "ITCI", 
-    "Intra-Cellular Therapies Inc.", 
-    "25.65", 
-    "$754.04M", 
-    "n/a", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/itci"
-  ], 
-  [
-    "ITEK", 
-    "Inotek Pharmaceuticals Corporation", 
-    "6.09", 
-    "$96.69M", 
-    "2015", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/itek"
-  ], 
-  [
-    "ITIC", 
-    "Investors Title Company", 
-    "73.81", 
-    "$149.75M", 
-    "n/a", 
-    "Finance", 
-    "Specialty Insurers", 
-    "http://www.nasdaq.com/symbol/itic"
-  ], 
-  [
-    "ITRI", 
-    "Itron, Inc.", 
-    "35.13", 
-    "$1.37B", 
-    "1993", 
-    "Capital Goods", 
-    "Electrical Products", 
-    "http://www.nasdaq.com/symbol/itri"
-  ], 
-  [
-    "ITRN", 
-    "Ituran Location and Control Ltd.", 
-    "23.09", 
-    "$542.05M", 
-    "2005", 
-    "Consumer Non-Durables", 
-    "Electronic Components", 
-    "http://www.nasdaq.com/symbol/itrn"
-  ], 
-  [
-    "IVAC", 
-    "Intevac, Inc.", 
-    "7", 
-    "$163.1M", 
-    "1995", 
-    "Technology", 
-    "Industrial Machinery/Components", 
-    "http://www.nasdaq.com/symbol/ivac"
-  ], 
-  [
-    "IVAN", 
-    "Ivanhoe Energy, Inc.", 
-    "0.424", 
-    "$6.96M", 
-    "n/a", 
-    "Energy", 
-    "Oil & Gas Production", 
-    "http://www.nasdaq.com/symbol/ivan"
-  ], 
-  [
-    "IXYS", 
-    "IXYS Corporation", 
-    "12.14", 
-    "$384.22M", 
-    "n/a", 
-    "Technology", 
-    "Semiconductors", 
-    "http://www.nasdaq.com/symbol/ixys"
-  ], 
-  [
-    "JACK", 
-    "Jack In The Box Inc.", 
-    "97.99", 
-    "$3.73B", 
-    "n/a", 
-    "Consumer Services", 
-    "Restaurants", 
-    "http://www.nasdaq.com/symbol/jack"
-  ], 
-  [
-    "JAKK", 
-    "JAKKS Pacific, Inc.", 
-    "6.96", 
-    "$161.92M", 
-    "1996", 
-    "Consumer Non-Durables", 
-    "Recreational Products/Toys", 
-    "http://www.nasdaq.com/symbol/jakk"
-  ], 
-  [
-    "JASN", 
-    "Jason Industries, Inc.", 
-    "8.01", 
-    "$176.15M", 
-    "2013", 
-    "Consumer Durables", 
-    "Miscellaneous manufacturing industries", 
-    "http://www.nasdaq.com/symbol/jasn"
-  ], 
-  [
-    "JASNW", 
-    "Jason Industries, Inc.", 
-    "1.07", 
-    "n/a", 
-    "2013", 
-    "Consumer Durables", 
-    "Miscellaneous manufacturing industries", 
-    "http://www.nasdaq.com/symbol/jasnw"
-  ], 
-  [
-    "JASO", 
-    "JA Solar Holdings, Co., Ltd.", 
-    "8.63", 
-    "$392.66M", 
-    "2007", 
-    "Technology", 
-    "Semiconductors", 
-    "http://www.nasdaq.com/symbol/jaso"
-  ], 
-  [
-    "JAXB", 
-    "Jacksonville Bancorp, Inc.", 
-    "10.4375", 
-    "$60.49M", 
-    "n/a", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/jaxb"
-  ], 
-  [
-    "JAZZ", 
-    "Jazz Pharmaceuticals plc", 
-    "172.42", 
-    "$10.43B", 
-    "2007", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/jazz"
-  ], 
-  [
-    "JBHT", 
-    "J.B. Hunt Transport Services, Inc.", 
-    "85.15", 
-    "$9.98B", 
-    "n/a", 
-    "Transportation", 
-    "Trucking Freight/Courier Services", 
-    "http://www.nasdaq.com/symbol/jbht"
-  ], 
-  [
-    "JBLU", 
-    "JetBlue Airways Corporation", 
-    "17.49", 
-    "$5.44B", 
-    "2002", 
-    "Transportation", 
-    "Air Freight/Delivery Services", 
-    "http://www.nasdaq.com/symbol/jblu"
-  ], 
-  [
-    "JBSS", 
-    "John B. Sanfilippo & Son, Inc.", 
-    "36.04", 
-    "$401.02M", 
-    "1991", 
-    "Consumer Non-Durables", 
-    "Specialty Foods", 
-    "http://www.nasdaq.com/symbol/jbss"
-  ], 
-  [
-    "JCOM", 
-    "j2 Global, Inc.", 
-    "67.16", 
-    "$3.21B", 
-    "1999", 
-    "Technology", 
-    "Telecommunications Equipment", 
-    "http://www.nasdaq.com/symbol/jcom"
-  ], 
-  [
-    "JCS", 
-    "Communications Systems, Inc.", 
-    "11.1", 
-    "$96.05M", 
-    "n/a", 
-    "Public Utilities", 
-    "Telecommunications Equipment", 
-    "http://www.nasdaq.com/symbol/jcs"
-  ], 
-  [
-    "JCTCF", 
-    "Jewett-Cameron Trading Company", 
-    "11.4239", 
-    "$29.54M", 
-    "n/a", 
-    "Consumer Services", 
-    "RETAIL: Building Materials", 
-    "http://www.nasdaq.com/symbol/jctcf"
-  ], 
-  [
-    "JD", 
-    "JD.com, Inc.", 
-    "28.21", 
-    "$38.43B", 
-    "2014", 
-    "Consumer Services", 
-    "Other Specialty Stores", 
-    "http://www.nasdaq.com/symbol/jd"
-  ], 
-  [
-    "JDSU", 
-    "JDS Uniphase Corporation", 
-    "13.53", 
-    "$3.15B", 
-    "n/a", 
-    "Technology", 
-    "Semiconductors", 
-    "http://www.nasdaq.com/symbol/jdsu"
-  ], 
-  [
-    "JGBB", 
-    "WisdomTree Japan Interest Rate Strategy Fund", 
-    "49.4", 
-    "$4.94M", 
-    "n/a", 
-    "n/a", 
-    "n/a", 
-    "http://www.nasdaq.com/symbol/jgbb"
-  ], 
-  [
-    "JIVE", 
-    "Jive Software, Inc.", 
-    "5.01", 
-    "$358.68M", 
-    "2011", 
-    "Technology", 
-    "EDP Services", 
-    "http://www.nasdaq.com/symbol/jive"
-  ], 
-  [
-    "JJSF", 
-    "J & J Snack Foods Corp.", 
-    "100.45", 
-    "$1.88B", 
-    "1986", 
-    "Consumer Non-Durables", 
-    "Specialty Foods", 
-    "http://www.nasdaq.com/symbol/jjsf"
-  ], 
-  [
-    "JKHY", 
-    "Jack Henry & Associates, Inc.", 
-    "67.26", 
-    "$5.5B", 
-    "1985", 
-    "Technology", 
-    "EDP Services", 
-    "http://www.nasdaq.com/symbol/jkhy"
-  ], 
-  [
-    "JMBA", 
-    "Jamba, Inc.", 
-    "14.98", 
-    "$260.7M", 
-    "n/a", 
-    "Consumer Services", 
-    "Restaurants", 
-    "http://www.nasdaq.com/symbol/jmba"
-  ], 
-  [
-    "JOBS", 
-    "51job, Inc.", 
-    "33.77", 
-    "$1.99B", 
-    "2004", 
-    "Technology", 
-    "Diversified Commercial Services", 
-    "http://www.nasdaq.com/symbol/jobs"
-  ], 
-  [
-    "JOEZ", 
-    "Joe&#39;s Jeans Inc.", 
-    "0.21", 
-    "$14.58M", 
-    "n/a", 
-    "Consumer Non-Durables", 
-    "Apparel", 
-    "http://www.nasdaq.com/symbol/joez"
-  ], 
-  [
-    "JOUT", 
-    "Johnson Outdoors Inc.", 
-    "29.5", 
-    "$295.09M", 
-    "n/a", 
-    "Consumer Non-Durables", 
-    "Recreational Products/Toys", 
-    "http://www.nasdaq.com/symbol/jout"
-  ], 
-  [
-    "JRJC", 
-    "China Finance Online Co. Limited", 
-    "5.8655", 
-    "$130.38M", 
-    "2004", 
-    "Miscellaneous", 
-    "Business Services", 
-    "http://www.nasdaq.com/symbol/jrjc"
-  ], 
-  [
-    "JRVR", 
-    "James River Group Holdings, Ltd.", 
-    "21.82", 
-    "$622.75M", 
-    "2014", 
-    "Finance", 
-    "Property-Casualty Insurers", 
-    "http://www.nasdaq.com/symbol/jrvr"
-  ], 
-  [
-    "JSM", 
-    "SLM Corporation", 
-    "22.7", 
-    "n/a", 
-    "n/a", 
-    "Finance", 
-    "Finance: Consumer Services", 
-    "http://www.nasdaq.com/symbol/jsm"
-  ], 
-  [
-    "JST", 
-    "Jinpan International Limited", 
-    "5.3699", 
-    "$88.17M", 
-    "1998", 
-    "Consumer Durables", 
-    "Electrical Products", 
-    "http://www.nasdaq.com/symbol/jst"
-  ], 
-  [
-    "JTPY", 
-    "JetPay Corporation", 
-    "2.62", 
-    "$36.32M", 
-    "2011", 
-    "Finance", 
-    "Business Services", 
-    "http://www.nasdaq.com/symbol/jtpy"
-  ], 
-  [
-    "JUNO", 
-    "Juno Therapeutics, Inc.", 
-    "45.52", 
-    "$4.12B", 
-    "2014", 
-    "Health Care", 
-    "Biotechnology: Biological Products (No Diagnostic Substances)", 
-    "http://www.nasdaq.com/symbol/juno"
-  ], 
-  [
-    "JVA", 
-    "Coffee Holding Co., Inc.", 
-    "5.05", 
-    "$32.6M", 
-    "2005", 
-    "Consumer Non-Durables", 
-    "Food Distributors", 
-    "http://www.nasdaq.com/symbol/jva"
-  ], 
-  [
-    "JXSB", 
-    "Jacksonville Bancorp Inc.", 
-    "23", 
-    "$41.83M", 
-    "n/a", 
-    "Finance", 
-    "Savings Institutions", 
-    "http://www.nasdaq.com/symbol/jxsb"
-  ], 
-  [
-    "JYNT", 
-    "The Joint Corp.", 
-    "7.19", 
-    "$69.92M", 
-    "2014", 
-    "Miscellaneous", 
-    "Multi-Sector Companies", 
-    "http://www.nasdaq.com/symbol/jynt"
-  ], 
-  [
-    "KALU", 
-    "Kaiser Aluminum Corporation", 
-    "75.34", 
-    "$1.34B", 
-    "n/a", 
-    "Capital Goods", 
-    "Metal Fabrications", 
-    "http://www.nasdaq.com/symbol/kalu"
-  ], 
-  [
-    "KANG", 
-    "iKang Healthcare Group, Inc.", 
-    "17.35", 
-    "$1.14B", 
-    "2014", 
-    "Health Care", 
-    "Medical/Nursing Services", 
-    "http://www.nasdaq.com/symbol/kang"
-  ], 
-  [
-    "KBAL", 
-    "Kimball International, Inc.", 
-    "9.27", 
-    "$360.32M", 
-    "n/a", 
-    "Consumer Durables", 
-    "Home Furnishings", 
-    "http://www.nasdaq.com/symbol/kbal"
-  ], 
-  [
-    "KBIO", 
-    "KaloBios Pharmaceuticals, Inc.", 
-    "0.452", 
-    "$14.91M", 
-    "2013", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/kbio"
-  ], 
-  [
-    "KBSF", 
-    "KBS Fashion Group Limited", 
-    "3.65", 
-    "$92.77M", 
-    "2013", 
-    "Consumer Non-Durables", 
-    "Apparel", 
-    "http://www.nasdaq.com/symbol/kbsf"
-  ], 
-  [
-    "KCAP", 
-    "KCAP Financial, Inc.", 
-    "7.33", 
-    "$269.4M", 
-    "2006", 
-    "n/a", 
-    "n/a", 
-    "http://www.nasdaq.com/symbol/kcap"
-  ], 
-  [
-    "KCLI", 
-    "Kansas City Life Insurance Company", 
-    "45.78", 
-    "$498.5M", 
-    "n/a", 
-    "Finance", 
-    "Life Insurance", 
-    "http://www.nasdaq.com/symbol/kcli"
-  ], 
-  [
-    "KE", 
-    "Kimball Electronics, Inc.", 
-    "12.05", 
-    "$351.52M", 
-    "n/a", 
-    "Technology", 
-    "Electrical Products", 
-    "http://www.nasdaq.com/symbol/ke"
-  ], 
-  [
-    "KELYA", 
-    "Kelly Services, Inc.", 
-    "17.68", 
-    "$666.99M", 
-    "n/a", 
-    "Technology", 
-    "Professional Services", 
-    "http://www.nasdaq.com/symbol/kelya"
-  ], 
-  [
-    "KELYB", 
-    "Kelly Services, Inc.", 
-    "17.914", 
-    "$675.82M", 
-    "n/a", 
-    "Technology", 
-    "Professional Services", 
-    "http://www.nasdaq.com/symbol/kelyb"
-  ], 
-  [
-    "KEQU", 
-    "Kewaunee Scientific Corporation", 
-    "17.84", 
-    "$46.86M", 
-    "n/a", 
-    "Capital Goods", 
-    "Medical Specialities", 
-    "http://www.nasdaq.com/symbol/kequ"
-  ], 
-  [
-    "KERX", 
-    "Keryx Biopharmaceuticals, Inc.", 
-    "12.07", 
-    "$1.12B", 
-    "n/a", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/kerx"
-  ], 
-  [
-    "KEYW", 
-    "The KEYW Holding Corporation", 
-    "8.77", 
-    "$329.67M", 
-    "2010", 
-    "Technology", 
-    "EDP Services", 
-    "http://www.nasdaq.com/symbol/keyw"
-  ], 
-  [
-    "KFFB", 
-    "Kentucky First Federal Bancorp", 
-    "7.98", 
-    "$67.49M", 
-    "n/a", 
-    "Finance", 
-    "Savings Institutions", 
-    "http://www.nasdaq.com/symbol/kffb"
-  ], 
-  [
-    "KFRC", 
-    "Kforce, Inc.", 
-    "23.57", 
-    "$720.95M", 
-    "1995", 
-    "Technology", 
-    "Professional Services", 
-    "http://www.nasdaq.com/symbol/kfrc"
-  ], 
-  [
-    "KFX", 
-    "Kofax Limited", 
-    "6.79", 
-    "$626.01M", 
-    "2013", 
-    "Technology", 
-    "Computer Software: Programming, Data Processing", 
-    "http://www.nasdaq.com/symbol/kfx"
-  ], 
-  [
-    "KGJI", 
-    "Kingold Jewelry Inc.", 
-    "1.06", 
-    "$69.91M", 
-    "n/a", 
-    "Miscellaneous", 
-    "Business Services", 
-    "http://www.nasdaq.com/symbol/kgji"
-  ], 
-  [
-    "KIN", 
-    "Kindred Biosciences, Inc.", 
-    "6.77", 
-    "$133.53M", 
-    "2013", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/kin"
-  ]
-]
\ No newline at end of file
diff --git a/examples/stocks/data/stock_data_15.json b/examples/stocks/data/stock_data_15.json
deleted file mode 100644
index 8666c06..0000000
--- a/examples/stocks/data/stock_data_15.json
+++ /dev/null
@@ -1,1002 +0,0 @@
-[
-  [
-    "KINS", 
-    "Kingstone Companies, Inc", 
-    "7.5499", 
-    "$55.08M", 
-    "n/a", 
-    "Finance", 
-    "Property-Casualty Insurers", 
-    "http://www.nasdaq.com/symbol/kins"
-  ], 
-  [
-    "KIRK", 
-    "Kirkland&#39;s, Inc.", 
-    "24.45", 
-    "$419.23M", 
-    "2002", 
-    "Consumer Services", 
-    "Other Specialty Stores", 
-    "http://www.nasdaq.com/symbol/kirk"
-  ], 
-  [
-    "KITE", 
-    "Kite Pharma, Inc.", 
-    "62.8", 
-    "$2.66B", 
-    "2014", 
-    "Health Care", 
-    "Biotechnology: Biological Products (No Diagnostic Substances)", 
-    "http://www.nasdaq.com/symbol/kite"
-  ], 
-  [
-    "KLAC", 
-    "KLA-Tencor Corporation", 
-    "64.97", 
-    "$10.57B", 
-    "1980", 
-    "Capital Goods", 
-    "Electronic Components", 
-    "http://www.nasdaq.com/symbol/klac"
-  ], 
-  [
-    "KLIC", 
-    "Kulicke and Soffa Industries, Inc.", 
-    "16.06", 
-    "$1.23B", 
-    "n/a", 
-    "Technology", 
-    "Semiconductors", 
-    "http://www.nasdaq.com/symbol/klic"
-  ], 
-  [
-    "KLXI", 
-    "KLX Inc.", 
-    "39.28", 
-    "n/a", 
-    "n/a", 
-    "Capital Goods", 
-    "Aerospace", 
-    "http://www.nasdaq.com/symbol/klxi"
-  ], 
-  [
-    "KMDA", 
-    "Kamada Ltd.", 
-    "4.57", 
-    "$164.47M", 
-    "2013", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/kmda"
-  ], 
-  [
-    "KNDI", 
-    "Kandi Technologies Group, Inc.", 
-    "13.62", 
-    "$630.26M", 
-    "n/a", 
-    "Capital Goods", 
-    "Auto Manufacturing", 
-    "http://www.nasdaq.com/symbol/kndi"
-  ], 
-  [
-    "KONA", 
-    "Kona Grill, Inc.", 
-    "25.19", 
-    "$278.05M", 
-    "2005", 
-    "Consumer Services", 
-    "Restaurants", 
-    "http://www.nasdaq.com/symbol/kona"
-  ], 
-  [
-    "KONE", 
-    "Kingtone Wirelessinfo Solution Holding Ltd", 
-    "3.38", 
-    "$4.75M", 
-    "2010", 
-    "Technology", 
-    "EDP Services", 
-    "http://www.nasdaq.com/symbol/kone"
-  ], 
-  [
-    "KOOL", 
-    "Cesca Therapeutics Inc.", 
-    "0.938", 
-    "$37.79M", 
-    "n/a", 
-    "Capital Goods", 
-    "Medical Specialities", 
-    "http://www.nasdaq.com/symbol/kool"
-  ], 
-  [
-    "KOPN", 
-    "Kopin Corporation", 
-    "3.9", 
-    "$257.04M", 
-    "1992", 
-    "Technology", 
-    "Semiconductors", 
-    "http://www.nasdaq.com/symbol/kopn"
-  ], 
-  [
-    "KOSS", 
-    "Koss Corporation", 
-    "1.93", 
-    "$14.25M", 
-    "n/a", 
-    "Consumer Non-Durables", 
-    "Consumer Electronics/Appliances", 
-    "http://www.nasdaq.com/symbol/koss"
-  ], 
-  [
-    "KPTI", 
-    "Karyopharm Therapeutics Inc.", 
-    "27.55", 
-    "$900.97M", 
-    "2013", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/kpti"
-  ], 
-  [
-    "KRFT", 
-    "Kraft Foods Group, Inc.", 
-    "64.42", 
-    "$37.88B", 
-    "n/a", 
-    "Consumer Non-Durables", 
-    "Packaged Foods", 
-    "http://www.nasdaq.com/symbol/krft"
-  ], 
-  [
-    "KRNY", 
-    "Kearny Financial", 
-    "13.38", 
-    "$901.48M", 
-    "n/a", 
-    "Finance", 
-    "Savings Institutions", 
-    "http://www.nasdaq.com/symbol/krny"
-  ], 
-  [
-    "KTCC", 
-    "Key Tronic Corporation", 
-    "9.79", 
-    "$103.3M", 
-    "1983", 
-    "Technology", 
-    "Computer peripheral equipment", 
-    "http://www.nasdaq.com/symbol/ktcc"
-  ], 
-  [
-    "KTEC", 
-    "Key Technology, Inc.", 
-    "12.53", 
-    "$78.17M", 
-    "1993", 
-    "Technology", 
-    "Industrial Machinery/Components", 
-    "http://www.nasdaq.com/symbol/ktec"
-  ], 
-  [
-    "KTOS", 
-    "Kratos Defense & Security Solutions, Inc.", 
-    "5.84", 
-    "$337.53M", 
-    "n/a", 
-    "Capital Goods", 
-    "Military/Government/Technical", 
-    "http://www.nasdaq.com/symbol/ktos"
-  ], 
-  [
-    "KTWO", 
-    "K2M Group Holdings, Inc.", 
-    "19.49", 
-    "$769.17M", 
-    "2014", 
-    "Health Care", 
-    "Medical/Dental Instruments", 
-    "http://www.nasdaq.com/symbol/ktwo"
-  ], 
-  [
-    "KUTV", 
-    "Ku6 Media Co., Ltd.", 
-    "0.9201", 
-    "$43.76M", 
-    "n/a", 
-    "Consumer Services", 
-    "Telecommunications Equipment", 
-    "http://www.nasdaq.com/symbol/kutv"
-  ], 
-  [
-    "KVHI", 
-    "KVH Industries, Inc.", 
-    "12.86", 
-    "$204.62M", 
-    "1996", 
-    "Technology", 
-    "Radio And Television Broadcasting And Communications Equipment", 
-    "http://www.nasdaq.com/symbol/kvhi"
-  ], 
-  [
-    "KWEB", 
-    "KraneShares CSI China Internet ETF", 
-    "33.58", 
-    "$94.02M", 
-    "n/a", 
-    "n/a", 
-    "n/a", 
-    "http://www.nasdaq.com/symbol/kweb"
-  ], 
-  [
-    "KYTH", 
-    "Kythera Biopharmaceuticals, Inc.", 
-    "43.43", 
-    "$984.79M", 
-    "2012", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/kyth"
-  ], 
-  [
-    "KZ", 
-    "KongZhong Corporation", 
-    "5.21", 
-    "$238.99M", 
-    "n/a", 
-    "Technology", 
-    "Telecommunications Equipment", 
-    "http://www.nasdaq.com/symbol/kz"
-  ], 
-  [
-    "LABC", 
-    "Louisiana Bancorp, Inc.", 
-    "22", 
-    "$61.52M", 
-    "n/a", 
-    "Finance", 
-    "Savings Institutions", 
-    "http://www.nasdaq.com/symbol/labc"
-  ], 
-  [
-    "LABL", 
-    "Multi-Color Corporation", 
-    "66.42", 
-    "$1.1B", 
-    "1987", 
-    "Miscellaneous", 
-    "Publishing", 
-    "http://www.nasdaq.com/symbol/labl"
-  ], 
-  [
-    "LACO", 
-    "Lakes Entertainment, Inc.", 
-    "8.45", 
-    "$113.14M", 
-    "n/a", 
-    "Consumer Services", 
-    "Services-Misc. Amusement & Recreation", 
-    "http://www.nasdaq.com/symbol/laco"
-  ], 
-  [
-    "LAKE", 
-    "Lakeland Industries, Inc.", 
-    "10", 
-    "$70.47M", 
-    "1986", 
-    "Health Care", 
-    "Industrial Specialties", 
-    "http://www.nasdaq.com/symbol/lake"
-  ], 
-  [
-    "LALT", 
-    "PowerShares Multi-Strategy Alternative Portfolio", 
-    "23.28", 
-    "$20.95M", 
-    "n/a", 
-    "n/a", 
-    "n/a", 
-    "http://www.nasdaq.com/symbol/lalt"
-  ], 
-  [
-    "LAMR", 
-    "Lamar Advertising Company", 
-    "58.24", 
-    "$6.41B", 
-    "1996", 
-    "Consumer Services", 
-    "Real Estate Investment Trusts", 
-    "http://www.nasdaq.com/symbol/lamr"
-  ], 
-  [
-    "LANC", 
-    "Lancaster Colony Corporation", 
-    "90.76", 
-    "$2.48B", 
-    "n/a", 
-    "Consumer Non-Durables", 
-    "Packaged Foods", 
-    "http://www.nasdaq.com/symbol/lanc"
-  ], 
-  [
-    "LAND", 
-    "Gladstone Land Corporation", 
-    "10.6", 
-    "$82.19M", 
-    "1993", 
-    "Consumer Services", 
-    "Real Estate Investment Trusts", 
-    "http://www.nasdaq.com/symbol/land"
-  ], 
-  [
-    "LARK", 
-    "Landmark Bancorp Inc.", 
-    "23.98", 
-    "$76.13M", 
-    "n/a", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/lark"
-  ], 
-  [
-    "LAWS", 
-    "Lawson Products, Inc.", 
-    "24.65", 
-    "$214.61M", 
-    "n/a", 
-    "Consumer Durables", 
-    "Industrial Specialties", 
-    "http://www.nasdaq.com/symbol/laws"
-  ], 
-  [
-    "LAYN", 
-    "Layne Christensen Company", 
-    "7.6", 
-    "$150.02M", 
-    "1992", 
-    "Basic Industries", 
-    "Engineering & Construction", 
-    "http://www.nasdaq.com/symbol/layn"
-  ], 
-  [
-    "LBAI", 
-    "Lakeland Bancorp, Inc.", 
-    "11.1", 
-    "$420.81M", 
-    "n/a", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/lbai"
-  ], 
-  [
-    "LBIX", 
-    "Leading Brands Inc", 
-    "2.86", 
-    "$8.38M", 
-    "n/a", 
-    "Consumer Non-Durables", 
-    "Beverages (Production/Distribution)", 
-    "http://www.nasdaq.com/symbol/lbix"
-  ], 
-  [
-    "LBRDA", 
-    "Liberty Broadband Corporation", 
-    "50.61", 
-    "$4.4B", 
-    "n/a", 
-    "Consumer Services", 
-    "Television Services", 
-    "http://www.nasdaq.com/symbol/lbrda"
-  ], 
-  [
-    "LBRDK", 
-    "Liberty Broadband Corporation", 
-    "50.28", 
-    "$4.37B", 
-    "n/a", 
-    "Consumer Services", 
-    "Television Services", 
-    "http://www.nasdaq.com/symbol/lbrdk"
-  ], 
-  [
-    "LBTYA", 
-    "Liberty Global plc", 
-    "53.25", 
-    "$47.24B", 
-    "n/a", 
-    "Consumer Services", 
-    "Television Services", 
-    "http://www.nasdaq.com/symbol/lbtya"
-  ], 
-  [
-    "LBTYB", 
-    "Liberty Global plc", 
-    "52.79", 
-    "$46.83B", 
-    "n/a", 
-    "Consumer Services", 
-    "Television Services", 
-    "http://www.nasdaq.com/symbol/lbtyb"
-  ], 
-  [
-    "LBTYK", 
-    "Liberty Global plc", 
-    "51.65", 
-    "$45.82B", 
-    "n/a", 
-    "Consumer Services", 
-    "Television Services", 
-    "http://www.nasdaq.com/symbol/lbtyk"
-  ], 
-  [
-    "LCNB", 
-    "LCNB Corporation", 
-    "15.12", 
-    "$140.7M", 
-    "n/a", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/lcnb"
-  ], 
-  [
-    "LCUT", 
-    "Lifetime Brands, Inc.", 
-    "16.06", 
-    "$219.76M", 
-    "1991", 
-    "Capital Goods", 
-    "Industrial Machinery/Components", 
-    "http://www.nasdaq.com/symbol/lcut"
-  ], 
-  [
-    "LDRH", 
-    "LDR Holding Corporation", 
-    "37.7", 
-    "$982.34M", 
-    "2013", 
-    "Health Care", 
-    "Medical/Dental Instruments", 
-    "http://www.nasdaq.com/symbol/ldrh"
-  ], 
-  [
-    "LDRI", 
-    "PowerShares LadderRite 0-5 Year Corporate Bond Portfolio", 
-    "25.0299", 
-    "$5.01M", 
-    "n/a", 
-    "n/a", 
-    "n/a", 
-    "http://www.nasdaq.com/symbol/ldri"
-  ], 
-  [
-    "LE", 
-    "Lands&#39; End, Inc.", 
-    "35.32", 
-    "$1.13B", 
-    "n/a", 
-    "Consumer Services", 
-    "Clothing/Shoe/Accessory Stores", 
-    "http://www.nasdaq.com/symbol/le"
-  ], 
-  [
-    "LECO", 
-    "Lincoln Electric Holdings, Inc.", 
-    "70.175", 
-    "$5.45B", 
-    "n/a", 
-    "Technology", 
-    "Industrial Machinery/Components", 
-    "http://www.nasdaq.com/symbol/leco"
-  ], 
-  [
-    "LEDS", 
-    "SemiLEDS Corporation", 
-    "1.36", 
-    "$38.66M", 
-    "2010", 
-    "Technology", 
-    "Semiconductors", 
-    "http://www.nasdaq.com/symbol/leds"
-  ], 
-  [
-    "LENS", 
-    "Presbia PLC", 
-    "7.125", 
-    "$95M", 
-    "2015", 
-    "Health Care", 
-    "Medical/Dental Instruments", 
-    "http://www.nasdaq.com/symbol/lens"
-  ], 
-  [
-    "LEVY", 
-    "Levy Acquisition Corp.", 
-    "9.9899", 
-    "$187.31M", 
-    "2014", 
-    "Finance", 
-    "Business Services", 
-    "http://www.nasdaq.com/symbol/levy"
-  ], 
-  [
-    "LEVYU", 
-    "Levy Acquisition Corp.", 
-    "10.33", 
-    "$193.69M", 
-    "2013", 
-    "Finance", 
-    "Business Services", 
-    "http://www.nasdaq.com/symbol/levyu"
-  ], 
-  [
-    "LEVYW", 
-    "Levy Acquisition Corp.", 
-    "0.6", 
-    "n/a", 
-    "2014", 
-    "Finance", 
-    "Business Services", 
-    "http://www.nasdaq.com/symbol/levyw"
-  ], 
-  [
-    "LFUS", 
-    "Littelfuse, Inc.", 
-    "98.71", 
-    "$2.22B", 
-    "n/a", 
-    "Consumer Durables", 
-    "Electrical Products", 
-    "http://www.nasdaq.com/symbol/lfus"
-  ], 
-  [
-    "LFVN", 
-    "Lifevantage Corporation", 
-    "1", 
-    "$98.22M", 
-    "n/a", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/lfvn"
-  ], 
-  [
-    "LGCY", 
-    "Legacy Reserves LP", 
-    "12.84", 
-    "$888.09M", 
-    "2007", 
-    "Energy", 
-    "Oil & Gas Production", 
-    "http://www.nasdaq.com/symbol/lgcy"
-  ], 
-  [
-    "LGCYO", 
-    "Legacy Reserves LP", 
-    "20.6", 
-    "$144.2M", 
-    "n/a", 
-    "Energy", 
-    "Oil & Gas Production", 
-    "http://www.nasdaq.com/symbol/lgcyo"
-  ], 
-  [
-    "LGCYP", 
-    "Legacy Reserves LP", 
-    "20.34", 
-    "$40.68M", 
-    "n/a", 
-    "Energy", 
-    "Oil & Gas Production", 
-    "http://www.nasdaq.com/symbol/lgcyp"
-  ], 
-  [
-    "LGIH", 
-    "LGI Homes, Inc.", 
-    "13.7", 
-    "$284.46M", 
-    "2013", 
-    "Capital Goods", 
-    "Homebuilding", 
-    "http://www.nasdaq.com/symbol/lgih"
-  ], 
-  [
-    "LGND", 
-    "Ligand Pharmaceuticals Incorporated", 
-    "57.54", 
-    "$1.13B", 
-    "n/a", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/lgnd"
-  ], 
-  [
-    "LHCG", 
-    "LHC Group", 
-    "29.27", 
-    "$520.96M", 
-    "2005", 
-    "Health Care", 
-    "Medical/Nursing Services", 
-    "http://www.nasdaq.com/symbol/lhcg"
-  ], 
-  [
-    "LIME", 
-    "Lime Energy Co.", 
-    "2.4", 
-    "$22.69M", 
-    "n/a", 
-    "Basic Industries", 
-    "Engineering & Construction", 
-    "http://www.nasdaq.com/symbol/lime"
-  ], 
-  [
-    "LINC", 
-    "Lincoln Educational Services Corporation", 
-    "2.22", 
-    "$53.4M", 
-    "2005", 
-    "Consumer Services", 
-    "Other Consumer Services", 
-    "http://www.nasdaq.com/symbol/linc"
-  ], 
-  [
-    "LINE", 
-    "Linn Energy, LLC", 
-    "12.75", 
-    "$4.28B", 
-    "2006", 
-    "Energy", 
-    "Oil & Gas Production", 
-    "http://www.nasdaq.com/symbol/line"
-  ], 
-  [
-    "LION", 
-    "Fidelity Southern Corporation", 
-    "15.84", 
-    "$337.83M", 
-    "n/a", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/lion"
-  ], 
-  [
-    "LIOX", 
-    "Lionbridge Technologies, Inc.", 
-    "5.86", 
-    "$373.77M", 
-    "1999", 
-    "Miscellaneous", 
-    "Business Services", 
-    "http://www.nasdaq.com/symbol/liox"
-  ], 
-  [
-    "LIQD", 
-    "Liquid Holdings Group, Inc.", 
-    "0.3625", 
-    "$21.87M", 
-    "2013", 
-    "Technology", 
-    "Computer Software: Prepackaged Software", 
-    "http://www.nasdaq.com/symbol/liqd"
-  ], 
-  [
-    "LIVE", 
-    "LiveDeal, Inc.", 
-    "3.14", 
-    "$50.22M", 
-    "n/a", 
-    "Technology", 
-    "EDP Services", 
-    "http://www.nasdaq.com/symbol/live"
-  ], 
-  [
-    "LJPC", 
-    "La Jolla Pharmaceutical Company", 
-    "18.69", 
-    "$284.57M", 
-    "1994", 
-    "Health Care", 
-    "Biotechnology: Biological Products (No Diagnostic Substances)", 
-    "http://www.nasdaq.com/symbol/ljpc"
-  ], 
-  [
-    "LKFN", 
-    "Lakeland Financial Corporation", 
-    "39.18", 
-    "$648.35M", 
-    "n/a", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/lkfn"
-  ], 
-  [
-    "LKQ", 
-    "LKQ Corporation", 
-    "27.38", 
-    "$8.3B", 
-    "n/a", 
-    "Consumer Services", 
-    "Motor Vehicles", 
-    "http://www.nasdaq.com/symbol/lkq"
-  ], 
-  [
-    "LLEX", 
-    "Lilis Energy, Inc.", 
-    "1.06", 
-    "$29.34M", 
-    "n/a", 
-    "Energy", 
-    "Oil & Gas Production", 
-    "http://www.nasdaq.com/symbol/llex"
-  ], 
-  [
-    "LLNW", 
-    "Limelight Networks, Inc.", 
-    "3.25", 
-    "$319.51M", 
-    "2007", 
-    "Miscellaneous", 
-    "Business Services", 
-    "http://www.nasdaq.com/symbol/llnw"
-  ], 
-  [
-    "LLTC", 
-    "Linear Technology Corporation", 
-    "48.25", 
-    "$11.54B", 
-    "1986", 
-    "Technology", 
-    "Semiconductors", 
-    "http://www.nasdaq.com/symbol/lltc"
-  ], 
-  [
-    "LMAT", 
-    "LeMaitre Vascular, Inc.", 
-    "7.63", 
-    "$132.54M", 
-    "2006", 
-    "Health Care", 
-    "Medical/Dental Instruments", 
-    "http://www.nasdaq.com/symbol/lmat"
-  ], 
-  [
-    "LMBS", 
-    "First Trust Low Duration Mortgage Opportunities ETF", 
-    "50.64", 
-    "n/a", 
-    "n/a", 
-    "n/a", 
-    "n/a", 
-    "http://www.nasdaq.com/symbol/lmbs"
-  ], 
-  [
-    "LMCA", 
-    "Liberty Media Corporation", 
-    "38.5", 
-    "$13.21B", 
-    "n/a", 
-    "Consumer Services", 
-    "Broadcasting", 
-    "http://www.nasdaq.com/symbol/lmca"
-  ], 
-  [
-    "LMCB", 
-    "Liberty Media Corporation", 
-    "39.391", 
-    "$13.51B", 
-    "n/a", 
-    "Consumer Services", 
-    "Broadcasting", 
-    "http://www.nasdaq.com/symbol/lmcb"
-  ], 
-  [
-    "LMCK", 
-    "Liberty Media Corporation", 
-    "38.49", 
-    "$13.2B", 
-    "n/a", 
-    "Consumer Services", 
-    "Broadcasting", 
-    "http://www.nasdaq.com/symbol/lmck"
-  ], 
-  [
-    "LMIA", 
-    "LMI Aerospace, Inc.", 
-    "14.38", 
-    "$182.6M", 
-    "1998", 
-    "Capital Goods", 
-    "Military/Government/Technical", 
-    "http://www.nasdaq.com/symbol/lmia"
-  ], 
-  [
-    "LMNR", 
-    "Limoneira Co", 
-    "20.66", 
-    "$291.51M", 
-    "n/a", 
-    "Consumer Non-Durables", 
-    "Farming/Seeds/Milling", 
-    "http://www.nasdaq.com/symbol/lmnr"
-  ], 
-  [
-    "LMNS", 
-    "Lumenis Ltd.", 
-    "11.3", 
-    "$398.23M", 
-    "2014", 
-    "Health Care", 
-    "Medical Specialities", 
-    "http://www.nasdaq.com/symbol/lmns"
-  ], 
-  [
-    "LMNX", 
-    "Luminex Corporation", 
-    "15.8", 
-    "$676.76M", 
-    "2000", 
-    "Health Care", 
-    "Medical/Dental Instruments", 
-    "http://www.nasdaq.com/symbol/lmnx"
-  ], 
-  [
-    "LMOS", 
-    "Lumos Networks Corp.", 
-    "18.04", 
-    "$405.4M", 
-    "n/a", 
-    "Public Utilities", 
-    "Telecommunications Equipment", 
-    "http://www.nasdaq.com/symbol/lmos"
-  ], 
-  [
-    "LMRK", 
-    "Landmark Infrastructure Partners LP", 
-    "16.66", 
-    "$130.58M", 
-    "2014", 
-    "Consumer Services", 
-    "Real Estate", 
-    "http://www.nasdaq.com/symbol/lmrk"
-  ], 
-  [
-    "LNBB", 
-    "LNB Bancorp, Inc.", 
-    "17.61", 
-    "$170.21M", 
-    "n/a", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/lnbb"
-  ], 
-  [
-    "LNCE", 
-    "Snyder&#39;s-Lance, Inc.", 
-    "30.77", 
-    "$2.16B", 
-    "n/a", 
-    "Consumer Non-Durables", 
-    "Specialty Foods", 
-    "http://www.nasdaq.com/symbol/lnce"
-  ], 
-  [
-    "LNCO", 
-    "Linn Co, LLC", 
-    "12.01", 
-    "$1.54B", 
-    "2012", 
-    "Energy", 
-    "Oil & Gas Production", 
-    "http://www.nasdaq.com/symbol/lnco"
-  ], 
-  [
-    "LNDC", 
-    "Landec Corporation", 
-    "14.16", 
-    "$380.56M", 
-    "1996", 
-    "Basic Industries", 
-    "Major Chemicals", 
-    "http://www.nasdaq.com/symbol/lndc"
-  ], 
-  [
-    "LOAN", 
-    "Manhattan Bridge Capital, Inc", 
-    "3.52", 
-    "$21.33M", 
-    "n/a", 
-    "Consumer Services", 
-    "Real Estate Investment Trusts", 
-    "http://www.nasdaq.com/symbol/loan"
-  ], 
-  [
-    "LOCM", 
-    "Local Corporation", 
-    "0.6701", 
-    "$15.57M", 
-    "n/a", 
-    "Miscellaneous", 
-    "Business Services", 
-    "http://www.nasdaq.com/symbol/locm"
-  ], 
-  [
-    "LOCO", 
-    "El Pollo Loco Holdings, Inc.", 
-    "24.78", 
-    "$915.59M", 
-    "2014", 
-    "Consumer Services", 
-    "Restaurants", 
-    "http://www.nasdaq.com/symbol/loco"
-  ], 
-  [
-    "LOGI", 
-    "Logitech International S.A.", 
-    "14.84", 
-    "$2.44B", 
-    "1997", 
-    "Technology", 
-    "Computer peripheral equipment", 
-    "http://www.nasdaq.com/symbol/logi"
-  ], 
-  [
-    "LOGM", 
-    "LogMein, Inc.", 
-    "53.54", 
-    "$1.31B", 
-    "2009", 
-    "Technology", 
-    "Computer Software: Prepackaged Software", 
-    "http://www.nasdaq.com/symbol/logm"
-  ], 
-  [
-    "LOJN", 
-    "LoJack Corporation", 
-    "2.47", 
-    "$46.34M", 
-    "n/a", 
-    "Consumer Durables", 
-    "Telecommunications Equipment", 
-    "http://www.nasdaq.com/symbol/lojn"
-  ], 
-  [
-    "LONG", 
-    "eLong, Inc.", 
-    "16.71", 
-    "$588.52M", 
-    "2004", 
-    "Consumer Services", 
-    "Transportation Services", 
-    "http://www.nasdaq.com/symbol/long"
-  ], 
-  [
-    "LOOK", 
-    "LookSmart, Ltd.", 
-    "0.7132", 
-    "$4.11M", 
-    "1999", 
-    "Technology", 
-    "EDP Services", 
-    "http://www.nasdaq.com/symbol/look"
-  ], 
-  [
-    "LOPE", 
-    "Grand Canyon Education, Inc.", 
-    "46.68", 
-    "$2.18B", 
-    "2008", 
-    "Consumer Services", 
-    "Other Consumer Services", 
-    "http://www.nasdaq.com/symbol/lope"
-  ], 
-  [
-    "LORL", 
-    "Loral Space and Communications, Inc.", 
-    "72.67", 
-    "$2.25B", 
-    "n/a", 
-    "Technology", 
-    "Radio And Television Broadcasting And Communications Equipment", 
-    "http://www.nasdaq.com/symbol/lorl"
-  ]
-]
\ No newline at end of file
diff --git a/examples/stocks/data/stock_data_16.json b/examples/stocks/data/stock_data_16.json
deleted file mode 100644
index 0a53a77..0000000
--- a/examples/stocks/data/stock_data_16.json
+++ /dev/null
@@ -1,1002 +0,0 @@
-[
-  [
-    "LOXO", 
-    "Loxo Oncology, Inc.", 
-    "13.66", 
-    "$227.22M", 
-    "2014", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/loxo"
-  ], 
-  [
-    "LPCN", 
-    "Lipocine Inc.", 
-    "6.0801", 
-    "$77.74M", 
-    "n/a", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/lpcn"
-  ], 
-  [
-    "LPHI", 
-    "Life Partners Holdings Inc", 
-    "0.19", 
-    "$3.54M", 
-    "n/a", 
-    "Finance", 
-    "Life Insurance", 
-    "http://www.nasdaq.com/symbol/lphi"
-  ], 
-  [
-    "LPLA", 
-    "LPL Financial Holdings Inc.", 
-    "45.69", 
-    "$4.51B", 
-    "2010", 
-    "Finance", 
-    "Investment Bankers/Brokers/Service", 
-    "http://www.nasdaq.com/symbol/lpla"
-  ], 
-  [
-    "LPNT", 
-    "LifePoint Hospitals, Inc.", 
-    "70.18", 
-    "$3.1B", 
-    "n/a", 
-    "Health Care", 
-    "Hospital/Nursing Management", 
-    "http://www.nasdaq.com/symbol/lpnt"
-  ], 
-  [
-    "LPSB", 
-    "LaPorte Bancorp, Inc.", 
-    "13.05", 
-    "$74.74M", 
-    "n/a", 
-    "Finance", 
-    "Savings Institutions", 
-    "http://www.nasdaq.com/symbol/lpsb"
-  ], 
-  [
-    "LPSN", 
-    "LivePerson, Inc.", 
-    "11.44", 
-    "$625.23M", 
-    "2000", 
-    "Technology", 
-    "Computer Software: Prepackaged Software", 
-    "http://www.nasdaq.com/symbol/lpsn"
-  ], 
-  [
-    "LPTH", 
-    "LightPath Technologies, Inc.", 
-    "0.9921", 
-    "$15.11M", 
-    "1996", 
-    "Technology", 
-    "Semiconductors", 
-    "http://www.nasdaq.com/symbol/lpth"
-  ], 
-  [
-    "LPTN", 
-    "Lpath, Inc.", 
-    "3.04", 
-    "$58.6M", 
-    "n/a", 
-    "Health Care", 
-    "Biotechnology: Biological Products (No Diagnostic Substances)", 
-    "http://www.nasdaq.com/symbol/lptn"
-  ], 
-  [
-    "LQDT", 
-    "Liquidity Services, Inc.", 
-    "9.62", 
-    "$288.39M", 
-    "2006", 
-    "Miscellaneous", 
-    "Business Services", 
-    "http://www.nasdaq.com/symbol/lqdt"
-  ], 
-  [
-    "LRAD", 
-    "LRAD Corporation", 
-    "2.62", 
-    "$87.1M", 
-    "n/a", 
-    "Consumer Non-Durables", 
-    "Consumer Electronics/Appliances", 
-    "http://www.nasdaq.com/symbol/lrad"
-  ], 
-  [
-    "LRCX", 
-    "Lam Research Corporation", 
-    "83.84", 
-    "$13.36B", 
-    "1984", 
-    "Technology", 
-    "Industrial Machinery/Components", 
-    "http://www.nasdaq.com/symbol/lrcx"
-  ], 
-  [
-    "LSBK", 
-    "Lake Shore Bancorp, Inc.", 
-    "13.95", 
-    "$82.85M", 
-    "n/a", 
-    "Finance", 
-    "Savings Institutions", 
-    "http://www.nasdaq.com/symbol/lsbk"
-  ], 
-  [
-    "LSCC", 
-    "Lattice Semiconductor Corporation", 
-    "6.33", 
-    "$747.15M", 
-    "n/a", 
-    "Technology", 
-    "Semiconductors", 
-    "http://www.nasdaq.com/symbol/lscc"
-  ], 
-  [
-    "LSTR", 
-    "Landstar System, Inc.", 
-    "70.44", 
-    "$3.15B", 
-    "1993", 
-    "Transportation", 
-    "Trucking Freight/Courier Services", 
-    "http://www.nasdaq.com/symbol/lstr"
-  ], 
-  [
-    "LTBR", 
-    "Lightbridge Corporation", 
-    "1.25", 
-    "$22.6M", 
-    "n/a", 
-    "Consumer Services", 
-    "Professional Services", 
-    "http://www.nasdaq.com/symbol/ltbr"
-  ], 
-  [
-    "LTRE", 
-    "Learning Tree International, Inc.", 
-    "1.75", 
-    "$23.14M", 
-    "1995", 
-    "Consumer Services", 
-    "Other Consumer Services", 
-    "http://www.nasdaq.com/symbol/ltre"
-  ], 
-  [
-    "LTRPA", 
-    "Liberty TripAdvisor Holdings, Inc.", 
-    "32.95", 
-    "$2.33B", 
-    "n/a", 
-    "Technology", 
-    "EDP Services", 
-    "http://www.nasdaq.com/symbol/ltrpa"
-  ], 
-  [
-    "LTRPB", 
-    "Liberty TripAdvisor Holdings, Inc.", 
-    "34.5", 
-    "$2.54B", 
-    "n/a", 
-    "Technology", 
-    "EDP Services", 
-    "http://www.nasdaq.com/symbol/ltrpb"
-  ], 
-  [
-    "LTRX", 
-    "Lantronix, Inc.", 
-    "1.8", 
-    "$26.9M", 
-    "2000", 
-    "Technology", 
-    "Computer Communications Equipment", 
-    "http://www.nasdaq.com/symbol/ltrx"
-  ], 
-  [
-    "LTXB", 
-    "LegacyTexas Financial Group, Inc.", 
-    "22.5", 
-    "$900.16M", 
-    "n/a", 
-    "Finance", 
-    "Savings Institutions", 
-    "http://www.nasdaq.com/symbol/ltxb"
-  ], 
-  [
-    "LULU", 
-    "lululemon athletica inc.", 
-    "67.37", 
-    "$8.9B", 
-    "2007", 
-    "Consumer Non-Durables", 
-    "Apparel", 
-    "http://www.nasdaq.com/symbol/lulu"
-  ], 
-  [
-    "LUNA", 
-    "Luna Innovations Incorporated", 
-    "1.4101", 
-    "$21.22M", 
-    "2006", 
-    "Health Care", 
-    "Biotechnology: Commercial Physical & Biological Resarch", 
-    "http://www.nasdaq.com/symbol/luna"
-  ], 
-  [
-    "LVNTA", 
-    "Liberty Interactive Corporation", 
-    "39.8", 
-    "$5.63B", 
-    "n/a", 
-    "Consumer Services", 
-    "Catalog/Specialty Distribution", 
-    "http://www.nasdaq.com/symbol/lvnta"
-  ], 
-  [
-    "LVNTB", 
-    "Liberty Interactive Corporation", 
-    "39.9341", 
-    "$5.64B", 
-    "n/a", 
-    "Consumer Services", 
-    "Catalog/Specialty Distribution", 
-    "http://www.nasdaq.com/symbol/lvntb"
-  ], 
-  [
-    "LWAY", 
-    "Lifeway Foods, Inc.", 
-    "19.43", 
-    "$317.6M", 
-    "n/a", 
-    "Consumer Non-Durables", 
-    "Packaged Foods", 
-    "http://www.nasdaq.com/symbol/lway"
-  ], 
-  [
-    "LXRX", 
-    "Lexicon Pharmaceuticals, Inc.", 
-    "0.93", 
-    "$673.65M", 
-    "n/a", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/lxrx"
-  ], 
-  [
-    "LYTS", 
-    "LSI Industries Inc.", 
-    "7.93", 
-    "$191.48M", 
-    "1985", 
-    "Consumer Durables", 
-    "Building Products", 
-    "http://www.nasdaq.com/symbol/lyts"
-  ], 
-  [
-    "MACK", 
-    "Merrimack Pharmaceuticals, Inc.", 
-    "11.01", 
-    "$1.17B", 
-    "2012", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/mack"
-  ], 
-  [
-    "MAG", 
-    "Magnetek, Inc.", 
-    "39.04", 
-    "$137.93M", 
-    "n/a", 
-    "Capital Goods", 
-    "Industrial Machinery/Components", 
-    "http://www.nasdaq.com/symbol/mag"
-  ], 
-  [
-    "MAGS", 
-    "Magal Security Systems Ltd.", 
-    "5.16", 
-    "$83.95M", 
-    "1993", 
-    "Consumer Durables", 
-    "Telecommunications Equipment", 
-    "http://www.nasdaq.com/symbol/mags"
-  ], 
-  [
-    "MAMS", 
-    "MAM Software Group, Inc.", 
-    "5.9324", 
-    "$84.82M", 
-    "n/a", 
-    "Technology", 
-    "Computer Software: Prepackaged Software", 
-    "http://www.nasdaq.com/symbol/mams"
-  ], 
-  [
-    "MANH", 
-    "Manhattan Associates, Inc.", 
-    "51.33", 
-    "$3.81B", 
-    "1998", 
-    "Technology", 
-    "Computer Software: Prepackaged Software", 
-    "http://www.nasdaq.com/symbol/manh"
-  ], 
-  [
-    "MANT", 
-    "ManTech International Corporation", 
-    "33.59", 
-    "$1.25B", 
-    "2002", 
-    "Consumer Services", 
-    "Other Consumer Services", 
-    "http://www.nasdaq.com/symbol/mant"
-  ], 
-  [
-    "MAR", 
-    "Marriott International", 
-    "83", 
-    "$22.95B", 
-    "n/a", 
-    "Consumer Services", 
-    "Hotels/Resorts", 
-    "http://www.nasdaq.com/symbol/mar"
-  ], 
-  [
-    "MARA", 
-    "Marathon Patent Group, Inc.", 
-    "7.04", 
-    "$97.04M", 
-    "n/a", 
-    "Miscellaneous", 
-    "Multi-Sector Companies", 
-    "http://www.nasdaq.com/symbol/mara"
-  ], 
-  [
-    "MARK", 
-    "Remark Media, Inc.", 
-    "4.85", 
-    "$62.33M", 
-    "n/a", 
-    "Consumer Services", 
-    "Telecommunications Equipment", 
-    "http://www.nasdaq.com/symbol/mark"
-  ], 
-  [
-    "MARPS", 
-    "Marine Petroleum Trust", 
-    "13.25", 
-    "$26.5M", 
-    "n/a", 
-    "Energy", 
-    "Oil & Gas Production", 
-    "http://www.nasdaq.com/symbol/marps"
-  ], 
-  [
-    "MASI", 
-    "Masimo Corporation", 
-    "29.9", 
-    "$1.57B", 
-    "2007", 
-    "Health Care", 
-    "Biotechnology: Electromedical & Electrotherapeutic Apparatus", 
-    "http://www.nasdaq.com/symbol/masi"
-  ], 
-  [
-    "MAT", 
-    "Mattel, Inc.", 
-    "25.77", 
-    "$8.73B", 
-    "n/a", 
-    "Consumer Non-Durables", 
-    "Recreational Products/Toys", 
-    "http://www.nasdaq.com/symbol/mat"
-  ], 
-  [
-    "MATR", 
-    "Mattersight Corporation", 
-    "7.35", 
-    "$163.43M", 
-    "n/a", 
-    "Consumer Services", 
-    "Professional Services", 
-    "http://www.nasdaq.com/symbol/matr"
-  ], 
-  [
-    "MATW", 
-    "Matthews International Corporation", 
-    "48.59", 
-    "$1.6B", 
-    "1994", 
-    "Capital Goods", 
-    "Metal Fabrications", 
-    "http://www.nasdaq.com/symbol/matw"
-  ], 
-  [
-    "MAYS", 
-    "J. W. Mays, Inc.", 
-    "51", 
-    "$102.8M", 
-    "n/a", 
-    "Consumer Services", 
-    "Building operators", 
-    "http://www.nasdaq.com/symbol/mays"
-  ], 
-  [
-    "MBCN", 
-    "Middlefield Banc Corp.", 
-    "33.5999", 
-    "$68.84M", 
-    "n/a", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/mbcn"
-  ], 
-  [
-    "MBFI", 
-    "MB Financial Inc.", 
-    "31.07", 
-    "$2.32B", 
-    "n/a", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/mbfi"
-  ], 
-  [
-    "MBFIP", 
-    "MB Financial Inc.", 
-    "27.2701", 
-    "$109.08M", 
-    "n/a", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/mbfip"
-  ], 
-  [
-    "MBII", 
-    "Marrone Bio Innovations, Inc.", 
-    "3.74", 
-    "$91.25M", 
-    "2013", 
-    "Basic Industries", 
-    "Agricultural Chemicals", 
-    "http://www.nasdaq.com/symbol/mbii"
-  ], 
-  [
-    "MBLX", 
-    "Metabolix, Inc.", 
-    "0.45", 
-    "$60.83M", 
-    "2006", 
-    "Basic Industries", 
-    "Containers/Packaging", 
-    "http://www.nasdaq.com/symbol/mblx"
-  ], 
-  [
-    "MBRG", 
-    "Middleburg Financial Corporation", 
-    "18.25", 
-    "$130.01M", 
-    "n/a", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/mbrg"
-  ], 
-  [
-    "MBSD", 
-    "Flexshares Trust-Flexshares Disciplined Duration Mbs Index Fun", 
-    "25.3", 
-    "$5.06M", 
-    "n/a", 
-    "n/a", 
-    "n/a", 
-    "http://www.nasdaq.com/symbol/mbsd"
-  ], 
-  [
-    "MBTF", 
-    "M B T Financial Corp", 
-    "5.38", 
-    "$122.11M", 
-    "n/a", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/mbtf"
-  ], 
-  [
-    "MBUU", 
-    "Malibu Boats, Inc.", 
-    "19.7", 
-    "$307.49M", 
-    "2014", 
-    "Capital Goods", 
-    "Marine Transportation", 
-    "http://www.nasdaq.com/symbol/mbuu"
-  ], 
-  [
-    "MBVT", 
-    "Merchants Bancshares, Inc.", 
-    "28.74", 
-    "$181.97M", 
-    "n/a", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/mbvt"
-  ], 
-  [
-    "MBWM", 
-    "Mercantile Bank Corporation", 
-    "19.21", 
-    "$323.93M", 
-    "1998", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/mbwm"
-  ], 
-  [
-    "MCBC", 
-    "Macatawa Bank Corporation", 
-    "5.44", 
-    "$183.89M", 
-    "n/a", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/mcbc"
-  ], 
-  [
-    "MCBK", 
-    "Madison County Financial, Inc.", 
-    "21", 
-    "$63.68M", 
-    "2012", 
-    "Finance", 
-    "Savings Institutions", 
-    "http://www.nasdaq.com/symbol/mcbk"
-  ], 
-  [
-    "MCEP", 
-    "Mid-Con Energy Partners, LP", 
-    "6.07", 
-    "$141.65M", 
-    "2011", 
-    "Energy", 
-    "Oil & Gas Production", 
-    "http://www.nasdaq.com/symbol/mcep"
-  ], 
-  [
-    "MCGC", 
-    "MCG Capital Corporation", 
-    "3.97", 
-    "$151.4M", 
-    "2001", 
-    "n/a", 
-    "n/a", 
-    "http://www.nasdaq.com/symbol/mcgc"
-  ], 
-  [
-    "MCHP", 
-    "Microchip Technology Incorporated", 
-    "50.925", 
-    "$10.26B", 
-    "1993", 
-    "Technology", 
-    "Semiconductors", 
-    "http://www.nasdaq.com/symbol/mchp"
-  ], 
-  [
-    "MCHX", 
-    "Marchex, Inc.", 
-    "4.15", 
-    "$177.8M", 
-    "2004", 
-    "Miscellaneous", 
-    "Business Services", 
-    "http://www.nasdaq.com/symbol/mchx"
-  ], 
-  [
-    "MCOX", 
-    "Mecox Lane Limited", 
-    "3.86", 
-    "$50.19M", 
-    "2010", 
-    "Consumer Non-Durables", 
-    "Apparel", 
-    "http://www.nasdaq.com/symbol/mcox"
-  ], 
-  [
-    "MCRI", 
-    "Monarch Casino & Resort, Inc.", 
-    "18.27", 
-    "$306.99M", 
-    "1993", 
-    "Consumer Services", 
-    "Hotels/Resorts", 
-    "http://www.nasdaq.com/symbol/mcri"
-  ], 
-  [
-    "MCRL", 
-    "Micrel, Incorporated", 
-    "14.79", 
-    "$837.96M", 
-    "1994", 
-    "Technology", 
-    "Semiconductors", 
-    "http://www.nasdaq.com/symbol/mcrl"
-  ], 
-  [
-    "MCUR", 
-    "MACROCURE LTD.", 
-    "10.2", 
-    "$166.26M", 
-    "2014", 
-    "Health Care", 
-    "Biotechnology: Biological Products (No Diagnostic Substances)", 
-    "http://www.nasdaq.com/symbol/mcur"
-  ], 
-  [
-    "MDAS", 
-    "MedAssets, Inc.", 
-    "19.73", 
-    "$1.19B", 
-    "2007", 
-    "Technology", 
-    "Computer Software: Prepackaged Software", 
-    "http://www.nasdaq.com/symbol/mdas"
-  ], 
-  [
-    "MDCA", 
-    "MDC Partners Inc.", 
-    "25.51", 
-    "$1.27B", 
-    "n/a", 
-    "Technology", 
-    "Advertising", 
-    "http://www.nasdaq.com/symbol/mdca"
-  ], 
-  [
-    "MDCO", 
-    "The Medicines Company", 
-    "28.46", 
-    "$1.86B", 
-    "2000", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/mdco"
-  ], 
-  [
-    "MDIV", 
-    "First Trust Exchange-Traded Fund VI Multi-Asset Diversified In", 
-    "21.44", 
-    "$979.81M", 
-    "n/a", 
-    "n/a", 
-    "n/a", 
-    "http://www.nasdaq.com/symbol/mdiv"
-  ], 
-  [
-    "MDLZ", 
-    "Mondelez International, Inc.", 
-    "36.97", 
-    "$62.11B", 
-    "n/a", 
-    "Consumer Non-Durables", 
-    "Packaged Foods", 
-    "http://www.nasdaq.com/symbol/mdlz"
-  ], 
-  [
-    "MDM", 
-    "Mountain Province Diamonds Inc.", 
-    "3.46", 
-    "$467.81M", 
-    "n/a", 
-    "Basic Industries", 
-    "Precious Metals", 
-    "http://www.nasdaq.com/symbol/mdm"
-  ], 
-  [
-    "MDRX", 
-    "Allscripts Healthcare Solutions, Inc.", 
-    "12.83", 
-    "$2.31B", 
-    "n/a", 
-    "Technology", 
-    "EDP Services", 
-    "http://www.nasdaq.com/symbol/mdrx"
-  ], 
-  [
-    "MDSO", 
-    "Medidata Solutions, Inc.", 
-    "47.42", 
-    "$2.57B", 
-    "2009", 
-    "Technology", 
-    "Computer Software: Prepackaged Software", 
-    "http://www.nasdaq.com/symbol/mdso"
-  ], 
-  [
-    "MDSY", 
-    "ModSys International Ltd.", 
-    "2.6", 
-    "$30.21M", 
-    "n/a", 
-    "Technology", 
-    "EDP Services", 
-    "http://www.nasdaq.com/symbol/mdsy"
-  ], 
-  [
-    "MDVN", 
-    "Medivation, Inc.", 
-    "110", 
-    "$8.54B", 
-    "n/a", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/mdvn"
-  ], 
-  [
-    "MDVX", 
-    "Medovex Corp.", 
-    "4.75", 
-    "$43.57M", 
-    "2015", 
-    "Health Care", 
-    "Medical/Dental Instruments", 
-    "http://www.nasdaq.com/symbol/mdvx"
-  ], 
-  [
-    "MDVXW", 
-    "Medovex Corp.", 
-    "0.19", 
-    "n/a", 
-    "2015", 
-    "Health Care", 
-    "Medical/Dental Instruments", 
-    "http://www.nasdaq.com/symbol/mdvxw"
-  ], 
-  [
-    "MDWD", 
-    "MediWound Ltd.", 
-    "7.52", 
-    "$162.06M", 
-    "2014", 
-    "Consumer Durables", 
-    "Specialty Chemicals", 
-    "http://www.nasdaq.com/symbol/mdwd"
-  ], 
-  [
-    "MDXG", 
-    "MiMedx Group, Inc", 
-    "9.855", 
-    "$1.05B", 
-    "n/a", 
-    "Health Care", 
-    "Medical/Dental Instruments", 
-    "http://www.nasdaq.com/symbol/mdxg"
-  ], 
-  [
-    "MEET", 
-    "MeetMe, Inc.", 
-    "1.79", 
-    "$80.33M", 
-    "n/a", 
-    "Consumer Services", 
-    "Advertising", 
-    "http://www.nasdaq.com/symbol/meet"
-  ], 
-  [
-    "MEIL", 
-    "METHES ENERGIES INTERNATIONAL LTD", 
-    "1.5999", 
-    "$18.34M", 
-    "2012", 
-    "Basic Industries", 
-    "Major Chemicals", 
-    "http://www.nasdaq.com/symbol/meil"
-  ], 
-  [
-    "MEILW", 
-    "METHES ENERGIES INTERNATIONAL LTD", 
-    "0.0514", 
-    "n/a", 
-    "2012", 
-    "Basic Industries", 
-    "Major Chemicals", 
-    "http://www.nasdaq.com/symbol/meilw"
-  ], 
-  [
-    "MEILZ", 
-    "METHES ENERGIES INTERNATIONAL LTD", 
-    "0.09", 
-    "n/a", 
-    "2012", 
-    "Basic Industries", 
-    "Major Chemicals", 
-    "http://www.nasdaq.com/symbol/meilz"
-  ], 
-  [
-    "MEIP", 
-    "MEI Pharma, Inc.", 
-    "5.42", 
-    "$180.44M", 
-    "n/a", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/meip"
-  ], 
-  [
-    "MELA", 
-    "MELA Sciences, Inc", 
-    "2.09", 
-    "$12.62M", 
-    "2005", 
-    "Health Care", 
-    "Medical/Dental Instruments", 
-    "http://www.nasdaq.com/symbol/mela"
-  ], 
-  [
-    "MELI", 
-    "MercadoLibre, Inc.", 
-    "130.92", 
-    "$5.78B", 
-    "2007", 
-    "Miscellaneous", 
-    "Business Services", 
-    "http://www.nasdaq.com/symbol/meli"
-  ], 
-  [
-    "MELR", 
-    "Melrose Bancorp, Inc.", 
-    "13.49", 
-    "$38.17M", 
-    "2014", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/melr"
-  ], 
-  [
-    "MEMP", 
-    "Memorial Production Partners LP", 
-    "17.41", 
-    "$1.51B", 
-    "2011", 
-    "Energy", 
-    "Oil & Gas Production", 
-    "http://www.nasdaq.com/symbol/memp"
-  ], 
-  [
-    "MENT", 
-    "Mentor Graphics Corporation", 
-    "25.3", 
-    "$2.91B", 
-    "1984", 
-    "Technology", 
-    "EDP Services", 
-    "http://www.nasdaq.com/symbol/ment"
-  ], 
-  [
-    "MEOH", 
-    "Methanex Corporation", 
-    "51.96", 
-    "$4.81B", 
-    "n/a", 
-    "Basic Industries", 
-    "Major Chemicals", 
-    "http://www.nasdaq.com/symbol/meoh"
-  ], 
-  [
-    "MERC", 
-    "Mercer International Inc.", 
-    "14.42", 
-    "$926.82M", 
-    "n/a", 
-    "Basic Industries", 
-    "Paper", 
-    "http://www.nasdaq.com/symbol/merc"
-  ], 
-  [
-    "MERU", 
-    "Meru Networks, Inc.", 
-    "2.73", 
-    "$64.97M", 
-    "2010", 
-    "Technology", 
-    "Computer Communications Equipment", 
-    "http://www.nasdaq.com/symbol/meru"
-  ], 
-  [
-    "METR", 
-    "Metro Bancorp, Inc", 
-    "25.43", 
-    "$361.28M", 
-    "n/a", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/metr"
-  ], 
-  [
-    "MFLX", 
-    "Multi-Fineline Electronix, Inc.", 
-    "17.93", 
-    "$435.76M", 
-    "2004", 
-    "Technology", 
-    "Electrical Products", 
-    "http://www.nasdaq.com/symbol/mflx"
-  ], 
-  [
-    "MFNC", 
-    "Mackinac Financial Corporation", 
-    "11.6", 
-    "$64.55M", 
-    "n/a", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/mfnc"
-  ], 
-  [
-    "MFRI", 
-    "MFRI, Inc.", 
-    "6.75", 
-    "$49.21M", 
-    "1989", 
-    "Capital Goods", 
-    "Pollution Control Equipment", 
-    "http://www.nasdaq.com/symbol/mfri"
-  ], 
-  [
-    "MFRM", 
-    "Mattress Firm Holding Corp.", 
-    "59.45", 
-    "$2.08B", 
-    "2011", 
-    "Consumer Services", 
-    "Other Specialty Stores", 
-    "http://www.nasdaq.com/symbol/mfrm"
-  ], 
-  [
-    "MFSF", 
-    "MutualFirst Financial Inc.", 
-    "22.5", 
-    "$161.98M", 
-    "n/a", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/mfsf"
-  ], 
-  [
-    "MGCD", 
-    "MGC Diagnostics Corporation", 
-    "7.1167", 
-    "$30.39M", 
-    "n/a", 
-    "Health Care", 
-    "Medical/Dental Instruments", 
-    "http://www.nasdaq.com/symbol/mgcd"
-  ], 
-  [
-    "MGEE", 
-    "MGE Energy Inc.", 
-    "43.41", 
-    "$1.5B", 
-    "n/a", 
-    "Energy", 
-    "Electric Utilities: Central", 
-    "http://www.nasdaq.com/symbol/mgee"
-  ], 
-  [
-    "MGI", 
-    "Moneygram International, Inc.", 
-    "8.53", 
-    "$460.29M", 
-    "n/a", 
-    "Miscellaneous", 
-    "Business Services", 
-    "http://www.nasdaq.com/symbol/mgi"
-  ]
-]
\ No newline at end of file
diff --git a/examples/stocks/data/stock_data_17.json b/examples/stocks/data/stock_data_17.json
deleted file mode 100644
index c429e56..0000000
--- a/examples/stocks/data/stock_data_17.json
+++ /dev/null
@@ -1,1002 +0,0 @@
-[
-  [
-    "MGIC", 
-    "Magic Software Enterprises Ltd.", 
-    "6.87", 
-    "$303.19M", 
-    "1991", 
-    "Technology", 
-    "Computer Software: Prepackaged Software", 
-    "http://www.nasdaq.com/symbol/mgic"
-  ], 
-  [
-    "MGLN", 
-    "Magellan Health, Inc.", 
-    "61.79", 
-    "$1.71B", 
-    "n/a", 
-    "Health Care", 
-    "Hospital/Nursing Management", 
-    "http://www.nasdaq.com/symbol/mgln"
-  ], 
-  [
-    "MGNX", 
-    "MacroGenics, Inc.", 
-    "35.86", 
-    "$996.73M", 
-    "2013", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/mgnx"
-  ], 
-  [
-    "MGPI", 
-    "MGP Ingredients, Inc.", 
-    "14.47", 
-    "$255.28M", 
-    "n/a", 
-    "Consumer Non-Durables", 
-    "Beverages (Production/Distribution)", 
-    "http://www.nasdaq.com/symbol/mgpi"
-  ], 
-  [
-    "MGRC", 
-    "McGrath RentCorp", 
-    "31.65", 
-    "$821.63M", 
-    "1984", 
-    "Technology", 
-    "Diversified Commercial Services", 
-    "http://www.nasdaq.com/symbol/mgrc"
-  ], 
-  [
-    "MGYR", 
-    "Magyar Bancorp, Inc.", 
-    "8.4", 
-    "$48.85M", 
-    "n/a", 
-    "Finance", 
-    "Savings Institutions", 
-    "http://www.nasdaq.com/symbol/mgyr"
-  ], 
-  [
-    "MHGC", 
-    "Morgans Hotel Group Co.", 
-    "7.81", 
-    "$268.49M", 
-    "2006", 
-    "n/a", 
-    "n/a", 
-    "http://www.nasdaq.com/symbol/mhgc"
-  ], 
-  [
-    "MHLD", 
-    "Maiden Holdings, Ltd.", 
-    "14.47", 
-    "$1.06B", 
-    "n/a", 
-    "Finance", 
-    "Property-Casualty Insurers", 
-    "http://www.nasdaq.com/symbol/mhld"
-  ], 
-  [
-    "MHLDO", 
-    "Maiden Holdings, Ltd.", 
-    "51.99", 
-    "$171.57M", 
-    "n/a", 
-    "Finance", 
-    "Property-Casualty Insurers", 
-    "http://www.nasdaq.com/symbol/mhldo"
-  ], 
-  [
-    "MICT", 
-    "Micronet Enertec Technologies, Inc.", 
-    "3.27", 
-    "$19.07M", 
-    "n/a", 
-    "Capital Goods", 
-    "Electrical Products", 
-    "http://www.nasdaq.com/symbol/mict"
-  ], 
-  [
-    "MICTW", 
-    "Micronet Enertec Technologies, Inc.", 
-    "0.6501", 
-    "n/a", 
-    "n/a", 
-    "Capital Goods", 
-    "Electrical Products", 
-    "http://www.nasdaq.com/symbol/mictw"
-  ], 
-  [
-    "MIDD", 
-    "The Middleby Corporation", 
-    "109", 
-    "$6.24B", 
-    "n/a", 
-    "Technology", 
-    "Industrial Machinery/Components", 
-    "http://www.nasdaq.com/symbol/midd"
-  ], 
-  [
-    "MIFI", 
-    "Novatel Wireless, Inc.", 
-    "4.97", 
-    "$221.85M", 
-    "n/a", 
-    "Consumer Durables", 
-    "Telecommunications Equipment", 
-    "http://www.nasdaq.com/symbol/mifi"
-  ], 
-  [
-    "MIK", 
-    "The Michaels Companies, Inc.", 
-    "27.84", 
-    "$5.69B", 
-    "2014", 
-    "Consumer Services", 
-    "Recreational Products/Toys", 
-    "http://www.nasdaq.com/symbol/mik"
-  ], 
-  [
-    "MIND", 
-    "Mitcham Industries, Inc.", 
-    "6.52", 
-    "$78.79M", 
-    "1994", 
-    "Technology", 
-    "Diversified Commercial Services", 
-    "http://www.nasdaq.com/symbol/mind"
-  ], 
-  [
-    "MINI", 
-    "Mobile Mini, Inc.", 
-    "41.79", 
-    "$1.93B", 
-    "1994", 
-    "Capital Goods", 
-    "Metal Fabrications", 
-    "http://www.nasdaq.com/symbol/mini"
-  ], 
-  [
-    "MITK", 
-    "Mitek Systems, Inc.", 
-    "3.4", 
-    "$104.23M", 
-    "n/a", 
-    "Technology", 
-    "Computer peripheral equipment", 
-    "http://www.nasdaq.com/symbol/mitk"
-  ], 
-  [
-    "MITL", 
-    "Mitel Networks Corporation", 
-    "10.07", 
-    "$1.01B", 
-    "n/a", 
-    "Technology", 
-    "Radio And Television Broadcasting And Communications Equipment", 
-    "http://www.nasdaq.com/symbol/mitl"
-  ], 
-  [
-    "MKSI", 
-    "MKS Instruments, Inc.", 
-    "35.8", 
-    "$1.9B", 
-    "1999", 
-    "Capital Goods", 
-    "Industrial Machinery/Components", 
-    "http://www.nasdaq.com/symbol/mksi"
-  ], 
-  [
-    "MKTO", 
-    "Marketo, Inc.", 
-    "27.53", 
-    "$1.13B", 
-    "2013", 
-    "Technology", 
-    "Computer Software: Prepackaged Software", 
-    "http://www.nasdaq.com/symbol/mkto"
-  ], 
-  [
-    "MKTX", 
-    "MarketAxess Holdings, Inc.", 
-    "78.97", 
-    "$2.95B", 
-    "2004", 
-    "Finance", 
-    "Investment Bankers/Brokers/Service", 
-    "http://www.nasdaq.com/symbol/mktx"
-  ], 
-  [
-    "MLAB", 
-    "Mesa Laboratories, Inc.", 
-    "73.33", 
-    "$259.25M", 
-    "n/a", 
-    "Capital Goods", 
-    "Industrial Machinery/Components", 
-    "http://www.nasdaq.com/symbol/mlab"
-  ], 
-  [
-    "MLHR", 
-    "Herman Miller, Inc.", 
-    "31.36", 
-    "$1.87B", 
-    "n/a", 
-    "Consumer Durables", 
-    "Office Equipment/Supplies/Services", 
-    "http://www.nasdaq.com/symbol/mlhr"
-  ], 
-  [
-    "MLNK", 
-    "ModusLink Global Solutions, Inc", 
-    "3.73", 
-    "$194.79M", 
-    "n/a", 
-    "Miscellaneous", 
-    "Business Services", 
-    "http://www.nasdaq.com/symbol/mlnk"
-  ], 
-  [
-    "MLNX", 
-    "Mellanox Technologies, Ltd.", 
-    "46.47", 
-    "$2.1B", 
-    "2007", 
-    "Technology", 
-    "Semiconductors", 
-    "http://www.nasdaq.com/symbol/mlnx"
-  ], 
-  [
-    "MLVF", 
-    "Malvern Bancorp, Inc.", 
-    "12.32", 
-    "$80.8M", 
-    "n/a", 
-    "Finance", 
-    "Banks", 
-    "http://www.nasdaq.com/symbol/mlvf"
-  ], 
-  [
-    "MMAC", 
-    "MMA Capital Management, LLC", 
-    "9.1601", 
-    "$66.68M", 
-    "n/a", 
-    "Finance", 
-    "Real Estate", 
-    "http://www.nasdaq.com/symbol/mmac"
-  ], 
-  [
-    "MMLP", 
-    "Martin Midstream Partners L.P.", 
-    "30.34", 
-    "$1.07B", 
-    "2002", 
-    "Energy", 
-    "Oil Refining/Marketing", 
-    "http://www.nasdaq.com/symbol/mmlp"
-  ], 
-  [
-    "MMSI", 
-    "Merit Medical Systems, Inc.", 
-    "17.84", 
-    "$774.3M", 
-    "n/a", 
-    "Health Care", 
-    "Medical/Dental Instruments", 
-    "http://www.nasdaq.com/symbol/mmsi"
-  ], 
-  [
-    "MMYT", 
-    "MakeMyTrip Limited", 
-    "25.02", 
-    "$1.04B", 
-    "2010", 
-    "Consumer Services", 
-    "Transportation Services", 
-    "http://www.nasdaq.com/symbol/mmyt"
-  ], 
-  [
-    "MNDO", 
-    "MIND C.T.I. Ltd.", 
-    "3.49", 
-    "$66.08M", 
-    "n/a", 
-    "Technology", 
-    "EDP Services", 
-    "http://www.nasdaq.com/symbol/mndo"
-  ], 
-  [
-    "MNGA", 
-    "MagneGas Corporation", 
-    "0.8335", 
-    "$30.49M", 
-    "n/a", 
-    "Technology", 
-    "Industrial Machinery/Components", 
-    "http://www.nasdaq.com/symbol/mnga"
-  ], 
-  [
-    "MNKD", 
-    "MannKind Corporation", 
-    "6.9", 
-    "$2.8B", 
-    "2004", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/mnkd"
-  ], 
-  [
-    "MNOV", 
-    "MediciNova, Inc.", 
-    "3.51", 
-    "$85.01M", 
-    "n/a", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/mnov"
-  ], 
-  [
-    "MNRK", 
-    "Monarch Financial Holdings, Inc.", 
-    "12.37", 
-    "$131.7M", 
-    "n/a", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/mnrk"
-  ], 
-  [
-    "MNRO", 
-    "Monro Muffler Brake, Inc.", 
-    "63.33", 
-    "$2.01B", 
-    "1991", 
-    "Consumer Services", 
-    "Automotive Aftermarket", 
-    "http://www.nasdaq.com/symbol/mnro"
-  ], 
-  [
-    "MNST", 
-    "Monster Beverage Corporation", 
-    "121.26", 
-    "$20.34B", 
-    "n/a", 
-    "Consumer Non-Durables", 
-    "Beverages (Production/Distribution)", 
-    "http://www.nasdaq.com/symbol/mnst"
-  ], 
-  [
-    "MNTA", 
-    "Momenta Pharmaceuticals, Inc.", 
-    "13.01", 
-    "$690.19M", 
-    "2004", 
-    "Health Care", 
-    "Biotechnology: Biological Products (No Diagnostic Substances)", 
-    "http://www.nasdaq.com/symbol/mnta"
-  ], 
-  [
-    "MNTX", 
-    "Manitex International, Inc.", 
-    "11.36", 
-    "$181.58M", 
-    "n/a", 
-    "Technology", 
-    "Industrial Machinery/Components", 
-    "http://www.nasdaq.com/symbol/mntx"
-  ], 
-  [
-    "MOBI", 
-    "Sky-mobi Limited", 
-    "4.07", 
-    "$112.38M", 
-    "2010", 
-    "Technology", 
-    "Computer Software: Prepackaged Software", 
-    "http://www.nasdaq.com/symbol/mobi"
-  ], 
-  [
-    "MOBL", 
-    "MobileIron, Inc.", 
-    "8.8", 
-    "$668.62M", 
-    "2014", 
-    "Technology", 
-    "Computer Software: Prepackaged Software", 
-    "http://www.nasdaq.com/symbol/mobl"
-  ], 
-  [
-    "MOCO", 
-    "MOCON, Inc.", 
-    "16.45", 
-    "$93.33M", 
-    "n/a", 
-    "Capital Goods", 
-    "Industrial Machinery/Components", 
-    "http://www.nasdaq.com/symbol/moco"
-  ], 
-  [
-    "MOFG", 
-    "MidWestOne Financial Group, Inc.", 
-    "28.26", 
-    "$235.96M", 
-    "n/a", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/mofg"
-  ], 
-  [
-    "MOKO", 
-    "Moko Social Media Ltd.", 
-    "5.2", 
-    "$78.07M", 
-    "2014", 
-    "Technology", 
-    "Computer Software: Programming, Data Processing", 
-    "http://www.nasdaq.com/symbol/moko"
-  ], 
-  [
-    "MOLG", 
-    "MOL Global, Inc.", 
-    "2.52", 
-    "$170.1M", 
-    "2014", 
-    "Miscellaneous", 
-    "Business Services", 
-    "http://www.nasdaq.com/symbol/molg"
-  ], 
-  [
-    "MOMO", 
-    "Momo Inc.", 
-    "11.5", 
-    "$2.14B", 
-    "2014", 
-    "Technology", 
-    "Computer Software: Prepackaged Software", 
-    "http://www.nasdaq.com/symbol/momo"
-  ], 
-  [
-    "MORN", 
-    "Morningstar, Inc.", 
-    "77.13", 
-    "$3.44B", 
-    "2005", 
-    "Finance", 
-    "Investment Managers", 
-    "http://www.nasdaq.com/symbol/morn"
-  ], 
-  [
-    "MOSY", 
-    "MoSys, Inc.", 
-    "1.94", 
-    "$96.57M", 
-    "2001", 
-    "Technology", 
-    "Semiconductors", 
-    "http://www.nasdaq.com/symbol/mosy"
-  ], 
-  [
-    "MPAA", 
-    "Motorcar Parts of America, Inc.", 
-    "22.95", 
-    "$412.24M", 
-    "n/a", 
-    "Capital Goods", 
-    "Auto Parts:O.E.M.", 
-    "http://www.nasdaq.com/symbol/mpaa"
-  ], 
-  [
-    "MPB", 
-    "Mid Penn Bancorp", 
-    "15.57", 
-    "$54.45M", 
-    "n/a", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/mpb"
-  ], 
-  [
-    "MPEL", 
-    "Melco Crown Entertainment Limited", 
-    "27.46", 
-    "$15.13B", 
-    "2006", 
-    "Consumer Services", 
-    "Hotels/Resorts", 
-    "http://www.nasdaq.com/symbol/mpel"
-  ], 
-  [
-    "MPET", 
-    "Magellan Petroleum Corporation", 
-    "0.879", 
-    "$40.17M", 
-    "n/a", 
-    "Energy", 
-    "Oil & Gas Production", 
-    "http://www.nasdaq.com/symbol/mpet"
-  ], 
-  [
-    "MPWR", 
-    "Monolithic Power Systems, Inc.", 
-    "51.99", 
-    "$2.01B", 
-    "2004", 
-    "Technology", 
-    "Semiconductors", 
-    "http://www.nasdaq.com/symbol/mpwr"
-  ], 
-  [
-    "MRCC", 
-    "Monroe Capital Corporation", 
-    "14.74", 
-    "$140.29M", 
-    "2012", 
-    "n/a", 
-    "n/a", 
-    "http://www.nasdaq.com/symbol/mrcc"
-  ], 
-  [
-    "MRCY", 
-    "Mercury Systems Inc", 
-    "17.06", 
-    "$582.59M", 
-    "1998", 
-    "Capital Goods", 
-    "Electrical Products", 
-    "http://www.nasdaq.com/symbol/mrcy"
-  ], 
-  [
-    "MRD", 
-    "Memorial Resource Development Corp.", 
-    "19.3", 
-    "$3.74B", 
-    "2014", 
-    "Energy", 
-    "Oil & Gas Production", 
-    "http://www.nasdaq.com/symbol/mrd"
-  ], 
-  [
-    "MRGE", 
-    "Merge Healthcare Incorporated.", 
-    "4.47", 
-    "$440.75M", 
-    "1998", 
-    "Technology", 
-    "EDP Services", 
-    "http://www.nasdaq.com/symbol/mrge"
-  ], 
-  [
-    "MRKT", 
-    "Markit Ltd.", 
-    "26.35", 
-    "$4.79B", 
-    "2014", 
-    "Finance", 
-    "Investment Bankers/Brokers/Service", 
-    "http://www.nasdaq.com/symbol/mrkt"
-  ], 
-  [
-    "MRLN", 
-    "Marlin Business Services Corp.", 
-    "18.83", 
-    "$241.41M", 
-    "2003", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/mrln"
-  ], 
-  [
-    "MRNS", 
-    "Marinus Pharmaceuticals, Inc.", 
-    "11.65", 
-    "$163.19M", 
-    "2014", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/mrns"
-  ], 
-  [
-    "MRTN", 
-    "Marten Transport, Ltd.", 
-    "23.01", 
-    "$768.67M", 
-    "1986", 
-    "Transportation", 
-    "Trucking Freight/Courier Services", 
-    "http://www.nasdaq.com/symbol/mrtn"
-  ], 
-  [
-    "MRTX", 
-    "Mirati Therapeutics, Inc.", 
-    "23.7", 
-    "$382.15M", 
-    "n/a", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/mrtx"
-  ], 
-  [
-    "MRVC", 
-    "MRV Communications, Inc.", 
-    "9.951", 
-    "$73.26M", 
-    "1992", 
-    "Technology", 
-    "Semiconductors", 
-    "http://www.nasdaq.com/symbol/mrvc"
-  ], 
-  [
-    "MRVL", 
-    "Marvell Technology Group Ltd.", 
-    "16.29", 
-    "$8.33B", 
-    "2000", 
-    "Technology", 
-    "Semiconductors", 
-    "http://www.nasdaq.com/symbol/mrvl"
-  ], 
-  [
-    "MSBF", 
-    "MSB Financial Corp.", 
-    "10.7199", 
-    "$53.71M", 
-    "n/a", 
-    "Finance", 
-    "Savings Institutions", 
-    "http://www.nasdaq.com/symbol/msbf"
-  ], 
-  [
-    "MSCC", 
-    "Microsemi Corporation", 
-    "31.14", 
-    "$2.96B", 
-    "n/a", 
-    "Technology", 
-    "Semiconductors", 
-    "http://www.nasdaq.com/symbol/mscc"
-  ], 
-  [
-    "MSEX", 
-    "Middlesex Water Company", 
-    "22.7", 
-    "$365.73M", 
-    "n/a", 
-    "Public Utilities", 
-    "Water Supply", 
-    "http://www.nasdaq.com/symbol/msex"
-  ], 
-  [
-    "MSFG", 
-    "MainSource Financial Group, Inc.", 
-    "19.14", 
-    "$415.09M", 
-    "n/a", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/msfg"
-  ], 
-  [
-    "MSFT", 
-    "Microsoft Corporation", 
-    "43.855", 
-    "$359.78B", 
-    "1986", 
-    "Technology", 
-    "Computer Software: Prepackaged Software", 
-    "http://www.nasdaq.com/symbol/msft"
-  ], 
-  [
-    "MSG", 
-    "The Madison Square Garden Company", 
-    "78.53", 
-    "$6.03B", 
-    "n/a", 
-    "Consumer Services", 
-    "Television Services", 
-    "http://www.nasdaq.com/symbol/msg"
-  ], 
-  [
-    "MSLI", 
-    "Merus Labs International Inc.", 
-    "1.88", 
-    "$152.68M", 
-    "n/a", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/msli"
-  ], 
-  [
-    "MSON", 
-    "MISONIX, Inc.", 
-    "12.25", 
-    "$93.55M", 
-    "1992", 
-    "Capital Goods", 
-    "Medical Specialities", 
-    "http://www.nasdaq.com/symbol/mson"
-  ], 
-  [
-    "MSTR", 
-    "MicroStrategy Incorporated", 
-    "179.55", 
-    "$2.03B", 
-    "1998", 
-    "Technology", 
-    "Computer Software: Prepackaged Software", 
-    "http://www.nasdaq.com/symbol/mstr"
-  ], 
-  [
-    "MTBC", 
-    "Medical Transcription Billing, Corp.", 
-    "2.6999", 
-    "$29.7M", 
-    "2014", 
-    "Technology", 
-    "Computer Software: Prepackaged Software", 
-    "http://www.nasdaq.com/symbol/mtbc"
-  ], 
-  [
-    "MTEX", 
-    "Mannatech, Incorporated", 
-    "23.3", 
-    "$62.17M", 
-    "n/a", 
-    "Consumer Durables", 
-    "Specialty Chemicals", 
-    "http://www.nasdaq.com/symbol/mtex"
-  ], 
-  [
-    "MTGE", 
-    "American Capital Mortgage Investment Corp.", 
-    "18.27", 
-    "$934.37M", 
-    "2011", 
-    "Consumer Services", 
-    "Real Estate Investment Trusts", 
-    "http://www.nasdaq.com/symbol/mtge"
-  ], 
-  [
-    "MTGEP", 
-    "American Capital Mortgage Investment Corp.", 
-    "25.24", 
-    "$50.48M", 
-    "n/a", 
-    "Consumer Services", 
-    "Real Estate Investment Trusts", 
-    "http://www.nasdaq.com/symbol/mtgep"
-  ], 
-  [
-    "MTLS", 
-    "Materialise NV", 
-    "8", 
-    "$376.58M", 
-    "2014", 
-    "Technology", 
-    "Computer Software: Prepackaged Software", 
-    "http://www.nasdaq.com/symbol/mtls"
-  ], 
-  [
-    "MTRX", 
-    "Matrix Service Company", 
-    "18.67", 
-    "$498.69M", 
-    "1990", 
-    "Basic Industries", 
-    "Engineering & Construction", 
-    "http://www.nasdaq.com/symbol/mtrx"
-  ], 
-  [
-    "MTSC", 
-    "MTS Systems Corporation", 
-    "72.06", 
-    "$1.08B", 
-    "n/a", 
-    "Capital Goods", 
-    "Industrial Machinery/Components", 
-    "http://www.nasdaq.com/symbol/mtsc"
-  ], 
-  [
-    "MTSI", 
-    "M/A-COM Technology Solutions Holdings, Inc.", 
-    "34.25", 
-    "$1.83B", 
-    "2012", 
-    "Technology", 
-    "Semiconductors", 
-    "http://www.nasdaq.com/symbol/mtsi"
-  ], 
-  [
-    "MTSL", 
-    "MER Telemanagement Solutions Ltd.", 
-    "1.6", 
-    "$7.45M", 
-    "1997", 
-    "Public Utilities", 
-    "Telecommunications Equipment", 
-    "http://www.nasdaq.com/symbol/mtsl"
-  ], 
-  [
-    "MTSN", 
-    "Mattson Technology, Inc.", 
-    "4.62", 
-    "$340.97M", 
-    "1994", 
-    "Technology", 
-    "Industrial Machinery/Components", 
-    "http://www.nasdaq.com/symbol/mtsn"
-  ], 
-  [
-    "MU", 
-    "Micron Technology, Inc.", 
-    "32.03", 
-    "$34.51B", 
-    "n/a", 
-    "Technology", 
-    "Semiconductors", 
-    "http://www.nasdaq.com/symbol/mu"
-  ], 
-  [
-    "MULT", 
-    "Advisorshares Trust-Advisorshares Sunrise Global Multi-Strateg", 
-    "23.25", 
-    "$2.33M", 
-    "n/a", 
-    "n/a", 
-    "n/a", 
-    "http://www.nasdaq.com/symbol/mult"
-  ], 
-  [
-    "MVIS", 
-    "Microvision, Inc.", 
-    "2", 
-    "$88.9M", 
-    "1996", 
-    "Capital Goods", 
-    "Industrial Machinery/Components", 
-    "http://www.nasdaq.com/symbol/mvis"
-  ], 
-  [
-    "MWIV", 
-    "MWI Veterinary Supply, Inc.", 
-    "189.9", 
-    "$2.45B", 
-    "2005", 
-    "Health Care", 
-    "Medical Specialities", 
-    "http://www.nasdaq.com/symbol/mwiv"
-  ], 
-  [
-    "MXIM", 
-    "Maxim Integrated Products, Inc.", 
-    "34.6", 
-    "$9.79B", 
-    "1988", 
-    "Technology", 
-    "Semiconductors", 
-    "http://www.nasdaq.com/symbol/mxim"
-  ], 
-  [
-    "MXWL", 
-    "Maxwell Technologies, Inc.", 
-    "6.87", 
-    "$205.35M", 
-    "n/a", 
-    "Miscellaneous", 
-    "Industrial Machinery/Components", 
-    "http://www.nasdaq.com/symbol/mxwl"
-  ], 
-  [
-    "MYGN", 
-    "Myriad Genetics, Inc.", 
-    "34.32", 
-    "$2.44B", 
-    "1995", 
-    "Health Care", 
-    "Biotechnology: In Vitro & In Vivo Diagnostic Substances", 
-    "http://www.nasdaq.com/symbol/mygn"
-  ], 
-  [
-    "MYL", 
-    "Mylan Inc.", 
-    "57.87", 
-    "$21.66B", 
-    "n/a", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/myl"
-  ], 
-  [
-    "MYOS", 
-    "MYOS Corporation", 
-    "5.46", 
-    "$15.89M", 
-    "n/a", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/myos"
-  ], 
-  [
-    "MYRG", 
-    "MYR Group, Inc.", 
-    "26.24", 
-    "$545.25M", 
-    "n/a", 
-    "Basic Industries", 
-    "Water Supply", 
-    "http://www.nasdaq.com/symbol/myrg"
-  ], 
-  [
-    "MZOR", 
-    "Mazor Robotics Ltd.", 
-    "11.5", 
-    "$240.6M", 
-    "n/a", 
-    "Health Care", 
-    "Medical/Dental Instruments", 
-    "http://www.nasdaq.com/symbol/mzor"
-  ], 
-  [
-    "NAII", 
-    "Natural Alternatives International, Inc.", 
-    "5.28", 
-    "$36.53M", 
-    "n/a", 
-    "Consumer Durables", 
-    "Specialty Chemicals", 
-    "http://www.nasdaq.com/symbol/naii"
-  ], 
-  [
-    "NAME", 
-    "Rightside Group, Ltd.", 
-    "7.3", 
-    "$135M", 
-    "n/a", 
-    "Miscellaneous", 
-    "Business Services", 
-    "http://www.nasdaq.com/symbol/name"
-  ], 
-  [
-    "NANO", 
-    "Nanometrics Incorporated", 
-    "17.39", 
-    "$420.11M", 
-    "1984", 
-    "Capital Goods", 
-    "Industrial Machinery/Components", 
-    "http://www.nasdaq.com/symbol/nano"
-  ], 
-  [
-    "NATH", 
-    "Nathan&#39;s Famous, Inc.", 
-    "76.25", 
-    "$342.87M", 
-    "1993", 
-    "Consumer Services", 
-    "Restaurants", 
-    "http://www.nasdaq.com/symbol/nath"
-  ], 
-  [
-    "NATI", 
-    "National Instruments Corporation", 
-    "31.3", 
-    "$4.01B", 
-    "1995", 
-    "Technology", 
-    "Computer Software: Prepackaged Software", 
-    "http://www.nasdaq.com/symbol/nati"
-  ], 
-  [
-    "NATL", 
-    "National Interstate Corporation", 
-    "26.19", 
-    "$518.07M", 
-    "2005", 
-    "Finance", 
-    "Property-Casualty Insurers", 
-    "http://www.nasdaq.com/symbol/natl"
-  ]
-]
\ No newline at end of file
diff --git a/examples/stocks/data/stock_data_18.json b/examples/stocks/data/stock_data_18.json
deleted file mode 100644
index cc07d8a..0000000
--- a/examples/stocks/data/stock_data_18.json
+++ /dev/null
@@ -1,1002 +0,0 @@
-[
-  [
-    "NATR", 
-    "Nature&#39;s Sunshine Products, Inc.", 
-    "13.85", 
-    "$259.57M", 
-    "n/a", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/natr"
-  ], 
-  [
-    "NAUH", 
-    "National American University Holdings, Inc.", 
-    "3.2716", 
-    "$82.39M", 
-    "n/a", 
-    "Consumer Services", 
-    "Other Consumer Services", 
-    "http://www.nasdaq.com/symbol/nauh"
-  ], 
-  [
-    "NAVG", 
-    "The Navigators Group, Inc.", 
-    "72.62", 
-    "$1.04B", 
-    "1986", 
-    "Finance", 
-    "Property-Casualty Insurers", 
-    "http://www.nasdaq.com/symbol/navg"
-  ], 
-  [
-    "NAVI", 
-    "Navient Corporation", 
-    "21.72", 
-    "$8.91B", 
-    "n/a", 
-    "Finance", 
-    "Investment Bankers/Brokers/Service", 
-    "http://www.nasdaq.com/symbol/navi"
-  ], 
-  [
-    "NBBC", 
-    "NewBridge Bancorp", 
-    "8.62", 
-    "$320.63M", 
-    "n/a", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/nbbc"
-  ], 
-  [
-    "NBIX", 
-    "Neurocrine Biosciences, Inc.", 
-    "39.4", 
-    "$3.04B", 
-    "1996", 
-    "Health Care", 
-    "Biotechnology: Biological Products (No Diagnostic Substances)", 
-    "http://www.nasdaq.com/symbol/nbix"
-  ], 
-  [
-    "NBN", 
-    "Northeast Bancorp", 
-    "9.18", 
-    "$90.32M", 
-    "n/a", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/nbn"
-  ], 
-  [
-    "NBS", 
-    "Neostem, Inc.", 
-    "4.07", 
-    "$145.46M", 
-    "n/a", 
-    "Health Care", 
-    "Hospital/Nursing Management", 
-    "http://www.nasdaq.com/symbol/nbs"
-  ], 
-  [
-    "NBTB", 
-    "NBT Bancorp Inc.", 
-    "24.35", 
-    "$1.06B", 
-    "n/a", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/nbtb"
-  ], 
-  [
-    "NBTF", 
-    "NB&T FINANCIAL GROUP INC", 
-    "29.96", 
-    "$102.87M", 
-    "n/a", 
-    "Finance", 
-    "Commercial Banks", 
-    "http://www.nasdaq.com/symbol/nbtf"
-  ], 
-  [
-    "NCIT", 
-    "NCI, Inc.", 
-    "11.75", 
-    "$152.82M", 
-    "2005", 
-    "Technology", 
-    "EDP Services", 
-    "http://www.nasdaq.com/symbol/ncit"
-  ], 
-  [
-    "NCLH", 
-    "Norwegian Cruise Line Holdings Ltd.", 
-    "47.77", 
-    "$9.71B", 
-    "2013", 
-    "Consumer Services", 
-    "Marine Transportation", 
-    "http://www.nasdaq.com/symbol/nclh"
-  ], 
-  [
-    "NCMI", 
-    "National CineMedia, Inc.", 
-    "15", 
-    "$913.06M", 
-    "2007", 
-    "Consumer Services", 
-    "Advertising", 
-    "http://www.nasdaq.com/symbol/ncmi"
-  ], 
-  [
-    "NCTY", 
-    "The9 Limited", 
-    "1.49", 
-    "$34.49M", 
-    "2004", 
-    "Miscellaneous", 
-    "Business Services", 
-    "http://www.nasdaq.com/symbol/ncty"
-  ], 
-  [
-    "NDAQ", 
-    "The NASDAQ OMX Group, Inc.", 
-    "50.94", 
-    "$8.6B", 
-    "n/a", 
-    "Finance", 
-    "Investment Bankers/Brokers/Service", 
-    "http://www.nasdaq.com/symbol/ndaq"
-  ], 
-  [
-    "NDLS", 
-    "Noodles & Company", 
-    "18.9", 
-    "$563.02M", 
-    "2013", 
-    "Consumer Services", 
-    "Restaurants", 
-    "http://www.nasdaq.com/symbol/ndls"
-  ], 
-  [
-    "NDRM", 
-    "NeuroDerm Ltd.", 
-    "11.58", 
-    "$196.82M", 
-    "2014", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/ndrm"
-  ], 
-  [
-    "NDSN", 
-    "Nordson Corporation", 
-    "78.46", 
-    "$4.86B", 
-    "n/a", 
-    "Capital Goods", 
-    "Industrial Machinery/Components", 
-    "http://www.nasdaq.com/symbol/ndsn"
-  ], 
-  [
-    "NECB", 
-    "Northeast Community Bancorp, Inc.", 
-    "6.92", 
-    "$85.64M", 
-    "n/a", 
-    "Finance", 
-    "Savings Institutions", 
-    "http://www.nasdaq.com/symbol/necb"
-  ], 
-  [
-    "NEO", 
-    "NeoGenomics, Inc.", 
-    "4.44", 
-    "$266.27M", 
-    "n/a", 
-    "Health Care", 
-    "Precision Instruments", 
-    "http://www.nasdaq.com/symbol/neo"
-  ], 
-  [
-    "NEOG", 
-    "Neogen Corporation", 
-    "49.34", 
-    "$1.82B", 
-    "1989", 
-    "Health Care", 
-    "Biotechnology: In Vitro & In Vivo Diagnostic Substances", 
-    "http://www.nasdaq.com/symbol/neog"
-  ], 
-  [
-    "NEON", 
-    "Neonode Inc.", 
-    "3.01", 
-    "$121.77M", 
-    "n/a", 
-    "Capital Goods", 
-    "Industrial Machinery/Components", 
-    "http://www.nasdaq.com/symbol/neon"
-  ], 
-  [
-    "NEOT", 
-    "Neothetics, Inc.", 
-    "6.805", 
-    "$92.69M", 
-    "1996", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/neot"
-  ], 
-  [
-    "NEPT", 
-    "Neptune Technologies & Bioresources Inc", 
-    "1.82", 
-    "$136.93M", 
-    "n/a", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/nept"
-  ], 
-  [
-    "NERV", 
-    "Minerva Neurosciences, Inc", 
-    "5.32", 
-    "$98.1M", 
-    "2014", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/nerv"
-  ], 
-  [
-    "NETE", 
-    "Net Element, Inc.", 
-    "1.25", 
-    "$57.03M", 
-    "n/a", 
-    "Technology", 
-    "EDP Services", 
-    "http://www.nasdaq.com/symbol/nete"
-  ], 
-  [
-    "NEWP", 
-    "Newport Corporation", 
-    "20.11", 
-    "$801.33M", 
-    "n/a", 
-    "Capital Goods", 
-    "Medical Specialities", 
-    "http://www.nasdaq.com/symbol/newp"
-  ], 
-  [
-    "NEWS", 
-    "NewStar Financial, Inc.", 
-    "9.87", 
-    "$469.84M", 
-    "2006", 
-    "Finance", 
-    "Finance: Consumer Services", 
-    "http://www.nasdaq.com/symbol/news"
-  ], 
-  [
-    "NEWT", 
-    "Newtek Business Services Corp.", 
-    "16.1", 
-    "$121.86M", 
-    "n/a", 
-    "Miscellaneous", 
-    "Business Services", 
-    "http://www.nasdaq.com/symbol/newt"
-  ], 
-  [
-    "NFBK", 
-    "Northfield Bancorp, Inc.", 
-    "14.445", 
-    "$707.53M", 
-    "n/a", 
-    "Finance", 
-    "Savings Institutions", 
-    "http://www.nasdaq.com/symbol/nfbk"
-  ], 
-  [
-    "NFEC", 
-    "NF Energy Saving Corporation", 
-    "2.09", 
-    "$11.95M", 
-    "n/a", 
-    "Capital Goods", 
-    "Metal Fabrications", 
-    "http://www.nasdaq.com/symbol/nfec"
-  ], 
-  [
-    "NFLX", 
-    "Netflix, Inc.", 
-    "478.2", 
-    "$28.93B", 
-    "2002", 
-    "Consumer Services", 
-    "Consumer Electronics/Video Chains", 
-    "http://www.nasdaq.com/symbol/nflx"
-  ], 
-  [
-    "NGHC", 
-    "National General Holdings Corp", 
-    "18.4", 
-    "$1.72B", 
-    "n/a", 
-    "Finance", 
-    "Property-Casualty Insurers", 
-    "http://www.nasdaq.com/symbol/nghc"
-  ], 
-  [
-    "NGHCP", 
-    "National General Holdings Corp", 
-    "25.62", 
-    "$56.36M", 
-    "n/a", 
-    "Finance", 
-    "Property-Casualty Insurers", 
-    "http://www.nasdaq.com/symbol/nghcp"
-  ], 
-  [
-    "NHTB", 
-    "New Hampshire Thrift Bancshares, Inc.", 
-    "15.43", 
-    "$127.42M", 
-    "n/a", 
-    "Finance", 
-    "Savings Institutions", 
-    "http://www.nasdaq.com/symbol/nhtb"
-  ], 
-  [
-    "NHTC", 
-    "Natural Health Trends Corp.", 
-    "13.5", 
-    "$172.84M", 
-    "n/a", 
-    "Consumer Durables", 
-    "Consumer Specialties", 
-    "http://www.nasdaq.com/symbol/nhtc"
-  ], 
-  [
-    "NICE", 
-    "NICE-Systems Limited", 
-    "58.88", 
-    "$3.54B", 
-    "n/a", 
-    "Technology", 
-    "Computer Manufacturing", 
-    "http://www.nasdaq.com/symbol/nice"
-  ], 
-  [
-    "NICK", 
-    "Nicholas Financial, Inc.", 
-    "14.89", 
-    "$183.31M", 
-    "n/a", 
-    "Finance", 
-    "Finance Companies", 
-    "http://www.nasdaq.com/symbol/nick"
-  ], 
-  [
-    "NILE", 
-    "Blue Nile, Inc.", 
-    "29.27", 
-    "$346.72M", 
-    "2004", 
-    "Consumer Services", 
-    "Consumer Specialties", 
-    "http://www.nasdaq.com/symbol/nile"
-  ], 
-  [
-    "NKSH", 
-    "National Bankshares, Inc.", 
-    "29.72", 
-    "$206.57M", 
-    "n/a", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/nksh"
-  ], 
-  [
-    "NKTR", 
-    "Nektar Therapeutics", 
-    "13.61", 
-    "$1.75B", 
-    "n/a", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/nktr"
-  ], 
-  [
-    "NLNK", 
-    "NewLink Genetics Corporation", 
-    "39.75", 
-    "$1.11B", 
-    "2011", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/nlnk"
-  ], 
-  [
-    "NLST", 
-    "Netlist, Inc.", 
-    "1.43", 
-    "$59.35M", 
-    "2006", 
-    "Technology", 
-    "Semiconductors", 
-    "http://www.nasdaq.com/symbol/nlst"
-  ], 
-  [
-    "NMIH", 
-    "NMI Holdings Inc", 
-    "7.54", 
-    "$440.06M", 
-    "2013", 
-    "Finance", 
-    "Property-Casualty Insurers", 
-    "http://www.nasdaq.com/symbol/nmih"
-  ], 
-  [
-    "NMRX", 
-    "Numerex Corp.", 
-    "11.3", 
-    "$214.43M", 
-    "n/a", 
-    "Consumer Durables", 
-    "Telecommunications Equipment", 
-    "http://www.nasdaq.com/symbol/nmrx"
-  ], 
-  [
-    "NNBR", 
-    "NN, Inc.", 
-    "27.1", 
-    "$513.74M", 
-    "1994", 
-    "Capital Goods", 
-    "Metal Fabrications", 
-    "http://www.nasdaq.com/symbol/nnbr"
-  ], 
-  [
-    "NPBC", 
-    "National Penn Bancshares, Inc.", 
-    "10.64", 
-    "$1.57B", 
-    "n/a", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/npbc"
-  ], 
-  [
-    "NPSP", 
-    "NPS Pharmaceuticals, Inc.", 
-    "45.97", 
-    "$4.99B", 
-    "1994", 
-    "Health Care", 
-    "Biotechnology: Biological Products (No Diagnostic Substances)", 
-    "http://www.nasdaq.com/symbol/npsp"
-  ], 
-  [
-    "NRCIA", 
-    "National Research Corporation", 
-    "14.04", 
-    "$342.21M", 
-    "n/a", 
-    "Health Care", 
-    "Biotechnology: Commercial Physical & Biological Resarch", 
-    "http://www.nasdaq.com/symbol/nrcia"
-  ], 
-  [
-    "NRCIB", 
-    "National Research Corporation", 
-    "33.02", 
-    "$804.84M", 
-    "n/a", 
-    "Health Care", 
-    "Biotechnology: Commercial Physical & Biological Resarch", 
-    "http://www.nasdaq.com/symbol/nrcib"
-  ], 
-  [
-    "NRIM", 
-    "Northrim BanCorp Inc", 
-    "22.36", 
-    "$152.81M", 
-    "n/a", 
-    "Finance", 
-    "Savings Institutions", 
-    "http://www.nasdaq.com/symbol/nrim"
-  ], 
-  [
-    "NRX", 
-    "NephroGenex, Inc.", 
-    "6.3", 
-    "$55.83M", 
-    "2014", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/nrx"
-  ], 
-  [
-    "NSEC", 
-    "National Security Group, Inc.", 
-    "13.11", 
-    "$32.87M", 
-    "n/a", 
-    "Finance", 
-    "Life Insurance", 
-    "http://www.nasdaq.com/symbol/nsec"
-  ], 
-  [
-    "NSIT", 
-    "Insight Enterprises, Inc.", 
-    "26.1", 
-    "$1.07B", 
-    "1995", 
-    "Consumer Services", 
-    "Catalog/Specialty Distribution", 
-    "http://www.nasdaq.com/symbol/nsit"
-  ], 
-  [
-    "NSPH", 
-    "Nanosphere, Inc.", 
-    "0.2935", 
-    "$34.43M", 
-    "2007", 
-    "Health Care", 
-    "Medical/Dental Instruments", 
-    "http://www.nasdaq.com/symbol/nsph"
-  ], 
-  [
-    "NSSC", 
-    "NAPCO Security Technologies, Inc.", 
-    "5.36", 
-    "$102.24M", 
-    "n/a", 
-    "Consumer Durables", 
-    "Telecommunications Equipment", 
-    "http://www.nasdaq.com/symbol/nssc"
-  ], 
-  [
-    "NSTG", 
-    "NanoString Technologies, Inc.", 
-    "12.28", 
-    "$223.53M", 
-    "2013", 
-    "Health Care", 
-    "Biotechnology: Biological Products (No Diagnostic Substances)", 
-    "http://www.nasdaq.com/symbol/nstg"
-  ], 
-  [
-    "NSYS", 
-    "Nortech Systems Incorporated", 
-    "5.58", 
-    "$15.31M", 
-    "n/a", 
-    "Capital Goods", 
-    "Industrial Machinery/Components", 
-    "http://www.nasdaq.com/symbol/nsys"
-  ], 
-  [
-    "NTAP", 
-    "NetApp, Inc.", 
-    "38.2", 
-    "$11.91B", 
-    "1995", 
-    "Technology", 
-    "Electronic Components", 
-    "http://www.nasdaq.com/symbol/ntap"
-  ], 
-  [
-    "NTCT", 
-    "NetScout Systems, Inc.", 
-    "39.13", 
-    "$1.61B", 
-    "1999", 
-    "Technology", 
-    "EDP Services", 
-    "http://www.nasdaq.com/symbol/ntct"
-  ], 
-  [
-    "NTES", 
-    "NetEase, Inc.", 
-    "110.08", 
-    "$14.31B", 
-    "n/a", 
-    "Miscellaneous", 
-    "Business Services", 
-    "http://www.nasdaq.com/symbol/ntes"
-  ], 
-  [
-    "NTGR", 
-    "NETGEAR, Inc.", 
-    "32.22", 
-    "$1.11B", 
-    "2003", 
-    "Public Utilities", 
-    "Telecommunications Equipment", 
-    "http://www.nasdaq.com/symbol/ntgr"
-  ], 
-  [
-    "NTIC", 
-    "Northern Technologies International Corporation", 
-    "20.9", 
-    "$94.51M", 
-    "n/a", 
-    "Capital Goods", 
-    "Industrial Specialties", 
-    "http://www.nasdaq.com/symbol/ntic"
-  ], 
-  [
-    "NTK", 
-    "Nortek Inc.", 
-    "80.31", 
-    "$1.3B", 
-    "n/a", 
-    "Consumer Durables", 
-    "Home Furnishings", 
-    "http://www.nasdaq.com/symbol/ntk"
-  ], 
-  [
-    "NTLS", 
-    "NTELOS Holdings Corp.", 
-    "4.97", 
-    "$107.38M", 
-    "2006", 
-    "Public Utilities", 
-    "Telecommunications Equipment", 
-    "http://www.nasdaq.com/symbol/ntls"
-  ], 
-  [
-    "NTRI", 
-    "NutriSystem Inc", 
-    "17.56", 
-    "$505.24M", 
-    "n/a", 
-    "Consumer Services", 
-    "Catalog/Specialty Distribution", 
-    "http://www.nasdaq.com/symbol/ntri"
-  ], 
-  [
-    "NTRS", 
-    "Northern Trust Corporation", 
-    "70.08", 
-    "$16.5B", 
-    "n/a", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/ntrs"
-  ], 
-  [
-    "NTRSP", 
-    "Northern Trust Corporation", 
-    "25.61", 
-    "$409.76M", 
-    "n/a", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/ntrsp"
-  ], 
-  [
-    "NTWK", 
-    "NetSol Technologies Inc.", 
-    "5.8", 
-    "$56.99M", 
-    "n/a", 
-    "Technology", 
-    "Computer Software: Prepackaged Software", 
-    "http://www.nasdaq.com/symbol/ntwk"
-  ], 
-  [
-    "NUAN", 
-    "Nuance Communications, Inc.", 
-    "14.025", 
-    "$4.56B", 
-    "n/a", 
-    "Technology", 
-    "Computer Software: Prepackaged Software", 
-    "http://www.nasdaq.com/symbol/nuan"
-  ], 
-  [
-    "NURO", 
-    "NeuroMetrix, Inc.", 
-    "1.72", 
-    "$13.66M", 
-    "2004", 
-    "n/a", 
-    "n/a", 
-    "http://www.nasdaq.com/symbol/nuro"
-  ], 
-  [
-    "NUTR", 
-    "Nutraceutical International Corporation", 
-    "17.82", 
-    "$171.7M", 
-    "1998", 
-    "Consumer Durables", 
-    "Specialty Chemicals", 
-    "http://www.nasdaq.com/symbol/nutr"
-  ], 
-  [
-    "NUVA", 
-    "NuVasive, Inc.", 
-    "47.98", 
-    "$2.26B", 
-    "2004", 
-    "Health Care", 
-    "Medical/Dental Instruments", 
-    "http://www.nasdaq.com/symbol/nuva"
-  ], 
-  [
-    "NVAX", 
-    "Novavax, Inc.", 
-    "9.51", 
-    "$2.27B", 
-    "n/a", 
-    "Health Care", 
-    "Biotechnology: Biological Products (No Diagnostic Substances)", 
-    "http://www.nasdaq.com/symbol/nvax"
-  ], 
-  [
-    "NVCN", 
-    "Neovasc Inc.", 
-    "9.54", 
-    "$613.02M", 
-    "n/a", 
-    "Health Care", 
-    "Medical/Dental Instruments", 
-    "http://www.nasdaq.com/symbol/nvcn"
-  ], 
-  [
-    "NVDA", 
-    "NVIDIA Corporation", 
-    "22.335", 
-    "$12.14B", 
-    "1999", 
-    "Technology", 
-    "Semiconductors", 
-    "http://www.nasdaq.com/symbol/nvda"
-  ], 
-  [
-    "NVDQ", 
-    "Novadaq Technologies Inc", 
-    "15.35", 
-    "$853.04M", 
-    "n/a", 
-    "Health Care", 
-    "Biotechnology: Electromedical & Electrotherapeutic Apparatus", 
-    "http://www.nasdaq.com/symbol/nvdq"
-  ], 
-  [
-    "NVEC", 
-    "NVE Corporation", 
-    "63.38", 
-    "$307.9M", 
-    "n/a", 
-    "Technology", 
-    "Semiconductors", 
-    "http://www.nasdaq.com/symbol/nvec"
-  ], 
-  [
-    "NVEE", 
-    "NV5 Holdings, Inc.", 
-    "12.3", 
-    "$70.75M", 
-    "2013", 
-    "Consumer Services", 
-    "Other Consumer Services", 
-    "http://www.nasdaq.com/symbol/nvee"
-  ], 
-  [
-    "NVET", 
-    "Nexvet Biopharma plc", 
-    "9.5", 
-    "$105.26M", 
-    "2015", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/nvet"
-  ], 
-  [
-    "NVFY", 
-    "Nova Lifestyle, Inc", 
-    "2.5997", 
-    "$54.04M", 
-    "n/a", 
-    "Consumer Durables", 
-    "Home Furnishings", 
-    "http://www.nasdaq.com/symbol/nvfy"
-  ], 
-  [
-    "NVGN", 
-    "Novogen Limited", 
-    "2.76", 
-    "$18.61M", 
-    "n/a", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/nvgn"
-  ], 
-  [
-    "NVMI", 
-    "Nova Measuring Instruments Ltd.", 
-    "11.45", 
-    "$317.49M", 
-    "2000", 
-    "Capital Goods", 
-    "Electronic Components", 
-    "http://www.nasdaq.com/symbol/nvmi"
-  ], 
-  [
-    "NVSL", 
-    "Naugatuck Valley Financial Corporation", 
-    "9.089", 
-    "$63.64M", 
-    "n/a", 
-    "Finance", 
-    "Savings Institutions", 
-    "http://www.nasdaq.com/symbol/nvsl"
-  ], 
-  [
-    "NWBI", 
-    "Northwest Bancshares, Inc.", 
-    "11.76", 
-    "$1.12B", 
-    "2009", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/nwbi"
-  ], 
-  [
-    "NWBO", 
-    "Northwest Biotherapeutics, Inc.", 
-    "6.37", 
-    "$396.33M", 
-    "2012", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/nwbo"
-  ], 
-  [
-    "NWBOW", 
-    "Northwest Biotherapeutics, Inc.", 
-    "3.2499", 
-    "n/a", 
-    "n/a", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/nwbow"
-  ], 
-  [
-    "NWFL", 
-    "Norwood Financial Corp.", 
-    "28.6001", 
-    "$104.27M", 
-    "n/a", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/nwfl"
-  ], 
-  [
-    "NWLI", 
-    "National Western Life Insurance Company", 
-    "252.91", 
-    "$919.62M", 
-    "n/a", 
-    "Finance", 
-    "Life Insurance", 
-    "http://www.nasdaq.com/symbol/nwli"
-  ], 
-  [
-    "NWPX", 
-    "Northwest Pipe Company", 
-    "25.11", 
-    "$239.05M", 
-    "1995", 
-    "Basic Industries", 
-    "Steel/Iron Ore", 
-    "http://www.nasdaq.com/symbol/nwpx"
-  ], 
-  [
-    "NWS", 
-    "News Corporation", 
-    "16.67", 
-    "$9.68B", 
-    "n/a", 
-    "Consumer Services", 
-    "Newspapers/Magazines", 
-    "http://www.nasdaq.com/symbol/nws"
-  ], 
-  [
-    "NWSA", 
-    "News Corporation", 
-    "17.14", 
-    "$9.95B", 
-    "n/a", 
-    "Consumer Services", 
-    "Newspapers/Magazines", 
-    "http://www.nasdaq.com/symbol/nwsa"
-  ], 
-  [
-    "NXPI", 
-    "NXP Semiconductors N.V.", 
-    "84.66", 
-    "$19.54B", 
-    "2010", 
-    "Technology", 
-    "Semiconductors", 
-    "http://www.nasdaq.com/symbol/nxpi"
-  ], 
-  [
-    "NXST", 
-    "Nexstar Broadcasting Group, Inc.", 
-    "54.21", 
-    "$1.67B", 
-    "2003", 
-    "Consumer Services", 
-    "Broadcasting", 
-    "http://www.nasdaq.com/symbol/nxst"
-  ], 
-  [
-    "NXTD", 
-    "NXT-ID Inc.", 
-    "2.67", 
-    "$65.93M", 
-    "n/a", 
-    "Consumer Services", 
-    "Diversified Commercial Services", 
-    "http://www.nasdaq.com/symbol/nxtd"
-  ], 
-  [
-    "NXTDW", 
-    "NXT-ID Inc.", 
-    "1", 
-    "n/a", 
-    "n/a", 
-    "Consumer Services", 
-    "Diversified Commercial Services", 
-    "http://www.nasdaq.com/symbol/nxtdw"
-  ], 
-  [
-    "NXTM", 
-    "NxStage Medical, Inc.", 
-    "17.77", 
-    "$1.1B", 
-    "2005", 
-    "Health Care", 
-    "Biotechnology: Electromedical & Electrotherapeutic Apparatus", 
-    "http://www.nasdaq.com/symbol/nxtm"
-  ], 
-  [
-    "NYMT", 
-    "New York Mortgage Trust, Inc.", 
-    "7.79", 
-    "$706.43M", 
-    "n/a", 
-    "Consumer Services", 
-    "Real Estate Investment Trusts", 
-    "http://www.nasdaq.com/symbol/nymt"
-  ], 
-  [
-    "NYMTP", 
-    "New York Mortgage Trust, Inc.", 
-    "24.68", 
-    "n/a", 
-    "n/a", 
-    "Finance", 
-    "Finance: Consumer Services", 
-    "http://www.nasdaq.com/symbol/nymtp"
-  ], 
-  [
-    "NYMX", 
-    "Nymox Pharmaceutical Corporation", 
-    "0.41", 
-    "$14.68M", 
-    "n/a", 
-    "Health Care", 
-    "Biotechnology: In Vitro & In Vivo Diagnostic Substances", 
-    "http://www.nasdaq.com/symbol/nymx"
-  ]
-]
\ No newline at end of file
diff --git a/examples/stocks/data/stock_data_19.json b/examples/stocks/data/stock_data_19.json
deleted file mode 100644
index 46ed9ce..0000000
--- a/examples/stocks/data/stock_data_19.json
+++ /dev/null
@@ -1,1002 +0,0 @@
-[
-  [
-    "NYNY", 
-    "Empire Resorts, Inc.", 
-    "6.2", 
-    "$244.94M", 
-    "n/a", 
-    "Consumer Services", 
-    "Restaurants", 
-    "http://www.nasdaq.com/symbol/nyny"
-  ], 
-  [
-    "OBAS", 
-    "Optibase Ltd.", 
-    "6.18", 
-    "$32.03M", 
-    "1999", 
-    "Finance", 
-    "Real Estate", 
-    "http://www.nasdaq.com/symbol/obas"
-  ], 
-  [
-    "OBCI", 
-    "Ocean Bio-Chem, Inc.", 
-    "5.36", 
-    "$47.78M", 
-    "n/a", 
-    "Consumer Durables", 
-    "Specialty Chemicals", 
-    "http://www.nasdaq.com/symbol/obci"
-  ], 
-  [
-    "OCC", 
-    "Optical Cable Corporation", 
-    "5.13", 
-    "$35.09M", 
-    "n/a", 
-    "Basic Industries", 
-    "Telecommunications Equipment", 
-    "http://www.nasdaq.com/symbol/occ"
-  ], 
-  [
-    "OCFC", 
-    "OceanFirst Financial Corp.", 
-    "16.84", 
-    "$295.93M", 
-    "n/a", 
-    "Finance", 
-    "Savings Institutions", 
-    "http://www.nasdaq.com/symbol/ocfc"
-  ], 
-  [
-    "OCLR", 
-    "Oclaro, Inc.", 
-    "1.51", 
-    "$164.62M", 
-    "n/a", 
-    "Technology", 
-    "Semiconductors", 
-    "http://www.nasdaq.com/symbol/oclr"
-  ], 
-  [
-    "OCLS", 
-    "Oculus Innovative Sciences, Inc.", 
-    "0.913", 
-    "$13.61M", 
-    "2007", 
-    "Health Care", 
-    "Medical/Dental Instruments", 
-    "http://www.nasdaq.com/symbol/ocls"
-  ], 
-  [
-    "OCLSW", 
-    "Oculus Innovative Sciences, Inc.", 
-    "0.265", 
-    "n/a", 
-    "n/a", 
-    "Health Care", 
-    "Medical/Dental Instruments", 
-    "http://www.nasdaq.com/symbol/oclsw"
-  ], 
-  [
-    "OCRX", 
-    "Ocera Therapeutics, Inc.", 
-    "6", 
-    "$118.45M", 
-    "2011", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/ocrx"
-  ], 
-  [
-    "OCUL", 
-    "Ocular Therapeutix, Inc.", 
-    "31.37", 
-    "$668.88M", 
-    "2014", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/ocul"
-  ], 
-  [
-    "ODFL", 
-    "Old Dominion Freight Line, Inc.", 
-    "77.775", 
-    "$6.7B", 
-    "1991", 
-    "Transportation", 
-    "Trucking Freight/Courier Services", 
-    "http://www.nasdaq.com/symbol/odfl"
-  ], 
-  [
-    "ODP", 
-    "Office Depot, Inc.", 
-    "9.49", 
-    "$5.11B", 
-    "n/a", 
-    "Consumer Services", 
-    "Other Specialty Stores", 
-    "http://www.nasdaq.com/symbol/odp"
-  ], 
-  [
-    "OFED", 
-    "Oconee Federal Financial Corp.", 
-    "20.6526", 
-    "$120.5M", 
-    "2011", 
-    "Finance", 
-    "Savings Institutions", 
-    "http://www.nasdaq.com/symbol/ofed"
-  ], 
-  [
-    "OFIX", 
-    "Orthofix International N.V.", 
-    "31.99", 
-    "$589.78M", 
-    "1992", 
-    "Health Care", 
-    "Medical/Dental Instruments", 
-    "http://www.nasdaq.com/symbol/ofix"
-  ], 
-  [
-    "OFLX", 
-    "Omega Flex, Inc.", 
-    "30.84", 
-    "$311.23M", 
-    "n/a", 
-    "Capital Goods", 
-    "Industrial Specialties", 
-    "http://www.nasdaq.com/symbol/oflx"
-  ], 
-  [
-    "OFS", 
-    "OFS Capital Corporation", 
-    "11.6701", 
-    "$112.48M", 
-    "2012", 
-    "n/a", 
-    "n/a", 
-    "http://www.nasdaq.com/symbol/ofs"
-  ], 
-  [
-    "OGXI", 
-    "OncoGenex Pharmaceuticals Inc.", 
-    "2.27", 
-    "$48.31M", 
-    "n/a", 
-    "Health Care", 
-    "Biotechnology: In Vitro & In Vivo Diagnostic Substances", 
-    "http://www.nasdaq.com/symbol/ogxi"
-  ], 
-  [
-    "OHAI", 
-    "OHA Investment Corporation", 
-    "4.75", 
-    "$97.93M", 
-    "n/a", 
-    "n/a", 
-    "n/a", 
-    "http://www.nasdaq.com/symbol/ohai"
-  ], 
-  [
-    "OHGI", 
-    "One Horizon Group, Inc.", 
-    "1.7966", 
-    "$59.15M", 
-    "n/a", 
-    "Public Utilities", 
-    "Telecommunications Equipment", 
-    "http://www.nasdaq.com/symbol/ohgi"
-  ], 
-  [
-    "OHRP", 
-    "Ohr Pharmaceuticals, Inc.", 
-    "7.15", 
-    "$212.01M", 
-    "n/a", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/ohrp"
-  ], 
-  [
-    "OIIM", 
-    "O2Micro International Limited", 
-    "2.54", 
-    "$67.42M", 
-    "n/a", 
-    "Technology", 
-    "Semiconductors", 
-    "http://www.nasdaq.com/symbol/oiim"
-  ], 
-  [
-    "OKSB", 
-    "Southwest Bancorp, Inc.", 
-    "16.62", 
-    "$323.36M", 
-    "1993", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/oksb"
-  ], 
-  [
-    "OLBK", 
-    "Old Line Bancshares, Inc.", 
-    "14.4", 
-    "$155.4M", 
-    "n/a", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/olbk"
-  ], 
-  [
-    "OLED", 
-    "Universal Display Corporation", 
-    "35.94", 
-    "$1.64B", 
-    "n/a", 
-    "Capital Goods", 
-    "Electrical Products", 
-    "http://www.nasdaq.com/symbol/oled"
-  ], 
-  [
-    "OMAB", 
-    "Grupo Aeroportuario del Centro Norte S.A.B. de C.V.", 
-    "37.69", 
-    "$1.86B", 
-    "2006", 
-    "Transportation", 
-    "Aerospace", 
-    "http://www.nasdaq.com/symbol/omab"
-  ], 
-  [
-    "OMCL", 
-    "Omnicell, Inc.", 
-    "35.21", 
-    "$1.25B", 
-    "2001", 
-    "Technology", 
-    "Computer Manufacturing", 
-    "http://www.nasdaq.com/symbol/omcl"
-  ], 
-  [
-    "OMED", 
-    "OncoMed Pharmaceuticals, Inc.", 
-    "27.05", 
-    "$806.96M", 
-    "2013", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/omed"
-  ], 
-  [
-    "OMER", 
-    "Omeros Corporation", 
-    "21.25", 
-    "$799.56M", 
-    "2009", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/omer"
-  ], 
-  [
-    "OMEX", 
-    "Odyssey Marine Exploration, Inc.", 
-    "0.7494", 
-    "$63.94M", 
-    "n/a", 
-    "Consumer Services", 
-    "Marine Transportation", 
-    "http://www.nasdaq.com/symbol/omex"
-  ], 
-  [
-    "ONB", 
-    "Old National Bancorp", 
-    "14.03", 
-    "$1.6B", 
-    "n/a", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/onb"
-  ], 
-  [
-    "ONCE", 
-    "Spark Therapeutics, Inc.", 
-    "51.44", 
-    "$1.21B", 
-    "2015", 
-    "Health Care", 
-    "Biotechnology: Biological Products (No Diagnostic Substances)", 
-    "http://www.nasdaq.com/symbol/once"
-  ], 
-  [
-    "ONCY", 
-    "Oncolytics Biotech, Inc.", 
-    "0.665", 
-    "$62.19M", 
-    "n/a", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/oncy"
-  ], 
-  [
-    "ONEQ", 
-    "Fidelity Nasdaq Composite Tracker Stock", 
-    "194.5468", 
-    "$447.46M", 
-    "n/a", 
-    "n/a", 
-    "n/a", 
-    "http://www.nasdaq.com/symbol/oneq"
-  ], 
-  [
-    "ONFC", 
-    "Oneida Financial Corp.", 
-    "13.12", 
-    "$92.13M", 
-    "n/a", 
-    "Finance", 
-    "Savings Institutions", 
-    "http://www.nasdaq.com/symbol/onfc"
-  ], 
-  [
-    "ONNN", 
-    "ON Semiconductor Corporation", 
-    "12.02", 
-    "$5.24B", 
-    "2000", 
-    "Technology", 
-    "Semiconductors", 
-    "http://www.nasdaq.com/symbol/onnn"
-  ], 
-  [
-    "ONTX", 
-    "Onconova Therapeutics, Inc.", 
-    "2.38", 
-    "$51.63M", 
-    "2013", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/ontx"
-  ], 
-  [
-    "ONTY", 
-    "Oncothyreon Inc.", 
-    "1.55", 
-    "$141.91M", 
-    "n/a", 
-    "Health Care", 
-    "Biotechnology: Commercial Physical & Biological Resarch", 
-    "http://www.nasdaq.com/symbol/onty"
-  ], 
-  [
-    "ONVI", 
-    "Onvia, Inc.", 
-    "4.51", 
-    "$33.36M", 
-    "2000", 
-    "Miscellaneous", 
-    "Business Services", 
-    "http://www.nasdaq.com/symbol/onvi"
-  ], 
-  [
-    "OPB", 
-    "Opus Bank", 
-    "28.49", 
-    "$800.6M", 
-    "2014", 
-    "n/a", 
-    "n/a", 
-    "http://www.nasdaq.com/symbol/opb"
-  ], 
-  [
-    "OPHC", 
-    "OptimumBank Holdings, Inc.", 
-    "1.043", 
-    "$9.7M", 
-    "n/a", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/ophc"
-  ], 
-  [
-    "OPHT", 
-    "Ophthotech Corporation", 
-    "55.82", 
-    "$1.88B", 
-    "2013", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/opht"
-  ], 
-  [
-    "OPOF", 
-    "Old Point Financial Corporation", 
-    "14.96", 
-    "$74.19M", 
-    "n/a", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/opof"
-  ], 
-  [
-    "OPTT", 
-    "Ocean Power Technologies, Inc.", 
-    "0.53", 
-    "$9.58M", 
-    "2007", 
-    "Public Utilities", 
-    "Electric Utilities: Central", 
-    "http://www.nasdaq.com/symbol/optt"
-  ], 
-  [
-    "OPXA", 
-    "Opexa Therapeutics, Inc.", 
-    "0.73", 
-    "$20.57M", 
-    "n/a", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/opxa"
-  ], 
-  [
-    "ORBC", 
-    "ORBCOMM Inc.", 
-    "5.71", 
-    "$388.99M", 
-    "2006", 
-    "Consumer Services", 
-    "Telecommunications Equipment", 
-    "http://www.nasdaq.com/symbol/orbc"
-  ], 
-  [
-    "ORBK", 
-    "Orbotech Ltd.", 
-    "16.2", 
-    "$672.38M", 
-    "n/a", 
-    "Capital Goods", 
-    "Industrial Machinery/Components", 
-    "http://www.nasdaq.com/symbol/orbk"
-  ], 
-  [
-    "OREX", 
-    "Orexigen Therapeutics, Inc.", 
-    "5.96", 
-    "$734.07M", 
-    "2007", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/orex"
-  ], 
-  [
-    "ORIG", 
-    "Ocean Rig UDW Inc.", 
-    "8.61", 
-    "$1.14B", 
-    "n/a", 
-    "Energy", 
-    "Oil & Gas Production", 
-    "http://www.nasdaq.com/symbol/orig"
-  ], 
-  [
-    "ORIT", 
-    "Oritani Financial Corp.", 
-    "14.33", 
-    "$632.51M", 
-    "n/a", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/orit"
-  ], 
-  [
-    "ORLY", 
-    "O&#39;Reilly Automotive, Inc.", 
-    "205.84", 
-    "$20.88B", 
-    "1993", 
-    "Consumer Services", 
-    "Other Specialty Stores", 
-    "http://www.nasdaq.com/symbol/orly"
-  ], 
-  [
-    "ORMP", 
-    "Oramed Pharmaceuticals Inc.", 
-    "4.7", 
-    "$50.92M", 
-    "n/a", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/ormp"
-  ], 
-  [
-    "ORPN", 
-    "Bio Blast Pharma Ltd.", 
-    "6.91", 
-    "$98.33M", 
-    "2014", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/orpn"
-  ], 
-  [
-    "ORRF", 
-    "Orrstown Financial Services Inc", 
-    "16.77", 
-    "$138.58M", 
-    "n/a", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/orrf"
-  ], 
-  [
-    "OSBC", 
-    "Old Second Bancorp, Inc.", 
-    "5.52", 
-    "$162.52M", 
-    "n/a", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/osbc"
-  ], 
-  [
-    "OSBCP", 
-    "Old Second Bancorp, Inc.", 
-    "10", 
-    "n/a", 
-    "n/a", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/osbcp"
-  ], 
-  [
-    "OSHC", 
-    "Ocean Shore Holding Co.", 
-    "14.39", 
-    "$92.4M", 
-    "n/a", 
-    "Finance", 
-    "Savings Institutions", 
-    "http://www.nasdaq.com/symbol/oshc"
-  ], 
-  [
-    "OSIR", 
-    "Osiris Therapeutics, Inc.", 
-    "16.52", 
-    "$566.97M", 
-    "2006", 
-    "Health Care", 
-    "Biotechnology: Biological Products (No Diagnostic Substances)", 
-    "http://www.nasdaq.com/symbol/osir"
-  ], 
-  [
-    "OSIS", 
-    "OSI Systems, Inc.", 
-    "72.5", 
-    "$1.44B", 
-    "1997", 
-    "Technology", 
-    "Semiconductors", 
-    "http://www.nasdaq.com/symbol/osis"
-  ], 
-  [
-    "OSM", 
-    "SLM Corporation", 
-    "24.49", 
-    "n/a", 
-    "n/a", 
-    "Finance", 
-    "Finance: Consumer Services", 
-    "http://www.nasdaq.com/symbol/osm"
-  ], 
-  [
-    "OSN", 
-    "Ossen Innovation Co., Ltd.", 
-    "0.75", 
-    "$14.93M", 
-    "2010", 
-    "Basic Industries", 
-    "Steel/Iron Ore", 
-    "http://www.nasdaq.com/symbol/osn"
-  ], 
-  [
-    "OSTK", 
-    "Overstock.com, Inc.", 
-    "21.33", 
-    "$512.71M", 
-    "2002", 
-    "Consumer Services", 
-    "Catalog/Specialty Distribution", 
-    "http://www.nasdaq.com/symbol/ostk"
-  ], 
-  [
-    "OSUR", 
-    "OraSure Technologies, Inc.", 
-    "7.84", 
-    "$439.49M", 
-    "n/a", 
-    "Health Care", 
-    "Medical/Dental Instruments", 
-    "http://www.nasdaq.com/symbol/osur"
-  ], 
-  [
-    "OTEL", 
-    "Otelco Inc.", 
-    "5.0372", 
-    "$15.63M", 
-    "n/a", 
-    "Public Utilities", 
-    "Telecommunications Equipment", 
-    "http://www.nasdaq.com/symbol/otel"
-  ], 
-  [
-    "OTEX", 
-    "Open Text Corporation", 
-    "59.75", 
-    "$7.3B", 
-    "1996", 
-    "Technology", 
-    "EDP Services", 
-    "http://www.nasdaq.com/symbol/otex"
-  ], 
-  [
-    "OTIC", 
-    "Otonomy, Inc.", 
-    "33.31", 
-    "$802.96M", 
-    "2014", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/otic"
-  ], 
-  [
-    "OTIV", 
-    "On Track Innovations Ltd", 
-    "1.41", 
-    "$47.35M", 
-    "n/a", 
-    "Technology", 
-    "Semiconductors", 
-    "http://www.nasdaq.com/symbol/otiv"
-  ], 
-  [
-    "OTTR", 
-    "Otter Tail Corporation", 
-    "32.42", 
-    "$1.19B", 
-    "n/a", 
-    "Public Utilities", 
-    "Electric Utilities: Central", 
-    "http://www.nasdaq.com/symbol/ottr"
-  ], 
-  [
-    "OUTR", 
-    "Outerwall Inc.", 
-    "67.27", 
-    "$1.28B", 
-    "n/a", 
-    "Consumer Services", 
-    "Other Consumer Services", 
-    "http://www.nasdaq.com/symbol/outr"
-  ], 
-  [
-    "OVAS", 
-    "Ovascience Inc.", 
-    "46.05", 
-    "$1.12B", 
-    "n/a", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/ovas"
-  ], 
-  [
-    "OVBC", 
-    "Ohio Valley Banc Corp.", 
-    "23.72", 
-    "$97.22M", 
-    "n/a", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/ovbc"
-  ], 
-  [
-    "OVLY", 
-    "Oak Valley Bancorp (CA)", 
-    "10.08", 
-    "$81.39M", 
-    "n/a", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/ovly"
-  ], 
-  [
-    "OVTI", 
-    "OmniVision Technologies, Inc.", 
-    "26.64", 
-    "$1.54B", 
-    "2000", 
-    "Technology", 
-    "Semiconductors", 
-    "http://www.nasdaq.com/symbol/ovti"
-  ], 
-  [
-    "OXBR", 
-    "Oxbridge Re Holdings Limited", 
-    "6.12", 
-    "$36.72M", 
-    "2014", 
-    "Finance", 
-    "Property-Casualty Insurers", 
-    "http://www.nasdaq.com/symbol/oxbr"
-  ], 
-  [
-    "OXBRW", 
-    "Oxbridge Re Holdings Limited", 
-    "1.35", 
-    "n/a", 
-    "2014", 
-    "Finance", 
-    "Property-Casualty Insurers", 
-    "http://www.nasdaq.com/symbol/oxbrw"
-  ], 
-  [
-    "OXFD", 
-    "Oxford Immunotec Global PLC", 
-    "13.26", 
-    "$233.53M", 
-    "2013", 
-    "Health Care", 
-    "Biotechnology: In Vitro & In Vivo Diagnostic Substances", 
-    "http://www.nasdaq.com/symbol/oxfd"
-  ], 
-  [
-    "OXGN", 
-    "OXiGENE, Inc.", 
-    "1.74", 
-    "$36.03M", 
-    "n/a", 
-    "Health Care", 
-    "Biotechnology: Biological Products (No Diagnostic Substances)", 
-    "http://www.nasdaq.com/symbol/oxgn"
-  ], 
-  [
-    "OXLC", 
-    "Oxford Lane Capital Corp.", 
-    "15.47", 
-    "$242.93M", 
-    "2011", 
-    "n/a", 
-    "n/a", 
-    "http://www.nasdaq.com/symbol/oxlc"
-  ], 
-  [
-    "OXLCN", 
-    "Oxford Lane Capital Corp.", 
-    "25.3", 
-    "$28.34M", 
-    "n/a", 
-    "n/a", 
-    "n/a", 
-    "http://www.nasdaq.com/symbol/oxlcn"
-  ], 
-  [
-    "OXLCO", 
-    "Oxford Lane Capital Corp.", 
-    "24.47", 
-    "n/a", 
-    "n/a", 
-    "n/a", 
-    "n/a", 
-    "http://www.nasdaq.com/symbol/oxlco"
-  ], 
-  [
-    "OXLCP", 
-    "Oxford Lane Capital Corp.", 
-    "25.483", 
-    "n/a", 
-    "n/a", 
-    "n/a", 
-    "n/a", 
-    "http://www.nasdaq.com/symbol/oxlcp"
-  ], 
-  [
-    "OZRK", 
-    "Bank of the Ozarks", 
-    "35.5", 
-    "$2.83B", 
-    "1997", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/ozrk"
-  ], 
-  [
-    "PAAS", 
-    "Pan American Silver Corp.", 
-    "10", 
-    "$1.52B", 
-    "n/a", 
-    "Basic Industries", 
-    "Precious Metals", 
-    "http://www.nasdaq.com/symbol/paas"
-  ], 
-  [
-    "PACB", 
-    "Pacific Biosciences of California, Inc.", 
-    "6.85", 
-    "$506.4M", 
-    "2010", 
-    "Capital Goods", 
-    "Biotechnology: Laboratory Analytical Instruments", 
-    "http://www.nasdaq.com/symbol/pacb"
-  ], 
-  [
-    "PACW", 
-    "PacWest Bancorp", 
-    "45.55", 
-    "$4.69B", 
-    "n/a", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/pacw"
-  ], 
-  [
-    "PAGG", 
-    "PowerShares Global Agriculture Portfolio", 
-    "30.79", 
-    "$70.82M", 
-    "n/a", 
-    "n/a", 
-    "n/a", 
-    "http://www.nasdaq.com/symbol/pagg"
-  ], 
-  [
-    "PAHC", 
-    "Phibro Animal Health Corporation", 
-    "34.5", 
-    "$1.35B", 
-    "2014", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/pahc"
-  ], 
-  [
-    "PANL", 
-    "Pangaea Logistics Solutions Ltd.", 
-    "2.6292", 
-    "$26.29", 
-    "2013", 
-    "Consumer Services", 
-    "Marine Transportation", 
-    "http://www.nasdaq.com/symbol/panl"
-  ], 
-  [
-    "PARN", 
-    "Parnell Pharmaceuticals Holdings Ltd", 
-    "4.4966", 
-    "$59.73M", 
-    "2014", 
-    "n/a", 
-    "n/a", 
-    "http://www.nasdaq.com/symbol/parn"
-  ], 
-  [
-    "PATI", 
-    "Patriot Transportation Holding, Inc.", 
-    "23.2", 
-    "$75.04M", 
-    "n/a", 
-    "Transportation", 
-    "Trucking Freight/Courier Services", 
-    "http://www.nasdaq.com/symbol/pati"
-  ], 
-  [
-    "PATK", 
-    "Patrick Industries, Inc.", 
-    "59.1", 
-    "$607.65M", 
-    "n/a", 
-    "Basic Industries", 
-    "Forest Products", 
-    "http://www.nasdaq.com/symbol/patk"
-  ], 
-  [
-    "PAYX", 
-    "Paychex, Inc.", 
-    "49.555", 
-    "$18B", 
-    "1983", 
-    "Consumer Services", 
-    "Diversified Commercial Services", 
-    "http://www.nasdaq.com/symbol/payx"
-  ], 
-  [
-    "PBCP", 
-    "Polonia Bancorp, Inc.", 
-    "10.4985", 
-    "$35.02M", 
-    "n/a", 
-    "Finance", 
-    "Savings Institutions", 
-    "http://www.nasdaq.com/symbol/pbcp"
-  ], 
-  [
-    "PBCT", 
-    "People&#39;s United Financial, Inc.", 
-    "14.97", 
-    "$4.61B", 
-    "n/a", 
-    "Finance", 
-    "Savings Institutions", 
-    "http://www.nasdaq.com/symbol/pbct"
-  ], 
-  [
-    "PBHC", 
-    "Pathfinder Bancorp, Inc.", 
-    "9.82", 
-    "$42.74M", 
-    "n/a", 
-    "Finance", 
-    "Banks", 
-    "http://www.nasdaq.com/symbol/pbhc"
-  ], 
-  [
-    "PBIB", 
-    "Porter Bancorp, Inc.", 
-    "0.8901", 
-    "$13.25M", 
-    "2006", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/pbib"
-  ], 
-  [
-    "PBIP", 
-    "Prudential Bancorp, Inc.", 
-    "12.22", 
-    "$113.69M", 
-    "n/a", 
-    "Finance", 
-    "Banks", 
-    "http://www.nasdaq.com/symbol/pbip"
-  ], 
-  [
-    "PBMD", 
-    "Prima BioMed Ltd", 
-    "0.8", 
-    "$32.77M", 
-    "n/a", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/pbmd"
-  ], 
-  [
-    "PBPB", 
-    "Potbelly Corporation", 
-    "15.34", 
-    "$444.32M", 
-    "2013", 
-    "Consumer Services", 
-    "Restaurants", 
-    "http://www.nasdaq.com/symbol/pbpb"
-  ], 
-  [
-    "PBSK", 
-    "Poage Bankshares, Inc.", 
-    "15", 
-    "$58.23M", 
-    "2011", 
-    "Finance", 
-    "Savings Institutions", 
-    "http://www.nasdaq.com/symbol/pbsk"
-  ], 
-  [
-    "PCAR", 
-    "PACCAR Inc.", 
-    "64.59", 
-    "$22.87B", 
-    "n/a", 
-    "Capital Goods", 
-    "Auto Manufacturing", 
-    "http://www.nasdaq.com/symbol/pcar"
-  ]
-]
\ No newline at end of file
diff --git a/examples/stocks/data/stock_data_2.json b/examples/stocks/data/stock_data_2.json
deleted file mode 100644
index 3dee177..0000000
--- a/examples/stocks/data/stock_data_2.json
+++ /dev/null
@@ -1,1002 +0,0 @@
-[
-  [
-    "AROW", 
-    "Arrow Financial Corporation", 
-    "26.31", 
-    "$331.69M", 
-    "n/a", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/arow"
-  ], 
-  [
-    "ARQL", 
-    "ArQule, Inc.", 
-    "1.35", 
-    "$84.74M", 
-    "1996", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/arql"
-  ], 
-  [
-    "ARRS", 
-    "ARRIS Group, Inc.", 
-    "28.59", 
-    "$4.14B", 
-    "n/a", 
-    "Technology", 
-    "Radio And Television Broadcasting And Communications Equipment", 
-    "http://www.nasdaq.com/symbol/arrs"
-  ], 
-  [
-    "ARRY", 
-    "Array BioPharma Inc.", 
-    "8.24", 
-    "$1.15B", 
-    "2000", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/arry"
-  ], 
-  [
-    "ARTNA", 
-    "Artesian Resources Corporation", 
-    "21.59", 
-    "$192.19M", 
-    "n/a", 
-    "Public Utilities", 
-    "Water Supply", 
-    "http://www.nasdaq.com/symbol/artna"
-  ], 
-  [
-    "ARTW", 
-    "Art&#39;s-Way Manufacturing Co., Inc.", 
-    "4.68", 
-    "$18.95M", 
-    "n/a", 
-    "Capital Goods", 
-    "Industrial Machinery/Components", 
-    "http://www.nasdaq.com/symbol/artw"
-  ], 
-  [
-    "ARTX", 
-    "Arotech Corporation", 
-    "2.61", 
-    "$63.8M", 
-    "1994", 
-    "Miscellaneous", 
-    "Industrial Machinery/Components", 
-    "http://www.nasdaq.com/symbol/artx"
-  ], 
-  [
-    "ARUN", 
-    "Aruba Networks, Inc.", 
-    "18.43", 
-    "$2.02B", 
-    "2007", 
-    "Technology", 
-    "Computer peripheral equipment", 
-    "http://www.nasdaq.com/symbol/arun"
-  ], 
-  [
-    "ARWR", 
-    "Arrowhead Research Corporation", 
-    "7.38", 
-    "$404.37M", 
-    "n/a", 
-    "Health Care", 
-    "Biotechnology: Commercial Physical & Biological Resarch", 
-    "http://www.nasdaq.com/symbol/arwr"
-  ], 
-  [
-    "ASBB", 
-    "ASB Bancorp, Inc.", 
-    "20.4", 
-    "$89.32M", 
-    "2011", 
-    "Finance", 
-    "Savings Institutions", 
-    "http://www.nasdaq.com/symbol/asbb"
-  ], 
-  [
-    "ASBI", 
-    "Ameriana Bancorp", 
-    "15.831", 
-    "$47.6M", 
-    "n/a", 
-    "Finance", 
-    "Savings Institutions", 
-    "http://www.nasdaq.com/symbol/asbi"
-  ], 
-  [
-    "ASCMA", 
-    "Ascent Capital Group, Inc.", 
-    "46.18", 
-    "$636.36M", 
-    "n/a", 
-    "Consumer Services", 
-    "Other Consumer Services", 
-    "http://www.nasdaq.com/symbol/ascma"
-  ], 
-  [
-    "ASEI", 
-    "American Science and Engineering, Inc.", 
-    "51.52", 
-    "$380.58M", 
-    "n/a", 
-    "Health Care", 
-    "Medical Electronics", 
-    "http://www.nasdaq.com/symbol/asei"
-  ], 
-  [
-    "ASFI", 
-    "Asta Funding, Inc.", 
-    "8.44", 
-    "$109.6M", 
-    "1995", 
-    "Finance", 
-    "Finance Companies", 
-    "http://www.nasdaq.com/symbol/asfi"
-  ], 
-  [
-    "ASMB", 
-    "Assembly Biosciences, Inc.", 
-    "14.95", 
-    "$159.17M", 
-    "n/a", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/asmb"
-  ], 
-  [
-    "ASMI", 
-    "ASM International N.V.", 
-    "44.23", 
-    "$2.82B", 
-    "n/a", 
-    "Technology", 
-    "Industrial Machinery/Components", 
-    "http://www.nasdaq.com/symbol/asmi"
-  ], 
-  [
-    "ASML", 
-    "ASML Holding N.V.", 
-    "104.85", 
-    "$45.39B", 
-    "1995", 
-    "Technology", 
-    "Industrial Machinery/Components", 
-    "http://www.nasdaq.com/symbol/asml"
-  ], 
-  [
-    "ASNA", 
-    "Ascena Retail Group, Inc.", 
-    "13.16", 
-    "$2.14B", 
-    "n/a", 
-    "Consumer Services", 
-    "Clothing/Shoe/Accessory Stores", 
-    "http://www.nasdaq.com/symbol/asna"
-  ], 
-  [
-    "ASND", 
-    "Ascendis Pharma A/S", 
-    "19.34", 
-    "$443.58M", 
-    "2015", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/asnd"
-  ], 
-  [
-    "ASPS", 
-    "Altisource Portfolio Solutions S.A.", 
-    "23.2", 
-    "$470.31M", 
-    "n/a", 
-    "Consumer Services", 
-    "Other Consumer Services", 
-    "http://www.nasdaq.com/symbol/asps"
-  ], 
-  [
-    "ASPX", 
-    "Auspex Pharmaceuticals, Inc.", 
-    "70.25", 
-    "$2.2B", 
-    "2014", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/aspx"
-  ], 
-  [
-    "ASRV", 
-    "AmeriServ Financial Inc.", 
-    "2.95", 
-    "$55.44M", 
-    "n/a", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/asrv"
-  ], 
-  [
-    "ASRVP", 
-    "AmeriServ Financial Inc.", 
-    "27.66", 
-    "n/a", 
-    "n/a", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/asrvp"
-  ], 
-  [
-    "ASTC", 
-    "Astrotech Corporation", 
-    "3.1799", 
-    "$63.64M", 
-    "n/a", 
-    "Capital Goods", 
-    "Military/Government/Technical", 
-    "http://www.nasdaq.com/symbol/astc"
-  ], 
-  [
-    "ASTE", 
-    "Astec Industries, Inc.", 
-    "39.27", 
-    "$900.41M", 
-    "1986", 
-    "Capital Goods", 
-    "Construction/Ag Equipment/Trucks", 
-    "http://www.nasdaq.com/symbol/aste"
-  ], 
-  [
-    "ASTI", 
-    "Ascent Solar Technologies, Inc.", 
-    "1.7", 
-    "$27.62M", 
-    "n/a", 
-    "Technology", 
-    "Semiconductors", 
-    "http://www.nasdaq.com/symbol/asti"
-  ], 
-  [
-    "ASUR", 
-    "Asure Software Inc", 
-    "5.93", 
-    "$35.87M", 
-    "n/a", 
-    "Technology", 
-    "EDP Services", 
-    "http://www.nasdaq.com/symbol/asur"
-  ], 
-  [
-    "ASYS", 
-    "Amtech Systems, Inc.", 
-    "10.49", 
-    "$136.96M", 
-    "n/a", 
-    "Technology", 
-    "Industrial Machinery/Components", 
-    "http://www.nasdaq.com/symbol/asys"
-  ], 
-  [
-    "ATAI", 
-    "ATA Inc.", 
-    "4.37", 
-    "$100.71M", 
-    "2008", 
-    "Consumer Services", 
-    "Other Consumer Services", 
-    "http://www.nasdaq.com/symbol/atai"
-  ], 
-  [
-    "ATAX", 
-    "America First Multifamily Investors, L.P.", 
-    "5.79", 
-    "$348.86M", 
-    "n/a", 
-    "Finance", 
-    "Finance: Consumer Services", 
-    "http://www.nasdaq.com/symbol/atax"
-  ], 
-  [
-    "ATEC", 
-    "Alphatec Holdings, Inc.", 
-    "1.35", 
-    "$134.45M", 
-    "2006", 
-    "Health Care", 
-    "Medical/Dental Instruments", 
-    "http://www.nasdaq.com/symbol/atec"
-  ], 
-  [
-    "ATHN", 
-    "athenahealth, Inc.", 
-    "132.96", 
-    "$5.08B", 
-    "2007", 
-    "Miscellaneous", 
-    "Business Services", 
-    "http://www.nasdaq.com/symbol/athn"
-  ], 
-  [
-    "ATHX", 
-    "Athersys, Inc.", 
-    "2.37", 
-    "$183.71M", 
-    "n/a", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/athx"
-  ], 
-  [
-    "ATLC", 
-    "Atlanticus Holdings Corporation", 
-    "2.88", 
-    "$40.06M", 
-    "1995", 
-    "Finance", 
-    "Finance: Consumer Services", 
-    "http://www.nasdaq.com/symbol/atlc"
-  ], 
-  [
-    "ATLO", 
-    "Ames National Corporation", 
-    "24.74", 
-    "$230.35M", 
-    "n/a", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/atlo"
-  ], 
-  [
-    "ATML", 
-    "Atmel Corporation", 
-    "8.38", 
-    "$3.5B", 
-    "1991", 
-    "Technology", 
-    "Semiconductors", 
-    "http://www.nasdaq.com/symbol/atml"
-  ], 
-  [
-    "ATNI", 
-    "Atlantic Tele-Network, Inc.", 
-    "65", 
-    "$1.03B", 
-    "n/a", 
-    "Public Utilities", 
-    "Telecommunications Equipment", 
-    "http://www.nasdaq.com/symbol/atni"
-  ], 
-  [
-    "ATNY", 
-    "API Technologies Corp.", 
-    "1.8548", 
-    "$102.75M", 
-    "n/a", 
-    "Technology", 
-    "Semiconductors", 
-    "http://www.nasdaq.com/symbol/atny"
-  ], 
-  [
-    "ATOS", 
-    "Atossa Genetics Inc.", 
-    "1.64", 
-    "$40.29M", 
-    "2012", 
-    "Health Care", 
-    "Medical/Dental Instruments", 
-    "http://www.nasdaq.com/symbol/atos"
-  ], 
-  [
-    "ATRA", 
-    "Atara Biotherapeutics, Inc.", 
-    "21.32", 
-    "$519.36M", 
-    "2014", 
-    "Health Care", 
-    "Biotechnology: Biological Products (No Diagnostic Substances)", 
-    "http://www.nasdaq.com/symbol/atra"
-  ], 
-  [
-    "ATRC", 
-    "AtriCure, Inc.", 
-    "18.5", 
-    "$508.21M", 
-    "2005", 
-    "Health Care", 
-    "Medical/Dental Instruments", 
-    "http://www.nasdaq.com/symbol/atrc"
-  ], 
-  [
-    "ATRI", 
-    "ATRION Corporation", 
-    "317.01", 
-    "$617.36M", 
-    "n/a", 
-    "Health Care", 
-    "Medical/Dental Instruments", 
-    "http://www.nasdaq.com/symbol/atri"
-  ], 
-  [
-    "ATRM", 
-    "ATRM Holdings, Inc.", 
-    "3.36", 
-    "$3.99M", 
-    "1993", 
-    "Capital Goods", 
-    "Electrical Products", 
-    "http://www.nasdaq.com/symbol/atrm"
-  ], 
-  [
-    "ATRO", 
-    "Astronics Corporation", 
-    "66.89", 
-    "$1.46B", 
-    "n/a", 
-    "Capital Goods", 
-    "Military/Government/Technical", 
-    "http://www.nasdaq.com/symbol/atro"
-  ], 
-  [
-    "ATRS", 
-    "Antares Pharma, Inc.", 
-    "2.59", 
-    "$341.06M", 
-    "n/a", 
-    "Health Care", 
-    "Medical/Dental Instruments", 
-    "http://www.nasdaq.com/symbol/atrs"
-  ], 
-  [
-    "ATSG", 
-    "Air Transport Services Group, Inc", 
-    "8.95", 
-    "$581.21M", 
-    "n/a", 
-    "Transportation", 
-    "Air Freight/Delivery Services", 
-    "http://www.nasdaq.com/symbol/atsg"
-  ], 
-  [
-    "ATTU", 
-    "Attunity Ltd.", 
-    "9.65", 
-    "$146.48M", 
-    "n/a", 
-    "Technology", 
-    "Computer Software: Prepackaged Software", 
-    "http://www.nasdaq.com/symbol/attu"
-  ], 
-  [
-    "ATVI", 
-    "Activision Blizzard, Inc", 
-    "23.31", 
-    "$16.76B", 
-    "n/a", 
-    "Technology", 
-    "Computer Software: Prepackaged Software", 
-    "http://www.nasdaq.com/symbol/atvi"
-  ], 
-  [
-    "AUBN", 
-    "Auburn National Bancorporation, Inc.", 
-    "24.7499", 
-    "$90.17M", 
-    "n/a", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/aubn"
-  ], 
-  [
-    "AUDC", 
-    "AudioCodes Ltd.", 
-    "5.37", 
-    "$227.15M", 
-    "1999", 
-    "Public Utilities", 
-    "Telecommunications Equipment", 
-    "http://www.nasdaq.com/symbol/audc"
-  ], 
-  [
-    "AUMA", 
-    "AR Capital Acquisition Corp.", 
-    "9.78", 
-    "$293.4M", 
-    "2014", 
-    "Finance", 
-    "Business Services", 
-    "http://www.nasdaq.com/symbol/auma"
-  ], 
-  [
-    "AUMAU", 
-    "AR Capital Acquisition Corp.", 
-    "9.85", 
-    "n/a", 
-    "2014", 
-    "n/a", 
-    "n/a", 
-    "http://www.nasdaq.com/symbol/aumau"
-  ], 
-  [
-    "AUMAW", 
-    "AR Capital Acquisition Corp.", 
-    "0.24", 
-    "n/a", 
-    "2014", 
-    "Finance", 
-    "Business Services", 
-    "http://www.nasdaq.com/symbol/aumaw"
-  ], 
-  [
-    "AUPH", 
-    "Aurinia Pharmaceuticals Inc", 
-    "3.84", 
-    "$122.18M", 
-    "n/a", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/auph"
-  ], 
-  [
-    "AVAV", 
-    "AeroVironment, Inc.", 
-    "27.88", 
-    "$650.21M", 
-    "2007", 
-    "Capital Goods", 
-    "Aerospace", 
-    "http://www.nasdaq.com/symbol/avav"
-  ], 
-  [
-    "AVEO", 
-    "AVEO Pharmaceuticals, Inc.", 
-    "0.9297", 
-    "$48.58M", 
-    "2010", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/aveo"
-  ], 
-  [
-    "AVGO", 
-    "Avago Technologies Limited", 
-    "112.06", 
-    "$28.61B", 
-    "2009", 
-    "Technology", 
-    "Semiconductors", 
-    "http://www.nasdaq.com/symbol/avgo"
-  ], 
-  [
-    "AVGR", 
-    "Avinger, Inc.", 
-    "10.41", 
-    "$106.49M", 
-    "2015", 
-    "Health Care", 
-    "Medical/Dental Instruments", 
-    "http://www.nasdaq.com/symbol/avgr"
-  ], 
-  [
-    "AVHI", 
-    "A V Homes, Inc.", 
-    "15.13", 
-    "$334.32M", 
-    "n/a", 
-    "Capital Goods", 
-    "Homebuilding", 
-    "http://www.nasdaq.com/symbol/avhi"
-  ], 
-  [
-    "AVID", 
-    "Avid Technology, Inc.", 
-    "14.74", 
-    "$578.01M", 
-    "1993", 
-    "Miscellaneous", 
-    "Industrial Machinery/Components", 
-    "http://www.nasdaq.com/symbol/avid"
-  ], 
-  [
-    "AVNU", 
-    "Avenue Financial Holdings, Inc.", 
-    "11.75", 
-    "$117.62M", 
-    "2015", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/avnu"
-  ], 
-  [
-    "AVNW", 
-    "Aviat Networks, Inc.", 
-    "1.27", 
-    "$79.16M", 
-    "n/a", 
-    "Technology", 
-    "Radio And Television Broadcasting And Communications Equipment", 
-    "http://www.nasdaq.com/symbol/avnw"
-  ], 
-  [
-    "AWAY", 
-    "HomeAway, Inc.", 
-    "30.985", 
-    "$2.92B", 
-    "2011", 
-    "Technology", 
-    "EDP Services", 
-    "http://www.nasdaq.com/symbol/away"
-  ], 
-  [
-    "AWRE", 
-    "Aware, Inc.", 
-    "4.59", 
-    "$104.95M", 
-    "1996", 
-    "Technology", 
-    "Computer Software: Prepackaged Software", 
-    "http://www.nasdaq.com/symbol/awre"
-  ], 
-  [
-    "AXAS", 
-    "Abraxas Petroleum Corporation", 
-    "3.16", 
-    "$332.99M", 
-    "n/a", 
-    "Energy", 
-    "Oil & Gas Production", 
-    "http://www.nasdaq.com/symbol/axas"
-  ], 
-  [
-    "AXDX", 
-    "Accelerate Diagnostics, Inc.", 
-    "18.05", 
-    "$805.21M", 
-    "n/a", 
-    "Capital Goods", 
-    "Biotechnology: Laboratory Analytical Instruments", 
-    "http://www.nasdaq.com/symbol/axdx"
-  ], 
-  [
-    "AXGN", 
-    "AxoGen, Inc.", 
-    "3.17", 
-    "$79.02M", 
-    "n/a", 
-    "Health Care", 
-    "Biotechnology: Electromedical & Electrotherapeutic Apparatus", 
-    "http://www.nasdaq.com/symbol/axgn"
-  ], 
-  [
-    "AXJS", 
-    "iShares MSCI All Country Asia ex Japan Small Cap Index Fund", 
-    "56.813", 
-    "$5.68M", 
-    "n/a", 
-    "n/a", 
-    "n/a", 
-    "http://www.nasdaq.com/symbol/axjs"
-  ], 
-  [
-    "AXPW", 
-    "Axion Power International, Inc.", 
-    "0.46", 
-    "$3.28M", 
-    "n/a", 
-    "Miscellaneous", 
-    "Industrial Machinery/Components", 
-    "http://www.nasdaq.com/symbol/axpw"
-  ], 
-  [
-    "AXPWW", 
-    "Axion Power International, Inc.", 
-    "0.14", 
-    "n/a", 
-    "n/a", 
-    "Miscellaneous", 
-    "Industrial Machinery/Components", 
-    "http://www.nasdaq.com/symbol/axpww"
-  ], 
-  [
-    "AXTI", 
-    "AXT Inc", 
-    "2.64", 
-    "$86.69M", 
-    "1998", 
-    "Technology", 
-    "Semiconductors", 
-    "http://www.nasdaq.com/symbol/axti"
-  ], 
-  [
-    "AZPN", 
-    "Aspen Technology, Inc.", 
-    "39.07", 
-    "$3.45B", 
-    "1994", 
-    "Technology", 
-    "EDP Services", 
-    "http://www.nasdaq.com/symbol/azpn"
-  ], 
-  [
-    "BABY", 
-    "Natus Medical Incorporated", 
-    "36.58", 
-    "$1.19B", 
-    "2001", 
-    "Health Care", 
-    "Biotechnology: Electromedical & Electrotherapeutic Apparatus", 
-    "http://www.nasdaq.com/symbol/baby"
-  ], 
-  [
-    "BAGR", 
-    "Diversified Restaurant Holdings, Inc.", 
-    "4.8", 
-    "$125.69M", 
-    "n/a", 
-    "Consumer Services", 
-    "Restaurants", 
-    "http://www.nasdaq.com/symbol/bagr"
-  ], 
-  [
-    "BAMM", 
-    "Books-A-Million, Inc.", 
-    "2.55", 
-    "$38.29M", 
-    "1992", 
-    "Consumer Services", 
-    "Other Specialty Stores", 
-    "http://www.nasdaq.com/symbol/bamm"
-  ], 
-  [
-    "BANF", 
-    "BancFirst Corporation", 
-    "58.97", 
-    "$913.24M", 
-    "1993", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/banf"
-  ], 
-  [
-    "BANFP", 
-    "BancFirst Corporation", 
-    "28.7", 
-    "$28.7M", 
-    "n/a", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/banfp"
-  ], 
-  [
-    "BANR", 
-    "Banner Corporation", 
-    "44.54", 
-    "$871.72M", 
-    "n/a", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/banr"
-  ], 
-  [
-    "BANX", 
-    "StoneCastle Financial Corp", 
-    "21.42", 
-    "$134.9M", 
-    "2013", 
-    "n/a", 
-    "n/a", 
-    "http://www.nasdaq.com/symbol/banx"
-  ], 
-  [
-    "BASI", 
-    "Bioanalytical Systems, Inc.", 
-    "2.0204", 
-    "$16.32M", 
-    "1997", 
-    "Health Care", 
-    "Biotechnology: Commercial Physical & Biological Resarch", 
-    "http://www.nasdaq.com/symbol/basi"
-  ], 
-  [
-    "BBBY", 
-    "Bed Bath & Beyond Inc.", 
-    "76.885", 
-    "$14.27B", 
-    "1992", 
-    "Consumer Services", 
-    "Home Furnishings", 
-    "http://www.nasdaq.com/symbol/bbby"
-  ], 
-  [
-    "BBC", 
-    "BioShares Biotechnology Clinical Trials Fund", 
-    "30.661", 
-    "n/a", 
-    "n/a", 
-    "n/a", 
-    "n/a", 
-    "http://www.nasdaq.com/symbol/bbc"
-  ], 
-  [
-    "BBCN", 
-    "BBCN Bancorp, Inc.", 
-    "13.78", 
-    "$1.1B", 
-    "n/a", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/bbcn"
-  ], 
-  [
-    "BBEP", 
-    "BreitBurn Energy Partners, L.P.", 
-    "7.59", 
-    "$1.05B", 
-    "2006", 
-    "Energy", 
-    "Oil & Gas Production", 
-    "http://www.nasdaq.com/symbol/bbep"
-  ], 
-  [
-    "BBEPP", 
-    "BreitBurn Energy Partners, L.P.", 
-    "22.35", 
-    "$178.8M", 
-    "n/a", 
-    "Energy", 
-    "Oil & Gas Production", 
-    "http://www.nasdaq.com/symbol/bbepp"
-  ], 
-  [
-    "BBGI", 
-    "Beasley Broadcast Group, Inc.", 
-    "5.02", 
-    "$116.02M", 
-    "2000", 
-    "Consumer Services", 
-    "Broadcasting", 
-    "http://www.nasdaq.com/symbol/bbgi"
-  ], 
-  [
-    "BBLU", 
-    "Blue Earth, Inc.", 
-    "1.2199", 
-    "$113.81M", 
-    "n/a", 
-    "Public Utilities", 
-    "Electric Utilities: Central", 
-    "http://www.nasdaq.com/symbol/bblu"
-  ], 
-  [
-    "BBNK", 
-    "Bridge Capital Holdings", 
-    "21.86", 
-    "$350.5M", 
-    "n/a", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/bbnk"
-  ], 
-  [
-    "BBOX", 
-    "Black Box Corporation", 
-    "22.21", 
-    "$341.22M", 
-    "n/a", 
-    "Technology", 
-    "Computer Communications Equipment", 
-    "http://www.nasdaq.com/symbol/bbox"
-  ], 
-  [
-    "BBP", 
-    "BioShares Biotechnology Products Fund", 
-    "29.7493", 
-    "n/a", 
-    "n/a", 
-    "n/a", 
-    "n/a", 
-    "http://www.nasdaq.com/symbol/bbp"
-  ], 
-  [
-    "BBRG", 
-    "Bravo Brio Restaurant Group, Inc.", 
-    "13.5", 
-    "$203.65M", 
-    "2010", 
-    "Consumer Services", 
-    "Restaurants", 
-    "http://www.nasdaq.com/symbol/bbrg"
-  ], 
-  [
-    "BBRY", 
-    "BlackBerry Limited", 
-    "10.27", 
-    "$5.43B", 
-    "n/a", 
-    "Public Utilities", 
-    "Telecommunications Equipment", 
-    "http://www.nasdaq.com/symbol/bbry"
-  ], 
-  [
-    "BBSI", 
-    "Barrett Business Services, Inc.", 
-    "38.57", 
-    "$274.48M", 
-    "1993", 
-    "Technology", 
-    "Professional Services", 
-    "http://www.nasdaq.com/symbol/bbsi"
-  ], 
-  [
-    "BCBP", 
-    "BCB Bancorp, Inc. (NJ)", 
-    "11.73", 
-    "$98.38M", 
-    "2005", 
-    "Finance", 
-    "Savings Institutions", 
-    "http://www.nasdaq.com/symbol/bcbp"
-  ], 
-  [
-    "BCLI", 
-    "Brainstorm Cell Therapeutics Inc.", 
-    "3.92", 
-    "$59.9M", 
-    "n/a", 
-    "Health Care", 
-    "Biotechnology: Biological Products (No Diagnostic Substances)", 
-    "http://www.nasdaq.com/symbol/bcli"
-  ], 
-  [
-    "BCOM", 
-    "B Communications Ltd.", 
-    "17.09", 
-    "$510.8M", 
-    "n/a", 
-    "Consumer Services", 
-    "Telecommunications Equipment", 
-    "http://www.nasdaq.com/symbol/bcom"
-  ], 
-  [
-    "BCOR", 
-    "Blucora, Inc.", 
-    "13.33", 
-    "$546.57M", 
-    "n/a", 
-    "Technology", 
-    "EDP Services", 
-    "http://www.nasdaq.com/symbol/bcor"
-  ], 
-  [
-    "BCOV", 
-    "Brightcove Inc.", 
-    "8.05", 
-    "$259.8M", 
-    "2012", 
-    "Technology", 
-    "EDP Services", 
-    "http://www.nasdaq.com/symbol/bcov"
-  ], 
-  [
-    "BCPC", 
-    "Balchem Corporation", 
-    "58.9", 
-    "$1.81B", 
-    "n/a", 
-    "Basic Industries", 
-    "Major Chemicals", 
-    "http://www.nasdaq.com/symbol/bcpc"
-  ], 
-  [
-    "BCRX", 
-    "BioCryst Pharmaceuticals, Inc.", 
-    "10.15", 
-    "$729.42M", 
-    "1994", 
-    "Health Care", 
-    "Biotechnology: Biological Products (No Diagnostic Substances)", 
-    "http://www.nasdaq.com/symbol/bcrx"
-  ]
-]
\ No newline at end of file
diff --git a/examples/stocks/data/stock_data_20.json b/examples/stocks/data/stock_data_20.json
deleted file mode 100644
index bc94c83..0000000
--- a/examples/stocks/data/stock_data_20.json
+++ /dev/null
@@ -1,1002 +0,0 @@
-[
-  [
-    "PCBK", 
-    "Pacific Continental Corporation (Ore)", 
-    "13.44", 
-    "$238.12M", 
-    "n/a", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/pcbk"
-  ], 
-  [
-    "PCCC", 
-    "PC Connection, Inc.", 
-    "24.64", 
-    "$648.1M", 
-    "1998", 
-    "Consumer Services", 
-    "Catalog/Specialty Distribution", 
-    "http://www.nasdaq.com/symbol/pccc"
-  ], 
-  [
-    "PCH", 
-    "Potlatch Corporation", 
-    "40.02", 
-    "$1.63B", 
-    "n/a", 
-    "Consumer Services", 
-    "Real Estate Investment Trusts", 
-    "http://www.nasdaq.com/symbol/pch"
-  ], 
-  [
-    "PCLN", 
-    "The Priceline Group Inc. ", 
-    "1216.23", 
-    "$63.17B", 
-    "1999", 
-    "Miscellaneous", 
-    "Business Services", 
-    "http://www.nasdaq.com/symbol/pcln"
-  ], 
-  [
-    "PCMI", 
-    "PCM, Inc.", 
-    "9.72", 
-    "$120.34M", 
-    "n/a", 
-    "Consumer Services", 
-    "Catalog/Specialty Distribution", 
-    "http://www.nasdaq.com/symbol/pcmi"
-  ], 
-  [
-    "PCO", 
-    "Pendrell Corporation", 
-    "1.17", 
-    "$312.18M", 
-    "n/a", 
-    "Miscellaneous", 
-    "Multi-Sector Companies", 
-    "http://www.nasdaq.com/symbol/pco"
-  ], 
-  [
-    "PCOM", 
-    "Points International, Ltd.", 
-    "10.59", 
-    "$165.72M", 
-    "n/a", 
-    "Miscellaneous", 
-    "Business Services", 
-    "http://www.nasdaq.com/symbol/pcom"
-  ], 
-  [
-    "PCRX", 
-    "Pacira Pharmaceuticals, Inc.", 
-    "117.33", 
-    "$4.23B", 
-    "2011", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/pcrx"
-  ], 
-  [
-    "PCTI", 
-    "PC-Tel, Inc.", 
-    "8.21", 
-    "$152.11M", 
-    "1999", 
-    "Technology", 
-    "Radio And Television Broadcasting And Communications Equipment", 
-    "http://www.nasdaq.com/symbol/pcti"
-  ], 
-  [
-    "PCTY", 
-    "Paylocity Holding Corporation", 
-    "30.21", 
-    "$1.53B", 
-    "2014", 
-    "Technology", 
-    "Computer Software: Prepackaged Software", 
-    "http://www.nasdaq.com/symbol/pcty"
-  ], 
-  [
-    "PCYC", 
-    "Pharmacyclics, Inc.", 
-    "177.56", 
-    "$13.5B", 
-    "1995", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/pcyc"
-  ], 
-  [
-    "PCYG", 
-    "Park City Group, Inc.", 
-    "13.2", 
-    "$229.27M", 
-    "n/a", 
-    "Technology", 
-    "EDP Services", 
-    "http://www.nasdaq.com/symbol/pcyg"
-  ], 
-  [
-    "PCYO", 
-    "Pure Cycle Corporation", 
-    "4.92", 
-    "$118.26M", 
-    "n/a", 
-    "Public Utilities", 
-    "Water Supply", 
-    "http://www.nasdaq.com/symbol/pcyo"
-  ], 
-  [
-    "PDBC", 
-    "PowerShares DB Optimum Yield Diversified Commodity Strategy Po", 
-    "20.85", 
-    "n/a", 
-    "n/a", 
-    "n/a", 
-    "n/a", 
-    "http://www.nasdaq.com/symbol/pdbc"
-  ], 
-  [
-    "PDCE", 
-    "PDC Energy, Inc.", 
-    "51.37", 
-    "$1.85B", 
-    "n/a", 
-    "Energy", 
-    "Oil & Gas Production", 
-    "http://www.nasdaq.com/symbol/pdce"
-  ], 
-  [
-    "PDCO", 
-    "Patterson Companies, Inc.", 
-    "49.29", 
-    "$5.08B", 
-    "1992", 
-    "Health Care", 
-    "Medical Specialities", 
-    "http://www.nasdaq.com/symbol/pdco"
-  ], 
-  [
-    "PDEX", 
-    "Pro-Dex, Inc.", 
-    "2.28", 
-    "$9.51M", 
-    "n/a", 
-    "Health Care", 
-    "Medical/Dental Instruments", 
-    "http://www.nasdaq.com/symbol/pdex"
-  ], 
-  [
-    "PDFS", 
-    "PDF Solutions, Inc.", 
-    "17.68", 
-    "$547.64M", 
-    "2001", 
-    "Technology", 
-    "EDP Services", 
-    "http://www.nasdaq.com/symbol/pdfs"
-  ], 
-  [
-    "PDII", 
-    "PDI, Inc.", 
-    "1.96", 
-    "$30.11M", 
-    "1998", 
-    "Miscellaneous", 
-    "Business Services", 
-    "http://www.nasdaq.com/symbol/pdii"
-  ], 
-  [
-    "PDLI", 
-    "PDL BioPharma, Inc.", 
-    "7.28", 
-    "$1.17B", 
-    "1992", 
-    "Health Care", 
-    "Biotechnology: Biological Products (No Diagnostic Substances)", 
-    "http://www.nasdaq.com/symbol/pdli"
-  ], 
-  [
-    "PDVW", 
-    "Pacific DataVision, Inc.", 
-    "55", 
-    "n/a", 
-    "2015", 
-    "Public Utilities", 
-    "Telecommunications Equipment", 
-    "http://www.nasdaq.com/symbol/pdvw"
-  ], 
-  [
-    "PEBK", 
-    "Peoples Bancorp of North Carolina, Inc.", 
-    "18.11", 
-    "$101.73M", 
-    "n/a", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/pebk"
-  ], 
-  [
-    "PEBO", 
-    "Peoples Bancorp Inc.", 
-    "23.94", 
-    "$338.76M", 
-    "n/a", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/pebo"
-  ], 
-  [
-    "PEGA", 
-    "Pegasystems Inc.", 
-    "22.56", 
-    "$1.72B", 
-    "1996", 
-    "Technology", 
-    "EDP Services", 
-    "http://www.nasdaq.com/symbol/pega"
-  ], 
-  [
-    "PEGI", 
-    "Pattern Energy Group Inc.", 
-    "28.26", 
-    "$1.95B", 
-    "2013", 
-    "n/a", 
-    "n/a", 
-    "http://www.nasdaq.com/symbol/pegi"
-  ], 
-  [
-    "PEIX", 
-    "Pacific Ethanol, Inc.", 
-    "9.73", 
-    "$238.24M", 
-    "n/a", 
-    "Basic Industries", 
-    "Major Chemicals", 
-    "http://www.nasdaq.com/symbol/peix"
-  ], 
-  [
-    "PENN", 
-    "Penn National Gaming, Inc.", 
-    "16.39", 
-    "$1.29B", 
-    "1994", 
-    "Consumer Services", 
-    "Hotels/Resorts", 
-    "http://www.nasdaq.com/symbol/penn"
-  ], 
-  [
-    "PENX", 
-    "Penford Corporation", 
-    "18.82", 
-    "$240.68M", 
-    "n/a", 
-    "Consumer Non-Durables", 
-    "Packaged Foods", 
-    "http://www.nasdaq.com/symbol/penx"
-  ], 
-  [
-    "PERF", 
-    "Perfumania Holdings, Inc", 
-    "5.63", 
-    "$87.13M", 
-    "n/a", 
-    "Consumer Services", 
-    "Other Specialty Stores", 
-    "http://www.nasdaq.com/symbol/perf"
-  ], 
-  [
-    "PERI", 
-    "Perion Network Ltd", 
-    "3.27", 
-    "$231.05M", 
-    "n/a", 
-    "Technology", 
-    "EDP Services", 
-    "http://www.nasdaq.com/symbol/peri"
-  ], 
-  [
-    "PERY", 
-    "Perry Ellis International Inc.", 
-    "23.03", 
-    "$357.02M", 
-    "1993", 
-    "Consumer Non-Durables", 
-    "Apparel", 
-    "http://www.nasdaq.com/symbol/pery"
-  ], 
-  [
-    "PESI", 
-    "Perma-Fix Environmental Services, Inc.", 
-    "4.19", 
-    "$48.05M", 
-    "n/a", 
-    "Basic Industries", 
-    "Environmental Services", 
-    "http://www.nasdaq.com/symbol/pesi"
-  ], 
-  [
-    "PETM", 
-    "PetSmart, Inc", 
-    "82.91", 
-    "$8.24B", 
-    "1993", 
-    "Consumer Services", 
-    "Other Specialty Stores", 
-    "http://www.nasdaq.com/symbol/petm"
-  ], 
-  [
-    "PETS", 
-    "PetMed Express, Inc.", 
-    "15.36", 
-    "$311.24M", 
-    "n/a", 
-    "Health Care", 
-    "Medical/Nursing Services", 
-    "http://www.nasdaq.com/symbol/pets"
-  ], 
-  [
-    "PETX", 
-    "Aratana Therapeutics, Inc.", 
-    "16.98", 
-    "$589.3M", 
-    "2013", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/petx"
-  ], 
-  [
-    "PFBC", 
-    "Preferred Bank", 
-    "27.63", 
-    "$372.87M", 
-    "n/a", 
-    "n/a", 
-    "n/a", 
-    "http://www.nasdaq.com/symbol/pfbc"
-  ], 
-  [
-    "PFBI", 
-    "Premier Financial Bancorp, Inc.", 
-    "14.9104", 
-    "$121M", 
-    "1996", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/pfbi"
-  ], 
-  [
-    "PFBX", 
-    "Peoples Financial Corporation", 
-    "10.62", 
-    "$54.41M", 
-    "n/a", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/pfbx"
-  ], 
-  [
-    "PFIE", 
-    "Profire Energy, Inc.", 
-    "2.2", 
-    "$116.73M", 
-    "n/a", 
-    "Energy", 
-    "Metal Fabrications", 
-    "http://www.nasdaq.com/symbol/pfie"
-  ], 
-  [
-    "PFIN", 
-    "P & F Industries, Inc.", 
-    "7.6", 
-    "$27.24M", 
-    "n/a", 
-    "Technology", 
-    "Industrial Machinery/Components", 
-    "http://www.nasdaq.com/symbol/pfin"
-  ], 
-  [
-    "PFIS", 
-    "Peoples Financial Services Corp. ", 
-    "41.54", 
-    "$313.56M", 
-    "n/a", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/pfis"
-  ], 
-  [
-    "PFLT", 
-    "PennantPark Floating Rate Capital Ltd.", 
-    "13.88", 
-    "$206.79M", 
-    "2011", 
-    "n/a", 
-    "n/a", 
-    "http://www.nasdaq.com/symbol/pflt"
-  ], 
-  [
-    "PFMT", 
-    "Performant Financial Corporation", 
-    "5.93", 
-    "$292.64M", 
-    "2012", 
-    "Consumer Services", 
-    "Other Consumer Services", 
-    "http://www.nasdaq.com/symbol/pfmt"
-  ], 
-  [
-    "PFPT", 
-    "Proofpoint, Inc.", 
-    "57.24", 
-    "$2.18B", 
-    "2012", 
-    "Technology", 
-    "EDP Services", 
-    "http://www.nasdaq.com/symbol/pfpt"
-  ], 
-  [
-    "PFSW", 
-    "PFSweb, Inc.", 
-    "10.83", 
-    "$185.78M", 
-    "1999", 
-    "Miscellaneous", 
-    "Business Services", 
-    "http://www.nasdaq.com/symbol/pfsw"
-  ], 
-  [
-    "PGC", 
-    "Peapack-Gladstone Financial Corporation", 
-    "19.25", 
-    "$236.57M", 
-    "n/a", 
-    "Finance", 
-    "Commercial Banks", 
-    "http://www.nasdaq.com/symbol/pgc"
-  ], 
-  [
-    "PGNX", 
-    "Progenics Pharmaceuticals Inc.", 
-    "6.23", 
-    "$433.33M", 
-    "1997", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/pgnx"
-  ], 
-  [
-    "PGTI", 
-    "PGT, Inc.", 
-    "8.43", 
-    "$401.44M", 
-    "2006", 
-    "Capital Goods", 
-    "Building Products", 
-    "http://www.nasdaq.com/symbol/pgti"
-  ], 
-  [
-    "PHII", 
-    "PHI, Inc.", 
-    "34.45", 
-    "$533.38M", 
-    "n/a", 
-    "Transportation", 
-    "Transportation Services", 
-    "http://www.nasdaq.com/symbol/phii"
-  ], 
-  [
-    "PHIIK", 
-    "PHI, Inc.", 
-    "32.99", 
-    "$510.77M", 
-    "n/a", 
-    "Transportation", 
-    "Transportation Services", 
-    "http://www.nasdaq.com/symbol/phiik"
-  ], 
-  [
-    "PHMD", 
-    "PhotoMedex, Inc.", 
-    "1.72", 
-    "$35.04M", 
-    "n/a", 
-    "Health Care", 
-    "Biotechnology: Electromedical & Electrotherapeutic Apparatus", 
-    "http://www.nasdaq.com/symbol/phmd"
-  ], 
-  [
-    "PICO", 
-    "PICO Holdings Inc.", 
-    "16.42", 
-    "$377.74M", 
-    "n/a", 
-    "Finance", 
-    "Real Estate", 
-    "http://www.nasdaq.com/symbol/pico"
-  ], 
-  [
-    "PIH", 
-    "1347 Property Insurance Holdings, Inc.", 
-    "7.66", 
-    "$48.7M", 
-    "2014", 
-    "Finance", 
-    "Property-Casualty Insurers", 
-    "http://www.nasdaq.com/symbol/pih"
-  ], 
-  [
-    "PINC", 
-    "Premier, Inc.", 
-    "35.31", 
-    "$1.32B", 
-    "2013", 
-    "Consumer Services", 
-    "Other Consumer Services", 
-    "http://www.nasdaq.com/symbol/pinc"
-  ], 
-  [
-    "PKBK", 
-    "Parke Bancorp, Inc.", 
-    "11.572", 
-    "$69.34M", 
-    "n/a", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/pkbk"
-  ], 
-  [
-    "PKOH", 
-    "Park-Ohio Holdings Corp.", 
-    "56.16", 
-    "$702.62M", 
-    "n/a", 
-    "Capital Goods", 
-    "Industrial Specialties", 
-    "http://www.nasdaq.com/symbol/pkoh"
-  ], 
-  [
-    "PKT", 
-    "Procera Networks, Inc.", 
-    "8.82", 
-    "$182.92M", 
-    "n/a", 
-    "Technology", 
-    "EDP Services", 
-    "http://www.nasdaq.com/symbol/pkt"
-  ], 
-  [
-    "PLAB", 
-    "Photronics, Inc.", 
-    "8.54", 
-    "$566.62M", 
-    "1987", 
-    "Technology", 
-    "Semiconductors", 
-    "http://www.nasdaq.com/symbol/plab"
-  ], 
-  [
-    "PLAY", 
-    "Dave & Buster&#39;s Entertainment, Inc.", 
-    "30.48", 
-    "$1.22B", 
-    "2014", 
-    "Consumer Services", 
-    "Restaurants", 
-    "http://www.nasdaq.com/symbol/play"
-  ], 
-  [
-    "PLBC", 
-    "Plumas Bancorp", 
-    "9", 
-    "$43.16M", 
-    "n/a", 
-    "Finance", 
-    "Finance Companies", 
-    "http://www.nasdaq.com/symbol/plbc"
-  ], 
-  [
-    "PLCE", 
-    "Children&#39;s Place, Inc. (The)", 
-    "56.96", 
-    "$1.21B", 
-    "1997", 
-    "Consumer Services", 
-    "Clothing/Shoe/Accessory Stores", 
-    "http://www.nasdaq.com/symbol/plce"
-  ], 
-  [
-    "PLCM", 
-    "Polycom, Inc.", 
-    "13.84", 
-    "$1.89B", 
-    "1996", 
-    "Public Utilities", 
-    "Telecommunications Equipment", 
-    "http://www.nasdaq.com/symbol/plcm"
-  ], 
-  [
-    "PLKI", 
-    "Popeyes Louisiana Kitchen, Inc.", 
-    "62.4", 
-    "$1.46B", 
-    "n/a", 
-    "Consumer Services", 
-    "Restaurants", 
-    "http://www.nasdaq.com/symbol/plki"
-  ], 
-  [
-    "PLMT", 
-    "Palmetto Bancshares, Inc. (SC)", 
-    "17.03", 
-    "$217.87M", 
-    "n/a", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/plmt"
-  ], 
-  [
-    "PLNR", 
-    "Planar Systems, Inc.", 
-    "6.07", 
-    "$136.02M", 
-    "1993", 
-    "Capital Goods", 
-    "Industrial Machinery/Components", 
-    "http://www.nasdaq.com/symbol/plnr"
-  ], 
-  [
-    "PLPC", 
-    "Preformed Line Products Company", 
-    "46.32", 
-    "$248.02M", 
-    "n/a", 
-    "Basic Industries", 
-    "Water Supply", 
-    "http://www.nasdaq.com/symbol/plpc"
-  ], 
-  [
-    "PLPM", 
-    "Planet Payment, Inc.", 
-    "1.62", 
-    "$90.41M", 
-    "n/a", 
-    "Miscellaneous", 
-    "Business Services", 
-    "http://www.nasdaq.com/symbol/plpm"
-  ], 
-  [
-    "PLTM", 
-    "First Trust ISE Global Platinum Index", 
-    "10.67", 
-    "$10.14M", 
-    "n/a", 
-    "n/a", 
-    "n/a", 
-    "http://www.nasdaq.com/symbol/pltm"
-  ], 
-  [
-    "PLUG", 
-    "Plug Power, Inc.", 
-    "3.24", 
-    "$560.93M", 
-    "1999", 
-    "Energy", 
-    "Industrial Machinery/Components", 
-    "http://www.nasdaq.com/symbol/plug"
-  ], 
-  [
-    "PLUS", 
-    "ePlus inc.", 
-    "80.59", 
-    "$595.59M", 
-    "1996", 
-    "Technology", 
-    "Retail: Computer Software & Peripheral Equipment", 
-    "http://www.nasdaq.com/symbol/plus"
-  ], 
-  [
-    "PLXS", 
-    "Plexus Corp.", 
-    "40.62", 
-    "$1.37B", 
-    "n/a", 
-    "Technology", 
-    "Electrical Products", 
-    "http://www.nasdaq.com/symbol/plxs"
-  ], 
-  [
-    "PMBC", 
-    "Pacific Mercantile Bancorp", 
-    "7.1", 
-    "$137.99M", 
-    "2000", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/pmbc"
-  ], 
-  [
-    "PMCS", 
-    "PMC - Sierra, Inc.", 
-    "9.47", 
-    "$1.88B", 
-    "n/a", 
-    "Technology", 
-    "Semiconductors", 
-    "http://www.nasdaq.com/symbol/pmcs"
-  ], 
-  [
-    "PMD", 
-    "Psychemedics Corporation", 
-    "16.07", 
-    "$86.38M", 
-    "n/a", 
-    "Health Care", 
-    "Medical Specialities", 
-    "http://www.nasdaq.com/symbol/pmd"
-  ], 
-  [
-    "PME", 
-    "Pingtan Marine Enterprise Ltd.", 
-    "2.51", 
-    "$198.43M", 
-    "n/a", 
-    "n/a", 
-    "n/a", 
-    "http://www.nasdaq.com/symbol/pme"
-  ], 
-  [
-    "PMFG", 
-    "PMFG, Inc.", 
-    "4.62", 
-    "$98.42M", 
-    "n/a", 
-    "Capital Goods", 
-    "Industrial Machinery/Components", 
-    "http://www.nasdaq.com/symbol/pmfg"
-  ], 
-  [
-    "PNBK", 
-    "Patriot National Bancorp Inc.", 
-    "1.58", 
-    "$61.87M", 
-    "n/a", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/pnbk"
-  ], 
-  [
-    "PNFP", 
-    "Pinnacle Financial Partners, Inc.", 
-    "40.48", 
-    "$1.44B", 
-    "n/a", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/pnfp"
-  ], 
-  [
-    "PNNT", 
-    "PennantPark Investment Corporation", 
-    "9.49", 
-    "$712.63M", 
-    "2007", 
-    "n/a", 
-    "n/a", 
-    "http://www.nasdaq.com/symbol/pnnt"
-  ], 
-  [
-    "PNQI", 
-    "PowerShares NASDAQ Internet Portfolio", 
-    "70.67", 
-    "$229.68M", 
-    "n/a", 
-    "n/a", 
-    "n/a", 
-    "http://www.nasdaq.com/symbol/pnqi"
-  ], 
-  [
-    "PNRA", 
-    "Panera Bread Company", 
-    "157.48", 
-    "$4.25B", 
-    "n/a", 
-    "Consumer Services", 
-    "Restaurants", 
-    "http://www.nasdaq.com/symbol/pnra"
-  ], 
-  [
-    "PNRG", 
-    "PrimeEnergy Corporation", 
-    "58.96", 
-    "$138.18M", 
-    "n/a", 
-    "Energy", 
-    "Oil & Gas Production", 
-    "http://www.nasdaq.com/symbol/pnrg"
-  ], 
-  [
-    "PNTR", 
-    "Pointer Telocation Ltd.", 
-    "8.33", 
-    "$64.05M", 
-    "n/a", 
-    "Technology", 
-    "Radio And Television Broadcasting And Communications Equipment", 
-    "http://www.nasdaq.com/symbol/pntr"
-  ], 
-  [
-    "PODD", 
-    "Insulet Corporation", 
-    "31.99", 
-    "$1.79B", 
-    "2007", 
-    "Health Care", 
-    "Medical/Dental Instruments", 
-    "http://www.nasdaq.com/symbol/podd"
-  ], 
-  [
-    "POOL", 
-    "Pool Corporation", 
-    "69.93", 
-    "$3.04B", 
-    "1995", 
-    "Consumer Durables", 
-    "Industrial Specialties", 
-    "http://www.nasdaq.com/symbol/pool"
-  ], 
-  [
-    "POPE", 
-    "Pope Resources", 
-    "62.974", 
-    "$272.42M", 
-    "n/a", 
-    "Consumer Non-Durables", 
-    "Environmental Services", 
-    "http://www.nasdaq.com/symbol/pope"
-  ], 
-  [
-    "POWI", 
-    "Power Integrations, Inc.", 
-    "54.66", 
-    "$1.6B", 
-    "1997", 
-    "Technology", 
-    "Semiconductors", 
-    "http://www.nasdaq.com/symbol/powi"
-  ], 
-  [
-    "POWL", 
-    "Powell Industries, Inc.", 
-    "33.41", 
-    "$402.91M", 
-    "n/a", 
-    "Consumer Durables", 
-    "Electrical Products", 
-    "http://www.nasdaq.com/symbol/powl"
-  ], 
-  [
-    "POZN", 
-    "Pozen, Inc.", 
-    "7.32", 
-    "$234.81M", 
-    "2000", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/pozn"
-  ], 
-  [
-    "PPBI", 
-    "Pacific Premier Bancorp Inc", 
-    "16.07", 
-    "$271.49M", 
-    "n/a", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/ppbi"
-  ], 
-  [
-    "PPC", 
-    "Pilgrim&#39;s Pride Corporation", 
-    "27.645", 
-    "$7.18B", 
-    "n/a", 
-    "Consumer Non-Durables", 
-    "Meat/Poultry/Fish", 
-    "http://www.nasdaq.com/symbol/ppc"
-  ], 
-  [
-    "PPHM", 
-    "Peregrine Pharmaceuticals Inc.", 
-    "1.29", 
-    "$234.88M", 
-    "n/a", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/pphm"
-  ], 
-  [
-    "PPHMP", 
-    "Peregrine Pharmaceuticals Inc.", 
-    "21.95", 
-    "$15.37M", 
-    "n/a", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/pphmp"
-  ], 
-  [
-    "PPSI", 
-    "Pioneer Power Solutions, Inc.", 
-    "9.07", 
-    "$65.05M", 
-    "n/a", 
-    "Consumer Durables", 
-    "Electrical Products", 
-    "http://www.nasdaq.com/symbol/ppsi"
-  ], 
-  [
-    "PRAA", 
-    "PRA Group, Inc.", 
-    "54.15", 
-    "$2.71B", 
-    "2002", 
-    "Finance", 
-    "Finance: Consumer Services", 
-    "http://www.nasdaq.com/symbol/praa"
-  ], 
-  [
-    "PRAH", 
-    "PRA Health Sciences, Inc.", 
-    "28.08", 
-    "$1.61B", 
-    "2014", 
-    "Health Care", 
-    "Biotechnology: Commercial Physical & Biological Resarch", 
-    "http://www.nasdaq.com/symbol/prah"
-  ], 
-  [
-    "PRAN", 
-    "Prana Biotechnology Ltd", 
-    "1.11", 
-    "$54.24M", 
-    "n/a", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/pran"
-  ], 
-  [
-    "PRCP", 
-    "Perceptron, Inc.", 
-    "11.06", 
-    "$102.41M", 
-    "1992", 
-    "Capital Goods", 
-    "Electronic Components", 
-    "http://www.nasdaq.com/symbol/prcp"
-  ], 
-  [
-    "PRFT", 
-    "Perficient, Inc.", 
-    "19.6", 
-    "$674.72M", 
-    "1999", 
-    "Technology", 
-    "EDP Services", 
-    "http://www.nasdaq.com/symbol/prft"
-  ], 
-  [
-    "PRFZ", 
-    "PowerShares FTSE RAFI US 1500 Small-Mid Portfolio", 
-    "102.73", 
-    "$1.13B", 
-    "n/a", 
-    "n/a", 
-    "n/a", 
-    "http://www.nasdaq.com/symbol/prfz"
-  ]
-]
\ No newline at end of file
diff --git a/examples/stocks/data/stock_data_21.json b/examples/stocks/data/stock_data_21.json
deleted file mode 100644
index d6f913b..0000000
--- a/examples/stocks/data/stock_data_21.json
+++ /dev/null
@@ -1,1002 +0,0 @@
-[
-  [
-    "PRGN", 
-    "Paragon Shipping Inc.", 
-    "1.89", 
-    "$46.48M", 
-    "2013", 
-    "Transportation", 
-    "Marine Transportation", 
-    "http://www.nasdaq.com/symbol/prgn"
-  ], 
-  [
-    "PRGNL", 
-    "Paragon Shipping Inc.", 
-    "18.4", 
-    "n/a", 
-    "n/a", 
-    "Transportation", 
-    "Marine Transportation", 
-    "http://www.nasdaq.com/symbol/prgnl"
-  ], 
-  [
-    "PRGS", 
-    "Progress Software Corporation", 
-    "27.3", 
-    "$1.38B", 
-    "1991", 
-    "Technology", 
-    "Computer Software: Prepackaged Software", 
-    "http://www.nasdaq.com/symbol/prgs"
-  ], 
-  [
-    "PRGX", 
-    "PRGX Global, Inc.", 
-    "5.33", 
-    "$145.25M", 
-    "1996", 
-    "Consumer Services", 
-    "Diversified Commercial Services", 
-    "http://www.nasdaq.com/symbol/prgx"
-  ], 
-  [
-    "PRIM", 
-    "Primoris Services Corporation", 
-    "21.3", 
-    "$1.1B", 
-    "n/a", 
-    "Basic Industries", 
-    "Water Supply", 
-    "http://www.nasdaq.com/symbol/prim"
-  ], 
-  [
-    "PRKR", 
-    "ParkerVision, Inc.", 
-    "1.04", 
-    "$101.03M", 
-    "1993", 
-    "Technology", 
-    "Radio And Television Broadcasting And Communications Equipment", 
-    "http://www.nasdaq.com/symbol/prkr"
-  ], 
-  [
-    "PRMW", 
-    "Primo Water Corporation", 
-    "4.04", 
-    "$99.1M", 
-    "2010", 
-    "Consumer Non-Durables", 
-    "Food Distributors", 
-    "http://www.nasdaq.com/symbol/prmw"
-  ], 
-  [
-    "PROV", 
-    "Provident Financial Holdings, Inc.", 
-    "15.38", 
-    "$138.35M", 
-    "n/a", 
-    "Finance", 
-    "Savings Institutions", 
-    "http://www.nasdaq.com/symbol/prov"
-  ], 
-  [
-    "PRPH", 
-    "ProPhase Labs, Inc.", 
-    "1.48", 
-    "$22.89M", 
-    "n/a", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/prph"
-  ], 
-  [
-    "PRQR", 
-    "ProQR Therapeutics N.V.", 
-    "18.97", 
-    "$442.72M", 
-    "2014", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/prqr"
-  ], 
-  [
-    "PRSC", 
-    "The Providence Service Corporation", 
-    "40.65", 
-    "$644.44M", 
-    "2003", 
-    "Consumer Services", 
-    "Transportation Services", 
-    "http://www.nasdaq.com/symbol/prsc"
-  ], 
-  [
-    "PRSS", 
-    "CafePress Inc.", 
-    "3.73", 
-    "$64.8M", 
-    "2012", 
-    "Consumer Services", 
-    "Other Specialty Stores", 
-    "http://www.nasdaq.com/symbol/prss"
-  ], 
-  [
-    "PRTA", 
-    "Prothena Corporation plc", 
-    "26.63", 
-    "$729.24M", 
-    "n/a", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/prta"
-  ], 
-  [
-    "PRTK", 
-    "Paratek Pharmaceuticals, Inc. ", 
-    "31.4", 
-    "$452.72M", 
-    "n/a", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/prtk"
-  ], 
-  [
-    "PRTO", 
-    "Proteon Therapeutics, Inc.", 
-    "10.56", 
-    "$173.7M", 
-    "2014", 
-    "Health Care", 
-    "Biotechnology: Biological Products (No Diagnostic Substances)", 
-    "http://www.nasdaq.com/symbol/prto"
-  ], 
-  [
-    "PRTS", 
-    "U.S. Auto Parts Network, Inc.", 
-    "2.79", 
-    "$93.64M", 
-    "2007", 
-    "Consumer Services", 
-    "Other Specialty Stores", 
-    "http://www.nasdaq.com/symbol/prts"
-  ], 
-  [
-    "PRXI", 
-    "Premier Exhibitions, Inc.", 
-    "0.391", 
-    "$19.22M", 
-    "n/a", 
-    "Consumer Services", 
-    "Services-Misc. Amusement & Recreation", 
-    "http://www.nasdaq.com/symbol/prxi"
-  ], 
-  [
-    "PRXL", 
-    "PAREXEL International Corporation", 
-    "63.56", 
-    "$3.48B", 
-    "1995", 
-    "Health Care", 
-    "Biotechnology: Commercial Physical & Biological Resarch", 
-    "http://www.nasdaq.com/symbol/prxl"
-  ], 
-  [
-    "PSAU", 
-    "PowerShares Global Gold and Precious Metals Portfolio", 
-    "17.67", 
-    "$21.2M", 
-    "n/a", 
-    "n/a", 
-    "n/a", 
-    "http://www.nasdaq.com/symbol/psau"
-  ], 
-  [
-    "PSBH", 
-    "PSB Holdings, Inc.", 
-    "7.56", 
-    "$49.45M", 
-    "n/a", 
-    "Finance", 
-    "Savings Institutions", 
-    "http://www.nasdaq.com/symbol/psbh"
-  ], 
-  [
-    "PSCC", 
-    "PowerShares S&P SmallCap Consumer Staples Portfolio", 
-    "53.39", 
-    "$21.36M", 
-    "n/a", 
-    "n/a", 
-    "n/a", 
-    "http://www.nasdaq.com/symbol/pscc"
-  ], 
-  [
-    "PSCD", 
-    "PowerShares S&P SmallCap Consumer Discretionary Portfolio", 
-    "52.96", 
-    "$121.81M", 
-    "n/a", 
-    "n/a", 
-    "n/a", 
-    "http://www.nasdaq.com/symbol/pscd"
-  ], 
-  [
-    "PSCE", 
-    "PowerShares S&P SmallCap Energy Portfolio", 
-    "29.76", 
-    "$23.81M", 
-    "n/a", 
-    "n/a", 
-    "n/a", 
-    "http://www.nasdaq.com/symbol/psce"
-  ], 
-  [
-    "PSCF", 
-    "PowerShares S&P SmallCap Financials Portfolio", 
-    "41.29", 
-    "$115.61M", 
-    "n/a", 
-    "n/a", 
-    "n/a", 
-    "http://www.nasdaq.com/symbol/pscf"
-  ], 
-  [
-    "PSCH", 
-    "PowerShares S&P SmallCap Health Care Portfolio", 
-    "64.779", 
-    "$181.38M", 
-    "n/a", 
-    "n/a", 
-    "n/a", 
-    "http://www.nasdaq.com/symbol/psch"
-  ], 
-  [
-    "PSCI", 
-    "PowerShares S&P SmallCap Industrials Portfolio", 
-    "46.85", 
-    "$117.13M", 
-    "n/a", 
-    "n/a", 
-    "n/a", 
-    "http://www.nasdaq.com/symbol/psci"
-  ], 
-  [
-    "PSCM", 
-    "PowerShares S&P SmallCap Materials Portfolio", 
-    "41.6101", 
-    "$56.17M", 
-    "n/a", 
-    "n/a", 
-    "n/a", 
-    "http://www.nasdaq.com/symbol/pscm"
-  ], 
-  [
-    "PSCT", 
-    "PowerShares S&P SmallCap Information Technology Portfolio", 
-    "52.0208", 
-    "$252.3M", 
-    "n/a", 
-    "n/a", 
-    "n/a", 
-    "http://www.nasdaq.com/symbol/psct"
-  ], 
-  [
-    "PSCU", 
-    "PowerShares S&P SmallCap Utilities Portfolio", 
-    "38.44", 
-    "$40.36M", 
-    "n/a", 
-    "n/a", 
-    "n/a", 
-    "http://www.nasdaq.com/symbol/pscu"
-  ], 
-  [
-    "PSDV", 
-    "pSivida Corp.", 
-    "4.5", 
-    "$132.36M", 
-    "n/a", 
-    "Capital Goods", 
-    "Biotechnology: Laboratory Analytical Instruments", 
-    "http://www.nasdaq.com/symbol/psdv"
-  ], 
-  [
-    "PSEC", 
-    "Prospect Capital Corporation", 
-    "8.8", 
-    "$3.15B", 
-    "2004", 
-    "n/a", 
-    "n/a", 
-    "http://www.nasdaq.com/symbol/psec"
-  ], 
-  [
-    "PSEM", 
-    "Pericom Semiconductor Corporation", 
-    "15.01", 
-    "$335.58M", 
-    "1997", 
-    "Technology", 
-    "Semiconductors", 
-    "http://www.nasdaq.com/symbol/psem"
-  ], 
-  [
-    "PSIX", 
-    "Power Solutions International, Inc.", 
-    "50.89", 
-    "$546.11M", 
-    "n/a", 
-    "Energy", 
-    "Industrial Machinery/Components", 
-    "http://www.nasdaq.com/symbol/psix"
-  ], 
-  [
-    "PSMT", 
-    "PriceSmart, Inc.", 
-    "82.42", 
-    "$2.49B", 
-    "n/a", 
-    "Consumer Services", 
-    "Department/Specialty Retail Stores", 
-    "http://www.nasdaq.com/symbol/psmt"
-  ], 
-  [
-    "PSTB", 
-    "Park Sterling Corporation", 
-    "6.99", 
-    "$313.5M", 
-    "2010", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/pstb"
-  ], 
-  [
-    "PSTI", 
-    "Pluristem Therapeutics, Inc.", 
-    "2.98", 
-    "$210.17M", 
-    "n/a", 
-    "Health Care", 
-    "Biotechnology: Biological Products (No Diagnostic Substances)", 
-    "http://www.nasdaq.com/symbol/psti"
-  ], 
-  [
-    "PSTR", 
-    "PostRock Energy Corporation", 
-    "4.04", 
-    "$25.51M", 
-    "n/a", 
-    "Energy", 
-    "Oil & Gas Production", 
-    "http://www.nasdaq.com/symbol/pstr"
-  ], 
-  [
-    "PSUN", 
-    "Pacific Sunwear of California, Inc.", 
-    "2.84", 
-    "$196.71M", 
-    "1999", 
-    "Consumer Services", 
-    "Clothing/Shoe/Accessory Stores", 
-    "http://www.nasdaq.com/symbol/psun"
-  ], 
-  [
-    "PTBI", 
-    "PlasmaTech Biopharmaceuticals, Inc.", 
-    "3.1", 
-    "$64.12M", 
-    "n/a", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/ptbi"
-  ], 
-  [
-    "PTBIW", 
-    "PlasmaTech Biopharmaceuticals, Inc.", 
-    "1.08", 
-    "n/a", 
-    "n/a", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/ptbiw"
-  ], 
-  [
-    "PTC", 
-    "PTC Inc.", 
-    "34.93", 
-    "$4.01B", 
-    "n/a", 
-    "Technology", 
-    "Computer Software: Prepackaged Software", 
-    "http://www.nasdaq.com/symbol/ptc"
-  ], 
-  [
-    "PTCT", 
-    "PTC Therapeutics, Inc.", 
-    "55.19", 
-    "$1.85B", 
-    "2013", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/ptct"
-  ], 
-  [
-    "PTEN", 
-    "Patterson-UTI Energy, Inc.", 
-    "18.32", 
-    "$2.68B", 
-    "1993", 
-    "Energy", 
-    "Oil & Gas Production", 
-    "http://www.nasdaq.com/symbol/pten"
-  ], 
-  [
-    "PTIE", 
-    "Pain Therapeutics", 
-    "1.96", 
-    "$89.68M", 
-    "2000", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/ptie"
-  ], 
-  [
-    "PTLA", 
-    "Portola Pharmaceuticals, Inc.", 
-    "37.78", 
-    "$1.84B", 
-    "2013", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/ptla"
-  ], 
-  [
-    "PTNR", 
-    "Partner Communications Company Ltd.", 
-    "3.83", 
-    "$597.32M", 
-    "n/a", 
-    "Public Utilities", 
-    "Telecommunications Equipment", 
-    "http://www.nasdaq.com/symbol/ptnr"
-  ], 
-  [
-    "PTNT", 
-    "Internet Patents Corporation", 
-    "2.65", 
-    "$20.54M", 
-    "n/a", 
-    "Miscellaneous", 
-    "Business Services", 
-    "http://www.nasdaq.com/symbol/ptnt"
-  ], 
-  [
-    "PTRY", 
-    "The Pantry, Inc.", 
-    "36.69", 
-    "$862.38M", 
-    "1999", 
-    "Consumer Durables", 
-    "Automotive Aftermarket", 
-    "http://www.nasdaq.com/symbol/ptry"
-  ], 
-  [
-    "PTSI", 
-    "P.A.M. Transportation Services, Inc.", 
-    "56.31", 
-    "$450.07M", 
-    "1986", 
-    "Transportation", 
-    "Trucking Freight/Courier Services", 
-    "http://www.nasdaq.com/symbol/ptsi"
-  ], 
-  [
-    "PTX", 
-    "Pernix Therapeutics Holdings, Inc.", 
-    "9.34", 
-    "$357.64M", 
-    "n/a", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/ptx"
-  ], 
-  [
-    "PULB", 
-    "Pulaski Financial Corp.", 
-    "11.75", 
-    "$141.75M", 
-    "n/a", 
-    "Finance", 
-    "Savings Institutions", 
-    "http://www.nasdaq.com/symbol/pulb"
-  ], 
-  [
-    "PUMP", 
-    "Asante Solutions, Inc.", 
-    "n/a", 
-    "n/a", 
-    "n/a", 
-    "n/a", 
-    "n/a", 
-    "http://www.nasdaq.com/symbol/pump"
-  ], 
-  [
-    "PVTB", 
-    "PrivateBancorp, Inc.", 
-    "35.16", 
-    "$2.75B", 
-    "1999", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/pvtb"
-  ], 
-  [
-    "PVTBP", 
-    "PrivateBancorp, Inc.", 
-    "27.92", 
-    "n/a", 
-    "n/a", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/pvtbp"
-  ], 
-  [
-    "PWOD", 
-    "Penns Woods Bancorp, Inc.", 
-    "46.51", 
-    "$223.62M", 
-    "n/a", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/pwod"
-  ], 
-  [
-    "PWRD", 
-    "Perfect World Co., Ltd.", 
-    "18.97", 
-    "$943.23M", 
-    "2007", 
-    "Miscellaneous", 
-    "Business Services", 
-    "http://www.nasdaq.com/symbol/pwrd"
-  ], 
-  [
-    "PWX", 
-    "Providence and Worcester Railroad Company", 
-    "18.1501", 
-    "$88.18M", 
-    "n/a", 
-    "Transportation", 
-    "Railroads", 
-    "http://www.nasdaq.com/symbol/pwx"
-  ], 
-  [
-    "PXLW", 
-    "Pixelworks, Inc.", 
-    "5.4", 
-    "$124.98M", 
-    "2000", 
-    "Technology", 
-    "Semiconductors", 
-    "http://www.nasdaq.com/symbol/pxlw"
-  ], 
-  [
-    "PZZA", 
-    "Papa John&#39;S International, Inc.", 
-    "64.83", 
-    "$2.6B", 
-    "1993", 
-    "Consumer Services", 
-    "Restaurants", 
-    "http://www.nasdaq.com/symbol/pzza"
-  ], 
-  [
-    "QABA", 
-    "First Trust NASDAQ ABA Community Bank Index Fund", 
-    "35.6099", 
-    "$92.59M", 
-    "n/a", 
-    "n/a", 
-    "n/a", 
-    "http://www.nasdaq.com/symbol/qaba"
-  ], 
-  [
-    "QADA", 
-    "QAD Inc.", 
-    "20.32", 
-    "$326.39M", 
-    "n/a", 
-    "Technology", 
-    "Computer Software: Prepackaged Software", 
-    "http://www.nasdaq.com/symbol/qada"
-  ], 
-  [
-    "QADB", 
-    "QAD Inc.", 
-    "18.23", 
-    "$292.82M", 
-    "n/a", 
-    "Technology", 
-    "Computer Software: Prepackaged Software", 
-    "http://www.nasdaq.com/symbol/qadb"
-  ], 
-  [
-    "QAT", 
-    "iShares MSCI Qatar Capped ETF", 
-    "24.5", 
-    "$33.08M", 
-    "n/a", 
-    "n/a", 
-    "n/a", 
-    "http://www.nasdaq.com/symbol/qat"
-  ], 
-  [
-    "QBAK", 
-    "Qualstar Corporation", 
-    "1.48", 
-    "$18.13M", 
-    "2000", 
-    "Technology", 
-    "Electronic Components", 
-    "http://www.nasdaq.com/symbol/qbak"
-  ], 
-  [
-    "QCCO", 
-    "QC Holdings, Inc.", 
-    "1.6512", 
-    "$28.91M", 
-    "2004", 
-    "Finance", 
-    "Investment Bankers/Brokers/Service", 
-    "http://www.nasdaq.com/symbol/qcco"
-  ], 
-  [
-    "QCLN", 
-    "First Trust NASDAQ Clean Edge US Liquid Series Index Fund", 
-    "18.14", 
-    "$117M", 
-    "n/a", 
-    "n/a", 
-    "n/a", 
-    "http://www.nasdaq.com/symbol/qcln"
-  ], 
-  [
-    "QCOM", 
-    "QUALCOMM Incorporated", 
-    "71.52", 
-    "$117.98B", 
-    "1991", 
-    "Technology", 
-    "Radio And Television Broadcasting And Communications Equipment", 
-    "http://www.nasdaq.com/symbol/qcom"
-  ], 
-  [
-    "QCRH", 
-    "QCR Holdings, Inc.", 
-    "17.73", 
-    "$140.81M", 
-    "n/a", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/qcrh"
-  ], 
-  [
-    "QDEL", 
-    "Quidel Corporation", 
-    "25.6", 
-    "$880.92M", 
-    "n/a", 
-    "Health Care", 
-    "Biotechnology: In Vitro & In Vivo Diagnostic Substances", 
-    "http://www.nasdaq.com/symbol/qdel"
-  ], 
-  [
-    "QGEN", 
-    "Qiagen N.V.", 
-    "24.47", 
-    "$5.68B", 
-    "n/a", 
-    "Health Care", 
-    "Biotechnology: Biological Products (No Diagnostic Substances)", 
-    "http://www.nasdaq.com/symbol/qgen"
-  ], 
-  [
-    "QINC", 
-    "First Trust RBA Quality Income ETF", 
-    "21.7864", 
-    "$5.45M", 
-    "n/a", 
-    "n/a", 
-    "n/a", 
-    "http://www.nasdaq.com/symbol/qinc"
-  ], 
-  [
-    "QIWI", 
-    "QIWI plc", 
-    "23.49", 
-    "$1.23B", 
-    "2013", 
-    "Miscellaneous", 
-    "Business Services", 
-    "http://www.nasdaq.com/symbol/qiwi"
-  ], 
-  [
-    "QKLS", 
-    "QKL Stores, Inc.", 
-    "2.1499", 
-    "$3.27M", 
-    "n/a", 
-    "Consumer Services", 
-    "Food Chains", 
-    "http://www.nasdaq.com/symbol/qkls"
-  ], 
-  [
-    "QLGC", 
-    "QLogic Corporation", 
-    "14.545", 
-    "$1.27B", 
-    "n/a", 
-    "Technology", 
-    "Computer Communications Equipment", 
-    "http://www.nasdaq.com/symbol/qlgc"
-  ], 
-  [
-    "QLIK", 
-    "Qlik Technologies Inc.", 
-    "31.5", 
-    "$2.84B", 
-    "2010", 
-    "Technology", 
-    "Computer Software: Prepackaged Software", 
-    "http://www.nasdaq.com/symbol/qlik"
-  ], 
-  [
-    "QLTI", 
-    "QLT Inc.", 
-    "4.04", 
-    "$207.05M", 
-    "n/a", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/qlti"
-  ], 
-  [
-    "QLTY", 
-    "Quality Distribution, Inc.", 
-    "10.93", 
-    "$306.69M", 
-    "2003", 
-    "Transportation", 
-    "Trucking Freight/Courier Services", 
-    "http://www.nasdaq.com/symbol/qlty"
-  ], 
-  [
-    "QLYS", 
-    "Qualys, Inc.", 
-    "47.89", 
-    "$1.6B", 
-    "2012", 
-    "Technology", 
-    "Computer Software: Prepackaged Software", 
-    "http://www.nasdaq.com/symbol/qlys"
-  ], 
-  [
-    "QNST", 
-    "QuinStreet, Inc.", 
-    "6.34", 
-    "$282.08M", 
-    "2010", 
-    "Miscellaneous", 
-    "Business Services", 
-    "http://www.nasdaq.com/symbol/qnst"
-  ], 
-  [
-    "QPACU", 
-    "Quinpario Acquisition Corp. 2", 
-    "10.06", 
-    "n/a", 
-    "2015", 
-    "Finance", 
-    "Business Services", 
-    "http://www.nasdaq.com/symbol/qpacu"
-  ], 
-  [
-    "QQEW", 
-    "First Trust NASDAQ-100 Equal Weighted Index Fund", 
-    "44.54", 
-    "$628.01M", 
-    "n/a", 
-    "n/a", 
-    "n/a", 
-    "http://www.nasdaq.com/symbol/qqew"
-  ], 
-  [
-    "QQQ", 
-    "PowerShares QQQ Trust, Series 1", 
-    "108.41", 
-    "$40.04B", 
-    "n/a", 
-    "n/a", 
-    "n/a", 
-    "http://www.nasdaq.com/symbol/qqq"
-  ], 
-  [
-    "QQQC", 
-    "Global X China Technology ETF", 
-    "21.79", 
-    "$17.43M", 
-    "n/a", 
-    "n/a", 
-    "n/a", 
-    "http://www.nasdaq.com/symbol/qqqc"
-  ], 
-  [
-    "QQQX", 
-    "Nuveen NASDAQ 100 Dynamic Overwrite Fund", 
-    "19.32", 
-    "$357.61M", 
-    "n/a", 
-    "n/a", 
-    "n/a", 
-    "http://www.nasdaq.com/symbol/qqqx"
-  ], 
-  [
-    "QQXT", 
-    "First Trust NASDAQ-100 Ex-Technology Sector Index Fund", 
-    "41.803", 
-    "$106.6M", 
-    "n/a", 
-    "n/a", 
-    "n/a", 
-    "http://www.nasdaq.com/symbol/qqxt"
-  ], 
-  [
-    "QRHC", 
-    "Quest Resource Holding Corporation.", 
-    "1.28", 
-    "$142.85M", 
-    "n/a", 
-    "Technology", 
-    "Diversified Commercial Services", 
-    "http://www.nasdaq.com/symbol/qrhc"
-  ], 
-  [
-    "QRVO", 
-    "Qorvo, Inc.", 
-    "65.17", 
-    "$9.68B", 
-    "n/a", 
-    "Technology", 
-    "Semiconductors", 
-    "http://www.nasdaq.com/symbol/qrvo"
-  ], 
-  [
-    "QSII", 
-    "Quality Systems, Inc.", 
-    "17.71", 
-    "$1.07B", 
-    "1982", 
-    "Technology", 
-    "EDP Services", 
-    "http://www.nasdaq.com/symbol/qsii"
-  ], 
-  [
-    "QTEC", 
-    "First Trust NASDAQ-100 Technology Sector Index Fund", 
-    "44.66", 
-    "$363.98M", 
-    "n/a", 
-    "n/a", 
-    "n/a", 
-    "http://www.nasdaq.com/symbol/qtec"
-  ], 
-  [
-    "QTNT", 
-    "Quotient Limited", 
-    "16.95", 
-    "$286.74M", 
-    "2014", 
-    "Health Care", 
-    "Biotechnology: In Vitro & In Vivo Diagnostic Substances", 
-    "http://www.nasdaq.com/symbol/qtnt"
-  ], 
-  [
-    "QTNTW", 
-    "Quotient Limited", 
-    "7", 
-    "n/a", 
-    "2014", 
-    "Health Care", 
-    "Biotechnology: In Vitro & In Vivo Diagnostic Substances", 
-    "http://www.nasdaq.com/symbol/qtntw"
-  ], 
-  [
-    "QTWW", 
-    "Quantum Fuel Systems Technologies Worldwide, Inc.", 
-    "3.03", 
-    "$84.47M", 
-    "n/a", 
-    "Capital Goods", 
-    "Auto Parts:O.E.M.", 
-    "http://www.nasdaq.com/symbol/qtww"
-  ], 
-  [
-    "QUIK", 
-    "QuickLogic Corporation", 
-    "2.15", 
-    "$120.1M", 
-    "1999", 
-    "Technology", 
-    "Semiconductors", 
-    "http://www.nasdaq.com/symbol/quik"
-  ], 
-  [
-    "QUMU", 
-    "Qumu Corporation", 
-    "14.6", 
-    "$131.73M", 
-    "n/a", 
-    "Technology", 
-    "Computer Software: Prepackaged Software", 
-    "http://www.nasdaq.com/symbol/qumu"
-  ], 
-  [
-    "QUNR", 
-    "Qunar Cayman Islands Limited", 
-    "28.82", 
-    "$3.43B", 
-    "2013", 
-    "Miscellaneous", 
-    "Business Services", 
-    "http://www.nasdaq.com/symbol/qunr"
-  ], 
-  [
-    "QURE", 
-    "uniQure N.V.", 
-    "19.27", 
-    "$343.79M", 
-    "2014", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/qure"
-  ], 
-  [
-    "QVCA", 
-    "Liberty Interactive Corporation", 
-    "29.23", 
-    "$13.91B", 
-    "n/a", 
-    "Consumer Services", 
-    "Catalog/Specialty Distribution", 
-    "http://www.nasdaq.com/symbol/qvca"
-  ], 
-  [
-    "QVCB", 
-    "Liberty Interactive Corporation", 
-    "29.37", 
-    "$13.98B", 
-    "n/a", 
-    "Consumer Services", 
-    "Catalog/Specialty Distribution", 
-    "http://www.nasdaq.com/symbol/qvcb"
-  ], 
-  [
-    "QYLD", 
-    "Recon Capital NASDAQ-100 Covered Call ETF", 
-    "23.78", 
-    "$11.89M", 
-    "n/a", 
-    "n/a", 
-    "n/a", 
-    "http://www.nasdaq.com/symbol/qyld"
-  ], 
-  [
-    "RADA", 
-    "Rada Electronics Industries Limited", 
-    "2.34", 
-    "$21.03M", 
-    "n/a", 
-    "Consumer Non-Durables", 
-    "Electronic Components", 
-    "http://www.nasdaq.com/symbol/rada"
-  ]
-]
\ No newline at end of file
diff --git a/examples/stocks/data/stock_data_22.json b/examples/stocks/data/stock_data_22.json
deleted file mode 100644
index 538c60a..0000000
--- a/examples/stocks/data/stock_data_22.json
+++ /dev/null
@@ -1,1002 +0,0 @@
-[
-  [
-    "RAIL", 
-    "Freightcar America, Inc.", 
-    "30.48", 
-    "$367.8M", 
-    "2005", 
-    "Capital Goods", 
-    "Railroads", 
-    "http://www.nasdaq.com/symbol/rail"
-  ], 
-  [
-    "RAND", 
-    "Rand Capital Corporation", 
-    "4.173", 
-    "$26.54M", 
-    "n/a", 
-    "n/a", 
-    "n/a", 
-    "http://www.nasdaq.com/symbol/rand"
-  ], 
-  [
-    "RARE", 
-    "Ultragenyx Pharmaceutical Inc.", 
-    "55.57", 
-    "$1.97B", 
-    "2014", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/rare"
-  ], 
-  [
-    "RAVE", 
-    "Rave Restaurant Group, Inc.", 
-    "12.51", 
-    "$125.11M", 
-    "n/a", 
-    "Consumer Non-Durables", 
-    "Food Distributors", 
-    "http://www.nasdaq.com/symbol/rave"
-  ], 
-  [
-    "RAVN", 
-    "Raven Industries, Inc.", 
-    "20.87", 
-    "$794.1M", 
-    "n/a", 
-    "Capital Goods", 
-    "Specialty Chemicals", 
-    "http://www.nasdaq.com/symbol/ravn"
-  ], 
-  [
-    "RBCAA", 
-    "Republic Bancorp, Inc.", 
-    "23.87", 
-    "$496.88M", 
-    "1998", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/rbcaa"
-  ], 
-  [
-    "RBCN", 
-    "Rubicon Technology, Inc.", 
-    "4.49", 
-    "$117.42M", 
-    "2007", 
-    "Technology", 
-    "Semiconductors", 
-    "http://www.nasdaq.com/symbol/rbcn"
-  ], 
-  [
-    "RBPAA", 
-    "Royal Bancshares of Pennsylvania, Inc.", 
-    "1.8", 
-    "$50.22M", 
-    "n/a", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/rbpaa"
-  ], 
-  [
-    "RCII", 
-    "Rent-A-Center Inc.", 
-    "29.18", 
-    "$1.54B", 
-    "1995", 
-    "Technology", 
-    "Diversified Commercial Services", 
-    "http://www.nasdaq.com/symbol/rcii"
-  ], 
-  [
-    "RCKY", 
-    "Rocky Brands, Inc.", 
-    "20.16", 
-    "$152.21M", 
-    "1993", 
-    "Consumer Non-Durables", 
-    "Shoe Manufacturing", 
-    "http://www.nasdaq.com/symbol/rcky"
-  ], 
-  [
-    "RCMT", 
-    "RCM Technologies, Inc.", 
-    "5.8", 
-    "$72.82M", 
-    "n/a", 
-    "Technology", 
-    "Professional Services", 
-    "http://www.nasdaq.com/symbol/rcmt"
-  ], 
-  [
-    "RCON", 
-    "Recon Technology, Ltd.", 
-    "1.68", 
-    "$7.94M", 
-    "2009", 
-    "Energy", 
-    "Oilfield Services/Equipment", 
-    "http://www.nasdaq.com/symbol/rcon"
-  ], 
-  [
-    "RCPI", 
-    "Rock Creek Pharmaceuticals, Inc.", 
-    "0.148", 
-    "$29.32M", 
-    "n/a", 
-    "Consumer Durables", 
-    "Specialty Chemicals", 
-    "http://www.nasdaq.com/symbol/rcpi"
-  ], 
-  [
-    "RCPT", 
-    "Receptos, Inc.", 
-    "125.43", 
-    "$3.95B", 
-    "2013", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/rcpt"
-  ], 
-  [
-    "RDCM", 
-    "Radcom Ltd.", 
-    "10.21", 
-    "$82.43M", 
-    "1997", 
-    "Technology", 
-    "Computer peripheral equipment", 
-    "http://www.nasdaq.com/symbol/rdcm"
-  ], 
-  [
-    "RDEN", 
-    "Elizabeth Arden, Inc.", 
-    "16.75", 
-    "$499.35M", 
-    "n/a", 
-    "Consumer Non-Durables", 
-    "Package Goods/Cosmetics", 
-    "http://www.nasdaq.com/symbol/rden"
-  ], 
-  [
-    "RDHL", 
-    "Redhill Biopharma Ltd.", 
-    "13.01", 
-    "$113.69M", 
-    "n/a", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/rdhl"
-  ], 
-  [
-    "RDI", 
-    "Reading International Inc", 
-    "12.72", 
-    "$297.4M", 
-    "n/a", 
-    "Consumer Services", 
-    "Movies/Entertainment", 
-    "http://www.nasdaq.com/symbol/rdi"
-  ], 
-  [
-    "RDIB", 
-    "Reading International Inc", 
-    "12.66", 
-    "$284.63M", 
-    "n/a", 
-    "Consumer Services", 
-    "Movies/Entertainment", 
-    "http://www.nasdaq.com/symbol/rdib"
-  ], 
-  [
-    "RDNT", 
-    "RadNet, Inc.", 
-    "8.83", 
-    "$377.14M", 
-    "n/a", 
-    "Health Care", 
-    "Medical Specialities", 
-    "http://www.nasdaq.com/symbol/rdnt"
-  ], 
-  [
-    "RDUS", 
-    "Radius Health, Inc.", 
-    "45.9", 
-    "$1.72B", 
-    "2014", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/rdus"
-  ], 
-  [
-    "RDVY", 
-    "First Trust NASDAQ Rising Dividend Achievers ETF", 
-    "22.65", 
-    "$7.93M", 
-    "n/a", 
-    "n/a", 
-    "n/a", 
-    "http://www.nasdaq.com/symbol/rdvy"
-  ], 
-  [
-    "RDWR", 
-    "Radware Ltd.", 
-    "21.11", 
-    "$950.56M", 
-    "1999", 
-    "Miscellaneous", 
-    "Business Services", 
-    "http://www.nasdaq.com/symbol/rdwr"
-  ], 
-  [
-    "RECN", 
-    "Resources Connection, Inc.", 
-    "17.69", 
-    "$665.95M", 
-    "2000", 
-    "Miscellaneous", 
-    "Business Services", 
-    "http://www.nasdaq.com/symbol/recn"
-  ], 
-  [
-    "REDF", 
-    "Rediff.com India Limited", 
-    "1.9016", 
-    "$52.47M", 
-    "n/a", 
-    "Consumer Services", 
-    "Newspapers/Magazines", 
-    "http://www.nasdaq.com/symbol/redf"
-  ], 
-  [
-    "REFR", 
-    "Research Frontiers Incorporated", 
-    "5.07", 
-    "$121.3M", 
-    "n/a", 
-    "Miscellaneous", 
-    "Multi-Sector Companies", 
-    "http://www.nasdaq.com/symbol/refr"
-  ], 
-  [
-    "REGI", 
-    "Renewable Energy Group, Inc.", 
-    "8.96", 
-    "$379.07M", 
-    "2012", 
-    "Basic Industries", 
-    "Major Chemicals", 
-    "http://www.nasdaq.com/symbol/regi"
-  ], 
-  [
-    "REGN", 
-    "Regeneron Pharmaceuticals, Inc.", 
-    "423.78", 
-    "$43.49B", 
-    "1991", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/regn"
-  ], 
-  [
-    "REIS", 
-    "Reis, Inc", 
-    "23.75", 
-    "$264.5M", 
-    "n/a", 
-    "Miscellaneous", 
-    "Business Services", 
-    "http://www.nasdaq.com/symbol/reis"
-  ], 
-  [
-    "RELL", 
-    "Richardson Electronics, Ltd.", 
-    "9.31", 
-    "$128.41M", 
-    "1983", 
-    "Consumer Non-Durables", 
-    "Electronic Components", 
-    "http://www.nasdaq.com/symbol/rell"
-  ], 
-  [
-    "RELV", 
-    "Reliv&#39; International, Inc.", 
-    "1.18", 
-    "$15.13M", 
-    "n/a", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/relv"
-  ], 
-  [
-    "REMY", 
-    "Remy International, Inc.", 
-    "23.3", 
-    "$745.49M", 
-    "n/a", 
-    "Capital Goods", 
-    "Auto Parts:O.E.M.", 
-    "http://www.nasdaq.com/symbol/remy"
-  ], 
-  [
-    "RENT", 
-    "Rentrak Corporation", 
-    "53", 
-    "$805.86M", 
-    "n/a", 
-    "Miscellaneous", 
-    "Business Services", 
-    "http://www.nasdaq.com/symbol/rent"
-  ], 
-  [
-    "REPH", 
-    "Recro Pharma, Inc.", 
-    "3.2299", 
-    "$24.89M", 
-    "2014", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/reph"
-  ], 
-  [
-    "RESN", 
-    "Resonant Inc.", 
-    "15.02", 
-    "$103.76M", 
-    "2014", 
-    "Technology", 
-    "Semiconductors", 
-    "http://www.nasdaq.com/symbol/resn"
-  ], 
-  [
-    "REXI", 
-    "Resource America, Inc.", 
-    "8.96", 
-    "$204.8M", 
-    "n/a", 
-    "Finance", 
-    "Finance/Investors Services", 
-    "http://www.nasdaq.com/symbol/rexi"
-  ], 
-  [
-    "REXX", 
-    "Rex Energy Corporation", 
-    "4.87", 
-    "$263.5M", 
-    "2007", 
-    "Energy", 
-    "Oil & Gas Production", 
-    "http://www.nasdaq.com/symbol/rexx"
-  ], 
-  [
-    "RFIL", 
-    "RF Industries, Ltd.", 
-    "4.44", 
-    "$37.78M", 
-    "n/a", 
-    "Capital Goods", 
-    "Electrical Products", 
-    "http://www.nasdaq.com/symbol/rfil"
-  ], 
-  [
-    "RGCO", 
-    "RGC Resources Inc.", 
-    "21.51", 
-    "$101.58M", 
-    "n/a", 
-    "Public Utilities", 
-    "Oil & Gas Production", 
-    "http://www.nasdaq.com/symbol/rgco"
-  ], 
-  [
-    "RGDO", 
-    "Regado BioSciences, Inc.", 
-    "1.13", 
-    "$37.98M", 
-    "2013", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/rgdo"
-  ], 
-  [
-    "RGDX", 
-    "Response Genetics, Inc.", 
-    "0.54", 
-    "$20.94M", 
-    "2007", 
-    "Health Care", 
-    "Biotechnology: In Vitro & In Vivo Diagnostic Substances", 
-    "http://www.nasdaq.com/symbol/rgdx"
-  ], 
-  [
-    "RGEN", 
-    "Repligen Corporation", 
-    "25.45", 
-    "$832.77M", 
-    "1986", 
-    "Health Care", 
-    "Biotechnology: Biological Products (No Diagnostic Substances)", 
-    "http://www.nasdaq.com/symbol/rgen"
-  ], 
-  [
-    "RGLD", 
-    "Royal Gold, Inc.", 
-    "69.99", 
-    "$4.54B", 
-    "n/a", 
-    "Basic Industries", 
-    "Precious Metals", 
-    "http://www.nasdaq.com/symbol/rgld"
-  ], 
-  [
-    "RGLS", 
-    "Regulus Therapeutics Inc.", 
-    "18.7", 
-    "$944.66M", 
-    "2012", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/rgls"
-  ], 
-  [
-    "RGSE", 
-    "Real Goods Solar, Inc.", 
-    "0.48", 
-    "$24.97M", 
-    "n/a", 
-    "Basic Industries", 
-    "Engineering & Construction", 
-    "http://www.nasdaq.com/symbol/rgse"
-  ], 
-  [
-    "RIBT", 
-    "RiceBran Technologies", 
-    "4.13", 
-    "$38.71M", 
-    "n/a", 
-    "Consumer Non-Durables", 
-    "Packaged Foods", 
-    "http://www.nasdaq.com/symbol/ribt"
-  ], 
-  [
-    "RIBTW", 
-    "RiceBran Technologies", 
-    "1.07", 
-    "n/a", 
-    "n/a", 
-    "Consumer Non-Durables", 
-    "Packaged Foods", 
-    "http://www.nasdaq.com/symbol/ribtw"
-  ], 
-  [
-    "RICK", 
-    "RCI Hospitality Holdings, Inc.", 
-    "10.44", 
-    "$107.48M", 
-    "1995", 
-    "Consumer Services", 
-    "Restaurants", 
-    "http://www.nasdaq.com/symbol/rick"
-  ], 
-  [
-    "RIGL", 
-    "Rigel Pharmaceuticals, Inc.", 
-    "2.55", 
-    "$223.87M", 
-    "2000", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/rigl"
-  ], 
-  [
-    "RITT", 
-    "RIT Technologies Ltd.", 
-    "1.31", 
-    "$20.36M", 
-    "1997", 
-    "Consumer Durables", 
-    "Telecommunications Equipment", 
-    "http://www.nasdaq.com/symbol/ritt"
-  ], 
-  [
-    "RITTW", 
-    "RIT Technologies Ltd.", 
-    "0.2999", 
-    "n/a", 
-    "n/a", 
-    "Consumer Durables", 
-    "Telecommunications Equipment", 
-    "http://www.nasdaq.com/symbol/rittw"
-  ], 
-  [
-    "RIVR", 
-    "River Valley Bancorp.", 
-    "21.35", 
-    "$53.67M", 
-    "n/a", 
-    "Finance", 
-    "Savings Institutions", 
-    "http://www.nasdaq.com/symbol/rivr"
-  ], 
-  [
-    "RJET", 
-    "Republic Airways Holdings, Inc.", 
-    "14.51", 
-    "$722.4M", 
-    "2004", 
-    "Transportation", 
-    "Air Freight/Delivery Services", 
-    "http://www.nasdaq.com/symbol/rjet"
-  ], 
-  [
-    "RLJE", 
-    "RLJ Entertainment, Inc.", 
-    "1.8", 
-    "$24.05M", 
-    "n/a", 
-    "Consumer Services", 
-    "Movies/Entertainment", 
-    "http://www.nasdaq.com/symbol/rlje"
-  ], 
-  [
-    "RLOC", 
-    "ReachLocal, Inc.", 
-    "3.23", 
-    "$94.21M", 
-    "2010", 
-    "Technology", 
-    "Advertising", 
-    "http://www.nasdaq.com/symbol/rloc"
-  ], 
-  [
-    "RLOG", 
-    "Rand Logistics, Inc.", 
-    "3.61", 
-    "$65.03M", 
-    "n/a", 
-    "Consumer Services", 
-    "Marine Transportation", 
-    "http://www.nasdaq.com/symbol/rlog"
-  ], 
-  [
-    "RLYP", 
-    "Relypsa, Inc.", 
-    "35.25", 
-    "$1.21B", 
-    "2013", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/rlyp"
-  ], 
-  [
-    "RMBS", 
-    "Rambus, Inc.", 
-    "12.06", 
-    "$1.38B", 
-    "1997", 
-    "Technology", 
-    "Semiconductors", 
-    "http://www.nasdaq.com/symbol/rmbs"
-  ], 
-  [
-    "RMCF", 
-    "Rocky Mountain Chocolate Factory, Inc.", 
-    "14.54", 
-    "$88.59M", 
-    "n/a", 
-    "Consumer Non-Durables", 
-    "Specialty Foods", 
-    "http://www.nasdaq.com/symbol/rmcf"
-  ], 
-  [
-    "RMGN", 
-    "RMG Networks Holding Corporation", 
-    "1.15", 
-    "$13.99M", 
-    "n/a", 
-    "Miscellaneous", 
-    "Business Services", 
-    "http://www.nasdaq.com/symbol/rmgn"
-  ], 
-  [
-    "RMTI", 
-    "Rockwell Medical, Inc.", 
-    "10.7", 
-    "$536.11M", 
-    "1998", 
-    "Health Care", 
-    "Biotechnology: Electromedical & Electrotherapeutic Apparatus", 
-    "http://www.nasdaq.com/symbol/rmti"
-  ], 
-  [
-    "RNET", 
-    "RigNet, Inc.", 
-    "36.74", 
-    "$647.16M", 
-    "2010", 
-    "Consumer Services", 
-    "Telecommunications Equipment", 
-    "http://www.nasdaq.com/symbol/rnet"
-  ], 
-  [
-    "RNST", 
-    "Renasant Corporation", 
-    "28.28", 
-    "$891.82M", 
-    "n/a", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/rnst"
-  ], 
-  [
-    "RNWK", 
-    "RealNetworks, Inc.", 
-    "6.99", 
-    "$251.88M", 
-    "1997", 
-    "Technology", 
-    "EDP Services", 
-    "http://www.nasdaq.com/symbol/rnwk"
-  ], 
-  [
-    "ROBO", 
-    "Robo-Stox Global Robotics & Automation Index ETF", 
-    "26.22", 
-    "$102.26M", 
-    "n/a", 
-    "n/a", 
-    "n/a", 
-    "http://www.nasdaq.com/symbol/robo"
-  ], 
-  [
-    "ROCK", 
-    "Gibraltar Industries, Inc.", 
-    "16.16", 
-    "$499.42M", 
-    "1993", 
-    "Capital Goods", 
-    "Steel/Iron Ore", 
-    "http://www.nasdaq.com/symbol/rock"
-  ], 
-  [
-    "ROIA", 
-    "Radio One, Inc.", 
-    "2.93", 
-    "$146.92M", 
-    "1999", 
-    "Consumer Services", 
-    "Broadcasting", 
-    "http://www.nasdaq.com/symbol/roia"
-  ], 
-  [
-    "ROIAK", 
-    "Radio One, Inc.", 
-    "2.9", 
-    "$145.41M", 
-    "n/a", 
-    "Consumer Services", 
-    "Broadcasting", 
-    "http://www.nasdaq.com/symbol/roiak"
-  ], 
-  [
-    "ROIC", 
-    "Retail Opportunity Investments Corp.", 
-    "16.93", 
-    "$1.57B", 
-    "n/a", 
-    "Consumer Services", 
-    "Real Estate Investment Trusts", 
-    "http://www.nasdaq.com/symbol/roic"
-  ], 
-  [
-    "ROIQ", 
-    "ROI Acquisition Corp. II", 
-    "9.74", 
-    "$152.19M", 
-    "2013", 
-    "Finance", 
-    "Business Services", 
-    "http://www.nasdaq.com/symbol/roiq"
-  ], 
-  [
-    "ROIQU", 
-    "ROI Acquisition Corp. II", 
-    "9.81", 
-    "$122.63M", 
-    "2013", 
-    "n/a", 
-    "n/a", 
-    "http://www.nasdaq.com/symbol/roiqu"
-  ], 
-  [
-    "ROIQW", 
-    "ROI Acquisition Corp. II", 
-    "0.26", 
-    "n/a", 
-    "2013", 
-    "Finance", 
-    "Business Services", 
-    "http://www.nasdaq.com/symbol/roiqw"
-  ], 
-  [
-    "ROKA", 
-    "Roka Bioscience, Inc.", 
-    "4.14", 
-    "$73.11M", 
-    "2014", 
-    "Capital Goods", 
-    "Biotechnology: Laboratory Analytical Instruments", 
-    "http://www.nasdaq.com/symbol/roka"
-  ], 
-  [
-    "ROLL", 
-    "RBC Bearings Incorporated", 
-    "60.83", 
-    "$1.42B", 
-    "2005", 
-    "Capital Goods", 
-    "Metal Fabrications", 
-    "http://www.nasdaq.com/symbol/roll"
-  ], 
-  [
-    "ROSE", 
-    "Rosetta Resources Inc.", 
-    "23.04", 
-    "$1.42B", 
-    "n/a", 
-    "Energy", 
-    "Oil & Gas Production", 
-    "http://www.nasdaq.com/symbol/rose"
-  ], 
-  [
-    "ROSG", 
-    "Rosetta Genomics Ltd.", 
-    "3.68", 
-    "$43.29M", 
-    "2007", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/rosg"
-  ], 
-  [
-    "ROST", 
-    "Ross Stores, Inc.", 
-    "97.92", 
-    "$20.41B", 
-    "1985", 
-    "Consumer Services", 
-    "Clothing/Shoe/Accessory Stores", 
-    "http://www.nasdaq.com/symbol/rost"
-  ], 
-  [
-    "ROVI", 
-    "Rovi Corporation", 
-    "23.85", 
-    "$2.19B", 
-    "n/a", 
-    "Miscellaneous", 
-    "Multi-Sector Companies", 
-    "http://www.nasdaq.com/symbol/rovi"
-  ], 
-  [
-    "ROYL", 
-    "Royale Energy, Inc.", 
-    "1.79", 
-    "$26.75M", 
-    "n/a", 
-    "Energy", 
-    "Oil & Gas Production", 
-    "http://www.nasdaq.com/symbol/royl"
-  ], 
-  [
-    "RP", 
-    "RealPage, Inc.", 
-    "19.7", 
-    "$1.55B", 
-    "2010", 
-    "Technology", 
-    "Computer Software: Prepackaged Software", 
-    "http://www.nasdaq.com/symbol/rp"
-  ], 
-  [
-    "RPRX", 
-    "Repros Therapeutics Inc.", 
-    "9.27", 
-    "$225.04M", 
-    "n/a", 
-    "Health Care", 
-    "Biotechnology: Biological Products (No Diagnostic Substances)", 
-    "http://www.nasdaq.com/symbol/rprx"
-  ], 
-  [
-    "RPRXW", 
-    "Repros Therapeutics Inc.", 
-    "8.46", 
-    "n/a", 
-    "n/a", 
-    "Health Care", 
-    "Biotechnology: Biological Products (No Diagnostic Substances)", 
-    "http://www.nasdaq.com/symbol/rprxw"
-  ], 
-  [
-    "RPRXZ", 
-    "Repros Therapeutics Inc.", 
-    "6.0227", 
-    "n/a", 
-    "n/a", 
-    "Health Care", 
-    "Biotechnology: Biological Products (No Diagnostic Substances)", 
-    "http://www.nasdaq.com/symbol/rprxz"
-  ], 
-  [
-    "RPTP", 
-    "Raptor Pharmaceutical Corp.", 
-    "9.89", 
-    "$628.65M", 
-    "n/a", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/rptp"
-  ], 
-  [
-    "RPXC", 
-    "RPX Corporation", 
-    "14.1", 
-    "$760.54M", 
-    "2011", 
-    "Miscellaneous", 
-    "Multi-Sector Companies", 
-    "http://www.nasdaq.com/symbol/rpxc"
-  ], 
-  [
-    "RRD", 
-    "R.R. Donnelley & Sons Company", 
-    "18.07", 
-    "$3.61B", 
-    "n/a", 
-    "Miscellaneous", 
-    "Publishing", 
-    "http://www.nasdaq.com/symbol/rrd"
-  ], 
-  [
-    "RRGB", 
-    "Red Robin Gourmet Burgers, Inc.", 
-    "80.64", 
-    "$1.13B", 
-    "2002", 
-    "Consumer Services", 
-    "Restaurants", 
-    "http://www.nasdaq.com/symbol/rrgb"
-  ], 
-  [
-    "RRM", 
-    "RR Media Ltd.", 
-    "7.48", 
-    "$130.13M", 
-    "n/a", 
-    "Consumer Services", 
-    "Telecommunications Equipment", 
-    "http://www.nasdaq.com/symbol/rrm"
-  ], 
-  [
-    "RSTI", 
-    "Rofin-Sinar Technologies, Inc.", 
-    "23.96", 
-    "$673.1M", 
-    "1996", 
-    "Miscellaneous", 
-    "Industrial Machinery/Components", 
-    "http://www.nasdaq.com/symbol/rsti"
-  ], 
-  [
-    "RSYS", 
-    "RadiSys Corporation", 
-    "2.25", 
-    "$82.08M", 
-    "1995", 
-    "Technology", 
-    "Computer peripheral equipment", 
-    "http://www.nasdaq.com/symbol/rsys"
-  ], 
-  [
-    "RTGN", 
-    "Ruthigen, Inc.", 
-    "4.06", 
-    "$19.51M", 
-    "2014", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/rtgn"
-  ], 
-  [
-    "RTIX", 
-    "RTI Surgical, Inc.", 
-    "5.32", 
-    "$302.7M", 
-    "2000", 
-    "Health Care", 
-    "Industrial Specialties", 
-    "http://www.nasdaq.com/symbol/rtix"
-  ], 
-  [
-    "RTK", 
-    "Rentech, Inc.", 
-    "1.27", 
-    "$290.18M", 
-    "1991", 
-    "Basic Industries", 
-    "Agricultural Chemicals", 
-    "http://www.nasdaq.com/symbol/rtk"
-  ], 
-  [
-    "RTRX", 
-    "Retrophin, Inc.", 
-    "14.5", 
-    "$387.15M", 
-    "n/a", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/rtrx"
-  ], 
-  [
-    "RUSHA", 
-    "Rush Enterprises, Inc.", 
-    "28.96", 
-    "$1.16B", 
-    "n/a", 
-    "Consumer Durables", 
-    "Automotive Aftermarket", 
-    "http://www.nasdaq.com/symbol/rusha"
-  ], 
-  [
-    "RUSHB", 
-    "Rush Enterprises, Inc.", 
-    "26", 
-    "$1.04B", 
-    "n/a", 
-    "Consumer Durables", 
-    "Automotive Aftermarket", 
-    "http://www.nasdaq.com/symbol/rushb"
-  ], 
-  [
-    "RUTH", 
-    "Ruth&#39;s Hospitality Group, Inc.", 
-    "15.38", 
-    "$543.78M", 
-    "2005", 
-    "Consumer Services", 
-    "Restaurants", 
-    "http://www.nasdaq.com/symbol/ruth"
-  ], 
-  [
-    "RVBD", 
-    "Riverbed Technology, Inc.", 
-    "20.88", 
-    "$3.29B", 
-    "2006", 
-    "Technology", 
-    "Computer Communications Equipment", 
-    "http://www.nasdaq.com/symbol/rvbd"
-  ], 
-  [
-    "RVLT", 
-    "Revolution Lighting Technologies, Inc.", 
-    "1.13", 
-    "$96.61M", 
-    "n/a", 
-    "Consumer Durables", 
-    "Building Products", 
-    "http://www.nasdaq.com/symbol/rvlt"
-  ], 
-  [
-    "RVNC", 
-    "Revance Therapeutics, Inc.", 
-    "15.76", 
-    "$373.83M", 
-    "2014", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/rvnc"
-  ]
-]
\ No newline at end of file
diff --git a/examples/stocks/data/stock_data_23.json b/examples/stocks/data/stock_data_23.json
deleted file mode 100644
index 0409ff4..0000000
--- a/examples/stocks/data/stock_data_23.json
+++ /dev/null
@@ -1,1002 +0,0 @@
-[
-  [
-    "RVSB", 
-    "Riverview Bancorp Inc", 
-    "4.41", 
-    "$99.1M", 
-    "n/a", 
-    "Finance", 
-    "Savings Institutions", 
-    "http://www.nasdaq.com/symbol/rvsb"
-  ], 
-  [
-    "RWLK", 
-    "ReWalk Robotics Ltd", 
-    "16.17", 
-    "$193.69M", 
-    "2014", 
-    "Health Care", 
-    "Industrial Specialties", 
-    "http://www.nasdaq.com/symbol/rwlk"
-  ], 
-  [
-    "RXDX", 
-    "Ignyta, Inc.", 
-    "7.17", 
-    "$140.39M", 
-    "n/a", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/rxdx"
-  ], 
-  [
-    "RXII", 
-    "RXI Pharmaceuticals Corporation", 
-    "1.15", 
-    "$24.3M", 
-    "n/a", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/rxii"
-  ], 
-  [
-    "RYAAY", 
-    "Ryanair Holdings plc", 
-    "64.25", 
-    "$17.83B", 
-    "1997", 
-    "Transportation", 
-    "Air Freight/Delivery Services", 
-    "http://www.nasdaq.com/symbol/ryaay"
-  ], 
-  [
-    "SAAS", 
-    "inContact, Inc.", 
-    "11.24", 
-    "$685.58M", 
-    "n/a", 
-    "Technology", 
-    "Computer Software: Prepackaged Software", 
-    "http://www.nasdaq.com/symbol/saas"
-  ], 
-  [
-    "SABR", 
-    "Sabre Corporation", 
-    "21.23", 
-    "$5.69B", 
-    "2014", 
-    "Technology", 
-    "Computer Software: Programming, Data Processing", 
-    "http://www.nasdaq.com/symbol/sabr"
-  ], 
-  [
-    "SAEX", 
-    "SAExploration Holdings, Inc.", 
-    "3.37", 
-    "$50.11M", 
-    "n/a", 
-    "Energy", 
-    "Oil & Gas Production", 
-    "http://www.nasdaq.com/symbol/saex"
-  ], 
-  [
-    "SAFM", 
-    "Sanderson Farms, Inc.", 
-    "83.39", 
-    "$1.93B", 
-    "1987", 
-    "Consumer Non-Durables", 
-    "Meat/Poultry/Fish", 
-    "http://www.nasdaq.com/symbol/safm"
-  ], 
-  [
-    "SAFT", 
-    "Safety Insurance Group, Inc.", 
-    "61.95", 
-    "$929.82M", 
-    "2002", 
-    "Finance", 
-    "Property-Casualty Insurers", 
-    "http://www.nasdaq.com/symbol/saft"
-  ], 
-  [
-    "SAGE", 
-    "Sage Therapeutics, Inc.", 
-    "42.5", 
-    "$1.1B", 
-    "2014", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/sage"
-  ], 
-  [
-    "SAIA", 
-    "Saia, Inc.", 
-    "46.14", 
-    "$1.14B", 
-    "n/a", 
-    "Transportation", 
-    "Trucking Freight/Courier Services", 
-    "http://www.nasdaq.com/symbol/saia"
-  ], 
-  [
-    "SAJA", 
-    "Sajan, Inc.", 
-    "5.75", 
-    "$27.45M", 
-    "n/a", 
-    "Miscellaneous", 
-    "Business Services", 
-    "http://www.nasdaq.com/symbol/saja"
-  ], 
-  [
-    "SAL", 
-    "Salisbury Bancorp, Inc.", 
-    "30.1799", 
-    "$51.71M", 
-    "n/a", 
-    "Finance", 
-    "Savings Institutions", 
-    "http://www.nasdaq.com/symbol/sal"
-  ], 
-  [
-    "SALE", 
-    "RetailMeNot, Inc.", 
-    "17.2", 
-    "$929.95M", 
-    "2013", 
-    "Consumer Services", 
-    "Advertising", 
-    "http://www.nasdaq.com/symbol/sale"
-  ], 
-  [
-    "SALM", 
-    "Salem Communications Corporation", 
-    "7.37", 
-    "$186.24M", 
-    "1999", 
-    "Consumer Services", 
-    "Broadcasting", 
-    "http://www.nasdaq.com/symbol/salm"
-  ], 
-  [
-    "SAMG", 
-    "Silvercrest Asset Management Group Inc.", 
-    "14.02", 
-    "$171.44M", 
-    "2013", 
-    "Finance", 
-    "Investment Managers", 
-    "http://www.nasdaq.com/symbol/samg"
-  ], 
-  [
-    "SANM", 
-    "Sanmina Corporation", 
-    "23", 
-    "$1.91B", 
-    "1993", 
-    "Technology", 
-    "Electrical Products", 
-    "http://www.nasdaq.com/symbol/sanm"
-  ], 
-  [
-    "SANW", 
-    "S&W Seed Company", 
-    "4.91", 
-    "n/a", 
-    "n/a", 
-    "Consumer Non-Durables", 
-    "Farming/Seeds/Milling", 
-    "http://www.nasdaq.com/symbol/sanw"
-  ], 
-  [
-    "SANWZ", 
-    "S&W Seed Company", 
-    "0.1201", 
-    "n/a", 
-    "n/a", 
-    "Consumer Non-Durables", 
-    "Farming/Seeds/Milling", 
-    "http://www.nasdaq.com/symbol/sanwz"
-  ], 
-  [
-    "SASR", 
-    "Sandy Spring Bancorp, Inc.", 
-    "25.94", 
-    "$649.56M", 
-    "n/a", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/sasr"
-  ], 
-  [
-    "SATS", 
-    "EchoStar Corporation", 
-    "55.31", 
-    "$2.43B", 
-    "n/a", 
-    "Technology", 
-    "Radio And Television Broadcasting And Communications Equipment", 
-    "http://www.nasdaq.com/symbol/sats"
-  ], 
-  [
-    "SAVE", 
-    "Spirit Airlines, Inc.", 
-    "81.77", 
-    "$5.95B", 
-    "2011", 
-    "Transportation", 
-    "Air Freight/Delivery Services", 
-    "http://www.nasdaq.com/symbol/save"
-  ], 
-  [
-    "SBAC", 
-    "SBA Communications Corporation", 
-    "121.25", 
-    "$15.65B", 
-    "1999", 
-    "Consumer Services", 
-    "Telecommunications Equipment", 
-    "http://www.nasdaq.com/symbol/sbac"
-  ], 
-  [
-    "SBBX", 
-    "Sussex Bancorp", 
-    "10.25", 
-    "$47.81M", 
-    "n/a", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/sbbx"
-  ], 
-  [
-    "SBCF", 
-    "Seacoast Banking Corporation of Florida", 
-    "12.97", 
-    "$429.56M", 
-    "n/a", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/sbcf"
-  ], 
-  [
-    "SBCP", 
-    "Sunshine Bancorp, Inc.", 
-    "12.08", 
-    "$51.12M", 
-    "2014", 
-    "Finance", 
-    "Savings Institutions", 
-    "http://www.nasdaq.com/symbol/sbcp"
-  ], 
-  [
-    "SBFG", 
-    "SB Financial Group, Inc.", 
-    "10.5", 
-    "$51.19M", 
-    "n/a", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/sbfg"
-  ], 
-  [
-    "SBFGP", 
-    "SB Financial Group, Inc.", 
-    "11", 
-    "n/a", 
-    "n/a", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/sbfgp"
-  ], 
-  [
-    "SBGI", 
-    "Sinclair Broadcast Group, Inc.", 
-    "27.9", 
-    "$2.67B", 
-    "1995", 
-    "Consumer Services", 
-    "Broadcasting", 
-    "http://www.nasdaq.com/symbol/sbgi"
-  ], 
-  [
-    "SBLK", 
-    "Star Bulk Carriers Corp.", 
-    "4.5", 
-    "$712.92M", 
-    "n/a", 
-    "Transportation", 
-    "Marine Transportation", 
-    "http://www.nasdaq.com/symbol/sblk"
-  ], 
-  [
-    "SBLKL", 
-    "Star Bulk Carriers Corp.", 
-    "22.4499", 
-    "n/a", 
-    "n/a", 
-    "Transportation", 
-    "Marine Transportation", 
-    "http://www.nasdaq.com/symbol/sblkl"
-  ], 
-  [
-    "SBNY", 
-    "Signature Bank", 
-    "125.7", 
-    "$6.32B", 
-    "2004", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/sbny"
-  ], 
-  [
-    "SBNYW", 
-    "Signature Bank", 
-    "89.18", 
-    "n/a", 
-    "n/a", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/sbnyw"
-  ], 
-  [
-    "SBRA", 
-    "Sabra Healthcare REIT, Inc.", 
-    "32.52", 
-    "$1.93B", 
-    "n/a", 
-    "Consumer Services", 
-    "Real Estate Investment Trusts", 
-    "http://www.nasdaq.com/symbol/sbra"
-  ], 
-  [
-    "SBRAP", 
-    "Sabra Healthcare REIT, Inc.", 
-    "26.25", 
-    "$150.94M", 
-    "n/a", 
-    "Consumer Services", 
-    "Real Estate Investment Trusts", 
-    "http://www.nasdaq.com/symbol/sbrap"
-  ], 
-  [
-    "SBSA", 
-    "Spanish Broadcasting System, Inc.", 
-    "3.27", 
-    "$21.28M", 
-    "1999", 
-    "Consumer Services", 
-    "Broadcasting", 
-    "http://www.nasdaq.com/symbol/sbsa"
-  ], 
-  [
-    "SBSI", 
-    "Southside Bancshares, Inc.", 
-    "29.64", 
-    "$560.71M", 
-    "n/a", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/sbsi"
-  ], 
-  [
-    "SBUX", 
-    "Starbucks Corporation", 
-    "93.51", 
-    "$70.11B", 
-    "1992", 
-    "Consumer Services", 
-    "Restaurants", 
-    "http://www.nasdaq.com/symbol/sbux"
-  ], 
-  [
-    "SCAI", 
-    "Surgical Care Affiliates, Inc.", 
-    "32.48", 
-    "$1.25B", 
-    "2013", 
-    "Health Care", 
-    "Medical Specialities", 
-    "http://www.nasdaq.com/symbol/scai"
-  ], 
-  [
-    "SCHL", 
-    "Scholastic Corporation", 
-    "36.99", 
-    "$1.21B", 
-    "1992", 
-    "Consumer Services", 
-    "Books", 
-    "http://www.nasdaq.com/symbol/schl"
-  ], 
-  [
-    "SCHN", 
-    "Schnitzer Steel Industries, Inc.", 
-    "16.36", 
-    "$438.19M", 
-    "1993", 
-    "Consumer Durables", 
-    "Industrial Specialties", 
-    "http://www.nasdaq.com/symbol/schn"
-  ], 
-  [
-    "SCLN", 
-    "SciClone Pharmaceuticals, Inc.", 
-    "7.68", 
-    "$389.94M", 
-    "1992", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/scln"
-  ], 
-  [
-    "SCMP", 
-    "Sucampo Pharmaceuticals, Inc.", 
-    "15.02", 
-    "$673.24M", 
-    "2007", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/scmp"
-  ], 
-  [
-    "SCOK", 
-    "SinoCoking Coal and Coke Chemical Industries, Inc", 
-    "2.74", 
-    "$65.65M", 
-    "n/a", 
-    "Basic Industries", 
-    "Steel/Iron Ore", 
-    "http://www.nasdaq.com/symbol/scok"
-  ], 
-  [
-    "SCON", 
-    "Superconductor Technologies Inc.", 
-    "2.09", 
-    "$27.69M", 
-    "1993", 
-    "Technology", 
-    "Radio And Television Broadcasting And Communications Equipment", 
-    "http://www.nasdaq.com/symbol/scon"
-  ], 
-  [
-    "SCOR", 
-    "comScore, Inc.", 
-    "51.44", 
-    "$1.76B", 
-    "2007", 
-    "Miscellaneous", 
-    "Business Services", 
-    "http://www.nasdaq.com/symbol/scor"
-  ], 
-  [
-    "SCSC", 
-    "ScanSource, Inc.", 
-    "36.79", 
-    "$1.05B", 
-    "n/a", 
-    "Technology", 
-    "Retail: Computer Software & Peripheral Equipment", 
-    "http://www.nasdaq.com/symbol/scsc"
-  ], 
-  [
-    "SCSS", 
-    "Select Comfort Corporation", 
-    "31.32", 
-    "$1.67B", 
-    "1998", 
-    "Consumer Durables", 
-    "Home Furnishings", 
-    "http://www.nasdaq.com/symbol/scss"
-  ], 
-  [
-    "SCTY", 
-    "SolarCity Corporation", 
-    "54.44", 
-    "$5.23B", 
-    "2012", 
-    "Basic Industries", 
-    "Engineering & Construction", 
-    "http://www.nasdaq.com/symbol/scty"
-  ], 
-  [
-    "SCVL", 
-    "Shoe Carnival, Inc.", 
-    "23.69", 
-    "$480.58M", 
-    "1993", 
-    "Consumer Services", 
-    "Clothing/Shoe/Accessory Stores", 
-    "http://www.nasdaq.com/symbol/scvl"
-  ], 
-  [
-    "SCYX", 
-    "SCYNEXIS, Inc.", 
-    "9.2", 
-    "$78.31M", 
-    "2014", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/scyx"
-  ], 
-  [
-    "SEAC", 
-    "SeaChange International, Inc.", 
-    "7.69", 
-    "$251.11M", 
-    "1996", 
-    "Technology", 
-    "Radio And Television Broadcasting And Communications Equipment", 
-    "http://www.nasdaq.com/symbol/seac"
-  ], 
-  [
-    "SEED", 
-    "Origin Agritech Limited", 
-    "1.35", 
-    "$30.7M", 
-    "n/a", 
-    "Consumer Non-Durables", 
-    "Farming/Seeds/Milling", 
-    "http://www.nasdaq.com/symbol/seed"
-  ], 
-  [
-    "SEIC", 
-    "SEI Investments Company", 
-    "43.37", 
-    "$7.25B", 
-    "1981", 
-    "Finance", 
-    "Investment Bankers/Brokers/Service", 
-    "http://www.nasdaq.com/symbol/seic"
-  ], 
-  [
-    "SEMI", 
-    "SunEdison Semiconductor Limited", 
-    "21.5", 
-    "$892.38M", 
-    "2014", 
-    "Technology", 
-    "Semiconductors", 
-    "http://www.nasdaq.com/symbol/semi"
-  ], 
-  [
-    "SENEA", 
-    "Seneca Foods Corp.", 
-    "27.25", 
-    "$292.48M", 
-    "n/a", 
-    "Consumer Non-Durables", 
-    "Packaged Foods", 
-    "http://www.nasdaq.com/symbol/senea"
-  ], 
-  [
-    "SENEB", 
-    "Seneca Foods Corp.", 
-    "38", 
-    "$407.86M", 
-    "n/a", 
-    "Consumer Non-Durables", 
-    "Packaged Foods", 
-    "http://www.nasdaq.com/symbol/seneb"
-  ], 
-  [
-    "SEV", 
-    "Sevcon, Inc.", 
-    "7.39", 
-    "$26.98M", 
-    "n/a", 
-    "Energy", 
-    "Industrial Machinery/Components", 
-    "http://www.nasdaq.com/symbol/sev"
-  ], 
-  [
-    "SFBC", 
-    "Sound Financial Bancorp, Inc.", 
-    "18.9", 
-    "$47.59M", 
-    "n/a", 
-    "Finance", 
-    "Savings Institutions", 
-    "http://www.nasdaq.com/symbol/sfbc"
-  ], 
-  [
-    "SFBS", 
-    "ServisFirst Bancshares, Inc.", 
-    "31.06", 
-    "$770.02M", 
-    "2014", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/sfbs"
-  ], 
-  [
-    "SFLY", 
-    "Shutterfly, Inc.", 
-    "45.77", 
-    "$1.73B", 
-    "2006", 
-    "Miscellaneous", 
-    "Other Consumer Services", 
-    "http://www.nasdaq.com/symbol/sfly"
-  ], 
-  [
-    "SFM", 
-    "Sprouts Farmers Market, Inc.", 
-    "37.48", 
-    "$5.67B", 
-    "2013", 
-    "Consumer Services", 
-    "Food Chains", 
-    "http://www.nasdaq.com/symbol/sfm"
-  ], 
-  [
-    "SFNC", 
-    "Simmons First National Corporation", 
-    "39.79", 
-    "$717.1M", 
-    "n/a", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/sfnc"
-  ], 
-  [
-    "SFST", 
-    "Southern First Bancshares, Inc.", 
-    "16.8001", 
-    "$81.24M", 
-    "n/a", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/sfst"
-  ], 
-  [
-    "SFXE", 
-    "SFX Entertainment, Inc.", 
-    "3.53", 
-    "$319.7M", 
-    "2013", 
-    "Consumer Services", 
-    "Services-Misc. Amusement & Recreation", 
-    "http://www.nasdaq.com/symbol/sfxe"
-  ], 
-  [
-    "SGBK", 
-    "Stonegate Bank", 
-    "28.33", 
-    "$290.23M", 
-    "n/a", 
-    "n/a", 
-    "n/a", 
-    "http://www.nasdaq.com/symbol/sgbk"
-  ], 
-  [
-    "SGC", 
-    "Superior Uniform Group, Inc.", 
-    "18.27", 
-    "$491.39M", 
-    "n/a", 
-    "Consumer Non-Durables", 
-    "Apparel", 
-    "http://www.nasdaq.com/symbol/sgc"
-  ], 
-  [
-    "SGEN", 
-    "Seattle Genetics, Inc.", 
-    "34.96", 
-    "$4.33B", 
-    "2001", 
-    "Health Care", 
-    "Biotechnology: Biological Products (No Diagnostic Substances)", 
-    "http://www.nasdaq.com/symbol/sgen"
-  ], 
-  [
-    "SGI", 
-    "Silicon Graphics International Corp", 
-    "9.2", 
-    "$316.69M", 
-    "n/a", 
-    "Technology", 
-    "Computer Manufacturing", 
-    "http://www.nasdaq.com/symbol/sgi"
-  ], 
-  [
-    "SGMA", 
-    "SigmaTron International, Inc.", 
-    "6.7", 
-    "$27.16M", 
-    "1994", 
-    "Technology", 
-    "Electrical Products", 
-    "http://www.nasdaq.com/symbol/sgma"
-  ], 
-  [
-    "SGMO", 
-    "Sangamo BioSciences, Inc.", 
-    "16.945", 
-    "$1.16B", 
-    "2000", 
-    "Health Care", 
-    "Biotechnology: Biological Products (No Diagnostic Substances)", 
-    "http://www.nasdaq.com/symbol/sgmo"
-  ], 
-  [
-    "SGMS", 
-    "Scientific Games Corp", 
-    "13.75", 
-    "$1.17B", 
-    "n/a", 
-    "Technology", 
-    "EDP Services", 
-    "http://www.nasdaq.com/symbol/sgms"
-  ], 
-  [
-    "SGNL", 
-    "Signal Genetics, Inc.", 
-    "2.57", 
-    "$9.72M", 
-    "2014", 
-    "Health Care", 
-    "Medical Specialities", 
-    "http://www.nasdaq.com/symbol/sgnl"
-  ], 
-  [
-    "SGNT", 
-    "Sagent Pharmaceuticals, Inc.", 
-    "28.49", 
-    "$909.12M", 
-    "2011", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/sgnt"
-  ], 
-  [
-    "SGOC", 
-    "SGOCO Group, Ltd", 
-    "0.52", 
-    "$9.06M", 
-    "2010", 
-    "Technology", 
-    "Radio And Television Broadcasting And Communications Equipment", 
-    "http://www.nasdaq.com/symbol/sgoc"
-  ], 
-  [
-    "SGRP", 
-    "SPAR Group, Inc.", 
-    "1.47", 
-    "$30.22M", 
-    "n/a", 
-    "Miscellaneous", 
-    "Business Services", 
-    "http://www.nasdaq.com/symbol/sgrp"
-  ], 
-  [
-    "SGYP", 
-    "Synergy Pharmaceuticals, Inc.", 
-    "2.87", 
-    "$277.27M", 
-    "n/a", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/sgyp"
-  ], 
-  [
-    "SGYPU", 
-    "Synergy Pharmaceuticals, Inc.", 
-    "6.48", 
-    "$11.78M", 
-    "n/a", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/sgypu"
-  ], 
-  [
-    "SGYPW", 
-    "Synergy Pharmaceuticals, Inc.", 
-    "0.7399", 
-    "n/a", 
-    "n/a", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/sgypw"
-  ], 
-  [
-    "SHBI", 
-    "Shore Bancshares Inc", 
-    "9.35", 
-    "$117.95M", 
-    "n/a", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/shbi"
-  ], 
-  [
-    "SHEN", 
-    "Shenandoah Telecommunications Co", 
-    "29.71", 
-    "$716.4M", 
-    "n/a", 
-    "Public Utilities", 
-    "Telecommunications Equipment", 
-    "http://www.nasdaq.com/symbol/shen"
-  ], 
-  [
-    "SHIP", 
-    "Seanergy Maritime Holdings Corp", 
-    "0.7856", 
-    "$9.4M", 
-    "n/a", 
-    "Transportation", 
-    "Marine Transportation", 
-    "http://www.nasdaq.com/symbol/ship"
-  ], 
-  [
-    "SHLD", 
-    "Sears Holdings Corporation", 
-    "36.66", 
-    "$3.9B", 
-    "n/a", 
-    "Consumer Services", 
-    "Department/Specialty Retail Stores", 
-    "http://www.nasdaq.com/symbol/shld"
-  ], 
-  [
-    "SHLDW", 
-    "Sears Holdings Corporation", 
-    "24.17", 
-    "n/a", 
-    "n/a", 
-    "Consumer Services", 
-    "Department/Specialty Retail Stores", 
-    "http://www.nasdaq.com/symbol/shldw"
-  ], 
-  [
-    "SHLM", 
-    "A. Schulman, Inc.", 
-    "40.3", 
-    "$1.17B", 
-    "1972", 
-    "Basic Industries", 
-    "Major Chemicals", 
-    "http://www.nasdaq.com/symbol/shlm"
-  ], 
-  [
-    "SHLO", 
-    "Shiloh Industries, Inc.", 
-    "12.63", 
-    "$217.49M", 
-    "1993", 
-    "Capital Goods", 
-    "Industrial Specialties", 
-    "http://www.nasdaq.com/symbol/shlo"
-  ], 
-  [
-    "SHOO", 
-    "Steven Madden, Ltd.", 
-    "34.15", 
-    "$2.19B", 
-    "1993", 
-    "Consumer Non-Durables", 
-    "Shoe Manufacturing", 
-    "http://www.nasdaq.com/symbol/shoo"
-  ], 
-  [
-    "SHOR", 
-    "ShoreTel, Inc.", 
-    "7.56", 
-    "$485.05M", 
-    "2007", 
-    "Public Utilities", 
-    "Telecommunications Equipment", 
-    "http://www.nasdaq.com/symbol/shor"
-  ], 
-  [
-    "SHOS", 
-    "Sears Hometown and Outlet Stores, Inc.", 
-    "13", 
-    "$295.57M", 
-    "n/a", 
-    "Consumer Services", 
-    "Department/Specialty Retail Stores", 
-    "http://www.nasdaq.com/symbol/shos"
-  ], 
-  [
-    "SHPG", 
-    "Shire plc", 
-    "237.29", 
-    "$47.35B", 
-    "n/a", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/shpg"
-  ], 
-  [
-    "SIAL", 
-    "Sigma-Aldrich Corporation", 
-    "138.75", 
-    "$16.57B", 
-    "n/a", 
-    "Consumer Durables", 
-    "Specialty Chemicals", 
-    "http://www.nasdaq.com/symbol/sial"
-  ], 
-  [
-    "SIBC", 
-    "State Investors Bancorp, Inc.", 
-    "20.91", 
-    "$48.26M", 
-    "2011", 
-    "Finance", 
-    "Savings Institutions", 
-    "http://www.nasdaq.com/symbol/sibc"
-  ], 
-  [
-    "SIEB", 
-    "Siebert Financial Corp.", 
-    "1.71", 
-    "$37.77M", 
-    "n/a", 
-    "Finance", 
-    "Investment Bankers/Brokers/Service", 
-    "http://www.nasdaq.com/symbol/sieb"
-  ], 
-  [
-    "SIEN", 
-    "Sientra, Inc.", 
-    "17.56", 
-    "$261.87M", 
-    "2014", 
-    "Health Care", 
-    "Industrial Specialties", 
-    "http://www.nasdaq.com/symbol/sien"
-  ], 
-  [
-    "SIFI", 
-    "SI Financial Group, Inc.", 
-    "11.49", 
-    "$146.88M", 
-    "n/a", 
-    "Finance", 
-    "Savings Institutions", 
-    "http://www.nasdaq.com/symbol/sifi"
-  ], 
-  [
-    "SIFY", 
-    "Sify Technologies Limited", 
-    "1.38", 
-    "$246.37M", 
-    "n/a", 
-    "Technology", 
-    "Computer Software: Programming, Data Processing", 
-    "http://www.nasdaq.com/symbol/sify"
-  ], 
-  [
-    "SIGA", 
-    "SIGA Technologies Inc.", 
-    "2.06", 
-    "$110.22M", 
-    "n/a", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/siga"
-  ], 
-  [
-    "SIGI", 
-    "Selective Insurance Group, Inc.", 
-    "27.72", 
-    "$1.56B", 
-    "n/a", 
-    "Finance", 
-    "Property-Casualty Insurers", 
-    "http://www.nasdaq.com/symbol/sigi"
-  ], 
-  [
-    "SIGM", 
-    "Sigma Designs, Inc.", 
-    "6.81", 
-    "$237.92M", 
-    "1986", 
-    "Technology", 
-    "Semiconductors", 
-    "http://www.nasdaq.com/symbol/sigm"
-  ]
-]
\ No newline at end of file
diff --git a/examples/stocks/data/stock_data_24.json b/examples/stocks/data/stock_data_24.json
deleted file mode 100644
index dfbf5f2..0000000
--- a/examples/stocks/data/stock_data_24.json
+++ /dev/null
@@ -1,1002 +0,0 @@
-[
-  [
-    "SILC", 
-    "Silicom Ltd", 
-    "47.22", 
-    "$340.86M", 
-    "n/a", 
-    "Technology", 
-    "Computer Communications Equipment", 
-    "http://www.nasdaq.com/symbol/silc"
-  ], 
-  [
-    "SIMG", 
-    "Silicon Image, Inc.", 
-    "7.245", 
-    "$560.74M", 
-    "1999", 
-    "Capital Goods", 
-    "Electrical Products", 
-    "http://www.nasdaq.com/symbol/simg"
-  ], 
-  [
-    "SIMO", 
-    "Silicon Motion Technology Corporation", 
-    "29.69", 
-    "$977.03M", 
-    "2005", 
-    "Technology", 
-    "Semiconductors", 
-    "http://www.nasdaq.com/symbol/simo"
-  ], 
-  [
-    "SINA", 
-    "Sina Corporation", 
-    "37.83", 
-    "$2.5B", 
-    "n/a", 
-    "Technology", 
-    "Computer Software: Prepackaged Software", 
-    "http://www.nasdaq.com/symbol/sina"
-  ], 
-  [
-    "SINO", 
-    "Sino-Global Shipping America, Ltd.", 
-    "1.5", 
-    "$9.3M", 
-    "n/a", 
-    "Transportation", 
-    "Oil Refining/Marketing", 
-    "http://www.nasdaq.com/symbol/sino"
-  ], 
-  [
-    "SIRI", 
-    "Sirius XM Holdings Inc.", 
-    "3.86", 
-    "$21.54B", 
-    "n/a", 
-    "Consumer Services", 
-    "Broadcasting", 
-    "http://www.nasdaq.com/symbol/siri"
-  ], 
-  [
-    "SIRO", 
-    "Sirona Dental Systems, Inc.", 
-    "91.49", 
-    "$5.3B", 
-    "n/a", 
-    "Health Care", 
-    "Medical/Dental Instruments", 
-    "http://www.nasdaq.com/symbol/siro"
-  ], 
-  [
-    "SIVB", 
-    "SVB Financial Group", 
-    "123.08", 
-    "$6.26B", 
-    "n/a", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/sivb"
-  ], 
-  [
-    "SIVBO", 
-    "SVB Financial Group", 
-    "25.75", 
-    "n/a", 
-    "n/a", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/sivbo"
-  ], 
-  [
-    "SIXD", 
-    "6D Global Technologies, Inc.", 
-    "8.52", 
-    "$660.94M", 
-    "n/a", 
-    "Consumer Services", 
-    "Professional Services", 
-    "http://www.nasdaq.com/symbol/sixd"
-  ], 
-  [
-    "SKBI", 
-    "Skystar Bio-Pharmaceutical Company", 
-    "4.28", 
-    "$37.22M", 
-    "n/a", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/skbi"
-  ], 
-  [
-    "SKIS", 
-    "Peak Resorts, Inc.", 
-    "7.25", 
-    "$101.37M", 
-    "2014", 
-    "Consumer Services", 
-    "Hotels/Resorts", 
-    "http://www.nasdaq.com/symbol/skis"
-  ], 
-  [
-    "SKOR", 
-    "FlexShares Credit-Scored US Corporate Bond Index Fund", 
-    "50.63", 
-    "$12.66M", 
-    "n/a", 
-    "n/a", 
-    "n/a", 
-    "http://www.nasdaq.com/symbol/skor"
-  ], 
-  [
-    "SKUL", 
-    "Skullcandy, Inc.", 
-    "10.17", 
-    "$286.12M", 
-    "2011", 
-    "Consumer Non-Durables", 
-    "Consumer Electronics/Appliances", 
-    "http://www.nasdaq.com/symbol/skul"
-  ], 
-  [
-    "SKYS", 
-    "Sky Solar Holdings, Ltd.", 
-    "11.296", 
-    "$541.36M", 
-    "2014", 
-    "n/a", 
-    "n/a", 
-    "http://www.nasdaq.com/symbol/skys"
-  ], 
-  [
-    "SKYW", 
-    "SkyWest, Inc.", 
-    "13.95", 
-    "$716.16M", 
-    "1986", 
-    "Transportation", 
-    "Air Freight/Delivery Services", 
-    "http://www.nasdaq.com/symbol/skyw"
-  ], 
-  [
-    "SKYY", 
-    "First Trust ISE Cloud Computing Index Fund", 
-    "29.72", 
-    "$425M", 
-    "n/a", 
-    "n/a", 
-    "n/a", 
-    "http://www.nasdaq.com/symbol/skyy"
-  ], 
-  [
-    "SLAB", 
-    "Silicon Laboratories, Inc.", 
-    "49.9", 
-    "$2.1B", 
-    "2000", 
-    "Technology", 
-    "Semiconductors", 
-    "http://www.nasdaq.com/symbol/slab"
-  ], 
-  [
-    "SLCT", 
-    "Select Bancorp, Inc.", 
-    "6.96", 
-    "$79.19M", 
-    "n/a", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/slct"
-  ], 
-  [
-    "SLGN", 
-    "Silgan Holdings Inc.", 
-    "57.04", 
-    "$3.61B", 
-    "1997", 
-    "Consumer Durables", 
-    "Containers/Packaging", 
-    "http://www.nasdaq.com/symbol/slgn"
-  ], 
-  [
-    "SLM", 
-    "SLM Corporation", 
-    "9.36", 
-    "$3.96B", 
-    "n/a", 
-    "Finance", 
-    "Finance: Consumer Services", 
-    "http://www.nasdaq.com/symbol/slm"
-  ], 
-  [
-    "SLMAP", 
-    "SLM Corporation", 
-    "49.2525", 
-    "$162.53M", 
-    "n/a", 
-    "Finance", 
-    "Finance: Consumer Services", 
-    "http://www.nasdaq.com/symbol/slmap"
-  ], 
-  [
-    "SLMBP", 
-    "SLM Corporation", 
-    "65.3", 
-    "$261.2M", 
-    "n/a", 
-    "Finance", 
-    "Finance: Consumer Services", 
-    "http://www.nasdaq.com/symbol/slmbp"
-  ], 
-  [
-    "SLP", 
-    "Simulations Plus, Inc.", 
-    "6.27", 
-    "$105.66M", 
-    "n/a", 
-    "Technology", 
-    "EDP Services", 
-    "http://www.nasdaq.com/symbol/slp"
-  ], 
-  [
-    "SLRC", 
-    "Solar Capital Ltd.", 
-    "19.58", 
-    "$831.47M", 
-    "2010", 
-    "n/a", 
-    "n/a", 
-    "http://www.nasdaq.com/symbol/slrc"
-  ], 
-  [
-    "SLTC", 
-    "Selectica, Inc.", 
-    "5.2", 
-    "$40.91M", 
-    "2000", 
-    "Technology", 
-    "Computer Software: Prepackaged Software", 
-    "http://www.nasdaq.com/symbol/sltc"
-  ], 
-  [
-    "SLVO", 
-    "Credit Suisse Silver Shares Covered Call ETN", 
-    "11.3468", 
-    "$9.64M", 
-    "n/a", 
-    "Finance", 
-    "Investment Bankers/Brokers/Service", 
-    "http://www.nasdaq.com/symbol/slvo"
-  ], 
-  [
-    "SLXP", 
-    "Salix Pharmaceuticals, Ltd.", 
-    "157.85", 
-    "$10.06B", 
-    "n/a", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/slxp"
-  ], 
-  [
-    "SMAC", 
-    "Sino Mercury Acquisition Corp.", 
-    "9.92", 
-    "$52.68M", 
-    "2014", 
-    "Finance", 
-    "Business Services", 
-    "http://www.nasdaq.com/symbol/smac"
-  ], 
-  [
-    "SMACR", 
-    "Sino Mercury Acquisition Corp.", 
-    "0.29", 
-    "n/a", 
-    "2014", 
-    "Finance", 
-    "Business Services", 
-    "http://www.nasdaq.com/symbol/smacr"
-  ], 
-  [
-    "SMACU", 
-    "Sino Mercury Acquisition Corp.", 
-    "10.0405", 
-    "$42.27M", 
-    "2014", 
-    "Finance", 
-    "Business Services", 
-    "http://www.nasdaq.com/symbol/smacu"
-  ], 
-  [
-    "SMBC", 
-    "Southern Missouri Bancorp, Inc.", 
-    "18.58", 
-    "$137.71M", 
-    "n/a", 
-    "Finance", 
-    "Banks", 
-    "http://www.nasdaq.com/symbol/smbc"
-  ], 
-  [
-    "SMCI", 
-    "Super Micro Computer, Inc.", 
-    "39.24", 
-    "$1.83B", 
-    "2007", 
-    "Technology", 
-    "Computer Manufacturing", 
-    "http://www.nasdaq.com/symbol/smci"
-  ], 
-  [
-    "SMED", 
-    "Sharps Compliance Corp", 
-    "5.05", 
-    "$78.45M", 
-    "n/a", 
-    "Basic Industries", 
-    "Environmental Services", 
-    "http://www.nasdaq.com/symbol/smed"
-  ], 
-  [
-    "SMIT", 
-    "Schmitt Industries, Inc.", 
-    "2.66", 
-    "$7.97M", 
-    "n/a", 
-    "Capital Goods", 
-    "Industrial Machinery/Components", 
-    "http://www.nasdaq.com/symbol/smit"
-  ], 
-  [
-    "SMLR", 
-    "Semler Scientific, Inc.", 
-    "4.875", 
-    "$22.99M", 
-    "2014", 
-    "Health Care", 
-    "Biotechnology: Electromedical & Electrotherapeutic Apparatus", 
-    "http://www.nasdaq.com/symbol/smlr"
-  ], 
-  [
-    "SMMF", 
-    "Summit Financial Group, Inc.", 
-    "11.42", 
-    "$85.19M", 
-    "n/a", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/smmf"
-  ], 
-  [
-    "SMPL", 
-    "Simplicity Bancorp Inc.", 
-    "17.3", 
-    "$128.02M", 
-    "n/a", 
-    "Finance", 
-    "Savings Institutions", 
-    "http://www.nasdaq.com/symbol/smpl"
-  ], 
-  [
-    "SMRT", 
-    "Stein Mart, Inc.", 
-    "16.2", 
-    "$728.03M", 
-    "1992", 
-    "Consumer Services", 
-    "Clothing/Shoe/Accessory Stores", 
-    "http://www.nasdaq.com/symbol/smrt"
-  ], 
-  [
-    "SMSI", 
-    "Smith Micro Software, Inc.", 
-    "1.46", 
-    "$65.78M", 
-    "1995", 
-    "Technology", 
-    "Computer Software: Prepackaged Software", 
-    "http://www.nasdaq.com/symbol/smsi"
-  ], 
-  [
-    "SMT", 
-    "SMART Technologies Inc.", 
-    "1.24", 
-    "$151.51M", 
-    "n/a", 
-    "Technology", 
-    "Computer peripheral equipment", 
-    "http://www.nasdaq.com/symbol/smt"
-  ], 
-  [
-    "SMTC", 
-    "Semtech Corporation", 
-    "27.58", 
-    "$1.84B", 
-    "n/a", 
-    "Technology", 
-    "Semiconductors", 
-    "http://www.nasdaq.com/symbol/smtc"
-  ], 
-  [
-    "SMTP", 
-    "SMTP, Inc.", 
-    "5.06", 
-    "$27.56M", 
-    "n/a", 
-    "Technology", 
-    "Advertising", 
-    "http://www.nasdaq.com/symbol/smtp"
-  ], 
-  [
-    "SMTX", 
-    "SMTC Corporation", 
-    "1.53", 
-    "$25.12M", 
-    "2000", 
-    "Technology", 
-    "Electrical Products", 
-    "http://www.nasdaq.com/symbol/smtx"
-  ], 
-  [
-    "SNAK", 
-    "Inventure Foods, Inc.", 
-    "10.72", 
-    "$209.44M", 
-    "1996", 
-    "Consumer Non-Durables", 
-    "Packaged Foods", 
-    "http://www.nasdaq.com/symbol/snak"
-  ], 
-  [
-    "SNBC", 
-    "Sun Bancorp, Inc.", 
-    "18.66", 
-    "$346.82M", 
-    "n/a", 
-    "Finance", 
-    "Commercial Banks", 
-    "http://www.nasdaq.com/symbol/snbc"
-  ], 
-  [
-    "SNC", 
-    "State National Companies, Inc.", 
-    "9.16", 
-    "$405.3M", 
-    "n/a", 
-    "Finance", 
-    "Property-Casualty Insurers", 
-    "http://www.nasdaq.com/symbol/snc"
-  ], 
-  [
-    "SNCR", 
-    "Synchronoss Technologies, Inc.", 
-    "44.81", 
-    "$1.9B", 
-    "2006", 
-    "Technology", 
-    "EDP Services", 
-    "http://www.nasdaq.com/symbol/sncr"
-  ], 
-  [
-    "SNDK", 
-    "SanDisk Corporation", 
-    "82.63", 
-    "$17.6B", 
-    "1995", 
-    "Technology", 
-    "Electronic Components", 
-    "http://www.nasdaq.com/symbol/sndk"
-  ], 
-  [
-    "SNFCA", 
-    "Security National Financial Corporation", 
-    "5.895", 
-    "$85.25M", 
-    "n/a", 
-    "Finance", 
-    "Finance: Consumer Services", 
-    "http://www.nasdaq.com/symbol/snfca"
-  ], 
-  [
-    "SNHY", 
-    "Sun Hydraulics Corporation", 
-    "40.18", 
-    "$1.07B", 
-    "1997", 
-    "Capital Goods", 
-    "Metal Fabrications", 
-    "http://www.nasdaq.com/symbol/snhy"
-  ], 
-  [
-    "SNMX", 
-    "Senomyx, Inc.", 
-    "6.11", 
-    "$264.9M", 
-    "2004", 
-    "Health Care", 
-    "Biotechnology: Commercial Physical & Biological Resarch", 
-    "http://www.nasdaq.com/symbol/snmx"
-  ], 
-  [
-    "SNPS", 
-    "Synopsys, Inc.", 
-    "46.95", 
-    "$7.21B", 
-    "1992", 
-    "Technology", 
-    "Computer Software: Prepackaged Software", 
-    "http://www.nasdaq.com/symbol/snps"
-  ], 
-  [
-    "SNSS", 
-    "Sunesis Pharmaceuticals, Inc.", 
-    "2.35", 
-    "$145.58M", 
-    "2005", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/snss"
-  ], 
-  [
-    "SNTA", 
-    "Synta Pharmaceuticals Corp.", 
-    "2.32", 
-    "$252.64M", 
-    "2007", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/snta"
-  ], 
-  [
-    "SOCB", 
-    "Southcoast Financial Corporation", 
-    "7.27", 
-    "$51.59M", 
-    "n/a", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/socb"
-  ], 
-  [
-    "SOCL", 
-    "Global X Social Media Index ETF", 
-    "18.74", 
-    "$95.57M", 
-    "n/a", 
-    "n/a", 
-    "n/a", 
-    "http://www.nasdaq.com/symbol/socl"
-  ], 
-  [
-    "SODA", 
-    "SodaStream International Ltd.", 
-    "18.73", 
-    "$393.29M", 
-    "2010", 
-    "Consumer Durables", 
-    "Consumer Electronics/Appliances", 
-    "http://www.nasdaq.com/symbol/soda"
-  ], 
-  [
-    "SOFO", 
-    "Sonic Foundry, Inc.", 
-    "8.19", 
-    "$35.6M", 
-    "n/a", 
-    "Technology", 
-    "Radio And Television Broadcasting And Communications Equipment", 
-    "http://www.nasdaq.com/symbol/sofo"
-  ], 
-  [
-    "SOHO", 
-    "Sotherly Hotels Inc.", 
-    "7.44", 
-    "$78.65M", 
-    "n/a", 
-    "Consumer Services", 
-    "Real Estate Investment Trusts", 
-    "http://www.nasdaq.com/symbol/soho"
-  ], 
-  [
-    "SOHOL", 
-    "Sotherly Hotels LP", 
-    "26.2535", 
-    "n/a", 
-    "n/a", 
-    "Consumer Services", 
-    "Hotels/Resorts", 
-    "http://www.nasdaq.com/symbol/sohol"
-  ], 
-  [
-    "SOHOM", 
-    "Sotherly Hotels LP", 
-    "25.2", 
-    "n/a", 
-    "n/a", 
-    "Consumer Services", 
-    "Hotels/Resorts", 
-    "http://www.nasdaq.com/symbol/sohom"
-  ], 
-  [
-    "SOHU", 
-    "Sohu.com Inc.", 
-    "53.26", 
-    "$2.05B", 
-    "n/a", 
-    "Technology", 
-    "EDP Services", 
-    "http://www.nasdaq.com/symbol/sohu"
-  ], 
-  [
-    "SONA", 
-    "Southern National Bancorp of Virginia, Inc.", 
-    "11.6501", 
-    "$142.09M", 
-    "n/a", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/sona"
-  ], 
-  [
-    "SONC", 
-    "Sonic Corp.", 
-    "32.88", 
-    "$1.76B", 
-    "1991", 
-    "Consumer Services", 
-    "Restaurants", 
-    "http://www.nasdaq.com/symbol/sonc"
-  ], 
-  [
-    "SONS", 
-    "Sonus Networks, Inc.", 
-    "16.75", 
-    "$33.11M", 
-    "n/a", 
-    "Technology", 
-    "EDP Services", 
-    "http://www.nasdaq.com/symbol/sons"
-  ], 
-  [
-    "SORL", 
-    "SORL Auto Parts, Inc.", 
-    "3.11", 
-    "$60.04M", 
-    "n/a", 
-    "Capital Goods", 
-    "Auto Parts:O.E.M.", 
-    "http://www.nasdaq.com/symbol/sorl"
-  ], 
-  [
-    "SOXX", 
-    "iShares PHLX SOX Semiconductor Sector Index Fund", 
-    "96.31", 
-    "$577.86M", 
-    "n/a", 
-    "n/a", 
-    "n/a", 
-    "http://www.nasdaq.com/symbol/soxx"
-  ], 
-  [
-    "SP", 
-    "SP Plus Corporation", 
-    "22.78", 
-    "$501.62M", 
-    "n/a", 
-    "Consumer Services", 
-    "Rental/Leasing Companies", 
-    "http://www.nasdaq.com/symbol/sp"
-  ], 
-  [
-    "SPAN", 
-    "Span-America Medical Systems, Inc.", 
-    "18.175", 
-    "$54.19M", 
-    "1983", 
-    "Health Care", 
-    "Industrial Specialties", 
-    "http://www.nasdaq.com/symbol/span"
-  ], 
-  [
-    "SPAR", 
-    "Spartan Motors, Inc.", 
-    "5.35", 
-    "$182.34M", 
-    "n/a", 
-    "Capital Goods", 
-    "Auto Manufacturing", 
-    "http://www.nasdaq.com/symbol/spar"
-  ], 
-  [
-    "SPCB", 
-    "SuperCom, Ltd.", 
-    "8.22", 
-    "$112.61M", 
-    "n/a", 
-    "Technology", 
-    "Semiconductors", 
-    "http://www.nasdaq.com/symbol/spcb"
-  ], 
-  [
-    "SPDC", 
-    "Speed Commerce, Inc.", 
-    "0.9871", 
-    "$65.16M", 
-    "n/a", 
-    "Technology", 
-    "Retail: Computer Software & Peripheral Equipment", 
-    "http://www.nasdaq.com/symbol/spdc"
-  ], 
-  [
-    "SPEX", 
-    "Spherix Incorporated", 
-    "0.93", 
-    "$26.61M", 
-    "n/a", 
-    "Miscellaneous", 
-    "Multi-Sector Companies", 
-    "http://www.nasdaq.com/symbol/spex"
-  ], 
-  [
-    "SPHS", 
-    "Sophiris Bio, Inc.", 
-    "0.47", 
-    "$7.92M", 
-    "2013", 
-    "n/a", 
-    "n/a", 
-    "http://www.nasdaq.com/symbol/sphs"
-  ], 
-  [
-    "SPIL", 
-    "Siliconware Precision Industries Company, Ltd.", 
-    "8.74", 
-    "$5.46B", 
-    "n/a", 
-    "Technology", 
-    "Semiconductors", 
-    "http://www.nasdaq.com/symbol/spil"
-  ], 
-  [
-    "SPKE", 
-    "Spark Energy, Inc.", 
-    "15.2", 
-    "$209M", 
-    "2014", 
-    "Public Utilities", 
-    "Power Generation", 
-    "http://www.nasdaq.com/symbol/spke"
-  ], 
-  [
-    "SPLK", 
-    "Splunk Inc.", 
-    "68.945", 
-    "$8.36B", 
-    "2012", 
-    "Technology", 
-    "Computer Software: Prepackaged Software", 
-    "http://www.nasdaq.com/symbol/splk"
-  ], 
-  [
-    "SPLS", 
-    "Staples, Inc.", 
-    "16.79", 
-    "$10.75B", 
-    "1989", 
-    "Consumer Services", 
-    "Other Specialty Stores", 
-    "http://www.nasdaq.com/symbol/spls"
-  ], 
-  [
-    "SPNC", 
-    "The Spectranetics Corporation", 
-    "33.78", 
-    "$1.42B", 
-    "1992", 
-    "Health Care", 
-    "Biotechnology: Electromedical & Electrotherapeutic Apparatus", 
-    "http://www.nasdaq.com/symbol/spnc"
-  ], 
-  [
-    "SPNS", 
-    "Sapiens International Corporation N.V.", 
-    "7.31", 
-    "$348.53M", 
-    "1992", 
-    "Technology", 
-    "Computer Software: Prepackaged Software", 
-    "http://www.nasdaq.com/symbol/spns"
-  ], 
-  [
-    "SPOK", 
-    "Spok Holdings, Inc.", 
-    "18.93", 
-    "$410.46M", 
-    "n/a", 
-    "Public Utilities", 
-    "Telecommunications Equipment", 
-    "http://www.nasdaq.com/symbol/spok"
-  ], 
-  [
-    "SPPI", 
-    "Spectrum Pharmaceuticals, Inc.", 
-    "7.46", 
-    "$491.52M", 
-    "n/a", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/sppi"
-  ], 
-  [
-    "SPPR", 
-    "Supertel Hospitality, Inc.", 
-    "1.69", 
-    "$7.93M", 
-    "n/a", 
-    "Consumer Services", 
-    "Real Estate Investment Trusts", 
-    "http://www.nasdaq.com/symbol/sppr"
-  ], 
-  [
-    "SPPRO", 
-    "Supertel Hospitality, Inc.", 
-    "15.5001", 
-    "n/a", 
-    "n/a", 
-    "Consumer Services", 
-    "Real Estate Investment Trusts", 
-    "http://www.nasdaq.com/symbol/sppro"
-  ], 
-  [
-    "SPPRP", 
-    "Supertel Hospitality, Inc.", 
-    "5.6991", 
-    "n/a", 
-    "n/a", 
-    "Consumer Services", 
-    "Real Estate Investment Trusts", 
-    "http://www.nasdaq.com/symbol/spprp"
-  ], 
-  [
-    "SPRO", 
-    "SmartPros Ltd.", 
-    "1.43", 
-    "$6.66M", 
-    "n/a", 
-    "Consumer Services", 
-    "Other Consumer Services", 
-    "http://www.nasdaq.com/symbol/spro"
-  ], 
-  [
-    "SPRT", 
-    "support.com, Inc.", 
-    "1.68", 
-    "$90.88M", 
-    "2000", 
-    "Technology", 
-    "EDP Services", 
-    "http://www.nasdaq.com/symbol/sprt"
-  ], 
-  [
-    "SPSC", 
-    "SPS Commerce, Inc.", 
-    "67.4", 
-    "$1.1B", 
-    "2010", 
-    "Technology", 
-    "Computer Software: Prepackaged Software", 
-    "http://www.nasdaq.com/symbol/spsc"
-  ], 
-  [
-    "SPTN", 
-    "SpartanNash Company", 
-    "26.21", 
-    "$982.77M", 
-    "n/a", 
-    "Consumer Non-Durables", 
-    "Food Distributors", 
-    "http://www.nasdaq.com/symbol/sptn"
-  ], 
-  [
-    "SPU", 
-    "SkyPeople Fruit Juice, Inc.", 
-    "n/a", 
-    "n/a", 
-    "n/a", 
-    "Consumer Non-Durables", 
-    "Packaged Foods", 
-    "http://www.nasdaq.com/symbol/spu"
-  ], 
-  [
-    "SPWH", 
-    "Sportsman&#39;s Warehouse Holdings, Inc.", 
-    "n/a", 
-    "n/a", 
-    "2014", 
-    "Consumer Services", 
-    "Other Specialty Stores", 
-    "http://www.nasdaq.com/symbol/spwh"
-  ], 
-  [
-    "SPWR", 
-    "SunPower Corporation", 
-    "n/a", 
-    "n/a", 
-    "2005", 
-    "Technology", 
-    "Semiconductors", 
-    "http://www.nasdaq.com/symbol/spwr"
-  ], 
-  [
-    "SQBG", 
-    "Sequential Brands Group, Inc.", 
-    "10.39", 
-    "$396.61M", 
-    "n/a", 
-    "Consumer Non-Durables", 
-    "Apparel", 
-    "http://www.nasdaq.com/symbol/sqbg"
-  ], 
-  [
-    "SQBK", 
-    "Square 1 Financial, Inc.", 
-    "24.96", 
-    "$716.57M", 
-    "2014", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/sqbk"
-  ], 
-  [
-    "SQI", 
-    "SciQuest, Inc.", 
-    "17.18", 
-    "$472.83M", 
-    "2010", 
-    "Technology", 
-    "Computer Software: Prepackaged Software", 
-    "http://www.nasdaq.com/symbol/sqi"
-  ], 
-  [
-    "SQNM", 
-    "Sequenom, Inc.", 
-    "3.49", 
-    "$409.6M", 
-    "2000", 
-    "Capital Goods", 
-    "Industrial Machinery/Components", 
-    "http://www.nasdaq.com/symbol/sqnm"
-  ], 
-  [
-    "SQQQ", 
-    "ProShares UltraPro Short QQQ Fund", 
-    "25.23", 
-    "$227.07M", 
-    "n/a", 
-    "n/a", 
-    "n/a", 
-    "http://www.nasdaq.com/symbol/sqqq"
-  ], 
-  [
-    "SRCE", 
-    "1st Source Corporation", 
-    "31.31", 
-    "$747.13M", 
-    "n/a", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/srce"
-  ], 
-  [
-    "SRCL", 
-    "Stericycle, Inc.", 
-    "134.61", 
-    "$11.43B", 
-    "1996", 
-    "Basic Industries", 
-    "Environmental Services", 
-    "http://www.nasdaq.com/symbol/srcl"
-  ]
-]
\ No newline at end of file
diff --git a/examples/stocks/data/stock_data_25.json b/examples/stocks/data/stock_data_25.json
deleted file mode 100644
index 80e6c8f..0000000
--- a/examples/stocks/data/stock_data_25.json
+++ /dev/null
@@ -1,1002 +0,0 @@
-[
-  [
-    "SRDX", 
-    "SurModics, Inc.", 
-    "23.57", 
-    "$304.98M", 
-    "1998", 
-    "Health Care", 
-    "Medical/Dental Instruments", 
-    "http://www.nasdaq.com/symbol/srdx"
-  ], 
-  [
-    "SREV", 
-    "ServiceSource International, Inc.", 
-    "3.84", 
-    "$321.74M", 
-    "2011", 
-    "Miscellaneous", 
-    "Business Services", 
-    "http://www.nasdaq.com/symbol/srev"
-  ], 
-  [
-    "SRNE", 
-    "Sorrento Therapeutics, Inc.", 
-    "12.37", 
-    "$357.9M", 
-    "n/a", 
-    "Health Care", 
-    "Biotechnology: Commercial Physical & Biological Resarch", 
-    "http://www.nasdaq.com/symbol/srne"
-  ], 
-  [
-    "SRPT", 
-    "Sarepta Therapeutics, Inc.", 
-    "15.21", 
-    "$628.32M", 
-    "n/a", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/srpt"
-  ], 
-  [
-    "SRSC", 
-    "Sears Canada Inc. ", 
-    "9.87", 
-    "$1.01B", 
-    "n/a", 
-    "Consumer Services", 
-    "Department/Specialty Retail Stores", 
-    "http://www.nasdaq.com/symbol/srsc"
-  ], 
-  [
-    "SSB", 
-    "South State Corporation", 
-    "65.05", 
-    "$1.57B", 
-    "n/a", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/ssb"
-  ], 
-  [
-    "SSBI", 
-    "Summit State Bank", 
-    "13.73", 
-    "$65.61M", 
-    "2006", 
-    "n/a", 
-    "n/a", 
-    "http://www.nasdaq.com/symbol/ssbi"
-  ], 
-  [
-    "SSFN", 
-    "Stewardship Financial Corp", 
-    "5.45", 
-    "$32.86M", 
-    "n/a", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/ssfn"
-  ], 
-  [
-    "SSH", 
-    "Sunshine Heart Inc", 
-    "5.25", 
-    "$88.89M", 
-    "n/a", 
-    "Health Care", 
-    "Biotechnology: Electromedical & Electrotherapeutic Apparatus", 
-    "http://www.nasdaq.com/symbol/ssh"
-  ], 
-  [
-    "SSNC", 
-    "SS&C Technologies Holdings, Inc.", 
-    "62.6", 
-    "$5.24B", 
-    "2010", 
-    "Technology", 
-    "Computer Software: Prepackaged Software", 
-    "http://www.nasdaq.com/symbol/ssnc"
-  ], 
-  [
-    "SSRG", 
-    "Symmetry Surgical Inc.", 
-    "7.85", 
-    "$75.26M", 
-    "n/a", 
-    "Health Care", 
-    "Industrial Specialties", 
-    "http://www.nasdaq.com/symbol/ssrg"
-  ], 
-  [
-    "SSRI", 
-    "Silver Standard Resources Inc.", 
-    "5.405", 
-    "$436.48M", 
-    "n/a", 
-    "Basic Industries", 
-    "Precious Metals", 
-    "http://www.nasdaq.com/symbol/ssri"
-  ], 
-  [
-    "SSYS", 
-    "Stratasys, Ltd.", 
-    "63.88", 
-    "$3.25B", 
-    "1994", 
-    "Technology", 
-    "Computer peripheral equipment", 
-    "http://www.nasdaq.com/symbol/ssys"
-  ], 
-  [
-    "STAA", 
-    "STAAR Surgical Company", 
-    "6.63", 
-    "$256.27M", 
-    "n/a", 
-    "Health Care", 
-    "Ophthalmic Goods", 
-    "http://www.nasdaq.com/symbol/staa"
-  ], 
-  [
-    "STB", 
-    "Student Transportation Inc", 
-    "5.75", 
-    "$480.27M", 
-    "n/a", 
-    "Transportation", 
-    "Other Transportation", 
-    "http://www.nasdaq.com/symbol/stb"
-  ], 
-  [
-    "STBA", 
-    "S&T Bancorp, Inc.", 
-    "28.81", 
-    "$858.43M", 
-    "n/a", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/stba"
-  ], 
-  [
-    "STBZ", 
-    "State Bank Financial Corporation.", 
-    "19.75", 
-    "$637.36M", 
-    "n/a", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/stbz"
-  ], 
-  [
-    "STCK", 
-    "Stock Building Supply Holdings, Inc.", 
-    "15.89", 
-    "$415.94M", 
-    "2013", 
-    "Consumer Services", 
-    "RETAIL: Building Materials", 
-    "http://www.nasdaq.com/symbol/stck"
-  ], 
-  [
-    "STEM", 
-    "StemCells, Inc.", 
-    "1.09", 
-    "$74.92M", 
-    "1992", 
-    "Health Care", 
-    "Biotechnology: Biological Products (No Diagnostic Substances)", 
-    "http://www.nasdaq.com/symbol/stem"
-  ], 
-  [
-    "STFC", 
-    "State Auto Financial Corporation", 
-    "24.23", 
-    "$992.63M", 
-    "1991", 
-    "Finance", 
-    "Property-Casualty Insurers", 
-    "http://www.nasdaq.com/symbol/stfc"
-  ], 
-  [
-    "STKL", 
-    "SunOpta, Inc.", 
-    "11.85", 
-    "$796.41M", 
-    "n/a", 
-    "Consumer Services", 
-    "Farming/Seeds/Milling", 
-    "http://www.nasdaq.com/symbol/stkl"
-  ], 
-  [
-    "STLD", 
-    "Steel Dynamics, Inc.", 
-    "19.47", 
-    "$4.68B", 
-    "1996", 
-    "Basic Industries", 
-    "Steel/Iron Ore", 
-    "http://www.nasdaq.com/symbol/stld"
-  ], 
-  [
-    "STLY", 
-    "Stanley Furniture Company, Inc.", 
-    "3.4", 
-    "$50.25M", 
-    "n/a", 
-    "Consumer Durables", 
-    "Home Furnishings", 
-    "http://www.nasdaq.com/symbol/stly"
-  ], 
-  [
-    "STML", 
-    "Stemline Therapeutics, Inc.", 
-    "14.1", 
-    "$187.32M", 
-    "2013", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/stml"
-  ], 
-  [
-    "STMP", 
-    "Stamps.com Inc.", 
-    "57.52", 
-    "$922.02M", 
-    "1999", 
-    "Miscellaneous", 
-    "Business Services", 
-    "http://www.nasdaq.com/symbol/stmp"
-  ], 
-  [
-    "STNR", 
-    "Steiner Leisure Limited", 
-    "47.57", 
-    "$645.31M", 
-    "1996", 
-    "Consumer Services", 
-    "Other Consumer Services", 
-    "http://www.nasdaq.com/symbol/stnr"
-  ], 
-  [
-    "STPP", 
-    "iPath US Treasury Steepener ETN", 
-    "34.29", 
-    "$13.96M", 
-    "n/a", 
-    "Finance", 
-    "Commercial Banks", 
-    "http://www.nasdaq.com/symbol/stpp"
-  ], 
-  [
-    "STRA", 
-    "Strayer Education, Inc.", 
-    "61.45", 
-    "$670.01M", 
-    "1996", 
-    "Consumer Services", 
-    "Other Consumer Services", 
-    "http://www.nasdaq.com/symbol/stra"
-  ], 
-  [
-    "STRL", 
-    "Sterling Construction Company Inc", 
-    "2.99", 
-    "$56.22M", 
-    "n/a", 
-    "Basic Industries", 
-    "Military/Government/Technical", 
-    "http://www.nasdaq.com/symbol/strl"
-  ], 
-  [
-    "STRM", 
-    "Streamline Health Solutions, Inc.", 
-    "4.15", 
-    "$76.65M", 
-    "n/a", 
-    "Technology", 
-    "EDP Services", 
-    "http://www.nasdaq.com/symbol/strm"
-  ], 
-  [
-    "STRN", 
-    "Sutron Corporation", 
-    "5.4201", 
-    "$27.56M", 
-    "n/a", 
-    "Capital Goods", 
-    "Industrial Machinery/Components", 
-    "http://www.nasdaq.com/symbol/strn"
-  ], 
-  [
-    "STRS", 
-    "Stratus Properties, Inc.", 
-    "13.45", 
-    "$108.12M", 
-    "n/a", 
-    "Consumer Services", 
-    "Homebuilding", 
-    "http://www.nasdaq.com/symbol/strs"
-  ], 
-  [
-    "STRT", 
-    "Strattec Security Corporation", 
-    "64.79", 
-    "$232.41M", 
-    "n/a", 
-    "Capital Goods", 
-    "Auto Parts:O.E.M.", 
-    "http://www.nasdaq.com/symbol/strt"
-  ], 
-  [
-    "STRZA", 
-    "Starz", 
-    "31.52", 
-    "$3.29B", 
-    "n/a", 
-    "Consumer Services", 
-    "Television Services", 
-    "http://www.nasdaq.com/symbol/strza"
-  ], 
-  [
-    "STRZB", 
-    "Starz", 
-    "30.3728", 
-    "$3.17B", 
-    "n/a", 
-    "Consumer Services", 
-    "Television Services", 
-    "http://www.nasdaq.com/symbol/strzb"
-  ], 
-  [
-    "STX", 
-    "Seagate Technology.", 
-    "62.18", 
-    "$20.42B", 
-    "2002", 
-    "Technology", 
-    "Electronic Components", 
-    "http://www.nasdaq.com/symbol/stx"
-  ], 
-  [
-    "STXS", 
-    "Stereotaxis, Inc.", 
-    "2.65", 
-    "$54.22M", 
-    "2004", 
-    "Health Care", 
-    "Biotechnology: Electromedical & Electrotherapeutic Apparatus", 
-    "http://www.nasdaq.com/symbol/stxs"
-  ], 
-  [
-    "SUBK", 
-    "Suffolk Bancorp", 
-    "23.14", 
-    "$269.99M", 
-    "n/a", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/subk"
-  ], 
-  [
-    "SUMR", 
-    "Summer Infant, Inc.", 
-    "2.65", 
-    "$48.06M", 
-    "n/a", 
-    "Consumer Durables", 
-    "Miscellaneous manufacturing industries", 
-    "http://www.nasdaq.com/symbol/sumr"
-  ], 
-  [
-    "SUNS", 
-    "Solar Senior Capital Ltd.", 
-    "15.73", 
-    "$181.42M", 
-    "2011", 
-    "n/a", 
-    "n/a", 
-    "http://www.nasdaq.com/symbol/suns"
-  ], 
-  [
-    "SUPN", 
-    "Supernus Pharmaceuticals, Inc.", 
-    "8.67", 
-    "$372.21M", 
-    "2012", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/supn"
-  ], 
-  [
-    "SURG", 
-    "Synergetics USA, Inc.", 
-    "4.49", 
-    "$113.88M", 
-    "n/a", 
-    "Health Care", 
-    "Biotechnology: Electromedical & Electrotherapeutic Apparatus", 
-    "http://www.nasdaq.com/symbol/surg"
-  ], 
-  [
-    "SUSQ", 
-    "Susquehanna Bancshares, Inc.", 
-    "13.5", 
-    "$2.45B", 
-    "n/a", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/susq"
-  ], 
-  [
-    "SUTR", 
-    "Sutor Technology Group Limited", 
-    "0.88", 
-    "$36.62M", 
-    "n/a", 
-    "Capital Goods", 
-    "Steel/Iron Ore", 
-    "http://www.nasdaq.com/symbol/sutr"
-  ], 
-  [
-    "SVA", 
-    "Sinovac Biotech, Ltd.", 
-    "5", 
-    "$278.49M", 
-    "n/a", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/sva"
-  ], 
-  [
-    "SVBI", 
-    "Severn Bancorp Inc", 
-    "4.41", 
-    "$44.4M", 
-    "n/a", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/svbi"
-  ], 
-  [
-    "SVVC", 
-    "Firsthand Technology Value Fund, Inc.", 
-    "13.7", 
-    "$124.29M", 
-    "n/a", 
-    "n/a", 
-    "n/a", 
-    "http://www.nasdaq.com/symbol/svvc"
-  ], 
-  [
-    "SWHC", 
-    "Smith & Wesson Holding Corporation", 
-    "12.78", 
-    "$686.34M", 
-    "n/a", 
-    "Capital Goods", 
-    "Ordnance And Accessories", 
-    "http://www.nasdaq.com/symbol/swhc"
-  ], 
-  [
-    "SWIR", 
-    "Sierra Wireless, Inc.", 
-    "37.77", 
-    "$1.2B", 
-    "n/a", 
-    "Technology", 
-    "Radio And Television Broadcasting And Communications Equipment", 
-    "http://www.nasdaq.com/symbol/swir"
-  ], 
-  [
-    "SWKS", 
-    "Skyworks Solutions, Inc.", 
-    "84.3", 
-    "$16.09B", 
-    "n/a", 
-    "Technology", 
-    "Semiconductors", 
-    "http://www.nasdaq.com/symbol/swks"
-  ], 
-  [
-    "SWSH", 
-    "Swisher Hygiene, Inc.", 
-    "1.98", 
-    "$34.83M", 
-    "n/a", 
-    "Basic Industries", 
-    "Package Goods/Cosmetics", 
-    "http://www.nasdaq.com/symbol/swsh"
-  ], 
-  [
-    "SYBT", 
-    "Stock Yards Bancorp, Inc.", 
-    "32.61", 
-    "$479.72M", 
-    "n/a", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/sybt"
-  ], 
-  [
-    "SYKE", 
-    "Sykes Enterprises, Incorporated", 
-    "22.82", 
-    "$987.91M", 
-    "1996", 
-    "Technology", 
-    "EDP Services", 
-    "http://www.nasdaq.com/symbol/syke"
-  ], 
-  [
-    "SYMC", 
-    "Symantec Corporation", 
-    "25.685", 
-    "$17.53B", 
-    "1989", 
-    "Technology", 
-    "Computer Software: Prepackaged Software", 
-    "http://www.nasdaq.com/symbol/symc"
-  ], 
-  [
-    "SYMX", 
-    "Synthesis Energy Systems, Inc.", 
-    "0.78", 
-    "$57.11M", 
-    "n/a", 
-    "Basic Industries", 
-    "Major Chemicals", 
-    "http://www.nasdaq.com/symbol/symx"
-  ], 
-  [
-    "SYNA", 
-    "Synaptics Incorporated", 
-    "82.225", 
-    "$3.02B", 
-    "2002", 
-    "Technology", 
-    "EDP Services", 
-    "http://www.nasdaq.com/symbol/syna"
-  ], 
-  [
-    "SYNC", 
-    "Synacor, Inc.", 
-    "2.2", 
-    "$60.24M", 
-    "2012", 
-    "Technology", 
-    "Computer Software: Programming, Data Processing", 
-    "http://www.nasdaq.com/symbol/sync"
-  ], 
-  [
-    "SYNL", 
-    "Synalloy Corporation", 
-    "15.37", 
-    "$133.86M", 
-    "n/a", 
-    "Basic Industries", 
-    "Steel/Iron Ore", 
-    "http://www.nasdaq.com/symbol/synl"
-  ], 
-  [
-    "SYNT", 
-    "Syntel, Inc.", 
-    "49.68", 
-    "$4.15B", 
-    "1997", 
-    "Technology", 
-    "EDP Services", 
-    "http://www.nasdaq.com/symbol/synt"
-  ], 
-  [
-    "SYPR", 
-    "Sypris Solutions, Inc.", 
-    "2.42", 
-    "$49.63M", 
-    "n/a", 
-    "Capital Goods", 
-    "Industrial Machinery/Components", 
-    "http://www.nasdaq.com/symbol/sypr"
-  ], 
-  [
-    "SYRX", 
-    "Sysorex Global Holding Corp.", 
-    "1.52", 
-    "$29.87M", 
-    "2014", 
-    "Technology", 
-    "EDP Services", 
-    "http://www.nasdaq.com/symbol/syrx"
-  ], 
-  [
-    "SYUT", 
-    "Synutra International, Inc.", 
-    "5.74", 
-    "$328.91M", 
-    "n/a", 
-    "Consumer Non-Durables", 
-    "Packaged Foods", 
-    "http://www.nasdaq.com/symbol/syut"
-  ], 
-  [
-    "SZMK", 
-    "Sizmek Inc.", 
-    "7.87", 
-    "$239.24M", 
-    "n/a", 
-    "Consumer Services", 
-    "Advertising", 
-    "http://www.nasdaq.com/symbol/szmk"
-  ], 
-  [
-    "SZYM", 
-    "Solazyme, Inc.", 
-    "2.56", 
-    "$203.01M", 
-    "2011", 
-    "Basic Industries", 
-    "Major Chemicals", 
-    "http://www.nasdaq.com/symbol/szym"
-  ], 
-  [
-    "TACT", 
-    "TransAct Technologies Incorporated", 
-    "6.61", 
-    "$54.34M", 
-    "1996", 
-    "Technology", 
-    "Computer peripheral equipment", 
-    "http://www.nasdaq.com/symbol/tact"
-  ], 
-  [
-    "TAIT", 
-    "Taitron Components Incorporated", 
-    "1", 
-    "$5.54M", 
-    "1995", 
-    "Consumer Non-Durables", 
-    "Electronic Components", 
-    "http://www.nasdaq.com/symbol/tait"
-  ], 
-  [
-    "TAPR", 
-    "Barclays Inverse US Treasury Composite ETN", 
-    "32.96", 
-    "n/a", 
-    "n/a", 
-    "Finance", 
-    "Commercial Banks", 
-    "http://www.nasdaq.com/symbol/tapr"
-  ], 
-  [
-    "TASR", 
-    "TASER International, Inc.", 
-    "27.58", 
-    "$1.45B", 
-    "n/a", 
-    "Capital Goods", 
-    "Ordnance And Accessories", 
-    "http://www.nasdaq.com/symbol/tasr"
-  ], 
-  [
-    "TAST", 
-    "Carrols Restaurant Group, Inc.", 
-    "8.8", 
-    "$309.96M", 
-    "2006", 
-    "Consumer Services", 
-    "Restaurants", 
-    "http://www.nasdaq.com/symbol/tast"
-  ], 
-  [
-    "TATT", 
-    "TAT Technologies Ltd.", 
-    "6.31", 
-    "$55.56M", 
-    "n/a", 
-    "Capital Goods", 
-    "Aerospace", 
-    "http://www.nasdaq.com/symbol/tatt"
-  ], 
-  [
-    "TAX", 
-    "Liberty Tax, Inc.", 
-    "33.92", 
-    "$430.21M", 
-    "n/a", 
-    "Miscellaneous", 
-    "Multi-Sector Companies", 
-    "http://www.nasdaq.com/symbol/tax"
-  ], 
-  [
-    "TAXI", 
-    "Medallion Financial Corp.", 
-    "10.8", 
-    "$271.76M", 
-    "1996", 
-    "Finance", 
-    "Finance: Consumer Services", 
-    "http://www.nasdaq.com/symbol/taxi"
-  ], 
-  [
-    "TAYD", 
-    "Taylor Devices, Inc.", 
-    "11.55", 
-    "$38.66M", 
-    "n/a", 
-    "Capital Goods", 
-    "Industrial Machinery/Components", 
-    "http://www.nasdaq.com/symbol/tayd"
-  ], 
-  [
-    "TBBK", 
-    "The Bancorp, Inc.", 
-    "8.99", 
-    "$339M", 
-    "n/a", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/tbbk"
-  ], 
-  [
-    "TBIO", 
-    "Transgenomic, Inc.", 
-    "2.54", 
-    "$21.04M", 
-    "2000", 
-    "Capital Goods", 
-    "Biotechnology: Laboratory Analytical Instruments", 
-    "http://www.nasdaq.com/symbol/tbio"
-  ], 
-  [
-    "TBK", 
-    "Triumph Bancorp, Inc.", 
-    "12.98", 
-    "$233.17M", 
-    "2014", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/tbk"
-  ], 
-  [
-    "TBNK", 
-    "Territorial Bancorp Inc.", 
-    "21.78", 
-    "$217.14M", 
-    "2009", 
-    "Finance", 
-    "Savings Institutions", 
-    "http://www.nasdaq.com/symbol/tbnk"
-  ], 
-  [
-    "TBPH", 
-    "Theravance Biopharma, Inc.", 
-    "19.52", 
-    "$629.1M", 
-    "n/a", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/tbph"
-  ], 
-  [
-    "TCBI", 
-    "Texas Capital Bancshares, Inc.", 
-    "46.99", 
-    "$2.15B", 
-    "2003", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/tcbi"
-  ], 
-  [
-    "TCBIL", 
-    "Texas Capital Bancshares, Inc.", 
-    "24.63", 
-    "n/a", 
-    "n/a", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/tcbil"
-  ], 
-  [
-    "TCBIP", 
-    "Texas Capital Bancshares, Inc.", 
-    "24.762", 
-    "$148.57M", 
-    "n/a", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/tcbip"
-  ], 
-  [
-    "TCBIW", 
-    "Texas Capital Bancshares, Inc.", 
-    "33.37", 
-    "n/a", 
-    "n/a", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/tcbiw"
-  ], 
-  [
-    "TCBK", 
-    "TriCo Bancshares", 
-    "24.47", 
-    "$555.84M", 
-    "n/a", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/tcbk"
-  ], 
-  [
-    "TCCO", 
-    "Technical Communications Corporation", 
-    "4.2699", 
-    "$7.85M", 
-    "n/a", 
-    "Technology", 
-    "Radio And Television Broadcasting And Communications Equipment", 
-    "http://www.nasdaq.com/symbol/tcco"
-  ], 
-  [
-    "TCFC", 
-    "The Community Financial Corporation", 
-    "19.6916", 
-    "$92.33M", 
-    "n/a", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/tcfc"
-  ], 
-  [
-    "TCON", 
-    "TRACON Pharmaceuticals, Inc.", 
-    "10.14", 
-    "$122.62M", 
-    "2015", 
-    "Health Care", 
-    "Biotechnology: Biological Products (No Diagnostic Substances)", 
-    "http://www.nasdaq.com/symbol/tcon"
-  ], 
-  [
-    "TCPC", 
-    "TCP Capital Corp.", 
-    "16.79", 
-    "$718.79M", 
-    "2012", 
-    "n/a", 
-    "n/a", 
-    "http://www.nasdaq.com/symbol/tcpc"
-  ], 
-  [
-    "TCRD", 
-    "THL Credit, Inc.", 
-    "11.9", 
-    "$403.47M", 
-    "2010", 
-    "n/a", 
-    "n/a", 
-    "http://www.nasdaq.com/symbol/tcrd"
-  ], 
-  [
-    "TCX", 
-    "Tucows Inc.", 
-    "18.44", 
-    "$208.92M", 
-    "n/a", 
-    "Technology", 
-    "EDP Services", 
-    "http://www.nasdaq.com/symbol/tcx"
-  ], 
-  [
-    "TDIV", 
-    "First Trust NASDAQ Technology Dividend Index Fund", 
-    "28.56", 
-    "$741.27M", 
-    "n/a", 
-    "n/a", 
-    "n/a", 
-    "http://www.nasdaq.com/symbol/tdiv"
-  ], 
-  [
-    "TEAR", 
-    "TearLab Corporation", 
-    "2.52", 
-    "$84.78M", 
-    "n/a", 
-    "Health Care", 
-    "Medical/Dental Instruments", 
-    "http://www.nasdaq.com/symbol/tear"
-  ], 
-  [
-    "TECD", 
-    "Tech Data Corporation", 
-    "61.78", 
-    "$2.36B", 
-    "1986", 
-    "Technology", 
-    "Retail: Computer Software & Peripheral Equipment", 
-    "http://www.nasdaq.com/symbol/tecd"
-  ], 
-  [
-    "TECH", 
-    "Bio-Techne Corp", 
-    "96.36", 
-    "$3.58B", 
-    "n/a", 
-    "Health Care", 
-    "Biotechnology: Biological Products (No Diagnostic Substances)", 
-    "http://www.nasdaq.com/symbol/tech"
-  ], 
-  [
-    "TECU", 
-    "Tecumseh Products Company", 
-    "3.1", 
-    "$57.29M", 
-    "n/a", 
-    "Capital Goods", 
-    "Industrial Machinery/Components", 
-    "http://www.nasdaq.com/symbol/tecu"
-  ], 
-  [
-    "TEDU", 
-    "Tarena International, Inc.", 
-    "11.2", 
-    "$567.36M", 
-    "2014", 
-    "Consumer Services", 
-    "Other Consumer Services", 
-    "http://www.nasdaq.com/symbol/tedu"
-  ], 
-  [
-    "TENX", 
-    "Tenax Therapeutics, Inc.", 
-    "3.31", 
-    "$93.08M", 
-    "n/a", 
-    "Health Care", 
-    "Biotechnology: Commercial Physical & Biological Resarch", 
-    "http://www.nasdaq.com/symbol/tenx"
-  ], 
-  [
-    "TERP", 
-    "TerraForm Power, Inc.", 
-    "33.4", 
-    "$1.41B", 
-    "2014", 
-    "Public Utilities", 
-    "Electric Utilities: Central", 
-    "http://www.nasdaq.com/symbol/terp"
-  ], 
-  [
-    "TESO", 
-    "Tesco Corporation", 
-    "10.79", 
-    "$427.74M", 
-    "n/a", 
-    "Energy", 
-    "Metal Fabrications", 
-    "http://www.nasdaq.com/symbol/teso"
-  ], 
-  [
-    "TESS", 
-    "TESSCO Technologies Incorporated", 
-    "25.27", 
-    "$206.85M", 
-    "1994", 
-    "Consumer Non-Durables", 
-    "Electronic Components", 
-    "http://www.nasdaq.com/symbol/tess"
-  ], 
-  [
-    "TFM", 
-    "The Fresh Market, Inc.", 
-    "37.09", 
-    "$1.8B", 
-    "2010", 
-    "Consumer Services", 
-    "Food Chains", 
-    "http://www.nasdaq.com/symbol/tfm"
-  ]
-]
\ No newline at end of file
diff --git a/examples/stocks/data/stock_data_26.json b/examples/stocks/data/stock_data_26.json
deleted file mode 100644
index 48aaf6b..0000000
--- a/examples/stocks/data/stock_data_26.json
+++ /dev/null
@@ -1,1002 +0,0 @@
-[
-  [
-    "TFSC", 
-    "1347 Capital Corp.", 
-    "9.43", 
-    "$56.09M", 
-    "2014", 
-    "Finance", 
-    "Business Services", 
-    "http://www.nasdaq.com/symbol/tfsc"
-  ], 
-  [
-    "TFSCR", 
-    "1347 Capital Corp.", 
-    "0.37", 
-    "n/a", 
-    "2014", 
-    "Finance", 
-    "Business Services", 
-    "http://www.nasdaq.com/symbol/tfscr"
-  ], 
-  [
-    "TFSCU", 
-    "1347 Capital Corp.", 
-    "9.97", 
-    "$41.67M", 
-    "2014", 
-    "n/a", 
-    "n/a", 
-    "http://www.nasdaq.com/symbol/tfscu"
-  ], 
-  [
-    "TFSCW", 
-    "1347 Capital Corp.", 
-    "0.2", 
-    "n/a", 
-    "2014", 
-    "Finance", 
-    "Business Services", 
-    "http://www.nasdaq.com/symbol/tfscw"
-  ], 
-  [
-    "TFSL", 
-    "TFS Financial Corporation", 
-    "14.18", 
-    "$4.23B", 
-    "n/a", 
-    "Finance", 
-    "Savings Institutions", 
-    "http://www.nasdaq.com/symbol/tfsl"
-  ], 
-  [
-    "TGA", 
-    "Transglobe Energy Corp", 
-    "3.03", 
-    "$228.04M", 
-    "n/a", 
-    "Energy", 
-    "Oil & Gas Production", 
-    "http://www.nasdaq.com/symbol/tga"
-  ], 
-  [
-    "TGEN", 
-    "Tecogen Inc.", 
-    "5.2099", 
-    "$82.36M", 
-    "2014", 
-    "Capital Goods", 
-    "Industrial Machinery/Components", 
-    "http://www.nasdaq.com/symbol/tgen"
-  ], 
-  [
-    "TGLS", 
-    "Tecnoglass Inc.", 
-    "9.8377", 
-    "$240.07M", 
-    "2012", 
-    "Consumer Durables", 
-    "Electronic Components", 
-    "http://www.nasdaq.com/symbol/tgls"
-  ], 
-  [
-    "TGTX", 
-    "TG Therapeutics, Inc.", 
-    "13.5", 
-    "$593.52M", 
-    "n/a", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/tgtx"
-  ], 
-  [
-    "THFF", 
-    "First Financial Corporation Indiana", 
-    "34.29", 
-    "$442.54M", 
-    "n/a", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/thff"
-  ], 
-  [
-    "THLD", 
-    "Threshold Pharmaceuticals, Inc.", 
-    "4.35", 
-    "$272.96M", 
-    "2005", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/thld"
-  ], 
-  [
-    "THOR", 
-    "Thoratec Corporation", 
-    "40.5", 
-    "$2.17B", 
-    "n/a", 
-    "Health Care", 
-    "Biotechnology: Electromedical & Electrotherapeutic Apparatus", 
-    "http://www.nasdaq.com/symbol/thor"
-  ], 
-  [
-    "THRM", 
-    "Gentherm Inc", 
-    "42.27", 
-    "$1.51B", 
-    "n/a", 
-    "Capital Goods", 
-    "Auto Parts:O.E.M.", 
-    "http://www.nasdaq.com/symbol/thrm"
-  ], 
-  [
-    "THRX", 
-    "Theravance, Inc.", 
-    "18.22", 
-    "$2.1B", 
-    "2004", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/thrx"
-  ], 
-  [
-    "THST", 
-    "Truett-Hurst, Inc.", 
-    "2.82", 
-    "$10.85M", 
-    "2013", 
-    "Consumer Non-Durables", 
-    "Beverages (Production/Distribution)", 
-    "http://www.nasdaq.com/symbol/thst"
-  ], 
-  [
-    "THTI", 
-    "THT Heat Transfer Technology, Inc.", 
-    "1.04", 
-    "$21.27M", 
-    "n/a", 
-    "Capital Goods", 
-    "Metal Fabrications", 
-    "http://www.nasdaq.com/symbol/thti"
-  ], 
-  [
-    "TICC", 
-    "TICC Capital Corp.", 
-    "7.61", 
-    "$459.32M", 
-    "2003", 
-    "n/a", 
-    "n/a", 
-    "http://www.nasdaq.com/symbol/ticc"
-  ], 
-  [
-    "TIGR", 
-    "TigerLogic Corporation", 
-    "0.35", 
-    "$10.83M", 
-    "n/a", 
-    "Technology", 
-    "Computer Software: Prepackaged Software", 
-    "http://www.nasdaq.com/symbol/tigr"
-  ], 
-  [
-    "TILE", 
-    "Interface, Inc.", 
-    "18.91", 
-    "$1.25B", 
-    "n/a", 
-    "Consumer Durables", 
-    "Home Furnishings", 
-    "http://www.nasdaq.com/symbol/tile"
-  ], 
-  [
-    "TINY", 
-    "Harris & Harris Group, Inc.", 
-    "3.19", 
-    "$99.67M", 
-    "n/a", 
-    "Finance", 
-    "Finance/Investors Services", 
-    "http://www.nasdaq.com/symbol/tiny"
-  ], 
-  [
-    "TIPT", 
-    "Tiptree Financial Inc.", 
-    "7.1", 
-    "$295.36M", 
-    "n/a", 
-    "Finance", 
-    "Specialty Insurers", 
-    "http://www.nasdaq.com/symbol/tipt"
-  ], 
-  [
-    "TISA", 
-    "Top Image Systems, Ltd.", 
-    "3.12", 
-    "$55.58M", 
-    "1996", 
-    "Technology", 
-    "Computer peripheral equipment", 
-    "http://www.nasdaq.com/symbol/tisa"
-  ], 
-  [
-    "TITN", 
-    "Titan Machinery Inc.", 
-    "14.89", 
-    "$318.81M", 
-    "2007", 
-    "Consumer Services", 
-    "Other Specialty Stores", 
-    "http://www.nasdaq.com/symbol/titn"
-  ], 
-  [
-    "TIVO", 
-    "TiVo Inc.", 
-    "10.83", 
-    "$1.11B", 
-    "1999", 
-    "Consumer Services", 
-    "Television Services", 
-    "http://www.nasdaq.com/symbol/tivo"
-  ], 
-  [
-    "TKAI", 
-    "Tokai Pharmaceuticals, Inc.", 
-    "14.49", 
-    "$324.31M", 
-    "2014", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/tkai"
-  ], 
-  [
-    "TKMR", 
-    "Tekmira Pharmaceuticals Corp", 
-    "19.89", 
-    "$446.3M", 
-    "n/a", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/tkmr"
-  ], 
-  [
-    "TLF", 
-    "Tandy Leather Factory, Inc.", 
-    "8.99", 
-    "$92.11M", 
-    "n/a", 
-    "Consumer Non-Durables", 
-    "Apparel", 
-    "http://www.nasdaq.com/symbol/tlf"
-  ], 
-  [
-    "TLMR", 
-    "Talmer Bancorp, Inc.", 
-    "13.7", 
-    "$965.9M", 
-    "2014", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/tlmr"
-  ], 
-  [
-    "TLOG", 
-    "TetraLogic Pharmaceuticals Corporation", 
-    "4.94", 
-    "$110.24M", 
-    "2013", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/tlog"
-  ], 
-  [
-    "TNAV", 
-    "TeleNav, Inc.", 
-    "8.23", 
-    "$328.4M", 
-    "2010", 
-    "Capital Goods", 
-    "Industrial Machinery/Components", 
-    "http://www.nasdaq.com/symbol/tnav"
-  ], 
-  [
-    "TNDM", 
-    "Tandem Diabetes Care, Inc.", 
-    "13.54", 
-    "$320M", 
-    "2013", 
-    "Health Care", 
-    "Medical/Dental Instruments", 
-    "http://www.nasdaq.com/symbol/tndm"
-  ], 
-  [
-    "TNGO", 
-    "Tangoe, Inc.", 
-    "12.19", 
-    "$473.51M", 
-    "2011", 
-    "Technology", 
-    "Computer Software: Prepackaged Software", 
-    "http://www.nasdaq.com/symbol/tngo"
-  ], 
-  [
-    "TNXP", 
-    "Tonix Pharmaceuticals Holding Corp.", 
-    "6.25", 
-    "$98.16M", 
-    "n/a", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/tnxp"
-  ], 
-  [
-    "TOPS", 
-    "TOP Ships Inc.", 
-    "1.18", 
-    "$22.38M", 
-    "n/a", 
-    "Transportation", 
-    "Marine Transportation", 
-    "http://www.nasdaq.com/symbol/tops"
-  ], 
-  [
-    "TORM          ", 
-    "TOR Minerals International Inc", 
-    "7.21", 
-    "$21.73M", 
-    "1988", 
-    "Basic Industries", 
-    "Major Chemicals", 
-    "http://www.nasdaq.com/symbol/torm          "
-  ], 
-  [
-    "TOUR", 
-    "Tuniu Corporation", 
-    "15.03", 
-    "$729.75M", 
-    "2014", 
-    "Consumer Services", 
-    "Transportation Services", 
-    "http://www.nasdaq.com/symbol/tour"
-  ], 
-  [
-    "TOWN", 
-    "Towne Bank", 
-    "15.63", 
-    "$552M", 
-    "n/a", 
-    "n/a", 
-    "n/a", 
-    "http://www.nasdaq.com/symbol/town"
-  ], 
-  [
-    "TQQQ", 
-    "ProShares UltraPro QQQ Fund", 
-    "111.33", 
-    "$1.02B", 
-    "n/a", 
-    "n/a", 
-    "n/a", 
-    "http://www.nasdaq.com/symbol/tqqq"
-  ], 
-  [
-    "TRAK", 
-    "Dealertrack Technologies, Inc.", 
-    "44.95", 
-    "$2.43B", 
-    "2005", 
-    "Technology", 
-    "EDP Services", 
-    "http://www.nasdaq.com/symbol/trak"
-  ], 
-  [
-    "TRCB", 
-    "Two River Bancorp", 
-    "8.57", 
-    "$68M", 
-    "n/a", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/trcb"
-  ], 
-  [
-    "TRCH", 
-    "Torchlight Energy Resources, Inc.", 
-    "0.513", 
-    "$11.9M", 
-    "n/a", 
-    "Energy", 
-    "Oil & Gas Production", 
-    "http://www.nasdaq.com/symbol/trch"
-  ], 
-  [
-    "TREE", 
-    "LendingTree, Inc.", 
-    "43.84", 
-    "$496.55M", 
-    "n/a", 
-    "Finance", 
-    "Finance: Consumer Services", 
-    "http://www.nasdaq.com/symbol/tree"
-  ], 
-  [
-    "TRGT", 
-    "Targacept, Inc.", 
-    "2.6", 
-    "$89.21M", 
-    "2006", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/trgt"
-  ], 
-  [
-    "TRIB", 
-    "Trinity Biotech plc", 
-    "17.82", 
-    "$411.18M", 
-    "1992", 
-    "Health Care", 
-    "Biotechnology: In Vitro & In Vivo Diagnostic Substances", 
-    "http://www.nasdaq.com/symbol/trib"
-  ], 
-  [
-    "TRIL", 
-    "Trillium Therapeutics Inc.", 
-    "13.57", 
-    "$58.09M", 
-    "n/a", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/tril"
-  ], 
-  [
-    "TRIP", 
-    "TripAdvisor, Inc.", 
-    "88.78", 
-    "$12.69B", 
-    "n/a", 
-    "Technology", 
-    "Computer Software: Programming, Data Processing", 
-    "http://www.nasdaq.com/symbol/trip"
-  ], 
-  [
-    "TRIV", 
-    "TriVascular Technologies, Inc.", 
-    "10.51", 
-    "$214.08M", 
-    "2014", 
-    "Health Care", 
-    "Medical/Dental Instruments", 
-    "http://www.nasdaq.com/symbol/triv"
-  ], 
-  [
-    "TRMB", 
-    "Trimble Navigation Limited", 
-    "26.53", 
-    "$6.87B", 
-    "1990", 
-    "Capital Goods", 
-    "Industrial Machinery/Components", 
-    "http://www.nasdaq.com/symbol/trmb"
-  ], 
-  [
-    "TRMK", 
-    "Trustmark Corporation", 
-    "23.33", 
-    "$1.57B", 
-    "n/a", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/trmk"
-  ], 
-  [
-    "TRNS", 
-    "Transcat, Inc.", 
-    "9.25", 
-    "$63.23M", 
-    "n/a", 
-    "Capital Goods", 
-    "Electrical Products", 
-    "http://www.nasdaq.com/symbol/trns"
-  ], 
-  [
-    "TRNX", 
-    "Tornier N.V.", 
-    "25.65", 
-    "$1.25B", 
-    "2011", 
-    "Health Care", 
-    "Industrial Specialties", 
-    "http://www.nasdaq.com/symbol/trnx"
-  ], 
-  [
-    "TROV", 
-    "TrovaGene, Inc.", 
-    "5.01", 
-    "$120.84M", 
-    "n/a", 
-    "Health Care", 
-    "Biotechnology: Biological Products (No Diagnostic Substances)", 
-    "http://www.nasdaq.com/symbol/trov"
-  ], 
-  [
-    "TROVU", 
-    "TrovaGene, Inc.", 
-    "15.82", 
-    "n/a", 
-    "n/a", 
-    "Health Care", 
-    "Biotechnology: Biological Products (No Diagnostic Substances)", 
-    "http://www.nasdaq.com/symbol/trovu"
-  ], 
-  [
-    "TROVW", 
-    "TrovaGene, Inc.", 
-    "3.94", 
-    "n/a", 
-    "n/a", 
-    "Health Care", 
-    "Biotechnology: Biological Products (No Diagnostic Substances)", 
-    "http://www.nasdaq.com/symbol/trovw"
-  ], 
-  [
-    "TROW", 
-    "T. Rowe Price Group, Inc.", 
-    "83.53", 
-    "$21.78B", 
-    "1986", 
-    "Finance", 
-    "Investment Bankers/Brokers/Service", 
-    "http://www.nasdaq.com/symbol/trow"
-  ], 
-  [
-    "TRS", 
-    "TriMas Corporation", 
-    "30", 
-    "$1.36B", 
-    "2007", 
-    "Capital Goods", 
-    "Industrial Specialties", 
-    "http://www.nasdaq.com/symbol/trs"
-  ], 
-  [
-    "TRST", 
-    "TrustCo Bank Corp NY", 
-    "6.7", 
-    "$635.78M", 
-    "n/a", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/trst"
-  ], 
-  [
-    "TRTL", 
-    "Terrapin 3 Acquisition Corporation", 
-    "9.95", 
-    "$264.61M", 
-    "2014", 
-    "Finance", 
-    "Business Services", 
-    "http://www.nasdaq.com/symbol/trtl"
-  ], 
-  [
-    "TRTLU", 
-    "Terrapin 3 Acquisition Corporation", 
-    "10.07", 
-    "$186.3M", 
-    "2014", 
-    "Finance", 
-    "Business Services", 
-    "http://www.nasdaq.com/symbol/trtlu"
-  ], 
-  [
-    "TRTLW", 
-    "Terrapin 3 Acquisition Corporation", 
-    "0.27", 
-    "n/a", 
-    "2014", 
-    "Finance", 
-    "Business Services", 
-    "http://www.nasdaq.com/symbol/trtlw"
-  ], 
-  [
-    "TRUE", 
-    "TrueCar, Inc.", 
-    "17.95", 
-    "$1.42B", 
-    "2014", 
-    "Technology", 
-    "Computer Software: Programming, Data Processing", 
-    "http://www.nasdaq.com/symbol/true"
-  ], 
-  [
-    "TRVN", 
-    "Trevena, Inc.", 
-    "5.44", 
-    "$213.42M", 
-    "2014", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/trvn"
-  ], 
-  [
-    "TSBK", 
-    "Timberland Bancorp, Inc.", 
-    "10.7", 
-    "$75.46M", 
-    "n/a", 
-    "Finance", 
-    "Banks", 
-    "http://www.nasdaq.com/symbol/tsbk"
-  ], 
-  [
-    "TSC", 
-    "TriState Capital Holdings, Inc.", 
-    "9.92", 
-    "$284.83M", 
-    "2013", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/tsc"
-  ], 
-  [
-    "TSCO", 
-    "Tractor Supply Company", 
-    "88.12", 
-    "$12B", 
-    "1994", 
-    "Consumer Services", 
-    "RETAIL: Building Materials", 
-    "http://www.nasdaq.com/symbol/tsco"
-  ], 
-  [
-    "TSEM", 
-    "Tower Semiconductor Ltd.", 
-    "13.69", 
-    "$872.1M", 
-    "1994", 
-    "Technology", 
-    "Semiconductors", 
-    "http://www.nasdaq.com/symbol/tsem"
-  ], 
-  [
-    "TSLA", 
-    "Tesla Motors, Inc.", 
-    "217.11", 
-    "$27.22B", 
-    "2010", 
-    "Capital Goods", 
-    "Auto Manufacturing", 
-    "http://www.nasdaq.com/symbol/tsla"
-  ], 
-  [
-    "TSRA", 
-    "Tessera Technologies, Inc.", 
-    "39.92", 
-    "$2.11B", 
-    "2003", 
-    "Technology", 
-    "Semiconductors", 
-    "http://www.nasdaq.com/symbol/tsra"
-  ], 
-  [
-    "TSRE", 
-    "Trade Street Residential, Inc.", 
-    "7.95", 
-    "$291.75M", 
-    "2013", 
-    "Consumer Services", 
-    "Real Estate Investment Trusts", 
-    "http://www.nasdaq.com/symbol/tsre"
-  ], 
-  [
-    "TSRI", 
-    "TSR, Inc.", 
-    "4.1147", 
-    "$8.07M", 
-    "n/a", 
-    "Technology", 
-    "EDP Services", 
-    "http://www.nasdaq.com/symbol/tsri"
-  ], 
-  [
-    "TSRO", 
-    "TESARO, Inc.", 
-    "44.2", 
-    "$1.59B", 
-    "2012", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/tsro"
-  ], 
-  [
-    "TST", 
-    "TheStreet, Inc.", 
-    "2.02", 
-    "$69.6M", 
-    "n/a", 
-    "Consumer Services", 
-    "Newspapers/Magazines", 
-    "http://www.nasdaq.com/symbol/tst"
-  ], 
-  [
-    "TSYS", 
-    "TeleCommunication Systems, Inc.", 
-    "3.27", 
-    "$195.07M", 
-    "2000", 
-    "Technology", 
-    "Computer Software: Prepackaged Software", 
-    "http://www.nasdaq.com/symbol/tsys"
-  ], 
-  [
-    "TTEC", 
-    "TeleTech Holdings, Inc.", 
-    "23.72", 
-    "$1.16B", 
-    "1996", 
-    "Technology", 
-    "Professional Services", 
-    "http://www.nasdaq.com/symbol/ttec"
-  ], 
-  [
-    "TTEK", 
-    "Tetra Tech, Inc.", 
-    "24.99", 
-    "$1.54B", 
-    "1991", 
-    "Consumer Services", 
-    "Military/Government/Technical", 
-    "http://www.nasdaq.com/symbol/ttek"
-  ], 
-  [
-    "TTGT", 
-    "TechTarget, Inc.", 
-    "11.29", 
-    "$372.26M", 
-    "2007", 
-    "Miscellaneous", 
-    "Business Services", 
-    "http://www.nasdaq.com/symbol/ttgt"
-  ], 
-  [
-    "TTHI", 
-    "Transition Therapeutics, Inc.", 
-    "7.05", 
-    "$273.92M", 
-    "n/a", 
-    "Consumer Durables", 
-    "Specialty Chemicals", 
-    "http://www.nasdaq.com/symbol/tthi"
-  ], 
-  [
-    "TTMI", 
-    "TTM Technologies, Inc.", 
-    "8.75", 
-    "$729.27M", 
-    "2000", 
-    "Technology", 
-    "Electrical Products", 
-    "http://www.nasdaq.com/symbol/ttmi"
-  ], 
-  [
-    "TTOO", 
-    "T2 Biosystems, Inc.", 
-    "17.52", 
-    "$351.13M", 
-    "2014", 
-    "Health Care", 
-    "Medical/Dental Instruments", 
-    "http://www.nasdaq.com/symbol/ttoo"
-  ], 
-  [
-    "TTPH", 
-    "Tetraphase Pharmaceuticals, Inc.", 
-    "41.66", 
-    "$1.28B", 
-    "2013", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/ttph"
-  ], 
-  [
-    "TTS", 
-    "Tile Shop Hldgs, Inc.", 
-    "11.1", 
-    "$569.59M", 
-    "n/a", 
-    "Consumer Services", 
-    "Home Furnishings", 
-    "http://www.nasdaq.com/symbol/tts"
-  ], 
-  [
-    "TTWO", 
-    "Take-Two Interactive Software, Inc.", 
-    "27.005", 
-    "$2.28B", 
-    "1997", 
-    "Technology", 
-    "Computer Software: Prepackaged Software", 
-    "http://www.nasdaq.com/symbol/ttwo"
-  ], 
-  [
-    "TUBE", 
-    "TubeMogul, Inc.", 
-    "15.99", 
-    "$476.38M", 
-    "2014", 
-    "Technology", 
-    "Computer Software: Prepackaged Software", 
-    "http://www.nasdaq.com/symbol/tube"
-  ], 
-  [
-    "TUES", 
-    "Tuesday Morning Corp.", 
-    "19.46", 
-    "$853.21M", 
-    "1999", 
-    "Consumer Services", 
-    "Department/Specialty Retail Stores", 
-    "http://www.nasdaq.com/symbol/tues"
-  ], 
-  [
-    "TUSA", 
-    "First Trust Total US Market AlphaDEX ETF", 
-    "26.7199", 
-    "$6.68M", 
-    "n/a", 
-    "n/a", 
-    "n/a", 
-    "http://www.nasdaq.com/symbol/tusa"
-  ], 
-  [
-    "TVIX", 
-    "VelocityShares Daily 2x VIX Short Term ETN", 
-    "2.28", 
-    "$31.74M", 
-    "n/a", 
-    "Finance", 
-    "Investment Bankers/Brokers/Service", 
-    "http://www.nasdaq.com/symbol/tvix"
-  ], 
-  [
-    "TVIZ", 
-    "VelocityShares Daily 2x VIX Medium Term ETN", 
-    "21", 
-    "$892332", 
-    "n/a", 
-    "Finance", 
-    "Investment Bankers/Brokers/Service", 
-    "http://www.nasdaq.com/symbol/tviz"
-  ], 
-  [
-    "TWER", 
-    "Towerstream Corporation", 
-    "2.3", 
-    "$153.3M", 
-    "n/a", 
-    "Consumer Services", 
-    "Telecommunications Equipment", 
-    "http://www.nasdaq.com/symbol/twer"
-  ], 
-  [
-    "TWIN", 
-    "Twin Disc, Incorporated", 
-    "17.43", 
-    "$196.7M", 
-    "n/a", 
-    "Technology", 
-    "Industrial Machinery/Components", 
-    "http://www.nasdaq.com/symbol/twin"
-  ], 
-  [
-    "TWMC", 
-    "Trans World Entertainment Corp.", 
-    "3.67", 
-    "$115.45M", 
-    "n/a", 
-    "Consumer Services", 
-    "Consumer Electronics/Video Chains", 
-    "http://www.nasdaq.com/symbol/twmc"
-  ], 
-  [
-    "TWOU", 
-    "2U, Inc.", 
-    "17.62", 
-    "$714.35M", 
-    "2014", 
-    "Technology", 
-    "Computer Software: Prepackaged Software", 
-    "http://www.nasdaq.com/symbol/twou"
-  ], 
-  [
-    "TXN", 
-    "Texas Instruments Incorporated", 
-    "58.52", 
-    "$61.81B", 
-    "n/a", 
-    "Technology", 
-    "Semiconductors", 
-    "http://www.nasdaq.com/symbol/txn"
-  ], 
-  [
-    "TXRH", 
-    "Texas Roadhouse, Inc.", 
-    "36.26", 
-    "$2.52B", 
-    "2004", 
-    "Consumer Services", 
-    "Restaurants", 
-    "http://www.nasdaq.com/symbol/txrh"
-  ], 
-  [
-    "TYPE", 
-    "Monotype Imaging Holdings Inc.", 
-    "32.82", 
-    "$1.29B", 
-    "2007", 
-    "Technology", 
-    "EDP Services", 
-    "http://www.nasdaq.com/symbol/type"
-  ], 
-  [
-    "TZOO", 
-    "Travelzoo Inc.", 
-    "9.68", 
-    "$142.59M", 
-    "n/a", 
-    "Technology", 
-    "EDP Services", 
-    "http://www.nasdaq.com/symbol/tzoo"
-  ], 
-  [
-    "UACL", 
-    "Universal Truckload Services, Inc.", 
-    "24.87", 
-    "$745.32M", 
-    "2005", 
-    "Transportation", 
-    "Trucking Freight/Courier Services", 
-    "http://www.nasdaq.com/symbol/uacl"
-  ], 
-  [
-    "UAE", 
-    "iShares MSCI UAE Capped ETF", 
-    "19.99", 
-    "$43.98M", 
-    "n/a", 
-    "n/a", 
-    "n/a", 
-    "http://www.nasdaq.com/symbol/uae"
-  ], 
-  [
-    "UBCP", 
-    "United Bancorp, Inc.", 
-    "7.95", 
-    "$42.73M", 
-    "n/a", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/ubcp"
-  ], 
-  [
-    "UBFO", 
-    "United Security Bancshares", 
-    "5.05", 
-    "$78.68M", 
-    "n/a", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/ubfo"
-  ], 
-  [
-    "UBIC", 
-    "UBIC, Inc.", 
-    "18.9699", 
-    "$335.87M", 
-    "2013", 
-    "Technology", 
-    "EDP Services", 
-    "http://www.nasdaq.com/symbol/ubic"
-  ]
-]
\ No newline at end of file
diff --git a/examples/stocks/data/stock_data_27.json b/examples/stocks/data/stock_data_27.json
deleted file mode 100644
index 9c8e087..0000000
--- a/examples/stocks/data/stock_data_27.json
+++ /dev/null
@@ -1,1002 +0,0 @@
-[
-  [
-    "UBNK", 
-    "United Financial Bancorp, Inc.", 
-    "12.61", 
-    "$644.03M", 
-    "n/a", 
-    "n/a", 
-    "n/a", 
-    "http://www.nasdaq.com/symbol/ubnk"
-  ], 
-  [
-    "UBNT", 
-    "Ubiquiti Networks, Inc.", 
-    "31.36", 
-    "$2.76B", 
-    "2011", 
-    "Technology", 
-    "Radio And Television Broadcasting And Communications Equipment", 
-    "http://www.nasdaq.com/symbol/ubnt"
-  ], 
-  [
-    "UBOH", 
-    "United Bancshares, Inc.", 
-    "14.92", 
-    "$50.25M", 
-    "n/a", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/uboh"
-  ], 
-  [
-    "UBSH", 
-    "Union Bankshares Corporation", 
-    "21.5", 
-    "$977.26M", 
-    "n/a", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/ubsh"
-  ], 
-  [
-    "UBSI", 
-    "United Bankshares, Inc.", 
-    "36.9", 
-    "$2.55B", 
-    "n/a", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/ubsi"
-  ], 
-  [
-    "UCBA", 
-    "United Community Bancorp", 
-    "12.17", 
-    "$56.4M", 
-    "n/a", 
-    "Finance", 
-    "Savings Institutions", 
-    "http://www.nasdaq.com/symbol/ucba"
-  ], 
-  [
-    "UCBI", 
-    "United Community Banks, Inc.", 
-    "19.01", 
-    "$1.15B", 
-    "n/a", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/ucbi"
-  ], 
-  [
-    "UCFC", 
-    "United Community Financial Corp.", 
-    "5.26", 
-    "$261.36M", 
-    "n/a", 
-    "Finance", 
-    "Banks", 
-    "http://www.nasdaq.com/symbol/ucfc"
-  ], 
-  [
-    "UCTT", 
-    "Ultra Clean Holdings, Inc.", 
-    "8.41", 
-    "$248.37M", 
-    "2004", 
-    "Technology", 
-    "Semiconductors", 
-    "http://www.nasdaq.com/symbol/uctt"
-  ], 
-  [
-    "UDF", 
-    "United Development Funding IV", 
-    "16.57", 
-    "$507.38M", 
-    "n/a", 
-    "n/a", 
-    "n/a", 
-    "http://www.nasdaq.com/symbol/udf"
-  ], 
-  [
-    "UEIC", 
-    "Universal Electronics Inc.", 
-    "57.51", 
-    "$908.44M", 
-    "1993", 
-    "Consumer Non-Durables", 
-    "Consumer Electronics/Appliances", 
-    "http://www.nasdaq.com/symbol/ueic"
-  ], 
-  [
-    "UEPS", 
-    "Net 1 UEPS Technologies, Inc.", 
-    "13.45", 
-    "$626.06M", 
-    "2005", 
-    "Finance", 
-    "Investment Bankers/Brokers/Service", 
-    "http://www.nasdaq.com/symbol/ueps"
-  ], 
-  [
-    "UFCS", 
-    "United Fire Group, Inc", 
-    "29.12", 
-    "$729.37M", 
-    "n/a", 
-    "Finance", 
-    "Property-Casualty Insurers", 
-    "http://www.nasdaq.com/symbol/ufcs"
-  ], 
-  [
-    "UFPI", 
-    "Universal Forest Products, Inc.", 
-    "52.9", 
-    "$1.06B", 
-    "1993", 
-    "Basic Industries", 
-    "Forest Products", 
-    "http://www.nasdaq.com/symbol/ufpi"
-  ], 
-  [
-    "UFPT", 
-    "UFP Technologies, Inc.", 
-    "23.36", 
-    "$164.84M", 
-    "1993", 
-    "Capital Goods", 
-    "Containers/Packaging", 
-    "http://www.nasdaq.com/symbol/ufpt"
-  ], 
-  [
-    "UG", 
-    "United-Guardian, Inc.", 
-    "20.5", 
-    "$94.23M", 
-    "n/a", 
-    "Consumer Non-Durables", 
-    "Package Goods/Cosmetics", 
-    "http://www.nasdaq.com/symbol/ug"
-  ], 
-  [
-    "UGLD", 
-    "VelocityShares 3x Long Gold ETN linked to the S&P GSCI Gold In", 
-    "11.56", 
-    "$11.39M", 
-    "n/a", 
-    "Finance", 
-    "Investment Bankers/Brokers/Service", 
-    "http://www.nasdaq.com/symbol/ugld"
-  ], 
-  [
-    "UHAL", 
-    "Amerco", 
-    "321.8", 
-    "$6.31B", 
-    "n/a", 
-    "Consumer Services", 
-    "Rental/Leasing Companies", 
-    "http://www.nasdaq.com/symbol/uhal"
-  ], 
-  [
-    "UIHC", 
-    "United Insurance Holdings Corp.", 
-    "22.97", 
-    "$480.19M", 
-    "n/a", 
-    "Finance", 
-    "Property-Casualty Insurers", 
-    "http://www.nasdaq.com/symbol/uihc"
-  ], 
-  [
-    "ULBI", 
-    "Ultralife Corporation", 
-    "3.722", 
-    "$64.75M", 
-    "1992", 
-    "Miscellaneous", 
-    "Industrial Machinery/Components", 
-    "http://www.nasdaq.com/symbol/ulbi"
-  ], 
-  [
-    "ULTA", 
-    "Ulta Salon, Cosmetics & Fragrance, Inc.", 
-    "138", 
-    "$8.88B", 
-    "2007", 
-    "Consumer Services", 
-    "Other Specialty Stores", 
-    "http://www.nasdaq.com/symbol/ulta"
-  ], 
-  [
-    "ULTI", 
-    "The Ultimate Software Group, Inc.", 
-    "168.88", 
-    "$4.79B", 
-    "1998", 
-    "Technology", 
-    "Computer Software: Prepackaged Software", 
-    "http://www.nasdaq.com/symbol/ulti"
-  ], 
-  [
-    "ULTR", 
-    "Ultrapetrol (Bahamas) Limited", 
-    "1.72", 
-    "$242.05M", 
-    "2006", 
-    "Transportation", 
-    "Marine Transportation", 
-    "http://www.nasdaq.com/symbol/ultr"
-  ], 
-  [
-    "UMBF", 
-    "UMB Financial Corporation", 
-    "52.2", 
-    "$2.37B", 
-    "n/a", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/umbf"
-  ], 
-  [
-    "UMPQ", 
-    "Umpqua Holdings Corporation", 
-    "16.72", 
-    "$3.63B", 
-    "n/a", 
-    "Finance", 
-    "Savings Institutions", 
-    "http://www.nasdaq.com/symbol/umpq"
-  ], 
-  [
-    "UNAM", 
-    "Unico American Corporation", 
-    "11.85", 
-    "$63.29M", 
-    "n/a", 
-    "Finance", 
-    "Property-Casualty Insurers", 
-    "http://www.nasdaq.com/symbol/unam"
-  ], 
-  [
-    "UNB", 
-    "Union Bankshares, Inc.", 
-    "24.56", 
-    "$109.5M", 
-    "n/a", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/unb"
-  ], 
-  [
-    "UNFI", 
-    "United Natural Foods, Inc.", 
-    "80.855", 
-    "$4.04B", 
-    "1996", 
-    "Consumer Non-Durables", 
-    "Food Distributors", 
-    "http://www.nasdaq.com/symbol/unfi"
-  ], 
-  [
-    "UNIS", 
-    "Unilife Corporation", 
-    "3.97", 
-    "$511.47M", 
-    "n/a", 
-    "Health Care", 
-    "Medical/Dental Instruments", 
-    "http://www.nasdaq.com/symbol/unis"
-  ], 
-  [
-    "UNTD", 
-    "United Online, Inc.", 
-    "15.91", 
-    "$226.51M", 
-    "n/a", 
-    "Technology", 
-    "Computer Software: Programming, Data Processing", 
-    "http://www.nasdaq.com/symbol/untd"
-  ], 
-  [
-    "UNTY", 
-    "Unity Bancorp, Inc.", 
-    "9.36", 
-    "$78.42M", 
-    "n/a", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/unty"
-  ], 
-  [
-    "UNXL", 
-    "Uni-Pixel, Inc.", 
-    "5.12", 
-    "$63.24M", 
-    "n/a", 
-    "Capital Goods", 
-    "Industrial Machinery/Components", 
-    "http://www.nasdaq.com/symbol/unxl"
-  ], 
-  [
-    "UPI", 
-    "Uroplasty, Inc.", 
-    "1.33", 
-    "$29.45M", 
-    "n/a", 
-    "Health Care", 
-    "Medical/Dental Instruments", 
-    "http://www.nasdaq.com/symbol/upi"
-  ], 
-  [
-    "UPIP", 
-    "Unwired Planet, Inc.", 
-    "0.77", 
-    "$86.33M", 
-    "n/a", 
-    "Technology", 
-    "Computer Software: Prepackaged Software", 
-    "http://www.nasdaq.com/symbol/upip"
-  ], 
-  [
-    "UPLD", 
-    "Upland Software, Inc.", 
-    "7.14", 
-    "$108.59M", 
-    "2014", 
-    "Technology", 
-    "Computer Software: Prepackaged Software", 
-    "http://www.nasdaq.com/symbol/upld"
-  ], 
-  [
-    "URBN", 
-    "Urban Outfitters, Inc.", 
-    "38.34", 
-    "$5.05B", 
-    "1993", 
-    "Consumer Services", 
-    "Clothing/Shoe/Accessory Stores", 
-    "http://www.nasdaq.com/symbol/urbn"
-  ], 
-  [
-    "URRE", 
-    "Uranium Resources, Inc.", 
-    "1.87", 
-    "$47.16M", 
-    "n/a", 
-    "Basic Industries", 
-    "Precious Metals", 
-    "http://www.nasdaq.com/symbol/urre"
-  ], 
-  [
-    "USAK", 
-    "USA Truck, Inc.", 
-    "31.31", 
-    "$329.74M", 
-    "1992", 
-    "Transportation", 
-    "Trucking Freight/Courier Services", 
-    "http://www.nasdaq.com/symbol/usak"
-  ], 
-  [
-    "USAP", 
-    "Universal Stainless & Alloy Products, Inc.", 
-    "23.98", 
-    "$169.59M", 
-    "1994", 
-    "Basic Industries", 
-    "Steel/Iron Ore", 
-    "http://www.nasdaq.com/symbol/usap"
-  ], 
-  [
-    "USAT", 
-    "USA Technologies, Inc.", 
-    "2.22", 
-    "$79.36M", 
-    "n/a", 
-    "Miscellaneous", 
-    "Office Equipment/Supplies/Services", 
-    "http://www.nasdaq.com/symbol/usat"
-  ], 
-  [
-    "USATP", 
-    "USA Technologies, Inc.", 
-    "19.2899", 
-    "$8.59M", 
-    "n/a", 
-    "Miscellaneous", 
-    "Office Equipment/Supplies/Services", 
-    "http://www.nasdaq.com/symbol/usatp"
-  ], 
-  [
-    "USBI", 
-    "United Security Bancshares, Inc.", 
-    "8.28", 
-    "$49.96M", 
-    "n/a", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/usbi"
-  ], 
-  [
-    "USCR", 
-    "U S Concrete, Inc.", 
-    "29.7", 
-    "$415.2M", 
-    "n/a", 
-    "Capital Goods", 
-    "Building Materials", 
-    "http://www.nasdaq.com/symbol/uscr"
-  ], 
-  [
-    "USEG", 
-    "U.S. Energy Corp.", 
-    "1.42", 
-    "$39.63M", 
-    "n/a", 
-    "Energy", 
-    "Oil & Gas Production", 
-    "http://www.nasdaq.com/symbol/useg"
-  ], 
-  [
-    "USLM", 
-    "United States Lime & Minerals, Inc.", 
-    "68.99", 
-    "$384.8M", 
-    "n/a", 
-    "Basic Industries", 
-    "Mining & Quarrying of Nonmetallic Minerals (No Fuels)", 
-    "http://www.nasdaq.com/symbol/uslm"
-  ], 
-  [
-    "USLV", 
-    "VelocityShares 3x Long Silver ETN linked to the S&P GSCI Silve", 
-    "19.7", 
-    "$38.66M", 
-    "n/a", 
-    "Finance", 
-    "Investment Bankers/Brokers/Service", 
-    "http://www.nasdaq.com/symbol/uslv"
-  ], 
-  [
-    "USMD", 
-    "USMD Holdings, Inc.", 
-    "13.31", 
-    "$135.51M", 
-    "n/a", 
-    "Health Care", 
-    "Hospital/Nursing Management", 
-    "http://www.nasdaq.com/symbol/usmd"
-  ], 
-  [
-    "USTR", 
-    "United Stationers Inc.", 
-    "40.85", 
-    "$1.58B", 
-    "1981", 
-    "Consumer Services", 
-    "Paper", 
-    "http://www.nasdaq.com/symbol/ustr"
-  ], 
-  [
-    "UTEK", 
-    "Ultratech, Inc.", 
-    "17.06", 
-    "$482.31M", 
-    "1993", 
-    "Technology", 
-    "Industrial Machinery/Components", 
-    "http://www.nasdaq.com/symbol/utek"
-  ], 
-  [
-    "UTHR", 
-    "United Therapeutics Corporation", 
-    "156.01", 
-    "$7.41B", 
-    "1999", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/uthr"
-  ], 
-  [
-    "UTIW", 
-    "UTi Worldwide Inc.", 
-    "12.48", 
-    "$1.32B", 
-    "2000", 
-    "Transportation", 
-    "Oil Refining/Marketing", 
-    "http://www.nasdaq.com/symbol/utiw"
-  ], 
-  [
-    "UTMD", 
-    "Utah Medical Products, Inc.", 
-    "58.56", 
-    "$219.24M", 
-    "n/a", 
-    "Health Care", 
-    "Medical/Dental Instruments", 
-    "http://www.nasdaq.com/symbol/utmd"
-  ], 
-  [
-    "UTSI", 
-    "UTStarcom Holdings Corp", 
-    "2.81", 
-    "$111.78M", 
-    "2000", 
-    "Consumer Durables", 
-    "Telecommunications Equipment", 
-    "http://www.nasdaq.com/symbol/utsi"
-  ], 
-  [
-    "UVSP", 
-    "Univest Corporation of Pennsylvania", 
-    "19.04", 
-    "$308.73M", 
-    "n/a", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/uvsp"
-  ], 
-  [
-    "VA", 
-    "Virgin America Inc.", 
-    "36.1", 
-    "$1.55B", 
-    "2014", 
-    "Transportation", 
-    "Air Freight/Delivery Services", 
-    "http://www.nasdaq.com/symbol/va"
-  ], 
-  [
-    "VALU", 
-    "Value Line, Inc.", 
-    "15.74", 
-    "$154.45M", 
-    "1983", 
-    "Finance", 
-    "Investment Managers", 
-    "http://www.nasdaq.com/symbol/valu"
-  ], 
-  [
-    "VALX", 
-    "Validea Market Legends ETF", 
-    "26.07", 
-    "n/a", 
-    "n/a", 
-    "n/a", 
-    "n/a", 
-    "http://www.nasdaq.com/symbol/valx"
-  ], 
-  [
-    "VASC", 
-    "Vascular Solutions, Inc.", 
-    "28.95", 
-    "$498M", 
-    "2000", 
-    "Health Care", 
-    "Medical/Dental Instruments", 
-    "http://www.nasdaq.com/symbol/vasc"
-  ], 
-  [
-    "VBFC", 
-    "Village Bank and Trust Financial Corp.", 
-    "17.25", 
-    "$5.77M", 
-    "n/a", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/vbfc"
-  ], 
-  [
-    "VBIV", 
-    "VBI Vaccines Inc.", 
-    "2.8294", 
-    "$56.62M", 
-    "n/a", 
-    "Health Care", 
-    "Biotechnology: Biological Products (No Diagnostic Substances)", 
-    "http://www.nasdaq.com/symbol/vbiv"
-  ], 
-  [
-    "VBLT", 
-    "Vascular Biogenics Ltd.", 
-    "4.25", 
-    "$84.57M", 
-    "2014", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/vblt"
-  ], 
-  [
-    "VBND", 
-    "Vident Core U.S. Bond Strategy Fund", 
-    "49.9", 
-    "n/a", 
-    "n/a", 
-    "n/a", 
-    "n/a", 
-    "http://www.nasdaq.com/symbol/vbnd"
-  ], 
-  [
-    "VBTX", 
-    "Veritex Holdings, Inc.", 
-    "14.2", 
-    "$134.39M", 
-    "2014", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/vbtx"
-  ], 
-  [
-    "VCEL", 
-    "Vericel Corporation", 
-    "3.6", 
-    "$85.63M", 
-    "n/a", 
-    "Health Care", 
-    "Biotechnology: Biological Products (No Diagnostic Substances)", 
-    "http://www.nasdaq.com/symbol/vcel"
-  ], 
-  [
-    "VCIT", 
-    "Vanguard Intermediate-Term Corporate Bond Index Fund", 
-    "87.17", 
-    "$4.07B", 
-    "n/a", 
-    "n/a", 
-    "n/a", 
-    "http://www.nasdaq.com/symbol/vcit"
-  ], 
-  [
-    "VCLT", 
-    "Vanguard Long-Term Corporate Bond ETF", 
-    "92.59", 
-    "$907.38M", 
-    "n/a", 
-    "n/a", 
-    "n/a", 
-    "http://www.nasdaq.com/symbol/vclt"
-  ], 
-  [
-    "VCSH", 
-    "Vanguard Short-Term Corporate Bond ETF", 
-    "79.96", 
-    "$9.48B", 
-    "n/a", 
-    "n/a", 
-    "n/a", 
-    "http://www.nasdaq.com/symbol/vcsh"
-  ], 
-  [
-    "VCYT", 
-    "Veracyte, Inc.", 
-    "8.79", 
-    "$197.83M", 
-    "2013", 
-    "Health Care", 
-    "Medical Specialities", 
-    "http://www.nasdaq.com/symbol/vcyt"
-  ], 
-  [
-    "VDSI", 
-    "VASCO Data Security International, Inc.", 
-    "27.58", 
-    "$1.09B", 
-    "n/a", 
-    "Technology", 
-    "EDP Services", 
-    "http://www.nasdaq.com/symbol/vdsi"
-  ], 
-  [
-    "VECO", 
-    "Veeco Instruments Inc.", 
-    "29.87", 
-    "$1.2B", 
-    "1994", 
-    "Technology", 
-    "Industrial Machinery/Components", 
-    "http://www.nasdaq.com/symbol/veco"
-  ], 
-  [
-    "VGGL", 
-    "Viggle Inc.", 
-    "1.81", 
-    "$29.97M", 
-    "n/a", 
-    "Technology", 
-    "Computer Software: Programming, Data Processing", 
-    "http://www.nasdaq.com/symbol/vggl"
-  ], 
-  [
-    "VGIT", 
-    "Vanguard Intermediate-Term Government Bond Index Fund", 
-    "64.618", 
-    "$174.47M", 
-    "n/a", 
-    "n/a", 
-    "n/a", 
-    "http://www.nasdaq.com/symbol/vgit"
-  ], 
-  [
-    "VGLT", 
-    "Vanguard Long-Term Government Bond ETF", 
-    "77.98", 
-    "$132.57M", 
-    "n/a", 
-    "n/a", 
-    "n/a", 
-    "http://www.nasdaq.com/symbol/vglt"
-  ], 
-  [
-    "VGSH", 
-    "Vanguard Short-Term Government Bond ETF", 
-    "60.93", 
-    "$578.84M", 
-    "n/a", 
-    "n/a", 
-    "n/a", 
-    "http://www.nasdaq.com/symbol/vgsh"
-  ], 
-  [
-    "VIA", 
-    "Viacom Inc.", 
-    "70.03", 
-    "$3.54B", 
-    "n/a", 
-    "Consumer Services", 
-    "Television Services", 
-    "http://www.nasdaq.com/symbol/via"
-  ], 
-  [
-    "VIAB", 
-    "Viacom Inc.", 
-    "69.71", 
-    "$24.76B", 
-    "n/a", 
-    "Consumer Services", 
-    "Television Services", 
-    "http://www.nasdaq.com/symbol/viab"
-  ], 
-  [
-    "VIAS", 
-    "Viasystems Group, Inc.", 
-    "17.41", 
-    "$364.24M", 
-    "n/a", 
-    "Technology", 
-    "Electrical Products", 
-    "http://www.nasdaq.com/symbol/vias"
-  ], 
-  [
-    "VICL", 
-    "Vical Incorporated", 
-    "1.01", 
-    "$91.23M", 
-    "1993", 
-    "Health Care", 
-    "Biotechnology: Biological Products (No Diagnostic Substances)", 
-    "http://www.nasdaq.com/symbol/vicl"
-  ], 
-  [
-    "VICR", 
-    "Vicor Corporation", 
-    "12.58", 
-    "$485.12M", 
-    "n/a", 
-    "Capital Goods", 
-    "Industrial Machinery/Components", 
-    "http://www.nasdaq.com/symbol/vicr"
-  ], 
-  [
-    "VIDE", 
-    "Video Display Corporation", 
-    "2.46", 
-    "$15.73M", 
-    "1985", 
-    "Capital Goods", 
-    "Electrical Products", 
-    "http://www.nasdaq.com/symbol/vide"
-  ], 
-  [
-    "VIDI", 
-    "Vident International Equity Fund", 
-    "24.11", 
-    "n/a", 
-    "n/a", 
-    "n/a", 
-    "n/a", 
-    "http://www.nasdaq.com/symbol/vidi"
-  ], 
-  [
-    "VIEW", 
-    "Viewtran Group, Inc.", 
-    "1.41", 
-    "$38.79M", 
-    "n/a", 
-    "Capital Goods", 
-    "Electrical Products", 
-    "http://www.nasdaq.com/symbol/view"
-  ], 
-  [
-    "VIIX", 
-    "VelocityShares VIX Short Term ETN", 
-    "39.25", 
-    "$6.59M", 
-    "n/a", 
-    "Finance", 
-    "Investment Bankers/Brokers/Service", 
-    "http://www.nasdaq.com/symbol/viix"
-  ], 
-  [
-    "VIIZ", 
-    "VelocityShares VIX Medium Term ETN", 
-    "17.98", 
-    "$2.25M", 
-    "n/a", 
-    "Finance", 
-    "Investment Bankers/Brokers/Service", 
-    "http://www.nasdaq.com/symbol/viiz"
-  ], 
-  [
-    "VIMC", 
-    "Vimicro International Corporation", 
-    "8.67", 
-    "$207.83M", 
-    "2005", 
-    "Technology", 
-    "Semiconductors", 
-    "http://www.nasdaq.com/symbol/vimc"
-  ], 
-  [
-    "VIP", 
-    "VimpelCom Ltd.", 
-    "5.22", 
-    "$9.17B", 
-    "n/a", 
-    "Public Utilities", 
-    "Telecommunications Equipment", 
-    "http://www.nasdaq.com/symbol/vip"
-  ], 
-  [
-    "VIRC", 
-    "Virco Manufacturing Corporation", 
-    "2.45", 
-    "$36.39M", 
-    "n/a", 
-    "Consumer Durables", 
-    "Industrial Specialties", 
-    "http://www.nasdaq.com/symbol/virc"
-  ], 
-  [
-    "VISN", 
-    "VisionChina Media, Inc.", 
-    "14.42", 
-    "$73.23M", 
-    "2007", 
-    "Technology", 
-    "Advertising", 
-    "http://www.nasdaq.com/symbol/visn"
-  ], 
-  [
-    "VIVO", 
-    "Meridian Bioscience Inc.", 
-    "19.34", 
-    "$806.59M", 
-    "1986", 
-    "Health Care", 
-    "Biotechnology: In Vitro & In Vivo Diagnostic Substances", 
-    "http://www.nasdaq.com/symbol/vivo"
-  ], 
-  [
-    "VLCCF", 
-    "Knightsbridge Shipping Limited", 
-    "4.58", 
-    "$366.96M", 
-    "1997", 
-    "Consumer Services", 
-    "Marine Transportation", 
-    "http://www.nasdaq.com/symbol/vlccf"
-  ], 
-  [
-    "VLGEA", 
-    "Village Super Market, Inc.", 
-    "27.57", 
-    "$387.57M", 
-    "n/a", 
-    "Consumer Services", 
-    "Food Chains", 
-    "http://www.nasdaq.com/symbol/vlgea"
-  ], 
-  [
-    "VLTC", 
-    "Voltari Corporation", 
-    "0.7701", 
-    "$3.67M", 
-    "n/a", 
-    "Miscellaneous", 
-    "Business Services", 
-    "http://www.nasdaq.com/symbol/vltc"
-  ], 
-  [
-    "VLYWW", 
-    "Valley National Bancorp", 
-    "0.0501", 
-    "n/a", 
-    "n/a", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/vlyww"
-  ], 
-  [
-    "VMBS", 
-    "Vanguard Mortgage-Backed Securities ETF", 
-    "53.11", 
-    "$557.66M", 
-    "n/a", 
-    "n/a", 
-    "n/a", 
-    "http://www.nasdaq.com/symbol/vmbs"
-  ], 
-  [
-    "VNDA", 
-    "Vanda Pharmaceuticals Inc.", 
-    "11.43", 
-    "$453.21M", 
-    "2006", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/vnda"
-  ], 
-  [
-    "VNET", 
-    "21Vianet Group, Inc.", 
-    "18.33", 
-    "$1.2B", 
-    "2011", 
-    "Technology", 
-    "Computer Software: Programming, Data Processing", 
-    "http://www.nasdaq.com/symbol/vnet"
-  ], 
-  [
-    "VNOM", 
-    "Viper Energy Partners LP", 
-    "18.26", 
-    "$1.46B", 
-    "2014", 
-    "Energy", 
-    "Oil & Gas Production", 
-    "http://www.nasdaq.com/symbol/vnom"
-  ], 
-  [
-    "VNQI", 
-    "Vanguard Global ex-U.S. Real Estate ETF", 
-    "57.01", 
-    "$2.26B", 
-    "n/a", 
-    "n/a", 
-    "n/a", 
-    "http://www.nasdaq.com/symbol/vnqi"
-  ], 
-  [
-    "VNR", 
-    "Vanguard Natural Resources LLC", 
-    "17.28", 
-    "$1.44B", 
-    "n/a", 
-    "Energy", 
-    "Oil & Gas Production", 
-    "http://www.nasdaq.com/symbol/vnr"
-  ], 
-  [
-    "VNRAP", 
-    "Vanguard Natural Resources LLC", 
-    "24.52", 
-    "n/a", 
-    "n/a", 
-    "Energy", 
-    "Oil & Gas Production", 
-    "http://www.nasdaq.com/symbol/vnrap"
-  ]
-]
\ No newline at end of file
diff --git a/examples/stocks/data/stock_data_28.json b/examples/stocks/data/stock_data_28.json
deleted file mode 100644
index 8486bcd..0000000
--- a/examples/stocks/data/stock_data_28.json
+++ /dev/null
@@ -1,1002 +0,0 @@
-[
-  [
-    "VNRBP", 
-    "Vanguard Natural Resources LLC", 
-    "22.14", 
-    "$154.98M", 
-    "n/a", 
-    "Energy", 
-    "Oil & Gas Production", 
-    "http://www.nasdaq.com/symbol/vnrbp"
-  ], 
-  [
-    "VNRCP", 
-    "Vanguard Natural Resources LLC", 
-    "22.2", 
-    "n/a", 
-    "n/a", 
-    "Energy", 
-    "Oil & Gas Production", 
-    "http://www.nasdaq.com/symbol/vnrcp"
-  ], 
-  [
-    "VOD", 
-    "Vodafone Group Plc", 
-    "35.91", 
-    "$95.17B", 
-    "n/a", 
-    "Public Utilities", 
-    "Telecommunications Equipment", 
-    "http://www.nasdaq.com/symbol/vod"
-  ], 
-  [
-    "VONE", 
-    "Vanguard Russell 1000 ETF", 
-    "97.5817", 
-    "$409.84M", 
-    "n/a", 
-    "n/a", 
-    "n/a", 
-    "http://www.nasdaq.com/symbol/vone"
-  ], 
-  [
-    "VONG", 
-    "Vanguard Russell 1000 Growth ETF", 
-    "103.02", 
-    "$319.36M", 
-    "n/a", 
-    "n/a", 
-    "n/a", 
-    "http://www.nasdaq.com/symbol/vong"
-  ], 
-  [
-    "VONV", 
-    "Vanguard Russell 1000 Value ETF", 
-    "92.29", 
-    "$313.79M", 
-    "n/a", 
-    "n/a", 
-    "n/a", 
-    "http://www.nasdaq.com/symbol/vonv"
-  ], 
-  [
-    "VOXX", 
-    "VOXX International Corporation", 
-    "8.77", 
-    "$211.57M", 
-    "n/a", 
-    "Consumer Non-Durables", 
-    "Electronic Components", 
-    "http://www.nasdaq.com/symbol/voxx"
-  ], 
-  [
-    "VPCO", 
-    "Vapor Corp.", 
-    "1.0999", 
-    "$18.22M", 
-    "n/a", 
-    "Consumer Non-Durables", 
-    "Tobacco", 
-    "http://www.nasdaq.com/symbol/vpco"
-  ], 
-  [
-    "VRA", 
-    "Vera Bradley, Inc.", 
-    "19.77", 
-    "$796.9M", 
-    "2010", 
-    "Consumer Non-Durables", 
-    "Apparel", 
-    "http://www.nasdaq.com/symbol/vra"
-  ], 
-  [
-    "VRML", 
-    "Vermillion, Inc.", 
-    "1.96", 
-    "$84.51M", 
-    "n/a", 
-    "Health Care", 
-    "Biotechnology: In Vitro & In Vivo Diagnostic Substances", 
-    "http://www.nasdaq.com/symbol/vrml"
-  ], 
-  [
-    "VRNG", 
-    "Vringo, Inc.", 
-    "0.6901", 
-    "$64.3M", 
-    "n/a", 
-    "Consumer Services", 
-    "Telecommunications Equipment", 
-    "http://www.nasdaq.com/symbol/vrng"
-  ], 
-  [
-    "VRNGW", 
-    "Vringo, Inc.", 
-    "0.0294", 
-    "n/a", 
-    "n/a", 
-    "Consumer Services", 
-    "Telecommunications Equipment", 
-    "http://www.nasdaq.com/symbol/vrngw"
-  ], 
-  [
-    "VRNS", 
-    "Varonis Systems, Inc.", 
-    "29.88", 
-    "$737.85M", 
-    "2014", 
-    "Technology", 
-    "Computer Software: Prepackaged Software", 
-    "http://www.nasdaq.com/symbol/vrns"
-  ], 
-  [
-    "VRNT", 
-    "Verint Systems Inc.", 
-    "58.235", 
-    "$3.54B", 
-    "2002", 
-    "Technology", 
-    "EDP Services", 
-    "http://www.nasdaq.com/symbol/vrnt"
-  ], 
-  [
-    "VRSK", 
-    "Verisk Analytics, Inc.", 
-    "67.8", 
-    "$11.18B", 
-    "2009", 
-    "Technology", 
-    "EDP Services", 
-    "http://www.nasdaq.com/symbol/vrsk"
-  ], 
-  [
-    "VRSN", 
-    "VeriSign, Inc.", 
-    "63.87", 
-    "$7.47B", 
-    "1998", 
-    "Technology", 
-    "EDP Services", 
-    "http://www.nasdaq.com/symbol/vrsn"
-  ], 
-  [
-    "VRTA", 
-    "Vestin Realty Mortgage I, Inc.", 
-    "3.44", 
-    "$1.2M", 
-    "n/a", 
-    "Consumer Services", 
-    "Real Estate Investment Trusts", 
-    "http://www.nasdaq.com/symbol/vrta"
-  ], 
-  [
-    "VRTB", 
-    "Vestin Realty Mortgage II, Inc.", 
-    "2.94", 
-    "$7.72M", 
-    "n/a", 
-    "Consumer Services", 
-    "Real Estate Investment Trusts", 
-    "http://www.nasdaq.com/symbol/vrtb"
-  ], 
-  [
-    "VRTS", 
-    "Virtus Investment Partners, Inc.", 
-    "145.52", 
-    "$1.32B", 
-    "n/a", 
-    "Finance", 
-    "Investment Managers", 
-    "http://www.nasdaq.com/symbol/vrts"
-  ], 
-  [
-    "VRTU", 
-    "Virtusa Corporation", 
-    "39.97", 
-    "$1.18B", 
-    "2007", 
-    "Technology", 
-    "EDP Services", 
-    "http://www.nasdaq.com/symbol/vrtu"
-  ], 
-  [
-    "VRTX", 
-    "Vertex Pharmaceuticals Incorporated", 
-    "118.61", 
-    "$28.71B", 
-    "1991", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/vrtx"
-  ], 
-  [
-    "VSAR", 
-    "Versartis, Inc.", 
-    "18.85", 
-    "$456.07M", 
-    "2014", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/vsar"
-  ], 
-  [
-    "VSAT", 
-    "ViaSat, Inc.", 
-    "66.08", 
-    "$3.15B", 
-    "1996", 
-    "Technology", 
-    "Radio And Television Broadcasting And Communications Equipment", 
-    "http://www.nasdaq.com/symbol/vsat"
-  ], 
-  [
-    "VSCI", 
-    "Vision-Sciences, Inc.", 
-    "0.51", 
-    "$24.64M", 
-    "1992", 
-    "Health Care", 
-    "Biotechnology: Electromedical & Electrotherapeutic Apparatus", 
-    "http://www.nasdaq.com/symbol/vsci"
-  ], 
-  [
-    "VSCP", 
-    "VirtualScopics, Inc.", 
-    "3.35", 
-    "$10.03M", 
-    "n/a", 
-    "Health Care", 
-    "Medical/Dental Instruments", 
-    "http://www.nasdaq.com/symbol/vscp"
-  ], 
-  [
-    "VSEC", 
-    "VSE Corporation", 
-    "79.57", 
-    "$426.18M", 
-    "n/a", 
-    "Consumer Services", 
-    "Military/Government/Technical", 
-    "http://www.nasdaq.com/symbol/vsec"
-  ], 
-  [
-    "VSTM", 
-    "Verastem, Inc.", 
-    "7.91", 
-    "$270.77M", 
-    "2012", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/vstm"
-  ], 
-  [
-    "VTAE", 
-    "Vitae Pharmaceuticals, Inc.", 
-    "14.2", 
-    "$310.53M", 
-    "2014", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/vtae"
-  ], 
-  [
-    "VTHR", 
-    "Vanguard Russell 3000 ETF ", 
-    "97.446", 
-    "$116.94M", 
-    "n/a", 
-    "n/a", 
-    "n/a", 
-    "http://www.nasdaq.com/symbol/vthr"
-  ], 
-  [
-    "VTIP", 
-    "Vanguard Short-Term Inflation-Protected Securities ETF", 
-    "48.35", 
-    "$1.28B", 
-    "n/a", 
-    "n/a", 
-    "n/a", 
-    "http://www.nasdaq.com/symbol/vtip"
-  ], 
-  [
-    "VTL", 
-    "Vital Therapies, Inc.", 
-    "21.96", 
-    "$523.64M", 
-    "2014", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/vtl"
-  ], 
-  [
-    "VTNR", 
-    "Vertex Energy, Inc", 
-    "3.45", 
-    "$96.97M", 
-    "n/a", 
-    "Energy", 
-    "Integrated oil Companies", 
-    "http://www.nasdaq.com/symbol/vtnr"
-  ], 
-  [
-    "VTSS", 
-    "Vitesse Semiconductor Corporation", 
-    "4.23", 
-    "$291.78M", 
-    "1991", 
-    "Technology", 
-    "Semiconductors", 
-    "http://www.nasdaq.com/symbol/vtss"
-  ], 
-  [
-    "VTWG", 
-    "Vanguard Russell 2000 Growth ETF", 
-    "107.87", 
-    "$107.87M", 
-    "n/a", 
-    "n/a", 
-    "n/a", 
-    "http://www.nasdaq.com/symbol/vtwg"
-  ], 
-  [
-    "VTWO", 
-    "Vanguard Russell 2000 ETF", 
-    "97.74", 
-    "$390.96M", 
-    "n/a", 
-    "n/a", 
-    "n/a", 
-    "http://www.nasdaq.com/symbol/vtwo"
-  ], 
-  [
-    "VTWV", 
-    "Vanguard Russell 2000 Value ETF", 
-    "88.11", 
-    "$70.49M", 
-    "n/a", 
-    "n/a", 
-    "n/a", 
-    "http://www.nasdaq.com/symbol/vtwv"
-  ], 
-  [
-    "VUSE", 
-    "Vident Core US Equity ETF", 
-    "27.46", 
-    "$186.73M", 
-    "n/a", 
-    "n/a", 
-    "n/a", 
-    "http://www.nasdaq.com/symbol/vuse"
-  ], 
-  [
-    "VUZI", 
-    "Vuzix Corporation", 
-    "6.8", 
-    "$83.38M", 
-    "n/a", 
-    "Technology", 
-    "Radio And Television Broadcasting And Communications Equipment", 
-    "http://www.nasdaq.com/symbol/vuzi"
-  ], 
-  [
-    "VVUS", 
-    "VIVUS, Inc.", 
-    "2.88", 
-    "$298.59M", 
-    "1994", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/vvus"
-  ], 
-  [
-    "VWOB", 
-    "Vanguard Emerging Markets Government Bond ETF", 
-    "77.02", 
-    "$200.25M", 
-    "n/a", 
-    "n/a", 
-    "n/a", 
-    "http://www.nasdaq.com/symbol/vwob"
-  ], 
-  [
-    "VWR", 
-    "VWR Corporation", 
-    "25.68", 
-    "$3.37B", 
-    "2014", 
-    "Consumer Durables", 
-    "Diversified Electronic Products", 
-    "http://www.nasdaq.com/symbol/vwr"
-  ], 
-  [
-    "VXUS", 
-    "Vanguard Total International Stock ETF", 
-    "51.15", 
-    "$3.14B", 
-    "n/a", 
-    "n/a", 
-    "n/a", 
-    "http://www.nasdaq.com/symbol/vxus"
-  ], 
-  [
-    "VYFC", 
-    "Valley Financial Corporation", 
-    "19.67", 
-    "$94.89M", 
-    "n/a", 
-    "Finance", 
-    "Savings Institutions", 
-    "http://www.nasdaq.com/symbol/vyfc"
-  ], 
-  [
-    "WABC", 
-    "Westamerica Bancorporation", 
-    "43.25", 
-    "$1.12B", 
-    "n/a", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/wabc"
-  ], 
-  [
-    "WAFD", 
-    "Washington Federal, Inc.", 
-    "20.96", 
-    "$2.02B", 
-    "n/a", 
-    "Finance", 
-    "Savings Institutions", 
-    "http://www.nasdaq.com/symbol/wafd"
-  ], 
-  [
-    "WAFDW", 
-    "Washington Federal, Inc.", 
-    "5.19", 
-    "n/a", 
-    "n/a", 
-    "Finance", 
-    "Savings Institutions", 
-    "http://www.nasdaq.com/symbol/wafdw"
-  ], 
-  [
-    "WASH", 
-    "Washington Trust Bancorp, Inc.", 
-    "37.84", 
-    "$632.88M", 
-    "n/a", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/wash"
-  ], 
-  [
-    "WATT", 
-    "Energous Corporation", 
-    "9.18", 
-    "$117.33M", 
-    "2014", 
-    "Technology", 
-    "Radio And Television Broadcasting And Communications Equipment", 
-    "http://www.nasdaq.com/symbol/watt"
-  ], 
-  [
-    "WAVX", 
-    "Wave Systems Corp.", 
-    "0.8284", 
-    "$38.08M", 
-    "1994", 
-    "Technology", 
-    "Computer peripheral equipment", 
-    "http://www.nasdaq.com/symbol/wavx"
-  ], 
-  [
-    "WAYN", 
-    "Wayne Savings Bancshares Inc.", 
-    "13.6", 
-    "$38.38M", 
-    "n/a", 
-    "Finance", 
-    "Savings Institutions", 
-    "http://www.nasdaq.com/symbol/wayn"
-  ], 
-  [
-    "WB", 
-    "Weibo Corporation", 
-    "13.76", 
-    "$2.75B", 
-    "2014", 
-    "Technology", 
-    "Computer Software: Programming, Data Processing", 
-    "http://www.nasdaq.com/symbol/wb"
-  ], 
-  [
-    "WBA", 
-    "Walgreens Boots Alliance, Inc.", 
-    "77.13", 
-    "$72.94B", 
-    "n/a", 
-    "Health Care", 
-    "Medical/Nursing Services", 
-    "http://www.nasdaq.com/symbol/wba"
-  ], 
-  [
-    "WBB", 
-    "Westbury Bancorp, Inc.", 
-    "16.5", 
-    "$81.26M", 
-    "2013", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/wbb"
-  ], 
-  [
-    "WBKC", 
-    "Wolverine Bancorp, Inc.", 
-    "23.7652", 
-    "$53.91M", 
-    "2011", 
-    "Finance", 
-    "Banks", 
-    "http://www.nasdaq.com/symbol/wbkc"
-  ], 
-  [
-    "WBMD", 
-    "WebMD Health Corp", 
-    "40.91", 
-    "$1.53B", 
-    "2005", 
-    "Miscellaneous", 
-    "Business Services", 
-    "http://www.nasdaq.com/symbol/wbmd"
-  ], 
-  [
-    "WDC", 
-    "Western Digital Corporation", 
-    "111.31", 
-    "$25.72B", 
-    "n/a", 
-    "Technology", 
-    "Electronic Components", 
-    "http://www.nasdaq.com/symbol/wdc"
-  ], 
-  [
-    "WDFC", 
-    "WD-40 Company", 
-    "81.86", 
-    "$1.2B", 
-    "1973", 
-    "Basic Industries", 
-    "Major Chemicals", 
-    "http://www.nasdaq.com/symbol/wdfc"
-  ], 
-  [
-    "WEBK", 
-    "Wellesley Bancorp, Inc.", 
-    "18.7999", 
-    "$46.14M", 
-    "2012", 
-    "Finance", 
-    "Banks", 
-    "http://www.nasdaq.com/symbol/webk"
-  ], 
-  [
-    "WEN", 
-    "Wendy&#39;s Company (The)", 
-    "11.26", 
-    "$4.11B", 
-    "n/a", 
-    "Consumer Services", 
-    "Restaurants", 
-    "http://www.nasdaq.com/symbol/wen"
-  ], 
-  [
-    "WERN", 
-    "Werner Enterprises, Inc.", 
-    "31.69", 
-    "$2.28B", 
-    "1986", 
-    "Transportation", 
-    "Trucking Freight/Courier Services", 
-    "http://www.nasdaq.com/symbol/wern"
-  ], 
-  [
-    "WETF", 
-    "WisdomTree Investments, Inc.", 
-    "18.95", 
-    "$2.53B", 
-    "n/a", 
-    "Finance", 
-    "Investment Bankers/Brokers/Service", 
-    "http://www.nasdaq.com/symbol/wetf"
-  ], 
-  [
-    "WEYS", 
-    "Weyco Group, Inc.", 
-    "27.04", 
-    "$291.44M", 
-    "n/a", 
-    "Consumer Non-Durables", 
-    "Apparel", 
-    "http://www.nasdaq.com/symbol/weys"
-  ], 
-  [
-    "WFBI", 
-    "WashingtonFirst Bankshares Inc", 
-    "15.99", 
-    "$129.88M", 
-    "n/a", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/wfbi"
-  ], 
-  [
-    "WFD", 
-    "Westfield Financial, Inc.", 
-    "7.26", 
-    "$136.44M", 
-    "n/a", 
-    "Finance", 
-    "Savings Institutions", 
-    "http://www.nasdaq.com/symbol/wfd"
-  ], 
-  [
-    "WFM", 
-    "Whole Foods Market, Inc.", 
-    "56.715", 
-    "$20.4B", 
-    "n/a", 
-    "Consumer Services", 
-    "Food Chains", 
-    "http://www.nasdaq.com/symbol/wfm"
-  ], 
-  [
-    "WGBS", 
-    "WaferGen Bio-systems, Inc.", 
-    "4.58", 
-    "$26.89M", 
-    "n/a", 
-    "Capital Goods", 
-    "Biotechnology: Laboratory Analytical Instruments", 
-    "http://www.nasdaq.com/symbol/wgbs"
-  ], 
-  [
-    "WHF", 
-    "WhiteHorse Finance, Inc.", 
-    "12.26", 
-    "$183.69M", 
-    "2012", 
-    "n/a", 
-    "n/a", 
-    "http://www.nasdaq.com/symbol/whf"
-  ], 
-  [
-    "WHFBL", 
-    "WhiteHorse Finance, Inc.", 
-    "25.0825", 
-    "n/a", 
-    "n/a", 
-    "n/a", 
-    "n/a", 
-    "http://www.nasdaq.com/symbol/whfbl"
-  ], 
-  [
-    "WHLM", 
-    "Wilhelmina International, Inc.", 
-    "5.75", 
-    "$33.75M", 
-    "n/a", 
-    "Consumer Services", 
-    "Professional Services", 
-    "http://www.nasdaq.com/symbol/whlm"
-  ], 
-  [
-    "WHLR", 
-    "Wheeler Real Estate Investment Trust, Inc.", 
-    "3.54", 
-    "$26.36M", 
-    "2012", 
-    "Consumer Services", 
-    "Real Estate Investment Trusts", 
-    "http://www.nasdaq.com/symbol/whlr"
-  ], 
-  [
-    "WHLRP", 
-    "Wheeler Real Estate Investment Trust, Inc.", 
-    "19.15", 
-    "$13.79M", 
-    "n/a", 
-    "Consumer Services", 
-    "Real Estate Investment Trusts", 
-    "http://www.nasdaq.com/symbol/whlrp"
-  ], 
-  [
-    "WHLRW", 
-    "Wheeler Real Estate Investment Trust, Inc.", 
-    "0.228", 
-    "n/a", 
-    "n/a", 
-    "Consumer Services", 
-    "Real Estate Investment Trusts", 
-    "http://www.nasdaq.com/symbol/whlrw"
-  ], 
-  [
-    "WIBC", 
-    "Wilshire Bancorp, Inc.", 
-    "9.78", 
-    "$765.84M", 
-    "n/a", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/wibc"
-  ], 
-  [
-    "WIFI", 
-    "Boingo Wireless, Inc.", 
-    "7.96", 
-    "$287.24M", 
-    "2011", 
-    "Consumer Services", 
-    "Telecommunications Equipment", 
-    "http://www.nasdaq.com/symbol/wifi"
-  ], 
-  [
-    "WILC", 
-    "G. Willi-Food International,  Ltd.", 
-    "6.09", 
-    "$79.01M", 
-    "n/a", 
-    "Consumer Non-Durables", 
-    "Food Distributors", 
-    "http://www.nasdaq.com/symbol/wilc"
-  ], 
-  [
-    "WILN", 
-    "Wi-Lan Inc", 
-    "2.669", 
-    "$320.94M", 
-    "n/a", 
-    "Miscellaneous", 
-    "Multi-Sector Companies", 
-    "http://www.nasdaq.com/symbol/wiln"
-  ], 
-  [
-    "WIN", 
-    "Windstream Holdings, Inc.", 
-    "8.63", 
-    "$5.2B", 
-    "n/a", 
-    "Public Utilities", 
-    "Telecommunications Equipment", 
-    "http://www.nasdaq.com/symbol/win"
-  ], 
-  [
-    "WINA", 
-    "Winmark Corporation", 
-    "80.09", 
-    "$400.25M", 
-    "n/a", 
-    "Consumer Services", 
-    "Other Specialty Stores", 
-    "http://www.nasdaq.com/symbol/wina"
-  ], 
-  [
-    "WIRE", 
-    "Encore Wire Corporation", 
-    "34.19", 
-    "$708.42M", 
-    "1992", 
-    "Capital Goods", 
-    "Metal Fabrications", 
-    "http://www.nasdaq.com/symbol/wire"
-  ], 
-  [
-    "WIX", 
-    "Wix.com Ltd.", 
-    "19.65", 
-    "$748.45M", 
-    "2013", 
-    "Technology", 
-    "Computer Software: Programming, Data Processing", 
-    "http://www.nasdaq.com/symbol/wix"
-  ], 
-  [
-    "WLB", 
-    "Westmoreland Coal Company", 
-    "29.75", 
-    "$507.96M", 
-    "n/a", 
-    "Energy", 
-    "Coal Mining", 
-    "http://www.nasdaq.com/symbol/wlb"
-  ], 
-  [
-    "WLDN", 
-    "Willdan Group, Inc.", 
-    "14.31", 
-    "$109.14M", 
-    "2006", 
-    "Consumer Services", 
-    "Military/Government/Technical", 
-    "http://www.nasdaq.com/symbol/wldn"
-  ], 
-  [
-    "WLFC", 
-    "Willis Lease Finance Corporation", 
-    "21.21", 
-    "$178.49M", 
-    "1996", 
-    "Consumer Durables", 
-    "Industrial Specialties", 
-    "http://www.nasdaq.com/symbol/wlfc"
-  ], 
-  [
-    "WLRH", 
-    "WL Ross Holding Corp.", 
-    "9.96", 
-    "$622.81M", 
-    "n/a", 
-    "Finance", 
-    "Business Services", 
-    "http://www.nasdaq.com/symbol/wlrh"
-  ], 
-  [
-    "WLRHU", 
-    "WL Ross Holding Corp.", 
-    "10.5", 
-    "$420M", 
-    "2014", 
-    "Finance", 
-    "Business Services", 
-    "http://www.nasdaq.com/symbol/wlrhu"
-  ], 
-  [
-    "WLRHW", 
-    "WL Ross Holding Corp.", 
-    "0.64", 
-    "n/a", 
-    "n/a", 
-    "Finance", 
-    "Business Services", 
-    "http://www.nasdaq.com/symbol/wlrhw"
-  ], 
-  [
-    "WMAR", 
-    "West Marine, Inc.", 
-    "12.28", 
-    "$298.57M", 
-    "1993", 
-    "Consumer Durables", 
-    "Automotive Aftermarket", 
-    "http://www.nasdaq.com/symbol/wmar"
-  ], 
-  [
-    "WMGI", 
-    "Wright Medical Group, Inc.", 
-    "26.17", 
-    "$1.34B", 
-    "2001", 
-    "Health Care", 
-    "Industrial Specialties", 
-    "http://www.nasdaq.com/symbol/wmgi"
-  ], 
-  [
-    "WMGIZ", 
-    "Wright Medical Group, Inc.", 
-    "4.2", 
-    "n/a", 
-    "n/a", 
-    "Health Care", 
-    "Industrial Specialties", 
-    "http://www.nasdaq.com/symbol/wmgiz"
-  ], 
-  [
-    "WOOD", 
-    "iShares S&P Global Timber & Forestry Index Fund", 
-    "56.3", 
-    "$324.29M", 
-    "n/a", 
-    "n/a", 
-    "n/a", 
-    "http://www.nasdaq.com/symbol/wood"
-  ], 
-  [
-    "WOOF", 
-    "VCA Inc. ", 
-    "53.07", 
-    "$4.46B", 
-    "2001", 
-    "Consumer Non-Durables", 
-    "Farming/Seeds/Milling", 
-    "http://www.nasdaq.com/symbol/woof"
-  ], 
-  [
-    "WPCS", 
-    "WPCS International Incorporated", 
-    "0.319", 
-    "$4.44M", 
-    "n/a", 
-    "Consumer Services", 
-    "Telecommunications Equipment", 
-    "http://www.nasdaq.com/symbol/wpcs"
-  ], 
-  [
-    "WPPGY", 
-    "WPP plc", 
-    "117.03", 
-    "$30.8B", 
-    "n/a", 
-    "Technology", 
-    "Advertising", 
-    "http://www.nasdaq.com/symbol/wppgy"
-  ], 
-  [
-    "WPRT", 
-    "Westport Innovations Inc", 
-    "5.53", 
-    "$352.22M", 
-    "n/a", 
-    "Energy", 
-    "Industrial Machinery/Components", 
-    "http://www.nasdaq.com/symbol/wprt"
-  ], 
-  [
-    "WRES", 
-    "Warren Resources, Inc.", 
-    "1.32", 
-    "$106.59M", 
-    "2004", 
-    "Energy", 
-    "Oil & Gas Production", 
-    "http://www.nasdaq.com/symbol/wres"
-  ], 
-  [
-    "WRLD", 
-    "World Acceptance Corporation", 
-    "81.76", 
-    "$779.29M", 
-    "1991", 
-    "Finance", 
-    "Finance: Consumer Services", 
-    "http://www.nasdaq.com/symbol/wrld"
-  ], 
-  [
-    "WSBC", 
-    "WesBanco, Inc.", 
-    "33.03", 
-    "$967.24M", 
-    "n/a", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/wsbc"
-  ], 
-  [
-    "WSBF", 
-    "Waterstone Financial, Inc.", 
-    "12.82", 
-    "$441.27M", 
-    "n/a", 
-    "Finance", 
-    "Savings Institutions", 
-    "http://www.nasdaq.com/symbol/wsbf"
-  ], 
-  [
-    "WSCI", 
-    "WSI Industries Inc.", 
-    "6.436", 
-    "$18.72M", 
-    "n/a", 
-    "Technology", 
-    "Industrial Machinery/Components", 
-    "http://www.nasdaq.com/symbol/wsci"
-  ], 
-  [
-    "WSFS", 
-    "WSFS Financial Corporation", 
-    "78.03", 
-    "$733.38M", 
-    "n/a", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/wsfs"
-  ]
-]
\ No newline at end of file
diff --git a/examples/stocks/data/stock_data_29.json b/examples/stocks/data/stock_data_29.json
deleted file mode 100644
index 93021fb..0000000
--- a/examples/stocks/data/stock_data_29.json
+++ /dev/null
@@ -1,632 +0,0 @@
-[
-  [
-    "WSFSL", 
-    "WSFS Financial Corporation", 
-    "26.3499", 
-    "n/a", 
-    "n/a", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/wsfsl"
-  ], 
-  [
-    "WSTC", 
-    "West Corporation", 
-    "34.78", 
-    "$2.93B", 
-    "2013", 
-    "Miscellaneous", 
-    "Business Services", 
-    "http://www.nasdaq.com/symbol/wstc"
-  ], 
-  [
-    "WSTG", 
-    "Wayside Technology Group, Inc.", 
-    "17.08", 
-    "$83.72M", 
-    "n/a", 
-    "Technology", 
-    "Retail: Computer Software & Peripheral Equipment", 
-    "http://www.nasdaq.com/symbol/wstg"
-  ], 
-  [
-    "WSTL", 
-    "Westell Technologies, Inc.", 
-    "1.54", 
-    "$92.7M", 
-    "1995", 
-    "Public Utilities", 
-    "Telecommunications Equipment", 
-    "http://www.nasdaq.com/symbol/wstl"
-  ], 
-  [
-    "WTBA", 
-    "West Bancorporation", 
-    "17.99", 
-    "$288.18M", 
-    "n/a", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/wtba"
-  ], 
-  [
-    "WTFC", 
-    "Wintrust Financial Corporation", 
-    "47.69", 
-    "$2.23B", 
-    "n/a", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/wtfc"
-  ], 
-  [
-    "WTFCW", 
-    "Wintrust Financial Corporation", 
-    "25.25", 
-    "n/a", 
-    "n/a", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/wtfcw"
-  ], 
-  [
-    "WVFC", 
-    "WVS Financial Corp.", 
-    "11.5", 
-    "$23.58M", 
-    "n/a", 
-    "Finance", 
-    "Banks", 
-    "http://www.nasdaq.com/symbol/wvfc"
-  ], 
-  [
-    "WVVI", 
-    "Willamette Valley Vineyards, Inc.", 
-    "5.9499", 
-    "$28.93M", 
-    "n/a", 
-    "Consumer Non-Durables", 
-    "Beverages (Production/Distribution)", 
-    "http://www.nasdaq.com/symbol/wvvi"
-  ], 
-  [
-    "WWD", 
-    "Woodward, Inc.", 
-    "48.75", 
-    "$3.17B", 
-    "n/a", 
-    "Energy", 
-    "Industrial Machinery/Components", 
-    "http://www.nasdaq.com/symbol/wwd"
-  ], 
-  [
-    "WWWW", 
-    "Web.com Group, Inc.", 
-    "18.01", 
-    "$946.04M", 
-    "n/a", 
-    "Technology", 
-    "Computer Software: Prepackaged Software", 
-    "http://www.nasdaq.com/symbol/wwww"
-  ], 
-  [
-    "WYNN", 
-    "Wynn Resorts, Limited", 
-    "158.47", 
-    "$16.06B", 
-    "2002", 
-    "Consumer Services", 
-    "Hotels/Resorts", 
-    "http://www.nasdaq.com/symbol/wynn"
-  ], 
-  [
-    "XBKS", 
-    "Xenith Bankshares, Inc.", 
-    "6.4001", 
-    "$82.71M", 
-    "n/a", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/xbks"
-  ], 
-  [
-    "XCRA", 
-    "Xcerra Corporation", 
-    "8.68", 
-    "$472.42M", 
-    "n/a", 
-    "Capital Goods", 
-    "Electrical Products", 
-    "http://www.nasdaq.com/symbol/xcra"
-  ], 
-  [
-    "XENE", 
-    "Xenon Pharmaceuticals Inc.", 
-    "19.38", 
-    "$274.83M", 
-    "2014", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/xene"
-  ], 
-  [
-    "XENT", 
-    "Intersect ENT, Inc.", 
-    "22.7", 
-    "$530.65M", 
-    "2014", 
-    "Health Care", 
-    "Medical/Dental Instruments", 
-    "http://www.nasdaq.com/symbol/xent"
-  ], 
-  [
-    "XGTI", 
-    "XG Technology, Inc", 
-    "0.49", 
-    "$12.26M", 
-    "2013", 
-    "Consumer Durables", 
-    "Telecommunications Equipment", 
-    "http://www.nasdaq.com/symbol/xgti"
-  ], 
-  [
-    "XGTIW", 
-    "XG Technology, Inc", 
-    "0.26", 
-    "n/a", 
-    "2013", 
-    "Consumer Durables", 
-    "Telecommunications Equipment", 
-    "http://www.nasdaq.com/symbol/xgtiw"
-  ], 
-  [
-    "XIV", 
-    "VelocityShares Daily Inverse VIX Short Term ETN", 
-    "31.285", 
-    "$485.35M", 
-    "n/a", 
-    "Finance", 
-    "Investment Bankers/Brokers/Service", 
-    "http://www.nasdaq.com/symbol/xiv"
-  ], 
-  [
-    "XLNX", 
-    "Xilinx, Inc.", 
-    "41.675", 
-    "$10.9B", 
-    "1990", 
-    "Technology", 
-    "Semiconductors", 
-    "http://www.nasdaq.com/symbol/xlnx"
-  ], 
-  [
-    "XLRN", 
-    "Acceleron Pharma Inc.", 
-    "39.98", 
-    "$1.29B", 
-    "2013", 
-    "Health Care", 
-    "Biotechnology: Biological Products (No Diagnostic Substances)", 
-    "http://www.nasdaq.com/symbol/xlrn"
-  ], 
-  [
-    "XNCR", 
-    "Xencor, Inc.", 
-    "15.06", 
-    "$473.52M", 
-    "2013", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/xncr"
-  ], 
-  [
-    "XNET", 
-    "Xunlei Limited", 
-    "7.25", 
-    "$471.36M", 
-    "2014", 
-    "Technology", 
-    "Computer Software: Prepackaged Software", 
-    "http://www.nasdaq.com/symbol/xnet"
-  ], 
-  [
-    "XNPT", 
-    "XenoPort, Inc.", 
-    "7.19", 
-    "$447.49M", 
-    "2005", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/xnpt"
-  ], 
-  [
-    "XOMA", 
-    "XOMA Corporation", 
-    "4.05", 
-    "$469.36M", 
-    "1986", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/xoma"
-  ], 
-  [
-    "XONE", 
-    "The ExOne Company", 
-    "16.32", 
-    "$235.71M", 
-    "2013", 
-    "Capital Goods", 
-    "Industrial Machinery/Components", 
-    "http://www.nasdaq.com/symbol/xone"
-  ], 
-  [
-    "XOOM", 
-    "Xoom Corporation", 
-    "16.43", 
-    "$631.69M", 
-    "2013", 
-    "Finance", 
-    "Investment Bankers/Brokers/Service", 
-    "http://www.nasdaq.com/symbol/xoom"
-  ], 
-  [
-    "XPLR", 
-    "Xplore Technologies Corp", 
-    "6.82", 
-    "$57.83M", 
-    "n/a", 
-    "Technology", 
-    "Computer Manufacturing", 
-    "http://www.nasdaq.com/symbol/xplr"
-  ], 
-  [
-    "XRAY", 
-    "DENTSPLY International Inc.", 
-    "52.53", 
-    "$7.43B", 
-    "1987", 
-    "Health Care", 
-    "Medical/Dental Instruments", 
-    "http://www.nasdaq.com/symbol/xray"
-  ], 
-  [
-    "XTLB", 
-    "XTL Biopharmaceuticals Ltd.", 
-    "2.21", 
-    "$25.73M", 
-    "n/a", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/xtlb"
-  ], 
-  [
-    "XXIA", 
-    "Ixia", 
-    "10.45", 
-    "$819.24M", 
-    "2000", 
-    "Capital Goods", 
-    "Electrical Products", 
-    "http://www.nasdaq.com/symbol/xxia"
-  ], 
-  [
-    "YDIV", 
-    "First Trust NASDAQ Technology Dividend Index Fund", 
-    "19.3412", 
-    "$12.57M", 
-    "n/a", 
-    "n/a", 
-    "n/a", 
-    "http://www.nasdaq.com/symbol/ydiv"
-  ], 
-  [
-    "YDLE", 
-    "Yodlee, Inc.", 
-    "13.01", 
-    "$380.3M", 
-    "2014", 
-    "Technology", 
-    "Computer Software: Prepackaged Software", 
-    "http://www.nasdaq.com/symbol/ydle"
-  ], 
-  [
-    "YHOO", 
-    "Yahoo! Inc.", 
-    "44.11", 
-    "$41.79B", 
-    "1996", 
-    "Technology", 
-    "EDP Services", 
-    "http://www.nasdaq.com/symbol/yhoo"
-  ], 
-  [
-    "YNDX", 
-    "Yandex N.V.", 
-    "17.01", 
-    "$5.41B", 
-    "2011", 
-    "Technology", 
-    "Computer Software: Programming, Data Processing", 
-    "http://www.nasdaq.com/symbol/yndx"
-  ], 
-  [
-    "YOD", 
-    "You On Demand Holdings, Inc.", 
-    "2.25", 
-    "$53.4M", 
-    "n/a", 
-    "Consumer Services", 
-    "Television Services", 
-    "http://www.nasdaq.com/symbol/yod"
-  ], 
-  [
-    "YORW", 
-    "The York Water Company", 
-    "23.07", 
-    "$295.51M", 
-    "n/a", 
-    "Public Utilities", 
-    "Water Supply", 
-    "http://www.nasdaq.com/symbol/yorw"
-  ], 
-  [
-    "YPRO", 
-    "AdvisorShares YieldPro ETF", 
-    "23.94", 
-    "$68.23M", 
-    "n/a", 
-    "n/a", 
-    "n/a", 
-    "http://www.nasdaq.com/symbol/ypro"
-  ], 
-  [
-    "YRCW", 
-    "YRC Worldwide, Inc.", 
-    "19.96", 
-    "$623.91M", 
-    "n/a", 
-    "Transportation", 
-    "Trucking Freight/Courier Services", 
-    "http://www.nasdaq.com/symbol/yrcw"
-  ], 
-  [
-    "YY", 
-    "YY Inc.", 
-    "61.82", 
-    "$3.5B", 
-    "2012", 
-    "Technology", 
-    "EDP Services", 
-    "http://www.nasdaq.com/symbol/yy"
-  ], 
-  [
-    "Z", 
-    "Zillow Group, Inc.", 
-    "125.42", 
-    "$5.12B", 
-    "2011", 
-    "Miscellaneous", 
-    "Business Services", 
-    "http://www.nasdaq.com/symbol/z"
-  ], 
-  [
-    "ZAGG", 
-    "ZAGG Inc", 
-    "6.51", 
-    "$197.48M", 
-    "n/a", 
-    "Consumer Services", 
-    "Other Specialty Stores", 
-    "http://www.nasdaq.com/symbol/zagg"
-  ], 
-  [
-    "ZAZA", 
-    "ZaZa Energy Corporation", 
-    "2.11", 
-    "$27.28M", 
-    "n/a", 
-    "Energy", 
-    "Oil & Gas Production", 
-    "http://www.nasdaq.com/symbol/zaza"
-  ], 
-  [
-    "ZBRA", 
-    "Zebra Technologies Corporation", 
-    "91", 
-    "$4.63B", 
-    "1991", 
-    "Technology", 
-    "Industrial Machinery/Components", 
-    "http://www.nasdaq.com/symbol/zbra"
-  ], 
-  [
-    "ZEUS", 
-    "Olympic Steel, Inc.", 
-    "16.35", 
-    "$179.56M", 
-    "1994", 
-    "Basic Industries", 
-    "Metal Fabrications", 
-    "http://www.nasdaq.com/symbol/zeus"
-  ], 
-  [
-    "ZFGN", 
-    "Zafgen, Inc.", 
-    "40.64", 
-    "$1.08B", 
-    "2014", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/zfgn"
-  ], 
-  [
-    "ZGNX", 
-    "Zogenix, Inc.", 
-    "1.55", 
-    "$237.21M", 
-    "2010", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/zgnx"
-  ], 
-  [
-    "ZHNE", 
-    "Zhone Technologies, Inc.", 
-    "1.54", 
-    "$50.05M", 
-    "n/a", 
-    "Public Utilities", 
-    "Telecommunications Equipment", 
-    "http://www.nasdaq.com/symbol/zhne"
-  ], 
-  [
-    "ZINC", 
-    "Horsehead Holding Corp.", 
-    "13.49", 
-    "$763.52M", 
-    "2007", 
-    "Capital Goods", 
-    "Metal Fabrications", 
-    "http://www.nasdaq.com/symbol/zinc"
-  ], 
-  [
-    "ZION", 
-    "Zions Bancorporation", 
-    "26.33", 
-    "$5.34B", 
-    "n/a", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/zion"
-  ], 
-  [
-    "ZIONW", 
-    "Zions Bancorporation", 
-    "3.4", 
-    "n/a", 
-    "n/a", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/zionw"
-  ], 
-  [
-    "ZIONZ", 
-    "Zions Bancorporation", 
-    "2.45", 
-    "n/a", 
-    "n/a", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/zionz"
-  ], 
-  [
-    "ZIOP", 
-    "ZIOPHARM Oncology Inc", 
-    "9.56", 
-    "$1.11B", 
-    "n/a", 
-    "Health Care", 
-    "Medical Specialities", 
-    "http://www.nasdaq.com/symbol/ziop"
-  ], 
-  [
-    "ZIV", 
-    "VelocityShares Daily Inverse VIX Medium Term ETN", 
-    "41.1", 
-    "$37.81M", 
-    "n/a", 
-    "Finance", 
-    "Investment Bankers/Brokers/Service", 
-    "http://www.nasdaq.com/symbol/ziv"
-  ], 
-  [
-    "ZIXI", 
-    "Zix Corporation", 
-    "3.81", 
-    "$216.48M", 
-    "n/a", 
-    "Technology", 
-    "EDP Services", 
-    "http://www.nasdaq.com/symbol/zixi"
-  ], 
-  [
-    "ZLTQ", 
-    "ZELTIQ Aesthetics, Inc.", 
-    "34.23", 
-    "$1.3B", 
-    "2011", 
-    "Health Care", 
-    "Biotechnology: Electromedical & Electrotherapeutic Apparatus", 
-    "http://www.nasdaq.com/symbol/zltq"
-  ], 
-  [
-    "ZN", 
-    "Zion Oil & Gas Inc", 
-    "1.85", 
-    "$65.29M", 
-    "n/a", 
-    "Energy", 
-    "Oil & Gas Production", 
-    "http://www.nasdaq.com/symbol/zn"
-  ], 
-  [
-    "ZNGA", 
-    "Zynga Inc.", 
-    "2.32", 
-    "$2.09B", 
-    "2011", 
-    "Technology", 
-    "EDP Services", 
-    "http://www.nasdaq.com/symbol/znga"
-  ], 
-  [
-    "ZNWAA", 
-    "Zion Oil & Gas Inc", 
-    "n/a", 
-    "n/a", 
-    "n/a", 
-    "Energy", 
-    "Oil & Gas Production", 
-    "http://www.nasdaq.com/symbol/znwaa"
-  ], 
-  [
-    "ZSAN", 
-    "Zosano Pharma Corporation", 
-    "11.09", 
-    "$131.04M", 
-    "2015", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/zsan"
-  ], 
-  [
-    "ZSPH", 
-    "ZS Pharma, Inc.", 
-    "50.51", 
-    "$1.05B", 
-    "2014", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/zsph"
-  ], 
-  [
-    "ZU", 
-    "zulily, inc.", 
-    "14.4", 
-    "$1.8B", 
-    "2013", 
-    "Consumer Services", 
-    "Catalog/Specialty Distribution", 
-    "http://www.nasdaq.com/symbol/zu"
-  ], 
-  [
-    "ZUMZ", 
-    "Zumiez Inc.", 
-    "38.77", 
-    "$1.13B", 
-    "2005", 
-    "Consumer Services", 
-    "Clothing/Shoe/Accessory Stores", 
-    "http://www.nasdaq.com/symbol/zumz"
-  ]
-]
\ No newline at end of file
diff --git a/examples/stocks/data/stock_data_3.json b/examples/stocks/data/stock_data_3.json
deleted file mode 100644
index 67edf86..0000000
--- a/examples/stocks/data/stock_data_3.json
+++ /dev/null
@@ -1,1002 +0,0 @@
-[
-  [
-    "BDBD", 
-    "Boulder Brands, Inc.", 
-    "10.81", 
-    "$660.85M", 
-    "n/a", 
-    "Consumer Non-Durables", 
-    "Packaged Foods", 
-    "http://www.nasdaq.com/symbol/bdbd"
-  ], 
-  [
-    "BDCV", 
-    "BDCA Venture, Inc.", 
-    "4.89", 
-    "$48.52M", 
-    "2011", 
-    "n/a", 
-    "n/a", 
-    "http://www.nasdaq.com/symbol/bdcv"
-  ], 
-  [
-    "BDE", 
-    "Black Diamond, Inc.", 
-    "6.67", 
-    "$218.04M", 
-    "n/a", 
-    "Consumer Non-Durables", 
-    "Recreational Products/Toys", 
-    "http://www.nasdaq.com/symbol/bde"
-  ], 
-  [
-    "BDGE", 
-    "Bridge Bancorp, Inc.", 
-    "25.68", 
-    "$299.19M", 
-    "n/a", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/bdge"
-  ], 
-  [
-    "BDMS", 
-    "Birner Dental Management Services, Inc.", 
-    "15", 
-    "$27.9M", 
-    "1998", 
-    "Health Care", 
-    "Medical/Nursing Services", 
-    "http://www.nasdaq.com/symbol/bdms"
-  ], 
-  [
-    "BDSI", 
-    "BioDelivery Sciences International, Inc.", 
-    "14.41", 
-    "$739.03M", 
-    "n/a", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/bdsi"
-  ], 
-  [
-    "BEAT", 
-    "BioTelemetry, Inc.", 
-    "9.51", 
-    "$253.76M", 
-    "2008", 
-    "Health Care", 
-    "Medical/Dental Instruments", 
-    "http://www.nasdaq.com/symbol/beat"
-  ], 
-  [
-    "BEAV", 
-    "B/E Aerospace, Inc.", 
-    "64.54", 
-    "$6.8B", 
-    "1990", 
-    "Consumer Durables", 
-    "Industrial Specialties", 
-    "http://www.nasdaq.com/symbol/beav"
-  ], 
-  [
-    "BEBE", 
-    "bebe stores, inc.", 
-    "3.84", 
-    "$305.72M", 
-    "1998", 
-    "Consumer Non-Durables", 
-    "Apparel", 
-    "http://www.nasdaq.com/symbol/bebe"
-  ], 
-  [
-    "BECN", 
-    "Beacon Roofing Supply, Inc.", 
-    "28.76", 
-    "$1.42B", 
-    "2004", 
-    "Consumer Services", 
-    "RETAIL: Building Materials", 
-    "http://www.nasdaq.com/symbol/becn"
-  ], 
-  [
-    "BELFA", 
-    "Bel Fuse Inc.", 
-    "19.38", 
-    "$230.23M", 
-    "n/a", 
-    "Capital Goods", 
-    "Electrical Products", 
-    "http://www.nasdaq.com/symbol/belfa"
-  ], 
-  [
-    "BELFB", 
-    "Bel Fuse Inc.", 
-    "19.51", 
-    "$231.77M", 
-    "n/a", 
-    "Capital Goods", 
-    "Electrical Products", 
-    "http://www.nasdaq.com/symbol/belfb"
-  ], 
-  [
-    "BFIN", 
-    "BankFinancial Corporation", 
-    "11.97", 
-    "$252.59M", 
-    "n/a", 
-    "Finance", 
-    "Savings Institutions", 
-    "http://www.nasdaq.com/symbol/bfin"
-  ], 
-  [
-    "BGCP", 
-    "BGC Partners, Inc.", 
-    "9.44", 
-    "$2.07B", 
-    "n/a", 
-    "Finance", 
-    "Investment Bankers/Brokers/Service", 
-    "http://www.nasdaq.com/symbol/bgcp"
-  ], 
-  [
-    "BGFV", 
-    "Big 5 Sporting Goods Corporation", 
-    "12.44", 
-    "$275.84M", 
-    "2002", 
-    "Consumer Services", 
-    "Other Specialty Stores", 
-    "http://www.nasdaq.com/symbol/bgfv"
-  ], 
-  [
-    "BGMD", 
-    "BG Medicine, Inc.", 
-    "0.8201", 
-    "$28.23M", 
-    "2011", 
-    "Health Care", 
-    "Biotechnology: In Vitro & In Vivo Diagnostic Substances", 
-    "http://www.nasdaq.com/symbol/bgmd"
-  ], 
-  [
-    "BHACU", 
-    "Barington/Hilco Acquisition Corp.", 
-    "9.96", 
-    "n/a", 
-    "2015", 
-    "Finance", 
-    "Business Services", 
-    "http://www.nasdaq.com/symbol/bhacu"
-  ], 
-  [
-    "BHBK", 
-    "Blue Hills Bancorp, Inc.", 
-    "12.87", 
-    "$366.37M", 
-    "2014", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/bhbk"
-  ], 
-  [
-    "BIB", 
-    "ProShares Ultra Nasdaq Biotechnology", 
-    "152.9", 
-    "$504.57M", 
-    "n/a", 
-    "n/a", 
-    "n/a", 
-    "http://www.nasdaq.com/symbol/bib"
-  ], 
-  [
-    "BICK", 
-    "First Trust BICK Index Fund", 
-    "23.96", 
-    "$16.77M", 
-    "n/a", 
-    "n/a", 
-    "n/a", 
-    "http://www.nasdaq.com/symbol/bick"
-  ], 
-  [
-    "BIDU", 
-    "Baidu, Inc.", 
-    "209.63", 
-    "$73.52B", 
-    "2005", 
-    "Technology", 
-    "Computer Software: Programming, Data Processing", 
-    "http://www.nasdaq.com/symbol/bidu"
-  ], 
-  [
-    "BIIB", 
-    "Biogen Idec Inc.", 
-    "408.05", 
-    "$95.73B", 
-    "n/a", 
-    "Health Care", 
-    "Biotechnology: Biological Products (No Diagnostic Substances)", 
-    "http://www.nasdaq.com/symbol/biib"
-  ], 
-  [
-    "BIND", 
-    "BIND Therapeutics, Inc.", 
-    "6.42", 
-    "$106.24M", 
-    "2013", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/bind"
-  ], 
-  [
-    "BIOC", 
-    "Biocept, Inc.", 
-    "1.45", 
-    "$6.45M", 
-    "2014", 
-    "Health Care", 
-    "Medical Specialities", 
-    "http://www.nasdaq.com/symbol/bioc"
-  ], 
-  [
-    "BIOD", 
-    "Biodel Inc.", 
-    "1.39", 
-    "$34.12M", 
-    "2007", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/biod"
-  ], 
-  [
-    "BIOL", 
-    "Biolase, Inc.", 
-    "2.06", 
-    "$119.72M", 
-    "n/a", 
-    "Health Care", 
-    "Medical/Dental Instruments", 
-    "http://www.nasdaq.com/symbol/biol"
-  ], 
-  [
-    "BIOS", 
-    "BioScrip, Inc.", 
-    "6.04", 
-    "$414.56M", 
-    "n/a", 
-    "Health Care", 
-    "Medical/Nursing Services", 
-    "http://www.nasdaq.com/symbol/bios"
-  ], 
-  [
-    "BIS", 
-    "ProShares UltraShort Nasdaq Biotechnology", 
-    "36.74", 
-    "$44.09M", 
-    "n/a", 
-    "n/a", 
-    "n/a", 
-    "http://www.nasdaq.com/symbol/bis"
-  ], 
-  [
-    "BJRI", 
-    "BJ&#39;s Restaurants, Inc.", 
-    "53.07", 
-    "$1.38B", 
-    "n/a", 
-    "Consumer Services", 
-    "Restaurants", 
-    "http://www.nasdaq.com/symbol/bjri"
-  ], 
-  [
-    "BKCC", 
-    "BlackRock Kelso Capital Corporation", 
-    "8.6", 
-    "$641.11M", 
-    "2007", 
-    "n/a", 
-    "n/a", 
-    "http://www.nasdaq.com/symbol/bkcc"
-  ], 
-  [
-    "BKEP", 
-    "Blueknight Energy Partners L.P., L.L.C.", 
-    "7.19", 
-    "$235.59M", 
-    "2011", 
-    "Energy", 
-    "Natural Gas Distribution", 
-    "http://www.nasdaq.com/symbol/bkep"
-  ], 
-  [
-    "BKEPP", 
-    "Blueknight Energy Partners L.P., L.L.C.", 
-    "8.82", 
-    "$266M", 
-    "n/a", 
-    "Energy", 
-    "Natural Gas Distribution", 
-    "http://www.nasdaq.com/symbol/bkepp"
-  ], 
-  [
-    "BKMU", 
-    "Bank Mutual Corporation", 
-    "7.15", 
-    "$332.93M", 
-    "n/a", 
-    "Finance", 
-    "Savings Institutions", 
-    "http://www.nasdaq.com/symbol/bkmu"
-  ], 
-  [
-    "BKSC", 
-    "Bank of South Carolina Corp.", 
-    "14.91", 
-    "$66.52M", 
-    "n/a", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/bksc"
-  ], 
-  [
-    "BKYF", 
-    "The Bank of Kentucky Financial Corp.", 
-    "47.68", 
-    "$366.75M", 
-    "n/a", 
-    "Finance", 
-    "Savings Institutions", 
-    "http://www.nasdaq.com/symbol/bkyf"
-  ], 
-  [
-    "BLCM", 
-    "Bellicum Pharmaceuticals, Inc.", 
-    "21.06", 
-    "$544.39M", 
-    "2014", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/blcm"
-  ], 
-  [
-    "BLDP", 
-    "Ballard Power Systems, Inc.", 
-    "2.41", 
-    "$318.37M", 
-    "n/a", 
-    "Energy", 
-    "Industrial Machinery/Components", 
-    "http://www.nasdaq.com/symbol/bldp"
-  ], 
-  [
-    "BLDR", 
-    "Builders FirstSource, Inc.", 
-    "6.5", 
-    "$637.94M", 
-    "2005", 
-    "Consumer Services", 
-    "RETAIL: Building Materials", 
-    "http://www.nasdaq.com/symbol/bldr"
-  ], 
-  [
-    "BLFS", 
-    "BioLife Solutions, Inc.", 
-    "2.15", 
-    "$25.98M", 
-    "n/a", 
-    "Health Care", 
-    "Biotechnology: Electromedical & Electrotherapeutic Apparatus", 
-    "http://www.nasdaq.com/symbol/blfs"
-  ], 
-  [
-    "BLIN          ", 
-    "Bridgeline Digital, Inc.", 
-    "0.5", 
-    "$10.99M", 
-    "n/a", 
-    "Technology", 
-    "Computer Software: Prepackaged Software", 
-    "http://www.nasdaq.com/symbol/blin          "
-  ], 
-  [
-    "BLKB", 
-    "Blackbaud, Inc.", 
-    "46.27", 
-    "$2.14B", 
-    "2004", 
-    "Technology", 
-    "Computer Software: Prepackaged Software", 
-    "http://www.nasdaq.com/symbol/blkb"
-  ], 
-  [
-    "BLMN", 
-    "Bloomin&#39; Brands, Inc.", 
-    "25.4", 
-    "$3.19B", 
-    "2012", 
-    "Consumer Services", 
-    "Restaurants", 
-    "http://www.nasdaq.com/symbol/blmn"
-  ], 
-  [
-    "BLMT", 
-    "BSB Bancorp, Inc.", 
-    "18.98", 
-    "$172.02M", 
-    "2011", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/blmt"
-  ], 
-  [
-    "BLPH", 
-    "Bellerophon Therapeutics, Inc.", 
-    "9.42", 
-    "$121.57M", 
-    "2015", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/blph"
-  ], 
-  [
-    "BLRX", 
-    "BioLineRx Ltd.", 
-    "2.42", 
-    "$82.56M", 
-    "n/a", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/blrx"
-  ], 
-  [
-    "BLUE", 
-    "bluebird bio, Inc.", 
-    "93.32", 
-    "$2.69B", 
-    "2013", 
-    "Health Care", 
-    "Biotechnology: Biological Products (No Diagnostic Substances)", 
-    "http://www.nasdaq.com/symbol/blue"
-  ], 
-  [
-    "BLVD", 
-    "Boulevard Acquisition Corp.", 
-    "9.75", 
-    "$268.73M", 
-    "2014", 
-    "Finance", 
-    "Business Services", 
-    "http://www.nasdaq.com/symbol/blvd"
-  ], 
-  [
-    "BLVDU", 
-    "Boulevard Acquisition Corp.", 
-    "9.95", 
-    "$274.25M", 
-    "2014", 
-    "Finance", 
-    "Business Services", 
-    "http://www.nasdaq.com/symbol/blvdu"
-  ], 
-  [
-    "BLVDW", 
-    "Boulevard Acquisition Corp.", 
-    "0.5501", 
-    "n/a", 
-    "2014", 
-    "Finance", 
-    "Business Services", 
-    "http://www.nasdaq.com/symbol/blvdw"
-  ], 
-  [
-    "BMRC", 
-    "Bank of Marin Bancorp", 
-    "50.18", 
-    "$297.74M", 
-    "n/a", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/bmrc"
-  ], 
-  [
-    "BMRN", 
-    "BioMarin Pharmaceutical Inc.", 
-    "107.16", 
-    "$15.8B", 
-    "1999", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/bmrn"
-  ], 
-  [
-    "BMTC", 
-    "Bryn Mawr Bank Corporation", 
-    "29.59", 
-    "$406.34M", 
-    "n/a", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/bmtc"
-  ], 
-  [
-    "BNCL", 
-    "Beneficial Bancorp, Inc.", 
-    "11.22", 
-    "$843.25M", 
-    "n/a", 
-    "Finance", 
-    "Savings Institutions", 
-    "http://www.nasdaq.com/symbol/bncl"
-  ], 
-  [
-    "BNCN", 
-    "BNC Bancorp", 
-    "16.41", 
-    "$484.04M", 
-    "n/a", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/bncn"
-  ], 
-  [
-    "BNDX", 
-    "Vanguard Total International Bond ETF", 
-    "53.57", 
-    "$1.85B", 
-    "n/a", 
-    "n/a", 
-    "n/a", 
-    "http://www.nasdaq.com/symbol/bndx"
-  ], 
-  [
-    "BNFT", 
-    "Benefitfocus, Inc.", 
-    "21.95", 
-    "$560.94M", 
-    "2013", 
-    "Technology", 
-    "Computer Software: Prepackaged Software", 
-    "http://www.nasdaq.com/symbol/bnft"
-  ], 
-  [
-    "BNSO", 
-    "Bonso Electronics International, Inc.", 
-    "1.419", 
-    "$7.45M", 
-    "n/a", 
-    "Capital Goods", 
-    "Industrial Machinery/Components", 
-    "http://www.nasdaq.com/symbol/bnso"
-  ], 
-  [
-    "BOBE", 
-    "Bob Evans Farms, Inc.", 
-    "56.9", 
-    "$1.34B", 
-    "n/a", 
-    "Consumer Services", 
-    "Restaurants", 
-    "http://www.nasdaq.com/symbol/bobe"
-  ], 
-  [
-    "BOCH", 
-    "Bank of Commerce Holdings (CA)", 
-    "5.7399", 
-    "$76.3M", 
-    "n/a", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/boch"
-  ], 
-  [
-    "BOFI", 
-    "BofI Holding, Inc.", 
-    "90.32", 
-    "$1.36B", 
-    "2005", 
-    "Finance", 
-    "Savings Institutions", 
-    "http://www.nasdaq.com/symbol/bofi"
-  ], 
-  [
-    "BOKF", 
-    "BOK Financial Corporation", 
-    "59.54", 
-    "$4.13B", 
-    "n/a", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/bokf"
-  ], 
-  [
-    "BONA", 
-    "Bona Film Group Limited", 
-    "6.89", 
-    "$419.44M", 
-    "2010", 
-    "Consumer Services", 
-    "Movies/Entertainment", 
-    "http://www.nasdaq.com/symbol/bona"
-  ], 
-  [
-    "BONT", 
-    "The Bon-Ton Stores, Inc.", 
-    "5.53", 
-    "$112.99M", 
-    "1991", 
-    "Consumer Services", 
-    "Department/Specialty Retail Stores", 
-    "http://www.nasdaq.com/symbol/bont"
-  ], 
-  [
-    "BOOM", 
-    "Dynamic Materials Corporation", 
-    "14.79", 
-    "$206.75M", 
-    "n/a", 
-    "Capital Goods", 
-    "Industrial Specialties", 
-    "http://www.nasdaq.com/symbol/boom"
-  ], 
-  [
-    "BOSC", 
-    "B.O.S. Better Online Solutions", 
-    "3.1", 
-    "$4.15M", 
-    "n/a", 
-    "Technology", 
-    "Computer Communications Equipment", 
-    "http://www.nasdaq.com/symbol/bosc"
-  ], 
-  [
-    "BOTA", 
-    "Biota Pharmaceuticals, Inc.", 
-    "2.46", 
-    "$86.35M", 
-    "n/a", 
-    "Health Care", 
-    "Biotechnology: Biological Products (No Diagnostic Substances)", 
-    "http://www.nasdaq.com/symbol/bota"
-  ], 
-  [
-    "BOTJ", 
-    "Bank of the James Financial Group, Inc.", 
-    "11", 
-    "$37.01M", 
-    "n/a", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/botj"
-  ], 
-  [
-    "BPFH", 
-    "Boston Private Financial Holdings, Inc.", 
-    "12.68", 
-    "$1.05B", 
-    "n/a", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/bpfh"
-  ], 
-  [
-    "BPFHP", 
-    "Boston Private Financial Holdings, Inc.", 
-    "25.6", 
-    "n/a", 
-    "n/a", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/bpfhp"
-  ], 
-  [
-    "BPFHW", 
-    "Boston Private Financial Holdings, Inc.", 
-    "5.652", 
-    "n/a", 
-    "n/a", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/bpfhw"
-  ], 
-  [
-    "BPOP", 
-    "Popular, Inc.", 
-    "33.21", 
-    "$3.44B", 
-    "n/a", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/bpop"
-  ], 
-  [
-    "BPOPM", 
-    "Popular, Inc.", 
-    "21.82", 
-    "n/a", 
-    "n/a", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/bpopm"
-  ], 
-  [
-    "BPOPN", 
-    "Popular, Inc.", 
-    "22.77", 
-    "$273.24M", 
-    "n/a", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/bpopn"
-  ], 
-  [
-    "BPTH", 
-    "Bio-Path Holdings, Inc.", 
-    "2.13", 
-    "$190.08M", 
-    "n/a", 
-    "Consumer Services", 
-    "Other Specialty Stores", 
-    "http://www.nasdaq.com/symbol/bpth"
-  ], 
-  [
-    "BRCD", 
-    "Brocade Communications Systems, Inc.", 
-    "12.06", 
-    "$5.2B", 
-    "1999", 
-    "Technology", 
-    "Computer Communications Equipment", 
-    "http://www.nasdaq.com/symbol/brcd"
-  ], 
-  [
-    "BRCM", 
-    "Broadcom Corporation", 
-    "44.68", 
-    "$26.76B", 
-    "1998", 
-    "Technology", 
-    "Semiconductors", 
-    "http://www.nasdaq.com/symbol/brcm"
-  ], 
-  [
-    "BRDR", 
-    "Borderfree, Inc.", 
-    "7.41", 
-    "$235.73M", 
-    "2014", 
-    "Miscellaneous", 
-    "Business Services", 
-    "http://www.nasdaq.com/symbol/brdr"
-  ], 
-  [
-    "BREW", 
-    "Craft Brew Alliance, Inc.", 
-    "12.26", 
-    "$233.85M", 
-    "n/a", 
-    "Consumer Non-Durables", 
-    "Beverages (Production/Distribution)", 
-    "http://www.nasdaq.com/symbol/brew"
-  ], 
-  [
-    "BRID", 
-    "Bridgford Foods Corporation", 
-    "7.58", 
-    "$69.07M", 
-    "n/a", 
-    "Consumer Non-Durables", 
-    "Specialty Foods", 
-    "http://www.nasdaq.com/symbol/brid"
-  ], 
-  [
-    "BRKL", 
-    "Brookline Bancorp, Inc.", 
-    "9.73", 
-    "$681.32M", 
-    "n/a", 
-    "Finance", 
-    "Savings Institutions", 
-    "http://www.nasdaq.com/symbol/brkl"
-  ], 
-  [
-    "BRKR", 
-    "Bruker Corporation", 
-    "18.77", 
-    "$3.16B", 
-    "n/a", 
-    "Capital Goods", 
-    "Biotechnology: Laboratory Analytical Instruments", 
-    "http://www.nasdaq.com/symbol/brkr"
-  ], 
-  [
-    "BRKS", 
-    "Brooks Automation, Inc.", 
-    "12.23", 
-    "$823.25M", 
-    "1995", 
-    "Technology", 
-    "Industrial Machinery/Components", 
-    "http://www.nasdaq.com/symbol/brks"
-  ], 
-  [
-    "BRLI", 
-    "Bio-Reference Laboratories, Inc.", 
-    "34.32", 
-    "$952.37M", 
-    "n/a", 
-    "Health Care", 
-    "Medical Specialities", 
-    "http://www.nasdaq.com/symbol/brli"
-  ], 
-  [
-    "BSDM", 
-    "BSD Medical Corporation", 
-    "0.41", 
-    "$16.27M", 
-    "n/a", 
-    "Health Care", 
-    "Biotechnology: Electromedical & Electrotherapeutic Apparatus", 
-    "http://www.nasdaq.com/symbol/bsdm"
-  ], 
-  [
-    "BSET", 
-    "Bassett Furniture Industries, Incorporated", 
-    "25.24", 
-    "$266.79M", 
-    "n/a", 
-    "Consumer Durables", 
-    "Home Furnishings", 
-    "http://www.nasdaq.com/symbol/bset"
-  ], 
-  [
-    "BSF", 
-    "Bear State Financial, Inc.", 
-    "10.5452", 
-    "$390.18M", 
-    "n/a", 
-    "Finance", 
-    "Savings Institutions", 
-    "http://www.nasdaq.com/symbol/bsf"
-  ], 
-  [
-    "BSFT", 
-    "BroadSoft, Inc.", 
-    "27.82", 
-    "$801.41M", 
-    "2010", 
-    "Technology", 
-    "Computer Software: Prepackaged Software", 
-    "http://www.nasdaq.com/symbol/bsft"
-  ], 
-  [
-    "BSPM", 
-    "Biostar Pharmaceuticals, Inc.", 
-    "1.25", 
-    "$19.35M", 
-    "n/a", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/bspm"
-  ], 
-  [
-    "BSQR", 
-    "BSQUARE Corporation", 
-    "4.71", 
-    "$55.23M", 
-    "1999", 
-    "Miscellaneous", 
-    "Business Services", 
-    "http://www.nasdaq.com/symbol/bsqr"
-  ], 
-  [
-    "BSRR", 
-    "Sierra Bancorp", 
-    "16.53", 
-    "$227.91M", 
-    "n/a", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/bsrr"
-  ], 
-  [
-    "BSTC", 
-    "BioSpecifics Technologies Corp", 
-    "39.29", 
-    "$255.41M", 
-    "n/a", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/bstc"
-  ], 
-  [
-    "BUR", 
-    "Burcon Nutrascience Corp", 
-    "2.57", 
-    "$87.75M", 
-    "n/a", 
-    "Consumer Non-Durables", 
-    "Packaged Foods", 
-    "http://www.nasdaq.com/symbol/bur"
-  ], 
-  [
-    "BUSE", 
-    "First Busey Corporation", 
-    "6.41", 
-    "$556.72M", 
-    "n/a", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/buse"
-  ], 
-  [
-    "BV", 
-    "Bazaarvoice, Inc.", 
-    "9.24", 
-    "$726.59M", 
-    "2012", 
-    "Technology", 
-    "Computer Software: Prepackaged Software", 
-    "http://www.nasdaq.com/symbol/bv"
-  ], 
-  [
-    "BVA", 
-    "Cordia Bancorp Inc.", 
-    "3.8901", 
-    "$25.3M", 
-    "n/a", 
-    "n/a", 
-    "n/a", 
-    "http://www.nasdaq.com/symbol/bva"
-  ], 
-  [
-    "BVSN", 
-    "BroadVision, Inc.", 
-    "6.1", 
-    "$29.42M", 
-    "1996", 
-    "Technology", 
-    "Computer Software: Prepackaged Software", 
-    "http://www.nasdaq.com/symbol/bvsn"
-  ], 
-  [
-    "BWEN", 
-    "Broadwind Energy, Inc.", 
-    "5.09", 
-    "$75.44M", 
-    "n/a", 
-    "Capital Goods", 
-    "Metal Fabrications", 
-    "http://www.nasdaq.com/symbol/bwen"
-  ], 
-  [
-    "BWFG", 
-    "Bankwell Financial Group, Inc.", 
-    "18.82", 
-    "$133.03M", 
-    "2014", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/bwfg"
-  ], 
-  [
-    "BWINA", 
-    "Baldwin & Lyons, Inc.", 
-    "23.8", 
-    "$356.41M", 
-    "n/a", 
-    "Finance", 
-    "Property-Casualty Insurers", 
-    "http://www.nasdaq.com/symbol/bwina"
-  ], 
-  [
-    "BWINB", 
-    "Baldwin & Lyons, Inc.", 
-    "23.19", 
-    "$347.27M", 
-    "n/a", 
-    "Finance", 
-    "Property-Casualty Insurers", 
-    "http://www.nasdaq.com/symbol/bwinb"
-  ]
-]
\ No newline at end of file
diff --git a/examples/stocks/data/stock_data_4.json b/examples/stocks/data/stock_data_4.json
deleted file mode 100644
index e2965e3..0000000
--- a/examples/stocks/data/stock_data_4.json
+++ /dev/null
@@ -1,1002 +0,0 @@
-[
-  [
-    "BWLD", 
-    "Buffalo Wild Wings, Inc.", 
-    "190.18", 
-    "$3.6B", 
-    "2003", 
-    "Consumer Services", 
-    "Restaurants", 
-    "http://www.nasdaq.com/symbol/bwld"
-  ], 
-  [
-    "BYBK", 
-    "Bay Bancorp, Inc.", 
-    "4.75", 
-    "$52.4M", 
-    "n/a", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/bybk"
-  ], 
-  [
-    "BYFC", 
-    "Broadway Financial Corporation", 
-    "1.37", 
-    "$39.84M", 
-    "n/a", 
-    "Finance", 
-    "Savings Institutions", 
-    "http://www.nasdaq.com/symbol/byfc"
-  ], 
-  [
-    "BYLK", 
-    "Baylake Corp", 
-    "12.31", 
-    "$112.28M", 
-    "n/a", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/bylk"
-  ], 
-  [
-    "CA", 
-    "CA Inc.", 
-    "32.83", 
-    "$14.54B", 
-    "n/a", 
-    "Technology", 
-    "Computer Software: Prepackaged Software", 
-    "http://www.nasdaq.com/symbol/ca"
-  ], 
-  [
-    "CAAS", 
-    "China Automotive Systems, Inc.", 
-    "6.78", 
-    "$217.78M", 
-    "n/a", 
-    "Capital Goods", 
-    "Auto Parts:O.E.M.", 
-    "http://www.nasdaq.com/symbol/caas"
-  ], 
-  [
-    "CAC", 
-    "Camden National Corporation", 
-    "37.75", 
-    "$280.16M", 
-    "n/a", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/cac"
-  ], 
-  [
-    "CACB", 
-    "Cascade Bancorp", 
-    "4.8", 
-    "$347.91M", 
-    "n/a", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/cacb"
-  ], 
-  [
-    "CACC", 
-    "Credit Acceptance Corporation", 
-    "172.26", 
-    "$3.55B", 
-    "1992", 
-    "Finance", 
-    "Finance: Consumer Services", 
-    "http://www.nasdaq.com/symbol/cacc"
-  ], 
-  [
-    "CACG", 
-    "Chart Acquisition Corp.", 
-    "9.77", 
-    "$85.83M", 
-    "2013", 
-    "Finance", 
-    "Business Services", 
-    "http://www.nasdaq.com/symbol/cacg"
-  ], 
-  [
-    "CACGU", 
-    "Chart Acquisition Corp.", 
-    "10.02", 
-    "n/a", 
-    "2012", 
-    "Finance", 
-    "Business Services", 
-    "http://www.nasdaq.com/symbol/cacgu"
-  ], 
-  [
-    "CACGW", 
-    "Chart Acquisition Corp.", 
-    "0.55", 
-    "n/a", 
-    "2013", 
-    "Finance", 
-    "Business Services", 
-    "http://www.nasdaq.com/symbol/cacgw"
-  ], 
-  [
-    "CACQ", 
-    "Caesars Acquisition Company", 
-    "7.87", 
-    "$1.07B", 
-    "n/a", 
-    "Consumer Services", 
-    "Hotels/Resorts", 
-    "http://www.nasdaq.com/symbol/cacq"
-  ], 
-  [
-    "CADC", 
-    "China Advanced Construction Materials Group, Inc.", 
-    "4.24", 
-    "$8.82M", 
-    "n/a", 
-    "Basic Industries", 
-    "Engineering & Construction", 
-    "http://www.nasdaq.com/symbol/cadc"
-  ], 
-  [
-    "CADT", 
-    "DT Asia Investments Limited", 
-    "9.66", 
-    "$86.24M", 
-    "2014", 
-    "Finance", 
-    "Business Services", 
-    "http://www.nasdaq.com/symbol/cadt"
-  ], 
-  [
-    "CADTR", 
-    "DT Asia Investments Limited", 
-    "0.16", 
-    "n/a", 
-    "2014", 
-    "Finance", 
-    "Business Services", 
-    "http://www.nasdaq.com/symbol/cadtr"
-  ], 
-  [
-    "CADTU", 
-    "DT Asia Investments Limited", 
-    "10.02", 
-    "n/a", 
-    "2014", 
-    "Finance", 
-    "Business Services", 
-    "http://www.nasdaq.com/symbol/cadtu"
-  ], 
-  [
-    "CADTW", 
-    "DT Asia Investments Limited", 
-    "0.11", 
-    "n/a", 
-    "2014", 
-    "Finance", 
-    "Business Services", 
-    "http://www.nasdaq.com/symbol/cadtw"
-  ], 
-  [
-    "CAKE", 
-    "The Cheesecake Factory Incorporated", 
-    "49.22", 
-    "$2.44B", 
-    "1992", 
-    "Consumer Services", 
-    "Restaurants", 
-    "http://www.nasdaq.com/symbol/cake"
-  ], 
-  [
-    "CALA", 
-    "Calithera Biosciences, Inc.", 
-    "16.21", 
-    "$290.65M", 
-    "2014", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/cala"
-  ], 
-  [
-    "CALD", 
-    "Callidus Software, Inc.", 
-    "14.33", 
-    "$696.85M", 
-    "2003", 
-    "Technology", 
-    "EDP Services", 
-    "http://www.nasdaq.com/symbol/cald"
-  ], 
-  [
-    "CALI", 
-    "China Auto Logistics Inc.", 
-    "1.31", 
-    "$5.29M", 
-    "n/a", 
-    "Consumer Services", 
-    "Motor Vehicles", 
-    "http://www.nasdaq.com/symbol/cali"
-  ], 
-  [
-    "CALL", 
-    "magicJack VocalTec Ltd", 
-    "7.86", 
-    "$140.16M", 
-    "n/a", 
-    "Public Utilities", 
-    "Telecommunications Equipment", 
-    "http://www.nasdaq.com/symbol/call"
-  ], 
-  [
-    "CALM", 
-    "Cal-Maine Foods, Inc.", 
-    "36.9", 
-    "$1.79B", 
-    "1996", 
-    "Consumer Non-Durables", 
-    "Farming/Seeds/Milling", 
-    "http://www.nasdaq.com/symbol/calm"
-  ], 
-  [
-    "CAMB", 
-    "CAMBRIDGE CAPITAL ACQUISITION CORPORATION", 
-    "9.88", 
-    "$104.08M", 
-    "2014", 
-    "Finance", 
-    "Business Services", 
-    "http://www.nasdaq.com/symbol/camb"
-  ], 
-  [
-    "CAMBU", 
-    "CAMBRIDGE CAPITAL ACQUISITION CORPORATION", 
-    "10.2999", 
-    "n/a", 
-    "2013", 
-    "Finance", 
-    "Business Services", 
-    "http://www.nasdaq.com/symbol/cambu"
-  ], 
-  [
-    "CAMBW", 
-    "CAMBRIDGE CAPITAL ACQUISITION CORPORATION", 
-    "0.22", 
-    "n/a", 
-    "2014", 
-    "Finance", 
-    "Business Services", 
-    "http://www.nasdaq.com/symbol/cambw"
-  ], 
-  [
-    "CAMP", 
-    "CalAmp Corp.", 
-    "18.8", 
-    "$680.66M", 
-    "1983", 
-    "Technology", 
-    "Radio And Television Broadcasting And Communications Equipment", 
-    "http://www.nasdaq.com/symbol/camp"
-  ], 
-  [
-    "CAMT", 
-    "Camtek Ltd.", 
-    "3.07", 
-    "$93.55M", 
-    "2000", 
-    "Capital Goods", 
-    "Electronic Components", 
-    "http://www.nasdaq.com/symbol/camt"
-  ], 
-  [
-    "CAPN", 
-    "Capnia, Inc.", 
-    "5.45", 
-    "$36.89M", 
-    "2014", 
-    "Health Care", 
-    "Biotechnology: Electromedical & Electrotherapeutic Apparatus", 
-    "http://www.nasdaq.com/symbol/capn"
-  ], 
-  [
-    "CAPNW", 
-    "Capnia, Inc.", 
-    "0.99", 
-    "n/a", 
-    "2014", 
-    "Health Care", 
-    "Biotechnology: Electromedical & Electrotherapeutic Apparatus", 
-    "http://www.nasdaq.com/symbol/capnw"
-  ], 
-  [
-    "CAR", 
-    "Avis Budget Group, Inc.", 
-    "62.45", 
-    "$6.63B", 
-    "n/a", 
-    "Consumer Services", 
-    "Rental/Leasing Companies", 
-    "http://www.nasdaq.com/symbol/car"
-  ], 
-  [
-    "CARA", 
-    "Cara Therapeutics, Inc.", 
-    "10.91", 
-    "$248.51M", 
-    "2014", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/cara"
-  ], 
-  [
-    "CARB", 
-    "Carbonite, Inc.", 
-    "14.8", 
-    "$402.84M", 
-    "2011", 
-    "Technology", 
-    "EDP Services", 
-    "http://www.nasdaq.com/symbol/carb"
-  ], 
-  [
-    "CARO", 
-    "Carolina Financial Corporation", 
-    "13.85", 
-    "$224.27M", 
-    "n/a", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/caro"
-  ], 
-  [
-    "CART", 
-    "Carolina Trust Bank", 
-    "5.55", 
-    "$25.72M", 
-    "n/a", 
-    "n/a", 
-    "n/a", 
-    "http://www.nasdaq.com/symbol/cart"
-  ], 
-  [
-    "CARV", 
-    "Carver Bancorp, Inc.", 
-    "5.99", 
-    "$22.14M", 
-    "n/a", 
-    "Finance", 
-    "Savings Institutions", 
-    "http://www.nasdaq.com/symbol/carv"
-  ], 
-  [
-    "CARZ", 
-    "First Trust NASDAQ Global Auto Index Fund", 
-    "40.719", 
-    "$69.22M", 
-    "n/a", 
-    "n/a", 
-    "n/a", 
-    "http://www.nasdaq.com/symbol/carz"
-  ], 
-  [
-    "CASH", 
-    "Meta Financial Group, Inc.", 
-    "35.8", 
-    "$229.88M", 
-    "1993", 
-    "Finance", 
-    "Savings Institutions", 
-    "http://www.nasdaq.com/symbol/cash"
-  ], 
-  [
-    "CASI", 
-    "CASI Pharmaceuticals, Inc.", 
-    "1.6501", 
-    "$53.54M", 
-    "n/a", 
-    "Health Care", 
-    "Biotechnology: Biological Products (No Diagnostic Substances)", 
-    "http://www.nasdaq.com/symbol/casi"
-  ], 
-  [
-    "CASM", 
-    "CAS Medical Systems, Inc.", 
-    "1.36", 
-    "$26.5M", 
-    "n/a", 
-    "Health Care", 
-    "Medical/Dental Instruments", 
-    "http://www.nasdaq.com/symbol/casm"
-  ], 
-  [
-    "CASS", 
-    "Cass Information Systems, Inc", 
-    "49.25", 
-    "$567.18M", 
-    "n/a", 
-    "Miscellaneous", 
-    "Business Services", 
-    "http://www.nasdaq.com/symbol/cass"
-  ], 
-  [
-    "CASY", 
-    "Caseys General Stores, Inc.", 
-    "91.15", 
-    "$3.53B", 
-    "1983", 
-    "Consumer Durables", 
-    "Automotive Aftermarket", 
-    "http://www.nasdaq.com/symbol/casy"
-  ], 
-  [
-    "CATM", 
-    "Cardtronics, Inc.", 
-    "38.27", 
-    "$1.7B", 
-    "2007", 
-    "Miscellaneous", 
-    "Business Services", 
-    "http://www.nasdaq.com/symbol/catm"
-  ], 
-  [
-    "CATY", 
-    "Cathay General Bancorp", 
-    "25.77", 
-    "$2.05B", 
-    "n/a", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/caty"
-  ], 
-  [
-    "CATYW", 
-    "Cathay General Bancorp", 
-    "6.495", 
-    "n/a", 
-    "n/a", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/catyw"
-  ], 
-  [
-    "CAVM", 
-    "Cavium, Inc.", 
-    "66.96", 
-    "$3.61B", 
-    "2007", 
-    "Technology", 
-    "Semiconductors", 
-    "http://www.nasdaq.com/symbol/cavm"
-  ], 
-  [
-    "CBAK", 
-    "China BAK Battery, Inc.", 
-    "2.4", 
-    "$30.29M", 
-    "n/a", 
-    "Miscellaneous", 
-    "Industrial Machinery/Components", 
-    "http://www.nasdaq.com/symbol/cbak"
-  ], 
-  [
-    "CBAN", 
-    "Colony Bankcorp, Inc.", 
-    "7.9399", 
-    "$67.01M", 
-    "n/a", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/cban"
-  ], 
-  [
-    "CBAY", 
-    "Cymabay Therapeutics Inc.", 
-    "12.7", 
-    "$186.52M", 
-    "n/a", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/cbay"
-  ], 
-  [
-    "CBDE", 
-    "CBD Energy Limited", 
-    "0.9", 
-    "$1.83M", 
-    "n/a", 
-    "Technology", 
-    "Semiconductors", 
-    "http://www.nasdaq.com/symbol/cbde"
-  ], 
-  [
-    "CBF", 
-    "Capital Bank Financial Corp.", 
-    "26.24", 
-    "$1.25B", 
-    "2012", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/cbf"
-  ], 
-  [
-    "CBFV", 
-    "CB Financial Services, Inc.", 
-    "20.22", 
-    "$88.68M", 
-    "n/a", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/cbfv"
-  ], 
-  [
-    "CBIN", 
-    "Community Bank Shares of Indiana, Inc.", 
-    "27.3499", 
-    "$94.24M", 
-    "n/a", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/cbin"
-  ], 
-  [
-    "CBLI", 
-    "Cleveland BioLabs, Inc.", 
-    "3.7", 
-    "$12.71M", 
-    "2006", 
-    "Health Care", 
-    "Biotechnology: Commercial Physical & Biological Resarch", 
-    "http://www.nasdaq.com/symbol/cbli"
-  ], 
-  [
-    "CBMG", 
-    "Cellular Biomedicine Group, Inc.", 
-    "25.79", 
-    "$256.51M", 
-    "n/a", 
-    "Health Care", 
-    "Biotechnology: Biological Products (No Diagnostic Substances)", 
-    "http://www.nasdaq.com/symbol/cbmg"
-  ], 
-  [
-    "CBMX", 
-    "CombiMatrix Corporation", 
-    "1.92", 
-    "$21.24M", 
-    "n/a", 
-    "Capital Goods", 
-    "Biotechnology: Laboratory Analytical Instruments", 
-    "http://www.nasdaq.com/symbol/cbmx"
-  ], 
-  [
-    "CBNJ", 
-    "Cape Bancorp, Inc.", 
-    "8.755", 
-    "$100.47M", 
-    "n/a", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/cbnj"
-  ], 
-  [
-    "CBNK", 
-    "Chicopee Bancorp, Inc.", 
-    "16.16", 
-    "$85.82M", 
-    "n/a", 
-    "Finance", 
-    "Banks", 
-    "http://www.nasdaq.com/symbol/cbnk"
-  ], 
-  [
-    "CBOE", 
-    "CBOE Holdings, Inc.", 
-    "62.61", 
-    "$5.28B", 
-    "2010", 
-    "Finance", 
-    "Investment Bankers/Brokers/Service", 
-    "http://www.nasdaq.com/symbol/cboe"
-  ], 
-  [
-    "CBPO", 
-    "China Biologic Products, Inc.", 
-    "77.25", 
-    "$1.9B", 
-    "n/a", 
-    "Health Care", 
-    "Biotechnology: Biological Products (No Diagnostic Substances)", 
-    "http://www.nasdaq.com/symbol/cbpo"
-  ], 
-  [
-    "CBRL", 
-    "Cracker Barrel Old Country Store, Inc.", 
-    "134.71", 
-    "$3.22B", 
-    "1981", 
-    "Consumer Services", 
-    "Restaurants", 
-    "http://www.nasdaq.com/symbol/cbrl"
-  ], 
-  [
-    "CBRX", 
-    "Columbia Laboratories, Inc.", 
-    "6", 
-    "$64.63M", 
-    "1988", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/cbrx"
-  ], 
-  [
-    "CBSH", 
-    "Commerce Bancshares, Inc.", 
-    "42.54", 
-    "$4.3B", 
-    "n/a", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/cbsh"
-  ], 
-  [
-    "CBSHP", 
-    "Commerce Bancshares, Inc.", 
-    "25.45", 
-    "$2.33B", 
-    "n/a", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/cbshp"
-  ], 
-  [
-    "CCBG", 
-    "Capital City Bank Group", 
-    "15.55", 
-    "$271.08M", 
-    "n/a", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/ccbg"
-  ], 
-  [
-    "CCCL", 
-    "China Ceramics Co., Ltd.", 
-    "0.8799", 
-    "$17.98M", 
-    "n/a", 
-    "Capital Goods", 
-    "Building Materials", 
-    "http://www.nasdaq.com/symbol/cccl"
-  ], 
-  [
-    "CCCR", 
-    "China Commercial Credit, Inc.", 
-    "2.9801", 
-    "$36.52M", 
-    "2013", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/cccr"
-  ], 
-  [
-    "CCIH", 
-    "ChinaCache International Holdings Ltd.", 
-    "10.46", 
-    "$244.81M", 
-    "2010", 
-    "Technology", 
-    "EDP Services", 
-    "http://www.nasdaq.com/symbol/ccih"
-  ], 
-  [
-    "CCLP", 
-    "CSI Compressco LP", 
-    "16.66", 
-    "$552.15M", 
-    "2011", 
-    "Energy", 
-    "Oilfield Services/Equipment", 
-    "http://www.nasdaq.com/symbol/cclp"
-  ], 
-  [
-    "CCMP", 
-    "Cabot Microelectronics Corporation", 
-    "51.52", 
-    "$1.24B", 
-    "2000", 
-    "Technology", 
-    "Semiconductors", 
-    "http://www.nasdaq.com/symbol/ccmp"
-  ], 
-  [
-    "CCNE", 
-    "CNB Financial Corporation", 
-    "17", 
-    "$244.27M", 
-    "n/a", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/ccne"
-  ], 
-  [
-    "CCOI", 
-    "Cogent Communications Holdings, Inc.", 
-    "39.4", 
-    "$1.82B", 
-    "n/a", 
-    "Technology", 
-    "Computer Software: Prepackaged Software", 
-    "http://www.nasdaq.com/symbol/ccoi"
-  ], 
-  [
-    "CCRN", 
-    "Cross Country Healthcare, Inc.", 
-    "12.19", 
-    "$381M", 
-    "2001", 
-    "Technology", 
-    "Professional Services", 
-    "http://www.nasdaq.com/symbol/ccrn"
-  ], 
-  [
-    "CCUR", 
-    "Concurrent Computer Corporation", 
-    "6.18", 
-    "$58.4M", 
-    "n/a", 
-    "Technology", 
-    "Computer Manufacturing", 
-    "http://www.nasdaq.com/symbol/ccur"
-  ], 
-  [
-    "CCXI", 
-    "ChemoCentryx, Inc.", 
-    "8.27", 
-    "$358.43M", 
-    "2012", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/ccxi"
-  ], 
-  [
-    "CDC", 
-    "Compass EMP US 100 High Dividend Enhanced Volatility Weighted ", 
-    "37.02", 
-    "$24.06M", 
-    "n/a", 
-    "n/a", 
-    "n/a", 
-    "http://www.nasdaq.com/symbol/cdc"
-  ], 
-  [
-    "CDK", 
-    "CDK Global, Inc.", 
-    "48", 
-    "$7.72B", 
-    "n/a", 
-    "Miscellaneous", 
-    "Business Services", 
-    "http://www.nasdaq.com/symbol/cdk"
-  ], 
-  [
-    "CDNA", 
-    "CareDx, Inc.", 
-    "6.1", 
-    "$72M", 
-    "2014", 
-    "Health Care", 
-    "Medical Specialities", 
-    "http://www.nasdaq.com/symbol/cdna"
-  ], 
-  [
-    "CDNS", 
-    "Cadence Design Systems, Inc.", 
-    "18.5", 
-    "$5.42B", 
-    "n/a", 
-    "Technology", 
-    "Computer Software: Prepackaged Software", 
-    "http://www.nasdaq.com/symbol/cdns"
-  ], 
-  [
-    "CDTI", 
-    "Clean Diesel Technologies, Inc.", 
-    "2.03", 
-    "$25.45M", 
-    "n/a", 
-    "Capital Goods", 
-    "Pollution Control Equipment", 
-    "http://www.nasdaq.com/symbol/cdti"
-  ], 
-  [
-    "CDW", 
-    "CDW Corporation", 
-    "37.75", 
-    "$6.5B", 
-    "2013", 
-    "Consumer Services", 
-    "Catalog/Specialty Distribution", 
-    "http://www.nasdaq.com/symbol/cdw"
-  ], 
-  [
-    "CDXS", 
-    "Codexis, Inc.", 
-    "3.47", 
-    "$137.24M", 
-    "2010", 
-    "Basic Industries", 
-    "Major Chemicals", 
-    "http://www.nasdaq.com/symbol/cdxs"
-  ], 
-  [
-    "CDZI", 
-    "Cadiz, Inc.", 
-    "10.87", 
-    "$176.15M", 
-    "n/a", 
-    "Public Utilities", 
-    "Water Supply", 
-    "http://www.nasdaq.com/symbol/cdzi"
-  ], 
-  [
-    "CECE", 
-    "CECO Environmental Corp.", 
-    "14.44", 
-    "$373.5M", 
-    "n/a", 
-    "Capital Goods", 
-    "Pollution Control Equipment", 
-    "http://www.nasdaq.com/symbol/cece"
-  ], 
-  [
-    "CECO", 
-    "Career Education Corporation", 
-    "5.27", 
-    "$354.56M", 
-    "1998", 
-    "Consumer Services", 
-    "Other Consumer Services", 
-    "http://www.nasdaq.com/symbol/ceco"
-  ], 
-  [
-    "CELG", 
-    "Celgene Corporation", 
-    "123.43", 
-    "$98.58B", 
-    "1987", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/celg"
-  ], 
-  [
-    "CELGZ", 
-    "Celgene Corporation", 
-    "3.18", 
-    "n/a", 
-    "n/a", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/celgz"
-  ], 
-  [
-    "CEMI", 
-    "Chembio Diagnostics, Inc.", 
-    "4.14", 
-    "$39.79M", 
-    "n/a", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/cemi"
-  ], 
-  [
-    "CEMP", 
-    "Cempra, Inc.", 
-    "29.61", 
-    "$1.27B", 
-    "2012", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/cemp"
-  ], 
-  [
-    "CENT", 
-    "Central Garden & Pet Company", 
-    "9.08", 
-    "$453.3M", 
-    "1993", 
-    "Consumer Durables", 
-    "Consumer Specialties", 
-    "http://www.nasdaq.com/symbol/cent"
-  ], 
-  [
-    "CENTA", 
-    "Central Garden & Pet Company", 
-    "9.72", 
-    "$485.25M", 
-    "n/a", 
-    "Consumer Durables", 
-    "Consumer Specialties", 
-    "http://www.nasdaq.com/symbol/centa"
-  ], 
-  [
-    "CENX", 
-    "Century Aluminum Company", 
-    "22.16", 
-    "$1.97B", 
-    "1996", 
-    "Basic Industries", 
-    "Aluminum", 
-    "http://www.nasdaq.com/symbol/cenx"
-  ], 
-  [
-    "CERE", 
-    "Ceres, Inc.", 
-    "0.373", 
-    "$18M", 
-    "2012", 
-    "Consumer Non-Durables", 
-    "Farming/Seeds/Milling", 
-    "http://www.nasdaq.com/symbol/cere"
-  ], 
-  [
-    "CERN", 
-    "Cerner Corporation", 
-    "72.075", 
-    "$24.69B", 
-    "1986", 
-    "Technology", 
-    "EDP Services", 
-    "http://www.nasdaq.com/symbol/cern"
-  ], 
-  [
-    "CERS", 
-    "Cerus Corporation", 
-    "5.5", 
-    "$430.48M", 
-    "1997", 
-    "Health Care", 
-    "Medical/Dental Instruments", 
-    "http://www.nasdaq.com/symbol/cers"
-  ], 
-  [
-    "CERU", 
-    "Cerulean Pharma Inc.", 
-    "6.63", 
-    "$133.43M", 
-    "2014", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/ceru"
-  ], 
-  [
-    "CETV", 
-    "Central European Media Enterprises Ltd.", 
-    "2.73", 
-    "$369.47M", 
-    "1994", 
-    "Consumer Services", 
-    "Broadcasting", 
-    "http://www.nasdaq.com/symbol/cetv"
-  ], 
-  [
-    "CEVA", 
-    "CEVA, Inc.", 
-    "19.2", 
-    "$387.68M", 
-    "n/a", 
-    "Technology", 
-    "Semiconductors", 
-    "http://www.nasdaq.com/symbol/ceva"
-  ], 
-  [
-    "CFA", 
-    "Compass EMP US 500 Volatility Weighted Index ETF", 
-    "37.636", 
-    "$7.53M", 
-    "n/a", 
-    "n/a", 
-    "n/a", 
-    "http://www.nasdaq.com/symbol/cfa"
-  ]
-]
\ No newline at end of file
diff --git a/examples/stocks/data/stock_data_5.json b/examples/stocks/data/stock_data_5.json
deleted file mode 100644
index 9ad8117..0000000
--- a/examples/stocks/data/stock_data_5.json
+++ /dev/null
@@ -1,1002 +0,0 @@
-[
-  [
-    "CFBK", 
-    "Central Federal Corporation", 
-    "1.3", 
-    "$20.57M", 
-    "n/a", 
-    "Finance", 
-    "Savings Institutions", 
-    "http://www.nasdaq.com/symbol/cfbk"
-  ], 
-  [
-    "CFFI", 
-    "C&F Financial Corporation", 
-    "36.14", 
-    "$123.03M", 
-    "n/a", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/cffi"
-  ], 
-  [
-    "CFFN", 
-    "Capitol Federal Financial, Inc.", 
-    "12.58", 
-    "$1.77B", 
-    "n/a", 
-    "Finance", 
-    "Savings Institutions", 
-    "http://www.nasdaq.com/symbol/cffn"
-  ], 
-  [
-    "CFGE", 
-    "Calamos Focus Growth ETF", 
-    "10.8499", 
-    "$28.21M", 
-    "n/a", 
-    "n/a", 
-    "n/a", 
-    "http://www.nasdaq.com/symbol/cfge"
-  ], 
-  [
-    "CFNB", 
-    "California First National Bancorp", 
-    "14.16", 
-    "$148.11M", 
-    "n/a", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/cfnb"
-  ], 
-  [
-    "CFNL", 
-    "Cardinal Financial Corporation", 
-    "19.35", 
-    "$619.78M", 
-    "1998", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/cfnl"
-  ], 
-  [
-    "CFO", 
-    "Compass EMP US 500 Enhanced Volatility Weighted Index ETF", 
-    "37.65", 
-    "$26.36M", 
-    "n/a", 
-    "n/a", 
-    "n/a", 
-    "http://www.nasdaq.com/symbol/cfo"
-  ], 
-  [
-    "CFRX", 
-    "ContraFect Corporation", 
-    "4.17", 
-    "$84.31M", 
-    "2014", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/cfrx"
-  ], 
-  [
-    "CFRXW", 
-    "ContraFect Corporation", 
-    "1.2501", 
-    "n/a", 
-    "2014", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/cfrxw"
-  ], 
-  [
-    "CFRXZ", 
-    "ContraFect Corporation", 
-    "0.6072", 
-    "n/a", 
-    "2014", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/cfrxz"
-  ], 
-  [
-    "CG", 
-    "The Carlyle Group L.P.", 
-    "27.04", 
-    "$8.6B", 
-    "2012", 
-    "Finance", 
-    "Investment Managers", 
-    "http://www.nasdaq.com/symbol/cg"
-  ], 
-  [
-    "CGEN", 
-    "Compugen Ltd.", 
-    "8.53", 
-    "$427.27M", 
-    "2000", 
-    "Health Care", 
-    "Biotechnology: Biological Products (No Diagnostic Substances)", 
-    "http://www.nasdaq.com/symbol/cgen"
-  ], 
-  [
-    "CGIX", 
-    "Cancer Genetics, Inc.", 
-    "8.95", 
-    "$87.03M", 
-    "n/a", 
-    "Health Care", 
-    "Medical Specialities", 
-    "http://www.nasdaq.com/symbol/cgix"
-  ], 
-  [
-    "CGNX", 
-    "Cognex Corporation", 
-    "42.62", 
-    "$3.69B", 
-    "1989", 
-    "Capital Goods", 
-    "Industrial Machinery/Components", 
-    "http://www.nasdaq.com/symbol/cgnx"
-  ], 
-  [
-    "CGO", 
-    "Calamos Global Total Return Fund", 
-    "13.48", 
-    "$112.6M", 
-    "2005", 
-    "n/a", 
-    "n/a", 
-    "http://www.nasdaq.com/symbol/cgo"
-  ], 
-  [
-    "CHCI", 
-    "Comstock Holding Companies, Inc.", 
-    "1.02", 
-    "$22.04M", 
-    "2004", 
-    "Capital Goods", 
-    "Homebuilding", 
-    "http://www.nasdaq.com/symbol/chci"
-  ], 
-  [
-    "CHCO", 
-    "City Holding Company", 
-    "46.14", 
-    "$702.14M", 
-    "n/a", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/chco"
-  ], 
-  [
-    "CHDN", 
-    "Churchill Downs, Incorporated", 
-    "104", 
-    "$1.8B", 
-    "n/a", 
-    "Consumer Services", 
-    "Services-Misc. Amusement & Recreation", 
-    "http://www.nasdaq.com/symbol/chdn"
-  ], 
-  [
-    "CHEF", 
-    "The Chefs&#39; Warehouse, Inc.", 
-    "23.39", 
-    "$586.1M", 
-    "2011", 
-    "Consumer Non-Durables", 
-    "Food Distributors", 
-    "http://www.nasdaq.com/symbol/chef"
-  ], 
-  [
-    "CHEKU", 
-    "Check-Cap Ltd.", 
-    "6.1", 
-    "n/a", 
-    "2015", 
-    "n/a", 
-    "n/a", 
-    "http://www.nasdaq.com/symbol/cheku"
-  ], 
-  [
-    "CHEV", 
-    "Cheviot Financial Corp", 
-    "14.4", 
-    "$96.59M", 
-    "2004", 
-    "Finance", 
-    "Savings Institutions", 
-    "http://www.nasdaq.com/symbol/chev"
-  ], 
-  [
-    "CHFC", 
-    "Chemical Financial Corporation", 
-    "30.09", 
-    "$985.83M", 
-    "n/a", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/chfc"
-  ], 
-  [
-    "CHFN", 
-    "Charter Financial Corp.", 
-    "11.53", 
-    "$194.43M", 
-    "2010", 
-    "Finance", 
-    "Savings Institutions", 
-    "http://www.nasdaq.com/symbol/chfn"
-  ], 
-  [
-    "CHI", 
-    "Calamos Convertible Opportunities and Income Fund", 
-    "13.3", 
-    "$910.47M", 
-    "2002", 
-    "n/a", 
-    "n/a", 
-    "http://www.nasdaq.com/symbol/chi"
-  ], 
-  [
-    "CHKE", 
-    "Cherokee Inc.", 
-    "18.36", 
-    "$154.83M", 
-    "n/a", 
-    "Consumer Non-Durables", 
-    "Apparel", 
-    "http://www.nasdaq.com/symbol/chke"
-  ], 
-  [
-    "CHKP", 
-    "Check Point Software Technologies Ltd.", 
-    "82.48", 
-    "$15.74B", 
-    "1996", 
-    "Technology", 
-    "Computer Software: Prepackaged Software", 
-    "http://www.nasdaq.com/symbol/chkp"
-  ], 
-  [
-    "CHLN", 
-    "China Housing & Land Development, Inc.", 
-    "0.3401", 
-    "$11.84M", 
-    "n/a", 
-    "Basic Industries", 
-    "Homebuilding", 
-    "http://www.nasdaq.com/symbol/chln"
-  ], 
-  [
-    "CHMG", 
-    "Chemung Financial Corp", 
-    "27.1199", 
-    "$125.26M", 
-    "n/a", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/chmg"
-  ], 
-  [
-    "CHNR", 
-    "China Natural Resources, Inc.", 
-    "2.1001", 
-    "$52.32M", 
-    "n/a", 
-    "Basic Industries", 
-    "Precious Metals", 
-    "http://www.nasdaq.com/symbol/chnr"
-  ], 
-  [
-    "CHOP", 
-    "China Gerui Advanced Materials Group Limited", 
-    "0.85", 
-    "$5.05M", 
-    "n/a", 
-    "Capital Goods", 
-    "Steel/Iron Ore", 
-    "http://www.nasdaq.com/symbol/chop"
-  ], 
-  [
-    "CHRS", 
-    "Coherus BioSciences, Inc.", 
-    "27.45", 
-    "$912.93M", 
-    "2014", 
-    "Health Care", 
-    "Biotechnology: Biological Products (No Diagnostic Substances)", 
-    "http://www.nasdaq.com/symbol/chrs"
-  ], 
-  [
-    "CHRW", 
-    "C.H. Robinson Worldwide, Inc.", 
-    "72.5", 
-    "$10.61B", 
-    "1997", 
-    "Transportation", 
-    "Oil Refining/Marketing", 
-    "http://www.nasdaq.com/symbol/chrw"
-  ], 
-  [
-    "CHSCL", 
-    "CHS Inc", 
-    "26.6368", 
-    "n/a", 
-    "n/a", 
-    "Consumer Services", 
-    "Farming/Seeds/Milling", 
-    "http://www.nasdaq.com/symbol/chscl"
-  ], 
-  [
-    "CHSCM", 
-    "CHS Inc", 
-    "25.46", 
-    "$483.74M", 
-    "n/a", 
-    "Consumer Services", 
-    "Farming/Seeds/Milling", 
-    "http://www.nasdaq.com/symbol/chscm"
-  ], 
-  [
-    "CHSCN", 
-    "CHS Inc", 
-    "26.6697", 
-    "$448.05M", 
-    "n/a", 
-    "Consumer Services", 
-    "Farming/Seeds/Milling", 
-    "http://www.nasdaq.com/symbol/chscn"
-  ], 
-  [
-    "CHSCO", 
-    "CHS Inc", 
-    "28.63", 
-    "$324.07M", 
-    "n/a", 
-    "Consumer Services", 
-    "Farming/Seeds/Milling", 
-    "http://www.nasdaq.com/symbol/chsco"
-  ], 
-  [
-    "CHSCP", 
-    "CHS Inc", 
-    "31", 
-    "$224.2M", 
-    "n/a", 
-    "Consumer Services", 
-    "Farming/Seeds/Milling", 
-    "http://www.nasdaq.com/symbol/chscp"
-  ], 
-  [
-    "CHTR", 
-    "Charter Communications, Inc.", 
-    "175.89", 
-    "$19.7B", 
-    "n/a", 
-    "Consumer Services", 
-    "Television Services", 
-    "http://www.nasdaq.com/symbol/chtr"
-  ], 
-  [
-    "CHUY", 
-    "Chuy&#39;s Holdings, Inc.", 
-    "23.35", 
-    "$383.9M", 
-    "2012", 
-    "Consumer Services", 
-    "Restaurants", 
-    "http://www.nasdaq.com/symbol/chuy"
-  ], 
-  [
-    "CHW", 
-    "Calamos Global Dynamic Income Fund", 
-    "8.99", 
-    "$530.47M", 
-    "2007", 
-    "n/a", 
-    "n/a", 
-    "http://www.nasdaq.com/symbol/chw"
-  ], 
-  [
-    "CHXF", 
-    "WisdomTree China Dividend ex-Financials Fund", 
-    "53.272", 
-    "$18.65M", 
-    "n/a", 
-    "n/a", 
-    "n/a", 
-    "http://www.nasdaq.com/symbol/chxf"
-  ], 
-  [
-    "CHY", 
-    "Calamos Convertible and High Income Fund", 
-    "14.63", 
-    "$1.06B", 
-    "2003", 
-    "n/a", 
-    "n/a", 
-    "http://www.nasdaq.com/symbol/chy"
-  ], 
-  [
-    "CHYR", 
-    "ChyronHego Corporation", 
-    "2.8116", 
-    "$113.54M", 
-    "n/a", 
-    "Consumer Services", 
-    "Professional Services", 
-    "http://www.nasdaq.com/symbol/chyr"
-  ], 
-  [
-    "CIDM", 
-    "Cinedigm Corp", 
-    "1.56", 
-    "$120.05M", 
-    "n/a", 
-    "Miscellaneous", 
-    "Business Services", 
-    "http://www.nasdaq.com/symbol/cidm"
-  ], 
-  [
-    "CIFC", 
-    "CIFC Corp.", 
-    "7.82", 
-    "$196.65M", 
-    "n/a", 
-    "Finance", 
-    "Finance: Consumer Services", 
-    "http://www.nasdaq.com/symbol/cifc"
-  ], 
-  [
-    "CINF", 
-    "Cincinnati Financial Corporation", 
-    "52.58", 
-    "$8.6B", 
-    "n/a", 
-    "Finance", 
-    "Property-Casualty Insurers", 
-    "http://www.nasdaq.com/symbol/cinf"
-  ], 
-  [
-    "CISAW", 
-    "CIS Acquisition Ltd.", 
-    "0.34", 
-    "n/a", 
-    "2013", 
-    "Basic Industries", 
-    "Major Chemicals", 
-    "http://www.nasdaq.com/symbol/cisaw"
-  ], 
-  [
-    "CISG", 
-    "CNinsure Inc.", 
-    "7.83", 
-    "$391.05M", 
-    "2007", 
-    "Finance", 
-    "Specialty Insurers", 
-    "http://www.nasdaq.com/symbol/cisg"
-  ], 
-  [
-    "CIZ", 
-    "Compass EMP Developed 500 Enhanced Volatility Weighted Index E", 
-    "35.89", 
-    "n/a", 
-    "n/a", 
-    "n/a", 
-    "n/a", 
-    "http://www.nasdaq.com/symbol/ciz"
-  ], 
-  [
-    "CIZN", 
-    "Citizens Holding Company", 
-    "18.94", 
-    "$92.38M", 
-    "n/a", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/cizn"
-  ], 
-  [
-    "CJJD", 
-    "China Jo-Jo Drugstores, Inc.", 
-    "2.7", 
-    "$41.54M", 
-    "n/a", 
-    "Consumer Durables", 
-    "Specialty Chemicals", 
-    "http://www.nasdaq.com/symbol/cjjd"
-  ], 
-  [
-    "CKEC", 
-    "Carmike Cinemas, Inc.", 
-    "31.52", 
-    "$769.68M", 
-    "n/a", 
-    "Consumer Services", 
-    "Movies/Entertainment", 
-    "http://www.nasdaq.com/symbol/ckec"
-  ], 
-  [
-    "CKSW", 
-    "ClickSoftware Technologies Ltd.", 
-    "8.24", 
-    "$267.76M", 
-    "2000", 
-    "Technology", 
-    "Computer Software: Prepackaged Software", 
-    "http://www.nasdaq.com/symbol/cksw"
-  ], 
-  [
-    "CLAC", 
-    "Capitol Acquisition Corp. II", 
-    "9.88", 
-    "$247M", 
-    "2013", 
-    "Finance", 
-    "Business Services", 
-    "http://www.nasdaq.com/symbol/clac"
-  ], 
-  [
-    "CLACU", 
-    "Capitol Acquisition Corp. II", 
-    "10", 
-    "$250M", 
-    "2013", 
-    "Finance", 
-    "Business Services", 
-    "http://www.nasdaq.com/symbol/clacu"
-  ], 
-  [
-    "CLACW", 
-    "Capitol Acquisition Corp. II", 
-    "0.3", 
-    "n/a", 
-    "2013", 
-    "Finance", 
-    "Business Services", 
-    "http://www.nasdaq.com/symbol/clacw"
-  ], 
-  [
-    "CLBH", 
-    "Carolina Bank Holdings Inc.", 
-    "9.57", 
-    "$32.87M", 
-    "n/a", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/clbh"
-  ], 
-  [
-    "CLCT", 
-    "Collectors Universe, Inc.", 
-    "23.09", 
-    "$205.13M", 
-    "1999", 
-    "Miscellaneous", 
-    "Business Services", 
-    "http://www.nasdaq.com/symbol/clct"
-  ], 
-  [
-    "CLDN", 
-    "Celladon Corporation", 
-    "16.3", 
-    "$379.87M", 
-    "2014", 
-    "Health Care", 
-    "Biotechnology: Biological Products (No Diagnostic Substances)", 
-    "http://www.nasdaq.com/symbol/cldn"
-  ], 
-  [
-    "CLDX", 
-    "Celldex Therapeutics, Inc.", 
-    "21.21", 
-    "$1.9B", 
-    "n/a", 
-    "Health Care", 
-    "Biotechnology: In Vitro & In Vivo Diagnostic Substances", 
-    "http://www.nasdaq.com/symbol/cldx"
-  ], 
-  [
-    "CLFD", 
-    "Clearfield, Inc.", 
-    "13.48", 
-    "$184.51M", 
-    "n/a", 
-    "Public Utilities", 
-    "Telecommunications Equipment", 
-    "http://www.nasdaq.com/symbol/clfd"
-  ], 
-  [
-    "CLIR", 
-    "ClearSign Combustion Corporation", 
-    "6.79", 
-    "$86.04M", 
-    "2012", 
-    "Capital Goods", 
-    "Industrial Machinery/Components", 
-    "http://www.nasdaq.com/symbol/clir"
-  ], 
-  [
-    "CLMS", 
-    "Calamos Asset Management, Inc.", 
-    "13.51", 
-    "$277.37M", 
-    "2004", 
-    "Finance", 
-    "Investment Bankers/Brokers/Service", 
-    "http://www.nasdaq.com/symbol/clms"
-  ], 
-  [
-    "CLMT", 
-    "Calumet Specialty Products Partners, L.P.", 
-    "26.45", 
-    "$1.84B", 
-    "2006", 
-    "Energy", 
-    "Integrated oil Companies", 
-    "http://www.nasdaq.com/symbol/clmt"
-  ], 
-  [
-    "CLNE", 
-    "Clean Energy Fuels Corp.", 
-    "4.92", 
-    "$443.07M", 
-    "2007", 
-    "Public Utilities", 
-    "Natural Gas Distribution", 
-    "http://www.nasdaq.com/symbol/clne"
-  ], 
-  [
-    "CLNT", 
-    "Cleantech Solutions International, Inc.", 
-    "3.23", 
-    "$12.47M", 
-    "n/a", 
-    "Technology", 
-    "Industrial Machinery/Components", 
-    "http://www.nasdaq.com/symbol/clnt"
-  ], 
-  [
-    "CLRB", 
-    "Cellectar Biosciences, Inc.", 
-    "2.86", 
-    "$21.63M", 
-    "n/a", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/clrb"
-  ], 
-  [
-    "CLRBW", 
-    "Cellectar Biosciences, Inc.", 
-    "0.56", 
-    "n/a", 
-    "n/a", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/clrbw"
-  ], 
-  [
-    "CLRO", 
-    "ClearOne, Inc.", 
-    "10.28", 
-    "$93.99M", 
-    "n/a", 
-    "Public Utilities", 
-    "Telecommunications Equipment", 
-    "http://www.nasdaq.com/symbol/clro"
-  ], 
-  [
-    "CLRX", 
-    "CollabRx, Inc.", 
-    "1.2", 
-    "$3.81M", 
-    "n/a", 
-    "Technology", 
-    "EDP Services", 
-    "http://www.nasdaq.com/symbol/clrx"
-  ], 
-  [
-    "CLSN", 
-    "Celsion Corporation", 
-    "3.15", 
-    "$62.93M", 
-    "n/a", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/clsn"
-  ], 
-  [
-    "CLTX", 
-    "Celsus Therapeutics Plc", 
-    "1.09", 
-    "$6.06M", 
-    "n/a", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/cltx"
-  ], 
-  [
-    "CLUB", 
-    "Town Sports International Holdings, Inc.", 
-    "7.01", 
-    "$170.32M", 
-    "2006", 
-    "Consumer Services", 
-    "Hotels/Resorts", 
-    "http://www.nasdaq.com/symbol/club"
-  ], 
-  [
-    "CLVS", 
-    "Clovis Oncology, Inc.", 
-    "73.8", 
-    "$2.51B", 
-    "2011", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/clvs"
-  ], 
-  [
-    "CLWT", 
-    "Euro Tech Holdings Company Limited", 
-    "2.6", 
-    "$5.8M", 
-    "1997", 
-    "Consumer Durables", 
-    "Diversified Electronic Products", 
-    "http://www.nasdaq.com/symbol/clwt"
-  ], 
-  [
-    "CMCO", 
-    "Columbus McKinnon Corporation", 
-    "25.71", 
-    "$513.63M", 
-    "1996", 
-    "Capital Goods", 
-    "Construction/Ag Equipment/Trucks", 
-    "http://www.nasdaq.com/symbol/cmco"
-  ], 
-  [
-    "CMCSA", 
-    "Comcast Corporation", 
-    "58.5", 
-    "$151.82B", 
-    "n/a", 
-    "Consumer Services", 
-    "Television Services", 
-    "http://www.nasdaq.com/symbol/cmcsa"
-  ], 
-  [
-    "CMCSK", 
-    "Comcast Corporation", 
-    "58.12", 
-    "$150.83B", 
-    "n/a", 
-    "Consumer Services", 
-    "Television Services", 
-    "http://www.nasdaq.com/symbol/cmcsk"
-  ], 
-  [
-    "CMCT", 
-    "CIM Commercial Trust Corporation", 
-    "16.98", 
-    "$1.66B", 
-    "n/a", 
-    "Consumer Services", 
-    "Real Estate Investment Trusts", 
-    "http://www.nasdaq.com/symbol/cmct"
-  ], 
-  [
-    "CME", 
-    "CME Group Inc.", 
-    "94.245", 
-    "$31.75B", 
-    "2002", 
-    "Finance", 
-    "Investment Bankers/Brokers/Service", 
-    "http://www.nasdaq.com/symbol/cme"
-  ], 
-  [
-    "CMFN", 
-    "CM Finance Inc", 
-    "13.71", 
-    "$187.37M", 
-    "2014", 
-    "n/a", 
-    "n/a", 
-    "http://www.nasdaq.com/symbol/cmfn"
-  ], 
-  [
-    "CMGE", 
-    "China Mobile Games and Entertainment Group Limited", 
-    "18.39", 
-    "$575.13M", 
-    "n/a", 
-    "Technology", 
-    "Computer Software: Prepackaged Software", 
-    "http://www.nasdaq.com/symbol/cmge"
-  ], 
-  [
-    "CMLS", 
-    "Cumulus Media Inc.", 
-    "3.91", 
-    "$907.9M", 
-    "1998", 
-    "Consumer Services", 
-    "Broadcasting", 
-    "http://www.nasdaq.com/symbol/cmls"
-  ], 
-  [
-    "CMPR", 
-    "Cimpress N.V", 
-    "82.93", 
-    "$2.7B", 
-    "n/a", 
-    "Miscellaneous", 
-    "Publishing", 
-    "http://www.nasdaq.com/symbol/cmpr"
-  ], 
-  [
-    "CMRX", 
-    "Chimerix, Inc.", 
-    "41.75", 
-    "$1.7B", 
-    "2013", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/cmrx"
-  ], 
-  [
-    "CMSB", 
-    "CMS Bancorp, Inc.", 
-    "13.03", 
-    "$24.27M", 
-    "n/a", 
-    "Finance", 
-    "Banks", 
-    "http://www.nasdaq.com/symbol/cmsb"
-  ], 
-  [
-    "CMTL", 
-    "Comtech Telecommunications Corp.", 
-    "35.65", 
-    "$578.07M", 
-    "n/a", 
-    "Technology", 
-    "Radio And Television Broadcasting And Communications Equipment", 
-    "http://www.nasdaq.com/symbol/cmtl"
-  ], 
-  [
-    "CNAT", 
-    "Conatus Pharmaceuticals Inc.", 
-    "6.32", 
-    "$99.16M", 
-    "2013", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/cnat"
-  ], 
-  [
-    "CNBKA", 
-    "Century Bancorp, Inc.", 
-    "38.43", 
-    "$213.97M", 
-    "1987", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/cnbka"
-  ], 
-  [
-    "CNCE", 
-    "Concert Pharmaceuticals, Inc.", 
-    "14.51", 
-    "$263.88M", 
-    "2014", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/cnce"
-  ], 
-  [
-    "CNDO", 
-    "Coronado Biosciences, Inc.", 
-    "2.41", 
-    "$106.79M", 
-    "n/a", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/cndo"
-  ], 
-  [
-    "CNET", 
-    "ChinaNet Online Holdings, Inc.", 
-    "1.59", 
-    "$45.92M", 
-    "n/a", 
-    "Technology", 
-    "Advertising", 
-    "http://www.nasdaq.com/symbol/cnet"
-  ], 
-  [
-    "CNIT", 
-    "China Information Technology, Inc.", 
-    "3.3201", 
-    "$99.52M", 
-    "n/a", 
-    "Technology", 
-    "Computer Software: Prepackaged Software", 
-    "http://www.nasdaq.com/symbol/cnit"
-  ], 
-  [
-    "CNLM", 
-    "CB Pharma Acquisition Corp.", 
-    "9.75", 
-    "$51.53M", 
-    "2015", 
-    "Finance", 
-    "Business Services", 
-    "http://www.nasdaq.com/symbol/cnlm"
-  ], 
-  [
-    "CNLMR", 
-    "CB Pharma Acquisition Corp.", 
-    "0.28", 
-    "n/a", 
-    "2015", 
-    "Finance", 
-    "Business Services", 
-    "http://www.nasdaq.com/symbol/cnlmr"
-  ], 
-  [
-    "CNLMU", 
-    "CB Pharma Acquisition Corp.", 
-    "10.1765", 
-    "n/a", 
-    "2014", 
-    "n/a", 
-    "n/a", 
-    "http://www.nasdaq.com/symbol/cnlmu"
-  ], 
-  [
-    "CNLMW", 
-    "CB Pharma Acquisition Corp.", 
-    "0.19", 
-    "n/a", 
-    "2015", 
-    "Finance", 
-    "Business Services", 
-    "http://www.nasdaq.com/symbol/cnlmw"
-  ], 
-  [
-    "CNMD", 
-    "CONMED Corporation", 
-    "51.06", 
-    "$1.41B", 
-    "1987", 
-    "Health Care", 
-    "Biotechnology: Electromedical & Electrotherapeutic Apparatus", 
-    "http://www.nasdaq.com/symbol/cnmd"
-  ], 
-  [
-    "CNOB", 
-    "ConnectOne Bancorp, Inc.", 
-    "18.46", 
-    "$547.62M", 
-    "n/a", 
-    "n/a", 
-    "n/a", 
-    "http://www.nasdaq.com/symbol/cnob"
-  ], 
-  [
-    "CNSI", 
-    "Comverse Inc.", 
-    "18.47", 
-    "$404.69M", 
-    "n/a", 
-    "Miscellaneous", 
-    "Business Services", 
-    "http://www.nasdaq.com/symbol/cnsi"
-  ]
-]
\ No newline at end of file
diff --git a/examples/stocks/data/stock_data_6.json b/examples/stocks/data/stock_data_6.json
deleted file mode 100644
index 215ca7e..0000000
--- a/examples/stocks/data/stock_data_6.json
+++ /dev/null
@@ -1,1002 +0,0 @@
-[
-  [
-    "CNSL", 
-    "Consolidated Communications Holdings, Inc.", 
-    "23.94", 
-    "$1.21B", 
-    "2005", 
-    "Public Utilities", 
-    "Telecommunications Equipment", 
-    "http://www.nasdaq.com/symbol/cnsl"
-  ], 
-  [
-    "CNTF", 
-    "China TechFaith Wireless Communication Technology Limited", 
-    "1.02", 
-    "$53.99M", 
-    "2005", 
-    "Miscellaneous", 
-    "Business Services", 
-    "http://www.nasdaq.com/symbol/cntf"
-  ], 
-  [
-    "CNTY", 
-    "Century Casinos, Inc.", 
-    "6.09", 
-    "$148.48M", 
-    "n/a", 
-    "Consumer Services", 
-    "Hotels/Resorts", 
-    "http://www.nasdaq.com/symbol/cnty"
-  ], 
-  [
-    "CNV", 
-    "Cnova N.V.", 
-    "6.23", 
-    "$2.73B", 
-    "2014", 
-    "Consumer Services", 
-    "Catalog/Specialty Distribution", 
-    "http://www.nasdaq.com/symbol/cnv"
-  ], 
-  [
-    "CNXR", 
-    "Connecture, Inc.", 
-    "9", 
-    "$195.13M", 
-    "2014", 
-    "Technology", 
-    "Computer Software: Prepackaged Software", 
-    "http://www.nasdaq.com/symbol/cnxr"
-  ], 
-  [
-    "CNYD", 
-    "China Yida Holding, Co.", 
-    "2.2101", 
-    "$8.65M", 
-    "n/a", 
-    "Consumer Services", 
-    "Advertising", 
-    "http://www.nasdaq.com/symbol/cnyd"
-  ], 
-  [
-    "COB", 
-    "CommunityOne Bancorp", 
-    "10.6", 
-    "$256.38M", 
-    "n/a", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/cob"
-  ], 
-  [
-    "COBK", 
-    "Colonial Financial Services, Inc.", 
-    "13.26", 
-    "$51.19M", 
-    "n/a", 
-    "Finance", 
-    "Savings Institutions", 
-    "http://www.nasdaq.com/symbol/cobk"
-  ], 
-  [
-    "COBZ", 
-    "CoBiz Financial Inc.", 
-    "11.4", 
-    "$464.91M", 
-    "1998", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/cobz"
-  ], 
-  [
-    "COHR", 
-    "Coherent, Inc.", 
-    "64.57", 
-    "$1.6B", 
-    "n/a", 
-    "Capital Goods", 
-    "Biotechnology: Laboratory Analytical Instruments", 
-    "http://www.nasdaq.com/symbol/cohr"
-  ], 
-  [
-    "COHU", 
-    "Cohu, Inc.", 
-    "11.06", 
-    "$282.41M", 
-    "n/a", 
-    "Capital Goods", 
-    "Electrical Products", 
-    "http://www.nasdaq.com/symbol/cohu"
-  ], 
-  [
-    "COKE", 
-    "Coca-Cola Bottling Co. Consolidated", 
-    "102.24", 
-    "$947.9M", 
-    "1972", 
-    "Consumer Non-Durables", 
-    "Beverages (Production/Distribution)", 
-    "http://www.nasdaq.com/symbol/coke"
-  ], 
-  [
-    "COLB", 
-    "Columbia Banking System, Inc.", 
-    "28.18", 
-    "$1.5B", 
-    "1992", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/colb"
-  ], 
-  [
-    "COLM", 
-    "Columbia Sportswear Company", 
-    "55.9", 
-    "$3.9B", 
-    "1998", 
-    "Consumer Non-Durables", 
-    "Apparel", 
-    "http://www.nasdaq.com/symbol/colm"
-  ], 
-  [
-    "COMM", 
-    "CommScope Holding Company, Inc.", 
-    "31.1", 
-    "$5.84B", 
-    "2013", 
-    "Technology", 
-    "Radio And Television Broadcasting And Communications Equipment", 
-    "http://www.nasdaq.com/symbol/comm"
-  ], 
-  [
-    "COMT", 
-    "iShares Commodities Select Strategy ETF", 
-    "40.93", 
-    "n/a", 
-    "n/a", 
-    "n/a", 
-    "n/a", 
-    "http://www.nasdaq.com/symbol/comt"
-  ], 
-  [
-    "CONE", 
-    "CyrusOne Inc", 
-    "30.08", 
-    "$1.16B", 
-    "2013", 
-    "Consumer Services", 
-    "Real Estate Investment Trusts", 
-    "http://www.nasdaq.com/symbol/cone"
-  ], 
-  [
-    "CONN", 
-    "Conn&#39;s, Inc.", 
-    "25.6", 
-    "$929.21M", 
-    "2003", 
-    "Consumer Services", 
-    "Consumer Electronics/Video Chains", 
-    "http://www.nasdaq.com/symbol/conn"
-  ], 
-  [
-    "COOL", 
-    "Majesco Entertainment Company", 
-    "1.14", 
-    "$8.06M", 
-    "n/a", 
-    "Technology", 
-    "Computer Software: Prepackaged Software", 
-    "http://www.nasdaq.com/symbol/cool"
-  ], 
-  [
-    "CORE", 
-    "Core-Mark Holding Company, Inc.", 
-    "69.35", 
-    "$1.6B", 
-    "n/a", 
-    "Consumer Non-Durables", 
-    "Food Distributors", 
-    "http://www.nasdaq.com/symbol/core"
-  ], 
-  [
-    "CORI", 
-    "Corium International, Inc.", 
-    "7.03", 
-    "$127.04M", 
-    "2014", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/cori"
-  ], 
-  [
-    "CORT", 
-    "Corcept Therapeutics Incorporated", 
-    "3.37", 
-    "$341.01M", 
-    "1982", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/cort"
-  ], 
-  [
-    "COSI", 
-    "Cosi, Inc.", 
-    "2.59", 
-    "$103.97M", 
-    "2002", 
-    "Consumer Services", 
-    "Restaurants", 
-    "http://www.nasdaq.com/symbol/cosi"
-  ], 
-  [
-    "COST", 
-    "Costco Wholesale Corporation", 
-    "147.535", 
-    "$64.99B", 
-    "n/a", 
-    "Consumer Services", 
-    "Department/Specialty Retail Stores", 
-    "http://www.nasdaq.com/symbol/cost"
-  ], 
-  [
-    "COVS", 
-    "Covisint Corporation", 
-    "2.55", 
-    "$99.48M", 
-    "2013", 
-    "Technology", 
-    "EDP Services", 
-    "http://www.nasdaq.com/symbol/covs"
-  ], 
-  [
-    "COWN", 
-    "Cowen Group, Inc.", 
-    "4.74", 
-    "$538.63M", 
-    "n/a", 
-    "Finance", 
-    "Investment Bankers/Brokers/Service", 
-    "http://www.nasdaq.com/symbol/cown"
-  ], 
-  [
-    "COWNL", 
-    "Cowen Group, Inc.", 
-    "26.438", 
-    "n/a", 
-    "n/a", 
-    "Finance", 
-    "Investment Bankers/Brokers/Service", 
-    "http://www.nasdaq.com/symbol/cownl"
-  ], 
-  [
-    "CPAH", 
-    "CounterPath Corporation", 
-    "0.4999", 
-    "$21.21M", 
-    "n/a", 
-    "Technology", 
-    "Computer Software: Prepackaged Software", 
-    "http://www.nasdaq.com/symbol/cpah"
-  ], 
-  [
-    "CPGI", 
-    "China Shengda Packaging Group, Inc.", 
-    "1.01", 
-    "$39.18M", 
-    "2010", 
-    "Consumer Durables", 
-    "Containers/Packaging", 
-    "http://www.nasdaq.com/symbol/cpgi"
-  ], 
-  [
-    "CPHC", 
-    "Canterbury Park Holding Corporation", 
-    "10.4101", 
-    "$43.74M", 
-    "n/a", 
-    "Consumer Services", 
-    "Services-Misc. Amusement & Recreation", 
-    "http://www.nasdaq.com/symbol/cphc"
-  ], 
-  [
-    "CPHD", 
-    "CEPHEID", 
-    "58.59", 
-    "$4.13B", 
-    "2000", 
-    "Capital Goods", 
-    "Biotechnology: Laboratory Analytical Instruments", 
-    "http://www.nasdaq.com/symbol/cphd"
-  ], 
-  [
-    "CPHR", 
-    "Cipher Pharmaceuticals Inc.", 
-    "13.01", 
-    "$336.84M", 
-    "n/a", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/cphr"
-  ], 
-  [
-    "CPIX", 
-    "Cumberland Pharmaceuticals Inc.", 
-    "5.87", 
-    "$101.89M", 
-    "2009", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/cpix"
-  ], 
-  [
-    "CPLA", 
-    "Capella Education Company", 
-    "65.37", 
-    "$798.48M", 
-    "2006", 
-    "Consumer Services", 
-    "Other Consumer Services", 
-    "http://www.nasdaq.com/symbol/cpla"
-  ], 
-  [
-    "CPLP", 
-    "Capital Product Partners L.P.", 
-    "9.3", 
-    "$988.04M", 
-    "2007", 
-    "Transportation", 
-    "Marine Transportation", 
-    "http://www.nasdaq.com/symbol/cplp"
-  ], 
-  [
-    "CPRT", 
-    "Copart, Inc.", 
-    "38", 
-    "$4.8B", 
-    "1994", 
-    "Consumer Durables", 
-    "Automotive Aftermarket", 
-    "http://www.nasdaq.com/symbol/cprt"
-  ], 
-  [
-    "CPRX", 
-    "Catalyst Pharmaceutical Partners, Inc.", 
-    "3.4", 
-    "$274.1M", 
-    "2006", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/cprx"
-  ], 
-  [
-    "CPSH", 
-    "CPS Technologies Corp.", 
-    "3.04", 
-    "$39.95M", 
-    "n/a", 
-    "Capital Goods", 
-    "Building Materials", 
-    "http://www.nasdaq.com/symbol/cpsh"
-  ], 
-  [
-    "CPSI", 
-    "Computer Programs and Systems, Inc.", 
-    "52.63", 
-    "$589.92M", 
-    "2002", 
-    "Technology", 
-    "EDP Services", 
-    "http://www.nasdaq.com/symbol/cpsi"
-  ], 
-  [
-    "CPSS", 
-    "Consumer Portfolio Services, Inc.", 
-    "7.04", 
-    "$178.61M", 
-    "1992", 
-    "Finance", 
-    "Finance: Consumer Services", 
-    "http://www.nasdaq.com/symbol/cpss"
-  ], 
-  [
-    "CPST", 
-    "Capstone Turbine Corporation", 
-    "0.7009", 
-    "$231.51M", 
-    "2000", 
-    "Energy", 
-    "Industrial Machinery/Components", 
-    "http://www.nasdaq.com/symbol/cpst"
-  ], 
-  [
-    "CPTA", 
-    "Capitala Finance Corp.", 
-    "18.64", 
-    "$241.84M", 
-    "2013", 
-    "n/a", 
-    "n/a", 
-    "http://www.nasdaq.com/symbol/cpta"
-  ], 
-  [
-    "CPXX", 
-    "Celator Pharmaceuticals Inc.", 
-    "2.9", 
-    "$97.68M", 
-    "n/a", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/cpxx"
-  ], 
-  [
-    "CRAI", 
-    "CRA International,Inc.", 
-    "31.82", 
-    "$303.23M", 
-    "1998", 
-    "Miscellaneous", 
-    "Other Consumer Services", 
-    "http://www.nasdaq.com/symbol/crai"
-  ], 
-  [
-    "CRAY", 
-    "Cray Inc", 
-    "34.21", 
-    "$1.4B", 
-    "n/a", 
-    "Technology", 
-    "Computer Manufacturing", 
-    "http://www.nasdaq.com/symbol/cray"
-  ], 
-  [
-    "CRDC", 
-    "Cardica, Inc.", 
-    "0.59", 
-    "$52.48M", 
-    "2006", 
-    "Health Care", 
-    "Medical/Dental Instruments", 
-    "http://www.nasdaq.com/symbol/crdc"
-  ], 
-  [
-    "CRDS", 
-    "Crossroads Systems, Inc.", 
-    "2.45", 
-    "$39.28M", 
-    "1999", 
-    "Technology", 
-    "Computer peripheral equipment", 
-    "http://www.nasdaq.com/symbol/crds"
-  ], 
-  [
-    "CRDT", 
-    "WisdomTree Strategic Corporate Bond Fund", 
-    "75.29", 
-    "$7.53M", 
-    "n/a", 
-    "n/a", 
-    "n/a", 
-    "http://www.nasdaq.com/symbol/crdt"
-  ], 
-  [
-    "CREE", 
-    "Cree, Inc.", 
-    "39.185", 
-    "$4.37B", 
-    "1993", 
-    "Technology", 
-    "Semiconductors", 
-    "http://www.nasdaq.com/symbol/cree"
-  ], 
-  [
-    "CREG", 
-    "China Recycling Energy Corporation", 
-    "0.7198", 
-    "$59.75M", 
-    "n/a", 
-    "Miscellaneous", 
-    "Business Services", 
-    "http://www.nasdaq.com/symbol/creg"
-  ], 
-  [
-    "CRESW", 
-    "Cresud S.A.C.I.F. y A.", 
-    "0.008", 
-    "n/a", 
-    "n/a", 
-    "Finance", 
-    "Real Estate", 
-    "http://www.nasdaq.com/symbol/cresw"
-  ], 
-  [
-    "CRESY", 
-    "Cresud S.A.C.I.F. y A.", 
-    "11.09", 
-    "$6.42M", 
-    "1997", 
-    "Finance", 
-    "Real Estate", 
-    "http://www.nasdaq.com/symbol/cresy"
-  ], 
-  [
-    "CRIS", 
-    "Curis, Inc.", 
-    "3.4", 
-    "$292.42M", 
-    "n/a", 
-    "Health Care", 
-    "Biotechnology: Biological Products (No Diagnostic Substances)", 
-    "http://www.nasdaq.com/symbol/cris"
-  ], 
-  [
-    "CRME", 
-    "Cardiome Pharma Corporation", 
-    "9.94", 
-    "$164.91M", 
-    "n/a", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/crme"
-  ], 
-  [
-    "CRMT", 
-    "America&#39;s Car-Mart, Inc.", 
-    "53.63", 
-    "$462.44M", 
-    "n/a", 
-    "Consumer Durables", 
-    "Automotive Aftermarket", 
-    "http://www.nasdaq.com/symbol/crmt"
-  ], 
-  [
-    "CRNT", 
-    "Ceragon Networks Ltd.", 
-    "1.2", 
-    "$96.73M", 
-    "n/a", 
-    "Technology", 
-    "Radio And Television Broadcasting And Communications Equipment", 
-    "http://www.nasdaq.com/symbol/crnt"
-  ], 
-  [
-    "CROX", 
-    "Crocs, Inc.", 
-    "10.75", 
-    "$886.84M", 
-    "2006", 
-    "Consumer Non-Durables", 
-    "Shoe Manufacturing", 
-    "http://www.nasdaq.com/symbol/crox"
-  ], 
-  [
-    "CRRC", 
-    "Courier Corporation", 
-    "23.51", 
-    "$270.94M", 
-    "n/a", 
-    "Consumer Services", 
-    "Publishing", 
-    "http://www.nasdaq.com/symbol/crrc"
-  ], 
-  [
-    "CRRS", 
-    "Corporate Resource Services, Inc.", 
-    "0.22", 
-    "$34.76M", 
-    "n/a", 
-    "Technology", 
-    "Professional Services", 
-    "http://www.nasdaq.com/symbol/crrs"
-  ], 
-  [
-    "CRTN", 
-    "Cartesian, Inc.", 
-    "3.89", 
-    "$34.26M", 
-    "n/a", 
-    "Consumer Services", 
-    "Professional Services", 
-    "http://www.nasdaq.com/symbol/crtn"
-  ], 
-  [
-    "CRTO", 
-    "Criteo S.A.", 
-    "44.63", 
-    "$2.64B", 
-    "2013", 
-    "Technology", 
-    "Advertising", 
-    "http://www.nasdaq.com/symbol/crto"
-  ], 
-  [
-    "CRUS", 
-    "Cirrus Logic, Inc.", 
-    "29.82", 
-    "$1.87B", 
-    "1989", 
-    "Technology", 
-    "Semiconductors", 
-    "http://www.nasdaq.com/symbol/crus"
-  ], 
-  [
-    "CRVL", 
-    "CorVel Corp.", 
-    "34.65", 
-    "$706.54M", 
-    "n/a", 
-    "Finance", 
-    "Specialty Insurers", 
-    "http://www.nasdaq.com/symbol/crvl"
-  ], 
-  [
-    "CRWN", 
-    "Crown Media Holdings, Inc.", 
-    "3.45", 
-    "$1.24B", 
-    "2000", 
-    "Consumer Services", 
-    "Television Services", 
-    "http://www.nasdaq.com/symbol/crwn"
-  ], 
-  [
-    "CRWS", 
-    "Crown Crafts, Inc.", 
-    "8.319", 
-    "$83.72M", 
-    "n/a", 
-    "Basic Industries", 
-    "Textiles", 
-    "http://www.nasdaq.com/symbol/crws"
-  ], 
-  [
-    "CRZO", 
-    "Carrizo Oil & Gas, Inc.", 
-    "52.26", 
-    "$2.41B", 
-    "1997", 
-    "Energy", 
-    "Oil & Gas Production", 
-    "http://www.nasdaq.com/symbol/crzo"
-  ], 
-  [
-    "CSBK", 
-    "Clifton Bancorp Inc.", 
-    "13.42", 
-    "$364.38M", 
-    "n/a", 
-    "Finance", 
-    "Savings Institutions", 
-    "http://www.nasdaq.com/symbol/csbk"
-  ], 
-  [
-    "CSCD", 
-    "Cascade Microtech, Inc.", 
-    "13.43", 
-    "$219.87M", 
-    "2004", 
-    "Capital Goods", 
-    "Electrical Products", 
-    "http://www.nasdaq.com/symbol/cscd"
-  ], 
-  [
-    "CSCO", 
-    "Cisco Systems, Inc.", 
-    "29.61", 
-    "$151.15B", 
-    "1990", 
-    "Technology", 
-    "Computer Communications Equipment", 
-    "http://www.nasdaq.com/symbol/csco"
-  ], 
-  [
-    "CSF", 
-    "Compass EMP US Discovery 500 Enhanced Volatility Weighted Fund", 
-    "38.39", 
-    "$7.68M", 
-    "n/a", 
-    "n/a", 
-    "n/a", 
-    "http://www.nasdaq.com/symbol/csf"
-  ], 
-  [
-    "CSFL", 
-    "CenterState Banks, Inc.", 
-    "11.88", 
-    "$537.18M", 
-    "n/a", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/csfl"
-  ], 
-  [
-    "CSGP", 
-    "CoStar Group, Inc.", 
-    "191.24", 
-    "$6.19B", 
-    "1998", 
-    "Miscellaneous", 
-    "Business Services", 
-    "http://www.nasdaq.com/symbol/csgp"
-  ], 
-  [
-    "CSGS", 
-    "CSG Systems International, Inc.", 
-    "30.41", 
-    "$1.04B", 
-    "1996", 
-    "Technology", 
-    "EDP Services", 
-    "http://www.nasdaq.com/symbol/csgs"
-  ], 
-  [
-    "CSII", 
-    "Cardiovascular Systems, Inc.", 
-    "35.31", 
-    "$1.12B", 
-    "1981", 
-    "Health Care", 
-    "Medical/Dental Instruments", 
-    "http://www.nasdaq.com/symbol/csii"
-  ], 
-  [
-    "CSIQ", 
-    "Canadian Solar Inc.", 
-    "28.95", 
-    "$1.57B", 
-    "2006", 
-    "Technology", 
-    "Semiconductors", 
-    "http://www.nasdaq.com/symbol/csiq"
-  ], 
-  [
-    "CSOD", 
-    "Cornerstone OnDemand, Inc.", 
-    "35.04", 
-    "$1.88B", 
-    "2011", 
-    "Technology", 
-    "Computer Software: Prepackaged Software", 
-    "http://www.nasdaq.com/symbol/csod"
-  ], 
-  [
-    "CSPI", 
-    "CSP Inc.", 
-    "7.73", 
-    "$28.26M", 
-    "1982", 
-    "Technology", 
-    "EDP Services", 
-    "http://www.nasdaq.com/symbol/cspi"
-  ], 
-  [
-    "CSQ", 
-    "Calamos Strategic Total Return Fund", 
-    "11.37", 
-    "$1.76B", 
-    "2004", 
-    "n/a", 
-    "n/a", 
-    "http://www.nasdaq.com/symbol/csq"
-  ], 
-  [
-    "CSRE", 
-    "CSR plc", 
-    "53.46", 
-    "$2.21B", 
-    "n/a", 
-    "Technology", 
-    "Semiconductors", 
-    "http://www.nasdaq.com/symbol/csre"
-  ], 
-  [
-    "CSTE", 
-    "CaesarStone Sdot-Yam Ltd.", 
-    "64.16", 
-    "$2.25B", 
-    "2012", 
-    "Capital Goods", 
-    "Building Materials", 
-    "http://www.nasdaq.com/symbol/cste"
-  ], 
-  [
-    "CSUN", 
-    "China Sunergy Co., Ltd.", 
-    "1.83", 
-    "$24.47M", 
-    "2007", 
-    "Technology", 
-    "Semiconductors", 
-    "http://www.nasdaq.com/symbol/csun"
-  ], 
-  [
-    "CSWC", 
-    "Capital Southwest Corporation", 
-    "48.93", 
-    "$760.54M", 
-    "n/a", 
-    "n/a", 
-    "n/a", 
-    "http://www.nasdaq.com/symbol/cswc"
-  ], 
-  [
-    "CTAS", 
-    "Cintas Corporation", 
-    "82.47", 
-    "$9.68B", 
-    "1983", 
-    "Consumer Non-Durables", 
-    "Apparel", 
-    "http://www.nasdaq.com/symbol/ctas"
-  ], 
-  [
-    "CTBI", 
-    "Community Trust Bancorp, Inc.", 
-    "32.49", 
-    "$566.54M", 
-    "n/a", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/ctbi"
-  ], 
-  [
-    "CTCM", 
-    "CTC Media, Inc.", 
-    "4.04", 
-    "$629.28M", 
-    "2006", 
-    "Consumer Services", 
-    "Broadcasting", 
-    "http://www.nasdaq.com/symbol/ctcm"
-  ], 
-  [
-    "CTCT", 
-    "Constant Contact, Inc.", 
-    "41.91", 
-    "$1.33B", 
-    "2007", 
-    "Technology", 
-    "Advertising", 
-    "http://www.nasdaq.com/symbol/ctct"
-  ], 
-  [
-    "CTG", 
-    "Computer Task Group, Incorporated", 
-    "8.27", 
-    "$153.44M", 
-    "n/a", 
-    "Technology", 
-    "EDP Services", 
-    "http://www.nasdaq.com/symbol/ctg"
-  ], 
-  [
-    "CTHR", 
-    "Charles & Colvard Ltd", 
-    "1.5884", 
-    "$32.34M", 
-    "1997", 
-    "Consumer Durables", 
-    "Consumer Specialties", 
-    "http://www.nasdaq.com/symbol/cthr"
-  ], 
-  [
-    "CTIB", 
-    "CTI Industries Corporation", 
-    "3.9999", 
-    "$13.2M", 
-    "1997", 
-    "Basic Industries", 
-    "Specialty Chemicals", 
-    "http://www.nasdaq.com/symbol/ctib"
-  ], 
-  [
-    "CTIC", 
-    "CTI BioPharma Corp.", 
-    "2.28", 
-    "$409.92M", 
-    "1997", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/ctic"
-  ], 
-  [
-    "CTRE", 
-    "CareTrust REIT, Inc.", 
-    "13.15", 
-    "$415.08M", 
-    "n/a", 
-    "Consumer Services", 
-    "Real Estate Investment Trusts", 
-    "http://www.nasdaq.com/symbol/ctre"
-  ], 
-  [
-    "CTRL", 
-    "Control4 Corporation", 
-    "13.21", 
-    "$315.47M", 
-    "2013", 
-    "Capital Goods", 
-    "Electrical Products", 
-    "http://www.nasdaq.com/symbol/ctrl"
-  ], 
-  [
-    "CTRN", 
-    "Citi Trends, Inc.", 
-    "26.42", 
-    "$411.58M", 
-    "2005", 
-    "Consumer Services", 
-    "Clothing/Shoe/Accessory Stores", 
-    "http://www.nasdaq.com/symbol/ctrn"
-  ], 
-  [
-    "CTRP", 
-    "Ctrip.com International, Ltd.", 
-    "46.95", 
-    "$6.35B", 
-    "2003", 
-    "Miscellaneous", 
-    "Business Services", 
-    "http://www.nasdaq.com/symbol/ctrp"
-  ], 
-  [
-    "CTRX", 
-    "Catamaran Corporation", 
-    "52.69", 
-    "$10.93B", 
-    "n/a", 
-    "Finance", 
-    "Specialty Insurers", 
-    "http://www.nasdaq.com/symbol/ctrx"
-  ], 
-  [
-    "CTSH", 
-    "Cognizant Technology Solutions Corporation", 
-    "63.05", 
-    "$38.39B", 
-    "1998", 
-    "Technology", 
-    "EDP Services", 
-    "http://www.nasdaq.com/symbol/ctsh"
-  ], 
-  [
-    "CTSO", 
-    "Cytosorbents Corporation", 
-    "9.95", 
-    "$244M", 
-    "n/a", 
-    "Health Care", 
-    "Medical/Dental Instruments", 
-    "http://www.nasdaq.com/symbol/ctso"
-  ], 
-  [
-    "CTWS", 
-    "Connecticut Water Service, Inc.", 
-    "37.47", 
-    "$416.39M", 
-    "n/a", 
-    "Public Utilities", 
-    "Water Supply", 
-    "http://www.nasdaq.com/symbol/ctws"
-  ], 
-  [
-    "CTXS", 
-    "Citrix Systems, Inc.", 
-    "64.92", 
-    "$10.38B", 
-    "1995", 
-    "Technology", 
-    "Computer Software: Prepackaged Software", 
-    "http://www.nasdaq.com/symbol/ctxs"
-  ], 
-  [
-    "CU", 
-    "ISE Global Copper Index First Trust", 
-    "17.57", 
-    "$21.96M", 
-    "n/a", 
-    "n/a", 
-    "n/a", 
-    "http://www.nasdaq.com/symbol/cu"
-  ]
-]
\ No newline at end of file
diff --git a/examples/stocks/data/stock_data_7.json b/examples/stocks/data/stock_data_7.json
deleted file mode 100644
index 0ac6c34..0000000
--- a/examples/stocks/data/stock_data_7.json
+++ /dev/null
@@ -1,1002 +0,0 @@
-[
-  [
-    "CUBA", 
-    "The Herzfeld Caribbean Basin Fund, Inc.", 
-    "8.94", 
-    "$49.79M", 
-    "n/a", 
-    "n/a", 
-    "n/a", 
-    "http://www.nasdaq.com/symbol/cuba"
-  ], 
-  [
-    "CUI", 
-    "CUI Global, Inc.", 
-    "5.75", 
-    "$119.27M", 
-    "n/a", 
-    "Consumer Non-Durables", 
-    "Electronic Components", 
-    "http://www.nasdaq.com/symbol/cui"
-  ], 
-  [
-    "CUNB", 
-    "CU Bancorp (CA)", 
-    "20.87", 
-    "$234.33M", 
-    "n/a", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/cunb"
-  ], 
-  [
-    "CUTR", 
-    "Cutera, Inc.", 
-    "12.58", 
-    "$176.62M", 
-    "2004", 
-    "Health Care", 
-    "Biotechnology: Electromedical & Electrotherapeutic Apparatus", 
-    "http://www.nasdaq.com/symbol/cutr"
-  ], 
-  [
-    "CVBF", 
-    "CVB Financial Corporation", 
-    "15.83", 
-    "$1.68B", 
-    "n/a", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/cvbf"
-  ], 
-  [
-    "CVCO", 
-    "Cavco Industries, Inc.", 
-    "72.71", 
-    "$644.15M", 
-    "n/a", 
-    "Basic Industries", 
-    "Homebuilding", 
-    "http://www.nasdaq.com/symbol/cvco"
-  ], 
-  [
-    "CVCY", 
-    "Central Valley Community Bancorp", 
-    "10.77", 
-    "$118.25M", 
-    "n/a", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/cvcy"
-  ], 
-  [
-    "CVGI", 
-    "Commercial Vehicle Group, Inc.", 
-    "5.97", 
-    "$177.26M", 
-    "2004", 
-    "Capital Goods", 
-    "Auto Parts:O.E.M.", 
-    "http://www.nasdaq.com/symbol/cvgi"
-  ], 
-  [
-    "CVGW", 
-    "Calavo Growers, Inc.", 
-    "42.78", 
-    "$739.9M", 
-    "n/a", 
-    "Consumer Non-Durables", 
-    "Farming/Seeds/Milling", 
-    "http://www.nasdaq.com/symbol/cvgw"
-  ], 
-  [
-    "CVLT", 
-    "CommVault Systems, Inc.", 
-    "45", 
-    "$2.02B", 
-    "2006", 
-    "Technology", 
-    "Computer Software: Prepackaged Software", 
-    "http://www.nasdaq.com/symbol/cvlt"
-  ], 
-  [
-    "CVLY", 
-    "Codorus Valley Bancorp, Inc", 
-    "20.2682", 
-    "$117.65M", 
-    "n/a", 
-    "Finance", 
-    "Savings Institutions", 
-    "http://www.nasdaq.com/symbol/cvly"
-  ], 
-  [
-    "CVTI", 
-    "Covenant Transportation Group, Inc.", 
-    "29.65", 
-    "$466.89M", 
-    "1994", 
-    "Transportation", 
-    "Trucking Freight/Courier Services", 
-    "http://www.nasdaq.com/symbol/cvti"
-  ], 
-  [
-    "CVV", 
-    "CVD Equipment Corporation", 
-    "14.53", 
-    "$89.22M", 
-    "n/a", 
-    "Technology", 
-    "Industrial Machinery/Components", 
-    "http://www.nasdaq.com/symbol/cvv"
-  ], 
-  [
-    "CWAY", 
-    "Coastway Bancorp, Inc.", 
-    "11.06", 
-    "$54.74M", 
-    "2014", 
-    "Finance", 
-    "Savings Institutions", 
-    "http://www.nasdaq.com/symbol/cway"
-  ], 
-  [
-    "CWBC", 
-    "Community West Bancshares", 
-    "6.682", 
-    "$54.81M", 
-    "n/a", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/cwbc"
-  ], 
-  [
-    "CWCO", 
-    "Consolidated Water Co. Ltd.", 
-    "10.6", 
-    "$155.85M", 
-    "n/a", 
-    "Public Utilities", 
-    "Water Supply", 
-    "http://www.nasdaq.com/symbol/cwco"
-  ], 
-  [
-    "CWST", 
-    "Casella Waste Systems, Inc.", 
-    "4.14", 
-    "$167.81M", 
-    "1997", 
-    "Public Utilities", 
-    "Environmental Services", 
-    "http://www.nasdaq.com/symbol/cwst"
-  ], 
-  [
-    "CXDC", 
-    "China XD Plastics Company Limited", 
-    "4.26", 
-    "$211.3M", 
-    "n/a", 
-    "Capital Goods", 
-    "Containers/Packaging", 
-    "http://www.nasdaq.com/symbol/cxdc"
-  ], 
-  [
-    "CY", 
-    "Cypress Semiconductor Corporation", 
-    "14.95", 
-    "$2.47B", 
-    "1986", 
-    "Technology", 
-    "Semiconductors", 
-    "http://www.nasdaq.com/symbol/cy"
-  ], 
-  [
-    "CYAN", 
-    "Cyanotech Corporation", 
-    "8.25", 
-    "$45.81M", 
-    "n/a", 
-    "Consumer Durables", 
-    "Specialty Chemicals", 
-    "http://www.nasdaq.com/symbol/cyan"
-  ], 
-  [
-    "CYBE", 
-    "CyberOptics Corporation", 
-    "9.87", 
-    "$65.5M", 
-    "1987", 
-    "Capital Goods", 
-    "Electronic Components", 
-    "http://www.nasdaq.com/symbol/cybe"
-  ], 
-  [
-    "CYBR", 
-    "CyberArk Software Ltd.", 
-    "70.35", 
-    "$2.08B", 
-    "2014", 
-    "Technology", 
-    "Computer Software: Prepackaged Software", 
-    "http://www.nasdaq.com/symbol/cybr"
-  ], 
-  [
-    "CYBX", 
-    "Cyberonics, Inc.", 
-    "58.3", 
-    "$1.53B", 
-    "1993", 
-    "Health Care", 
-    "Biotechnology: Electromedical & Electrotherapeutic Apparatus", 
-    "http://www.nasdaq.com/symbol/cybx"
-  ], 
-  [
-    "CYCC", 
-    "Cyclacel Pharmaceuticals, Inc.", 
-    "0.79", 
-    "$18.15M", 
-    "n/a", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/cycc"
-  ], 
-  [
-    "CYCCP", 
-    "Cyclacel Pharmaceuticals, Inc.", 
-    "7", 
-    "$2.35M", 
-    "n/a", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/cyccp"
-  ], 
-  [
-    "CYHHZ", 
-    "Community Health Systems, Inc.", 
-    "0.025", 
-    "n/a", 
-    "n/a", 
-    "Health Care", 
-    "Hospital/Nursing Management", 
-    "http://www.nasdaq.com/symbol/cyhhz"
-  ], 
-  [
-    "CYNO", 
-    "Cynosure, Inc.", 
-    "30.58", 
-    "$662M", 
-    "2005", 
-    "Health Care", 
-    "Biotechnology: Electromedical & Electrotherapeutic Apparatus", 
-    "http://www.nasdaq.com/symbol/cyno"
-  ], 
-  [
-    "CYOU", 
-    "Changyou.com Limited", 
-    "26.02", 
-    "$1.37B", 
-    "2009", 
-    "Technology", 
-    "Computer Software: Prepackaged Software", 
-    "http://www.nasdaq.com/symbol/cyou"
-  ], 
-  [
-    "CYRN", 
-    "CYREN Ltd.", 
-    "3.17", 
-    "$84.29M", 
-    "n/a", 
-    "Technology", 
-    "Computer Software: Prepackaged Software", 
-    "http://www.nasdaq.com/symbol/cyrn"
-  ], 
-  [
-    "CYTK", 
-    "Cytokinetics, Incorporated", 
-    "7.94", 
-    "$290.67M", 
-    "2004", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/cytk"
-  ], 
-  [
-    "CYTR", 
-    "CytRx Corporation", 
-    "3.18", 
-    "$177.24M", 
-    "1986", 
-    "Health Care", 
-    "Biotechnology: Biological Products (No Diagnostic Substances)", 
-    "http://www.nasdaq.com/symbol/cytr"
-  ], 
-  [
-    "CYTX", 
-    "Cytori Therapeutics Inc", 
-    "0.55", 
-    "$50.85M", 
-    "n/a", 
-    "Health Care", 
-    "Medical/Dental Instruments", 
-    "http://www.nasdaq.com/symbol/cytx"
-  ], 
-  [
-    "CZFC", 
-    "Citizens First Corporation", 
-    "12.327", 
-    "$24.27M", 
-    "n/a", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/czfc"
-  ], 
-  [
-    "CZNC", 
-    "Citizens & Northern Corp", 
-    "19.32", 
-    "$237.49M", 
-    "n/a", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/cznc"
-  ], 
-  [
-    "CZR", 
-    "Caesars Entertainment Corporation", 
-    "10.94", 
-    "$1.58B", 
-    "2012", 
-    "Consumer Services", 
-    "Hotels/Resorts", 
-    "http://www.nasdaq.com/symbol/czr"
-  ], 
-  [
-    "CZWI", 
-    "Citizens Community Bancorp, Inc.", 
-    "9.18", 
-    "$47.68M", 
-    "n/a", 
-    "Finance", 
-    "Savings Institutions", 
-    "http://www.nasdaq.com/symbol/czwi"
-  ], 
-  [
-    "DAEG", 
-    "Daegis Inc", 
-    "0.7415", 
-    "$12.15M", 
-    "n/a", 
-    "Technology", 
-    "Computer Software: Prepackaged Software", 
-    "http://www.nasdaq.com/symbol/daeg"
-  ], 
-  [
-    "DAIO", 
-    "Data I/O Corporation", 
-    "3.161", 
-    "$24.85M", 
-    "1981", 
-    "Capital Goods", 
-    "Electrical Products", 
-    "http://www.nasdaq.com/symbol/daio"
-  ], 
-  [
-    "DAKT", 
-    "Daktronics, Inc.", 
-    "12.68", 
-    "$552.31M", 
-    "1994", 
-    "Consumer Durables", 
-    "Miscellaneous manufacturing industries", 
-    "http://www.nasdaq.com/symbol/dakt"
-  ], 
-  [
-    "DARA", 
-    "DARA Biosciences, Inc.", 
-    "0.89", 
-    "$17.44M", 
-    "n/a", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/dara"
-  ], 
-  [
-    "DATE", 
-    "Jiayuan.com International Ltd.", 
-    "4.91", 
-    "$160.49M", 
-    "2011", 
-    "Technology", 
-    "EDP Services", 
-    "http://www.nasdaq.com/symbol/date"
-  ], 
-  [
-    "DAVE", 
-    "Famous Dave&#39;s of America, Inc.", 
-    "28.53", 
-    "$203.81M", 
-    "n/a", 
-    "Consumer Services", 
-    "Restaurants", 
-    "http://www.nasdaq.com/symbol/dave"
-  ], 
-  [
-    "DAX", 
-    "Recon Capital DAX Germany ETF", 
-    "27.86", 
-    "n/a", 
-    "n/a", 
-    "n/a", 
-    "n/a", 
-    "http://www.nasdaq.com/symbol/dax"
-  ], 
-  [
-    "DBVT", 
-    "DBV Technologies S.A.", 
-    "23.34", 
-    "$722.1M", 
-    "2014", 
-    "Health Care", 
-    "Biotechnology: Biological Products (No Diagnostic Substances)", 
-    "http://www.nasdaq.com/symbol/dbvt"
-  ], 
-  [
-    "DCIX", 
-    "Diana Containerships Inc.", 
-    "2.22", 
-    "$162.41M", 
-    "n/a", 
-    "Transportation", 
-    "Marine Transportation", 
-    "http://www.nasdaq.com/symbol/dcix"
-  ], 
-  [
-    "DCOM", 
-    "Dime Community Bancshares, Inc.", 
-    "15.7", 
-    "$578.59M", 
-    "n/a", 
-    "Finance", 
-    "Savings Institutions", 
-    "http://www.nasdaq.com/symbol/dcom"
-  ], 
-  [
-    "DCTH", 
-    "Delcath Systems, Inc.", 
-    "1.09", 
-    "$10.58M", 
-    "2000", 
-    "Health Care", 
-    "Medical/Dental Instruments", 
-    "http://www.nasdaq.com/symbol/dcth"
-  ], 
-  [
-    "DENN", 
-    "Denny&#39;s Corporation", 
-    "11.75", 
-    "$995.54M", 
-    "n/a", 
-    "Consumer Services", 
-    "Restaurants", 
-    "http://www.nasdaq.com/symbol/denn"
-  ], 
-  [
-    "DEPO", 
-    "Depomed, Inc.", 
-    "20.02", 
-    "$1.18B", 
-    "n/a", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/depo"
-  ], 
-  [
-    "DERM", 
-    "Dermira, Inc.", 
-    "16", 
-    "$393.6M", 
-    "2014", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/derm"
-  ], 
-  [
-    "DEST", 
-    "Destination Maternity Corporation", 
-    "16.41", 
-    "$226.42M", 
-    "n/a", 
-    "Consumer Services", 
-    "Clothing/Shoe/Accessory Stores", 
-    "http://www.nasdaq.com/symbol/dest"
-  ], 
-  [
-    "DFRG", 
-    "Del Frisco&#39;s Restaurant Group, Inc.", 
-    "19.72", 
-    "$461.79M", 
-    "2012", 
-    "Consumer Services", 
-    "Restaurants", 
-    "http://www.nasdaq.com/symbol/dfrg"
-  ], 
-  [
-    "DFVL", 
-    "iPath US Treasury 5-year Bull ETN", 
-    "62.98", 
-    "$1.89M", 
-    "n/a", 
-    "Finance", 
-    "Commercial Banks", 
-    "http://www.nasdaq.com/symbol/dfvl"
-  ], 
-  [
-    "DFVS", 
-    "iPath US Treasury 5-year Bear Exchange Traded Note", 
-    "34.32", 
-    "$1.73M", 
-    "n/a", 
-    "Finance", 
-    "Commercial Banks", 
-    "http://www.nasdaq.com/symbol/dfvs"
-  ], 
-  [
-    "DGAS", 
-    "Delta Natural Gas Company, Inc.", 
-    "20", 
-    "$140.25M", 
-    "1981", 
-    "Public Utilities", 
-    "Oil & Gas Production", 
-    "http://www.nasdaq.com/symbol/dgas"
-  ], 
-  [
-    "DGICA", 
-    "Donegal Group, Inc.", 
-    "15.81", 
-    "$425.8M", 
-    "n/a", 
-    "Finance", 
-    "Property-Casualty Insurers", 
-    "http://www.nasdaq.com/symbol/dgica"
-  ], 
-  [
-    "DGICB", 
-    "Donegal Group, Inc.", 
-    "27", 
-    "$727.17M", 
-    "1986", 
-    "Finance", 
-    "Property-Casualty Insurers", 
-    "http://www.nasdaq.com/symbol/dgicb"
-  ], 
-  [
-    "DGII", 
-    "Digi International Inc.", 
-    "10.2", 
-    "$248.45M", 
-    "1989", 
-    "Technology", 
-    "Computer Communications Equipment", 
-    "http://www.nasdaq.com/symbol/dgii"
-  ], 
-  [
-    "DGLD", 
-    "3X Inverse Gold ETN Velocityshares", 
-    "72.22", 
-    "$9.82M", 
-    "n/a", 
-    "Finance", 
-    "Investment Bankers/Brokers/Service", 
-    "http://www.nasdaq.com/symbol/dgld"
-  ], 
-  [
-    "DGLY", 
-    "Digital Ally, Inc.", 
-    "11.04", 
-    "$33.24M", 
-    "n/a", 
-    "Technology", 
-    "Radio And Television Broadcasting And Communications Equipment", 
-    "http://www.nasdaq.com/symbol/dgly"
-  ], 
-  [
-    "DGRE", 
-    "WisdomTree Emerging Markets Dividend Growth Fund", 
-    "25.38", 
-    "$15.23M", 
-    "n/a", 
-    "n/a", 
-    "n/a", 
-    "http://www.nasdaq.com/symbol/dgre"
-  ], 
-  [
-    "DGRS", 
-    "WisdomTree U.S. SmallCap Dividend Growth Fund", 
-    "29.69", 
-    "$26.72M", 
-    "n/a", 
-    "n/a", 
-    "n/a", 
-    "http://www.nasdaq.com/symbol/dgrs"
-  ], 
-  [
-    "DGRW", 
-    "WisdomTree US Dividend Growth Fund", 
-    "32.01", 
-    "$144.05M", 
-    "n/a", 
-    "n/a", 
-    "n/a", 
-    "http://www.nasdaq.com/symbol/dgrw"
-  ], 
-  [
-    "DHIL", 
-    "Diamond Hill Investment Group, Inc.", 
-    "139.5", 
-    "$462.47M", 
-    "n/a", 
-    "Finance", 
-    "Investment Managers", 
-    "http://www.nasdaq.com/symbol/dhil"
-  ], 
-  [
-    "DHRM", 
-    "Dehaier Medical Systems Limited", 
-    "2.65", 
-    "$15.48M", 
-    "2010", 
-    "Health Care", 
-    "Medical/Dental Instruments", 
-    "http://www.nasdaq.com/symbol/dhrm"
-  ], 
-  [
-    "DIOD", 
-    "Diodes Incorporated", 
-    "28.15", 
-    "$1.34B", 
-    "n/a", 
-    "Technology", 
-    "Semiconductors", 
-    "http://www.nasdaq.com/symbol/diod"
-  ], 
-  [
-    "DISCA", 
-    "Discovery Communications, Inc.", 
-    "30.93", 
-    "$13.59B", 
-    "n/a", 
-    "Consumer Services", 
-    "Television Services", 
-    "http://www.nasdaq.com/symbol/disca"
-  ], 
-  [
-    "DISCB", 
-    "Discovery Communications, Inc.", 
-    "35", 
-    "$15.37B", 
-    "n/a", 
-    "Consumer Services", 
-    "Television Services", 
-    "http://www.nasdaq.com/symbol/discb"
-  ], 
-  [
-    "DISCK", 
-    "Discovery Communications, Inc.", 
-    "29.505", 
-    "$12.96B", 
-    "n/a", 
-    "Consumer Services", 
-    "Television Services", 
-    "http://www.nasdaq.com/symbol/disck"
-  ], 
-  [
-    "DISH", 
-    "DISH Network Corporation", 
-    "78.31", 
-    "$17.47B", 
-    "1995", 
-    "Consumer Services", 
-    "Television Services", 
-    "http://www.nasdaq.com/symbol/dish"
-  ], 
-  [
-    "DJCO", 
-    "Daily Journal Corp. (S.C.)", 
-    "189.25", 
-    "$261.31M", 
-    "n/a", 
-    "Consumer Services", 
-    "Newspapers/Magazines", 
-    "http://www.nasdaq.com/symbol/djco"
-  ], 
-  [
-    "DLBL", 
-    "iPath US Treasury Long Bond Bull ETN", 
-    "78.1401", 
-    "$4.4M", 
-    "n/a", 
-    "Finance", 
-    "Commercial Banks", 
-    "http://www.nasdaq.com/symbol/dlbl"
-  ], 
-  [
-    "DLBS", 
-    "iPath US Treasury Long Bond Bear ETN", 
-    "21.46", 
-    "$17.8M", 
-    "n/a", 
-    "Finance", 
-    "Commercial Banks", 
-    "http://www.nasdaq.com/symbol/dlbs"
-  ], 
-  [
-    "DLHC", 
-    "DLH Holdings Corp.", 
-    "2.13", 
-    "$20.51M", 
-    "n/a", 
-    "Technology", 
-    "Professional Services", 
-    "http://www.nasdaq.com/symbol/dlhc"
-  ], 
-  [
-    "DLTR", 
-    "Dollar Tree, Inc.", 
-    "77.69", 
-    "$15.98B", 
-    "1995", 
-    "Consumer Services", 
-    "Department/Specialty Retail Stores", 
-    "http://www.nasdaq.com/symbol/dltr"
-  ], 
-  [
-    "DMLP", 
-    "Dorchester Minerals, L.P.", 
-    "23.98", 
-    "$735.6M", 
-    "n/a", 
-    "Energy", 
-    "Oil & Gas Production", 
-    "http://www.nasdaq.com/symbol/dmlp"
-  ], 
-  [
-    "DMND", 
-    "Diamond Foods, Inc.", 
-    "26.15", 
-    "$821.53M", 
-    "2005", 
-    "Consumer Non-Durables", 
-    "Packaged Foods", 
-    "http://www.nasdaq.com/symbol/dmnd"
-  ], 
-  [
-    "DMRC", 
-    "Digimarc Corporation", 
-    "27.5", 
-    "$211.58M", 
-    "n/a", 
-    "Technology", 
-    "EDP Services", 
-    "http://www.nasdaq.com/symbol/dmrc"
-  ], 
-  [
-    "DNBF", 
-    "DNB Financial Corp", 
-    "22.5", 
-    "$62.47M", 
-    "n/a", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/dnbf"
-  ], 
-  [
-    "DNKN", 
-    "Dunkin&#39; Brands Group, Inc.", 
-    "46.38", 
-    "$4.53B", 
-    "2011", 
-    "Consumer Services", 
-    "Restaurants", 
-    "http://www.nasdaq.com/symbol/dnkn"
-  ], 
-  [
-    "DORM", 
-    "Dorman Products, Inc.", 
-    "44.88", 
-    "$1.6B", 
-    "n/a", 
-    "Capital Goods", 
-    "Auto Parts:O.E.M.", 
-    "http://www.nasdaq.com/symbol/dorm"
-  ], 
-  [
-    "DOVR", 
-    "Dover Saddlery, Inc.", 
-    "4.71", 
-    "$25.45M", 
-    "2005", 
-    "Consumer Services", 
-    "Other Specialty Stores", 
-    "http://www.nasdaq.com/symbol/dovr"
-  ], 
-  [
-    "DOX", 
-    "Amdocs Limited", 
-    "51.57", 
-    "$8.01B", 
-    "n/a", 
-    "Technology", 
-    "EDP Services", 
-    "http://www.nasdaq.com/symbol/dox"
-  ], 
-  [
-    "DPRX", 
-    "Dipexium Pharmaceuticals, Inc.", 
-    "13.63", 
-    "$116.37M", 
-    "2014", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/dprx"
-  ], 
-  [
-    "DRAD", 
-    "Digirad Corporation", 
-    "4.37", 
-    "$72.48M", 
-    "2004", 
-    "Health Care", 
-    "Biotechnology: Electromedical & Electrotherapeutic Apparatus", 
-    "http://www.nasdaq.com/symbol/drad"
-  ], 
-  [
-    "DRAM", 
-    "Dataram Corporation", 
-    "2.4", 
-    "$6.22M", 
-    "n/a", 
-    "Technology", 
-    "Electronic Components", 
-    "http://www.nasdaq.com/symbol/dram"
-  ], 
-  [
-    "DRNA", 
-    "Dicerna Pharmaceuticals, Inc.", 
-    "26.02", 
-    "$462.46M", 
-    "2014", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/drna"
-  ], 
-  [
-    "DRRX", 
-    "Durect Corporation", 
-    "0.99", 
-    "$112.54M", 
-    "2000", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/drrx"
-  ], 
-  [
-    "DRWI", 
-    "DragonWave Inc", 
-    "0.92", 
-    "$69.26M", 
-    "2009", 
-    "Public Utilities", 
-    "Telecommunications Equipment", 
-    "http://www.nasdaq.com/symbol/drwi"
-  ], 
-  [
-    "DRWIW", 
-    "DragonWave Inc", 
-    "0.0848", 
-    "$675326", 
-    "n/a", 
-    "Public Utilities", 
-    "Telecommunications Equipment", 
-    "http://www.nasdaq.com/symbol/drwiw"
-  ], 
-  [
-    "DRYS", 
-    "DryShips Inc.", 
-    "0.98", 
-    "$671.36M", 
-    "2005", 
-    "Transportation", 
-    "Marine Transportation", 
-    "http://www.nasdaq.com/symbol/drys"
-  ], 
-  [
-    "DSCI", 
-    "Derma Sciences, Inc.", 
-    "8.38", 
-    "$211.58M", 
-    "n/a", 
-    "Health Care", 
-    "Medical/Dental Instruments", 
-    "http://www.nasdaq.com/symbol/dsci"
-  ], 
-  [
-    "DSCO", 
-    "Discovery Laboratories, Inc.", 
-    "1.52", 
-    "$129.71M", 
-    "n/a", 
-    "Health Care", 
-    "Biotechnology: Biological Products (No Diagnostic Substances)", 
-    "http://www.nasdaq.com/symbol/dsco"
-  ], 
-  [
-    "DSGX", 
-    "The Descartes Systems Group Inc.", 
-    "15.27", 
-    "$1.15B", 
-    "n/a", 
-    "Technology", 
-    "Computer Software: Prepackaged Software", 
-    "http://www.nasdaq.com/symbol/dsgx"
-  ], 
-  [
-    "DSKX", 
-    "DS Healthcare Group, Inc.", 
-    "0.7753", 
-    "$12.52M", 
-    "n/a", 
-    "Consumer Non-Durables", 
-    "Package Goods/Cosmetics", 
-    "http://www.nasdaq.com/symbol/dskx"
-  ], 
-  [
-    "DSKY", 
-    "iDreamSky Technology Limited", 
-    "11.61", 
-    "$491.37M", 
-    "2014", 
-    "Technology", 
-    "Computer Software: Prepackaged Software", 
-    "http://www.nasdaq.com/symbol/dsky"
-  ], 
-  [
-    "DSLV", 
-    "VelocityShares 3x Inverse Silver ETN linked to S&P GSCI Silver", 
-    "60", 
-    "$34.02M", 
-    "n/a", 
-    "Finance", 
-    "Investment Bankers/Brokers/Service", 
-    "http://www.nasdaq.com/symbol/dslv"
-  ], 
-  [
-    "DSPG", 
-    "DSP Group, Inc.", 
-    "11.43", 
-    "$247.03M", 
-    "1994", 
-    "Technology", 
-    "Semiconductors", 
-    "http://www.nasdaq.com/symbol/dspg"
-  ], 
-  [
-    "DSWL", 
-    "Deswell Industries, Inc.", 
-    "1.89", 
-    "$30.35M", 
-    "1995", 
-    "Consumer Non-Durables", 
-    "Plastic Products", 
-    "http://www.nasdaq.com/symbol/dswl"
-  ], 
-  [
-    "DTLK", 
-    "Datalink Corporation", 
-    "12.11", 
-    "$278.95M", 
-    "1999", 
-    "Technology", 
-    "EDP Services", 
-    "http://www.nasdaq.com/symbol/dtlk"
-  ]
-]
\ No newline at end of file
diff --git a/examples/stocks/data/stock_data_8.json b/examples/stocks/data/stock_data_8.json
deleted file mode 100644
index dd47967..0000000
--- a/examples/stocks/data/stock_data_8.json
+++ /dev/null
@@ -1,1002 +0,0 @@
-[
-  [
-    "DTSI", 
-    "DTS, Inc.", 
-    "30.65", 
-    "$526.75M", 
-    "2003", 
-    "Miscellaneous", 
-    "Multi-Sector Companies", 
-    "http://www.nasdaq.com/symbol/dtsi"
-  ], 
-  [
-    "DTUL", 
-    "iPath US Treasury 2-year Bull ETN", 
-    "61.4", 
-    "$4.39M", 
-    "n/a", 
-    "Finance", 
-    "Commercial Banks", 
-    "http://www.nasdaq.com/symbol/dtul"
-  ], 
-  [
-    "DTUS", 
-    "iPath US Treasury 2-year Bear ETN", 
-    "34.81", 
-    "$13.02M", 
-    "n/a", 
-    "Finance", 
-    "Commercial Banks", 
-    "http://www.nasdaq.com/symbol/dtus"
-  ], 
-  [
-    "DTV", 
-    "DIRECTV", 
-    "87.26", 
-    "$43.83B", 
-    "n/a", 
-    "Consumer Services", 
-    "Telecommunications Equipment", 
-    "http://www.nasdaq.com/symbol/dtv"
-  ], 
-  [
-    "DTYL", 
-    "iPath US Treasury 10-year Bull ETN", 
-    "74.72", 
-    "$5.38M", 
-    "n/a", 
-    "Finance", 
-    "Commercial Banks", 
-    "http://www.nasdaq.com/symbol/dtyl"
-  ], 
-  [
-    "DTYS", 
-    "iPath US Treasury 10-year Bear ETN", 
-    "21.71", 
-    "$68.19M", 
-    "n/a", 
-    "Finance", 
-    "Commercial Banks", 
-    "http://www.nasdaq.com/symbol/dtys"
-  ], 
-  [
-    "DVAX", 
-    "Dynavax Technologies Corporation", 
-    "17.75", 
-    "$46.67M", 
-    "2004", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/dvax"
-  ], 
-  [
-    "DVCR", 
-    "Diversicare Healthcare Services Inc.", 
-    "10.11", 
-    "$62.24M", 
-    "n/a", 
-    "Health Care", 
-    "Hospital/Nursing Management", 
-    "http://www.nasdaq.com/symbol/dvcr"
-  ], 
-  [
-    "DWA", 
-    "Dreamworks Animation SKG, Inc.", 
-    "20.35", 
-    "$1.73B", 
-    "2004", 
-    "Consumer Services", 
-    "Movies/Entertainment", 
-    "http://www.nasdaq.com/symbol/dwa"
-  ], 
-  [
-    "DWAT", 
-    "Arrow DWA Tactical ETF", 
-    "10.7499", 
-    "n/a", 
-    "n/a", 
-    "n/a", 
-    "n/a", 
-    "http://www.nasdaq.com/symbol/dwat"
-  ], 
-  [
-    "DWCH", 
-    "Datawatch Corporation", 
-    "6.78", 
-    "$76.96M", 
-    "1992", 
-    "Technology", 
-    "Computer Software: Prepackaged Software", 
-    "http://www.nasdaq.com/symbol/dwch"
-  ], 
-  [
-    "DWSN", 
-    "Dawson Geophysical Company", 
-    "5.91", 
-    "$43.34M", 
-    "n/a", 
-    "Energy", 
-    "Oil & Gas Production", 
-    "http://www.nasdaq.com/symbol/dwsn"
-  ], 
-  [
-    "DXCM", 
-    "DexCom, Inc.", 
-    "64.42", 
-    "$4.93B", 
-    "2005", 
-    "Health Care", 
-    "Medical/Dental Instruments", 
-    "http://www.nasdaq.com/symbol/dxcm"
-  ], 
-  [
-    "DXGE", 
-    "WisdomTree Germany Hedged Equity Fund", 
-    "29.58", 
-    "$13.31M", 
-    "n/a", 
-    "n/a", 
-    "n/a", 
-    "http://www.nasdaq.com/symbol/dxge"
-  ], 
-  [
-    "DXJS", 
-    "WisdomTree Japan Hedged SmallCap Equity Fund", 
-    "32.9199", 
-    "$95.47M", 
-    "n/a", 
-    "n/a", 
-    "n/a", 
-    "http://www.nasdaq.com/symbol/dxjs"
-  ], 
-  [
-    "DXKW", 
-    "WisdomTree Korea Hedged Equity Fund", 
-    "21.54", 
-    "$8.62M", 
-    "n/a", 
-    "n/a", 
-    "n/a", 
-    "http://www.nasdaq.com/symbol/dxkw"
-  ], 
-  [
-    "DXLG", 
-    "Destination XL Group, Inc.", 
-    "4.91", 
-    "$248.85M", 
-    "n/a", 
-    "Consumer Services", 
-    "Clothing/Shoe/Accessory Stores", 
-    "http://www.nasdaq.com/symbol/dxlg"
-  ], 
-  [
-    "DXM", 
-    "Dex Media, Inc.", 
-    "7.27", 
-    "$128.16M", 
-    "n/a", 
-    "Consumer Services", 
-    "Advertising", 
-    "http://www.nasdaq.com/symbol/dxm"
-  ], 
-  [
-    "DXPE", 
-    "DXP Enterprises, Inc.", 
-    "47.11", 
-    "$681.49M", 
-    "n/a", 
-    "Capital Goods", 
-    "Industrial Machinery/Components", 
-    "http://www.nasdaq.com/symbol/dxpe"
-  ], 
-  [
-    "DXPS", 
-    "WisdomTree United Kingdom Hedged Equity Fund", 
-    "26.78", 
-    "$22.76M", 
-    "n/a", 
-    "n/a", 
-    "n/a", 
-    "http://www.nasdaq.com/symbol/dxps"
-  ], 
-  [
-    "DXYN", 
-    "The Dixie Group, Inc.", 
-    "9.02", 
-    "$143.7M", 
-    "n/a", 
-    "Consumer Durables", 
-    "Home Furnishings", 
-    "http://www.nasdaq.com/symbol/dxyn"
-  ], 
-  [
-    "DYAX", 
-    "Dyax Corp.", 
-    "15.95", 
-    "$2.18B", 
-    "2000", 
-    "Health Care", 
-    "Biotechnology: Commercial Physical & Biological Resarch", 
-    "http://www.nasdaq.com/symbol/dyax"
-  ], 
-  [
-    "DYNT", 
-    "Dynatronics Corporation", 
-    "3.85", 
-    "$9.7M", 
-    "n/a", 
-    "n/a", 
-    "n/a", 
-    "http://www.nasdaq.com/symbol/dynt"
-  ], 
-  [
-    "DYSL", 
-    "Dynasil Corporation of America", 
-    "1.4", 
-    "$22.96M", 
-    "n/a", 
-    "Capital Goods", 
-    "Industrial Machinery/Components", 
-    "http://www.nasdaq.com/symbol/dysl"
-  ], 
-  [
-    "EA", 
-    "Electronic Arts Inc.", 
-    "57.67", 
-    "$17.88B", 
-    "n/a", 
-    "Technology", 
-    "Computer Software: Prepackaged Software", 
-    "http://www.nasdaq.com/symbol/ea"
-  ], 
-  [
-    "EAC           ", 
-    "Erickson Incorporated", 
-    "7.2", 
-    "$99.45M", 
-    "2012", 
-    "Capital Goods", 
-    "Aerospace", 
-    "http://www.nasdaq.com/symbol/eac           "
-  ], 
-  [
-    "EARS", 
-    "Auris Medical Holding AG", 
-    "5.8", 
-    "$167.94M", 
-    "2014", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/ears"
-  ], 
-  [
-    "EBAY", 
-    "eBay Inc.", 
-    "58.02", 
-    "$70.21B", 
-    "1998", 
-    "Miscellaneous", 
-    "Business Services", 
-    "http://www.nasdaq.com/symbol/ebay"
-  ], 
-  [
-    "EBIO", 
-    "Eleven Biotherapeutics, Inc.", 
-    "10.85", 
-    "$176.74M", 
-    "2014", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/ebio"
-  ], 
-  [
-    "EBIX", 
-    "Ebix, Inc.", 
-    "28.13", 
-    "$1.03B", 
-    "n/a", 
-    "Technology", 
-    "EDP Services", 
-    "http://www.nasdaq.com/symbol/ebix"
-  ], 
-  [
-    "EBMT", 
-    "Eagle Bancorp Montana, Inc.", 
-    "11.05", 
-    "$42.72M", 
-    "n/a", 
-    "Finance", 
-    "Savings Institutions", 
-    "http://www.nasdaq.com/symbol/ebmt"
-  ], 
-  [
-    "EBSB", 
-    "Meridian Bancorp, Inc.", 
-    "12.41", 
-    "$678.93M", 
-    "n/a", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/ebsb"
-  ], 
-  [
-    "EBTC", 
-    "Enterprise Bancorp Inc", 
-    "21.33", 
-    "$216.82M", 
-    "n/a", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/ebtc"
-  ], 
-  [
-    "ECHO", 
-    "Echo Global Logistics, Inc.", 
-    "27.76", 
-    "$659.22M", 
-    "2009", 
-    "Transportation", 
-    "Oil Refining/Marketing", 
-    "http://www.nasdaq.com/symbol/echo"
-  ], 
-  [
-    "ECOL", 
-    "US Ecology, Inc.", 
-    "46.55", 
-    "$1.01B", 
-    "n/a", 
-    "Public Utilities", 
-    "Environmental Services", 
-    "http://www.nasdaq.com/symbol/ecol"
-  ], 
-  [
-    "ECPG", 
-    "Encore Capital Group Inc", 
-    "43.01", 
-    "$1.11B", 
-    "n/a", 
-    "Finance", 
-    "Finance Companies", 
-    "http://www.nasdaq.com/symbol/ecpg"
-  ], 
-  [
-    "ECTE", 
-    "Echo Therapeutics, Inc.", 
-    "2.89", 
-    "$36.51M", 
-    "n/a", 
-    "Health Care", 
-    "Biotechnology: Electromedical & Electrotherapeutic Apparatus", 
-    "http://www.nasdaq.com/symbol/ecte"
-  ], 
-  [
-    "ECYT", 
-    "Endocyte, Inc.", 
-    "5.69", 
-    "$237.33M", 
-    "2011", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/ecyt"
-  ], 
-  [
-    "EDAP", 
-    "EDAP TMS S.A.", 
-    "3.52", 
-    "$87.26M", 
-    "1997", 
-    "Health Care", 
-    "Biotechnology: Electromedical & Electrotherapeutic Apparatus", 
-    "http://www.nasdaq.com/symbol/edap"
-  ], 
-  [
-    "EDGW", 
-    "Edgewater Technology, Inc.", 
-    "7.23", 
-    "$82.26M", 
-    "n/a", 
-    "Technology", 
-    "Computer Software: Programming, Data Processing", 
-    "http://www.nasdaq.com/symbol/edgw"
-  ], 
-  [
-    "EDS", 
-    "Exceed Company Ltd.", 
-    "1.56", 
-    "$51.7M", 
-    "n/a", 
-    "Consumer Non-Durables", 
-    "Shoe Manufacturing", 
-    "http://www.nasdaq.com/symbol/eds"
-  ], 
-  [
-    "EDUC", 
-    "Educational Development Corporation", 
-    "4.22", 
-    "$16.97M", 
-    "n/a", 
-    "Consumer Durables", 
-    "Consumer Specialties", 
-    "http://www.nasdaq.com/symbol/educ"
-  ], 
-  [
-    "EEFT", 
-    "Euronet Worldwide, Inc.", 
-    "54.33", 
-    "$2.86B", 
-    "1997", 
-    "Finance", 
-    "Investment Bankers/Brokers/Service", 
-    "http://www.nasdaq.com/symbol/eeft"
-  ], 
-  [
-    "EEI", 
-    "Ecology and Environment, Inc.", 
-    "10.26", 
-    "$44M", 
-    "1987", 
-    "Consumer Services", 
-    "Military/Government/Technical", 
-    "http://www.nasdaq.com/symbol/eei"
-  ], 
-  [
-    "EEMA", 
-    "iShares MSCI Emerging Markets Asia Index", 
-    "60.76", 
-    "$91.14M", 
-    "n/a", 
-    "n/a", 
-    "n/a", 
-    "http://www.nasdaq.com/symbol/eema"
-  ], 
-  [
-    "EEME", 
-    "iShares MSCI Emerging Markets EMEA Index Fund", 
-    "45.11", 
-    "$9.02M", 
-    "n/a", 
-    "n/a", 
-    "n/a", 
-    "http://www.nasdaq.com/symbol/eeme"
-  ], 
-  [
-    "EEML", 
-    "iShares MSCI Emerging Markets Latin America ETF", 
-    "35.52", 
-    "$10.66M", 
-    "n/a", 
-    "n/a", 
-    "n/a", 
-    "http://www.nasdaq.com/symbol/eeml"
-  ], 
-  [
-    "EFII", 
-    "Electronics for Imaging, Inc.", 
-    "40", 
-    "$1.88B", 
-    "1992", 
-    "Technology", 
-    "Computer Communications Equipment", 
-    "http://www.nasdaq.com/symbol/efii"
-  ], 
-  [
-    "EFOI", 
-    "Energy Focus, Inc.", 
-    "4.68", 
-    "$44.09M", 
-    "n/a", 
-    "Consumer Durables", 
-    "Building Products", 
-    "http://www.nasdaq.com/symbol/efoi"
-  ], 
-  [
-    "EFSC", 
-    "Enterprise Financial Services Corporation", 
-    "20.27", 
-    "$401.04M", 
-    "n/a", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/efsc"
-  ], 
-  [
-    "EFUT", 
-    "eFuture Information Technology Inc.", 
-    "4.02", 
-    "$16.04M", 
-    "n/a", 
-    "Technology", 
-    "EDP Services", 
-    "http://www.nasdaq.com/symbol/efut"
-  ], 
-  [
-    "EGAN", 
-    "eGain Corporation", 
-    "3.605", 
-    "$96.2M", 
-    "1999", 
-    "Technology", 
-    "Computer Software: Prepackaged Software", 
-    "http://www.nasdaq.com/symbol/egan"
-  ], 
-  [
-    "EGBN", 
-    "Eagle Bancorp, Inc.", 
-    "36.37", 
-    "$946.85M", 
-    "n/a", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/egbn"
-  ], 
-  [
-    "EGHT", 
-    "8x8 Inc", 
-    "7.62", 
-    "$684.79M", 
-    "n/a", 
-    "Public Utilities", 
-    "Telecommunications Equipment", 
-    "http://www.nasdaq.com/symbol/eght"
-  ], 
-  [
-    "EGLE", 
-    "Eagle Bulk Shipping Inc.", 
-    "9.97", 
-    "$379.31M", 
-    "n/a", 
-    "Transportation", 
-    "Marine Transportation", 
-    "http://www.nasdaq.com/symbol/egle"
-  ], 
-  [
-    "EGLT", 
-    "Egalet Corporation", 
-    "14.5", 
-    "$250.61M", 
-    "2014", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/eglt"
-  ], 
-  [
-    "EGOV", 
-    "NIC Inc.", 
-    "17.05", 
-    "$1.11B", 
-    "1999", 
-    "Consumer Services", 
-    "Professional Services", 
-    "http://www.nasdaq.com/symbol/egov"
-  ], 
-  [
-    "EGRW", 
-    "iShares MSCI Emerging Markets Growth ETF", 
-    "55", 
-    "$5.5M", 
-    "n/a", 
-    "n/a", 
-    "n/a", 
-    "http://www.nasdaq.com/symbol/egrw"
-  ], 
-  [
-    "EGRX", 
-    "Eagle Pharmaceuticals, Inc.", 
-    "33.68", 
-    "$472.76M", 
-    "2014", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/egrx"
-  ], 
-  [
-    "EGT", 
-    "Entertainment Gaming Asia Incorporated", 
-    "0.5203", 
-    "$15.66M", 
-    "n/a", 
-    "Consumer Durables", 
-    "Miscellaneous manufacturing industries", 
-    "http://www.nasdaq.com/symbol/egt"
-  ], 
-  [
-    "EHTH", 
-    "eHealth, Inc.", 
-    "10.47", 
-    "$186.55M", 
-    "2006", 
-    "Finance", 
-    "Specialty Insurers", 
-    "http://www.nasdaq.com/symbol/ehth"
-  ], 
-  [
-    "EIGI", 
-    "Endurance International Group Holdings, Inc.", 
-    "19.89", 
-    "$2.63B", 
-    "2013", 
-    "Technology", 
-    "Computer Software: Prepackaged Software", 
-    "http://www.nasdaq.com/symbol/eigi"
-  ], 
-  [
-    "ELGX", 
-    "Endologix, Inc.", 
-    "14.82", 
-    "$992.77M", 
-    "n/a", 
-    "Health Care", 
-    "Medical/Dental Instruments", 
-    "http://www.nasdaq.com/symbol/elgx"
-  ], 
-  [
-    "ELNK", 
-    "EarthLink Holdings Corp.", 
-    "4.6", 
-    "$470.79M", 
-    "n/a", 
-    "Technology", 
-    "Computer Software: Programming, Data Processing", 
-    "http://www.nasdaq.com/symbol/elnk"
-  ], 
-  [
-    "ELON", 
-    "Echelon Corporation", 
-    "1.16", 
-    "$50.99M", 
-    "1998", 
-    "Technology", 
-    "Computer Communications Equipment", 
-    "http://www.nasdaq.com/symbol/elon"
-  ], 
-  [
-    "ELOS", 
-    "Syneron Medical Ltd.", 
-    "11.1", 
-    "$407.03M", 
-    "2004", 
-    "Health Care", 
-    "Biotechnology: Electromedical & Electrotherapeutic Apparatus", 
-    "http://www.nasdaq.com/symbol/elos"
-  ], 
-  [
-    "ELRC", 
-    "Electro Rent Corporation", 
-    "13.03", 
-    "$314.09M", 
-    "n/a", 
-    "Technology", 
-    "Diversified Commercial Services", 
-    "http://www.nasdaq.com/symbol/elrc"
-  ], 
-  [
-    "ELSE", 
-    "Electro-Sensors, Inc.", 
-    "4.031", 
-    "$13.69M", 
-    "n/a", 
-    "Capital Goods", 
-    "Industrial Machinery/Components", 
-    "http://www.nasdaq.com/symbol/else"
-  ], 
-  [
-    "ELTK", 
-    "Eltek Ltd.", 
-    "1.21", 
-    "$12.27M", 
-    "1997", 
-    "Technology", 
-    "Electrical Products", 
-    "http://www.nasdaq.com/symbol/eltk"
-  ], 
-  [
-    "EMCB", 
-    "WisdomTree Emerging Markets Corporate Bond", 
-    "71.6399", 
-    "$107.46M", 
-    "n/a", 
-    "n/a", 
-    "n/a", 
-    "http://www.nasdaq.com/symbol/emcb"
-  ], 
-  [
-    "EMCF", 
-    "Emclaire Financial Corp", 
-    "25.16", 
-    "$44.59M", 
-    "n/a", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/emcf"
-  ], 
-  [
-    "EMCG", 
-    "WisdomTree Emerging Markets Consumer Growth Fund", 
-    "25.5", 
-    "$20.4M", 
-    "n/a", 
-    "n/a", 
-    "n/a", 
-    "http://www.nasdaq.com/symbol/emcg"
-  ], 
-  [
-    "EMCI", 
-    "EMC Insurance Group Inc.", 
-    "30", 
-    "$406.39M", 
-    "1982", 
-    "Finance", 
-    "Property-Casualty Insurers", 
-    "http://www.nasdaq.com/symbol/emci"
-  ], 
-  [
-    "EMDI", 
-    "iShares MSCI Emerging Markets Consumer Discretionary Index", 
-    "53.89", 
-    "$5.39M", 
-    "n/a", 
-    "n/a", 
-    "n/a", 
-    "http://www.nasdaq.com/symbol/emdi"
-  ], 
-  [
-    "EMEY", 
-    "iShares MSCI Emerging Markets Energy Sector Capped Index Fund", 
-    "29.28", 
-    "$1.46M", 
-    "n/a", 
-    "n/a", 
-    "n/a", 
-    "http://www.nasdaq.com/symbol/emey"
-  ], 
-  [
-    "EMIF", 
-    "iShares S&P Emerging Markets Infrastructure Index Fund", 
-    "32.71", 
-    "$85.05M", 
-    "n/a", 
-    "n/a", 
-    "n/a", 
-    "http://www.nasdaq.com/symbol/emif"
-  ], 
-  [
-    "EMITF", 
-    "Elbit Imaging Ltd.", 
-    "1.75", 
-    "$2.41M", 
-    "n/a", 
-    "Consumer Services", 
-    "Building operators", 
-    "http://www.nasdaq.com/symbol/emitf"
-  ], 
-  [
-    "EMKR", 
-    "EMCORE Corporation", 
-    "5.5", 
-    "$176.59M", 
-    "1997", 
-    "Technology", 
-    "Semiconductors", 
-    "http://www.nasdaq.com/symbol/emkr"
-  ], 
-  [
-    "EML", 
-    "Eastern Company (The)", 
-    "19.025", 
-    "$118.4M", 
-    "n/a", 
-    "Capital Goods", 
-    "Industrial Machinery/Components", 
-    "http://www.nasdaq.com/symbol/eml"
-  ], 
-  [
-    "EMMS", 
-    "Emmis Communications Corporation", 
-    "2.14", 
-    "$93.24M", 
-    "1994", 
-    "Consumer Services", 
-    "Broadcasting", 
-    "http://www.nasdaq.com/symbol/emms"
-  ], 
-  [
-    "EMMSP", 
-    "Emmis Communications Corporation", 
-    "12.5", 
-    "$16.64M", 
-    "n/a", 
-    "Consumer Services", 
-    "Broadcasting", 
-    "http://www.nasdaq.com/symbol/emmsp"
-  ], 
-  [
-    "ENDP", 
-    "Endo International plc", 
-    "86.32", 
-    "$14.91B", 
-    "n/a", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/endp"
-  ], 
-  [
-    "ENFC", 
-    "Entegra Financial Corp.", 
-    "15.8", 
-    "$103.43M", 
-    "2014", 
-    "Finance", 
-    "Banks", 
-    "http://www.nasdaq.com/symbol/enfc"
-  ], 
-  [
-    "ENG", 
-    "ENGlobal Corporation", 
-    "1.84", 
-    "$51.03M", 
-    "n/a", 
-    "Consumer Services", 
-    "Military/Government/Technical", 
-    "http://www.nasdaq.com/symbol/eng"
-  ], 
-  [
-    "ENOC", 
-    "EnerNOC, Inc.", 
-    "17.86", 
-    "$521.07M", 
-    "2007", 
-    "Technology", 
-    "Computer Software: Programming, Data Processing", 
-    "http://www.nasdaq.com/symbol/enoc"
-  ], 
-  [
-    "ENPH", 
-    "Enphase Energy, Inc.", 
-    "13.3", 
-    "$580.21M", 
-    "2012", 
-    "Technology", 
-    "Semiconductors", 
-    "http://www.nasdaq.com/symbol/enph"
-  ], 
-  [
-    "ENSG", 
-    "The Ensign Group, Inc.", 
-    "41.41", 
-    "$936.53M", 
-    "2007", 
-    "Health Care", 
-    "Hospital/Nursing Management", 
-    "http://www.nasdaq.com/symbol/ensg"
-  ], 
-  [
-    "ENT", 
-    "Global Eagle Entertainment Inc.", 
-    "13.31", 
-    "$1.02B", 
-    "2011", 
-    "Consumer Services", 
-    "Telecommunications Equipment", 
-    "http://www.nasdaq.com/symbol/ent"
-  ], 
-  [
-    "ENTA", 
-    "Enanta Pharmaceuticals, Inc.", 
-    "35.9", 
-    "$670.63M", 
-    "2013", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/enta"
-  ], 
-  [
-    "ENTG", 
-    "Entegris, Inc.", 
-    "13.71", 
-    "$1.91B", 
-    "2000", 
-    "Consumer Non-Durables", 
-    "Plastic Products", 
-    "http://www.nasdaq.com/symbol/entg"
-  ], 
-  [
-    "ENTL", 
-    "Entellus Medical, Inc.", 
-    "23.09", 
-    "$431.29M", 
-    "2015", 
-    "Health Care", 
-    "Medical/Dental Instruments", 
-    "http://www.nasdaq.com/symbol/entl"
-  ], 
-  [
-    "ENTR", 
-    "Entropic Communications, Inc.", 
-    "2.95", 
-    "$265.72M", 
-    "2007", 
-    "Technology", 
-    "Semiconductors", 
-    "http://www.nasdaq.com/symbol/entr"
-  ], 
-  [
-    "ENVI", 
-    "Envivio, Inc.", 
-    "1.36", 
-    "$37.69M", 
-    "2012", 
-    "Technology", 
-    "Radio And Television Broadcasting And Communications Equipment", 
-    "http://www.nasdaq.com/symbol/envi"
-  ], 
-  [
-    "ENZN", 
-    "Enzon Pharmaceuticals, Inc.", 
-    "1.1", 
-    "$48.56M", 
-    "1984", 
-    "Health Care", 
-    "Biotechnology: Biological Products (No Diagnostic Substances)", 
-    "http://www.nasdaq.com/symbol/enzn"
-  ], 
-  [
-    "ENZY          ", 
-    "Enzymotec Ltd.", 
-    "7.06", 
-    "$156.13M", 
-    "2013", 
-    "Consumer Durables", 
-    "Specialty Chemicals", 
-    "http://www.nasdaq.com/symbol/enzy          "
-  ], 
-  [
-    "EOPN", 
-    "E2open, Inc.", 
-    "8.55", 
-    "$250.69M", 
-    "2012", 
-    "Technology", 
-    "Computer Software: Prepackaged Software", 
-    "http://www.nasdaq.com/symbol/eopn"
-  ], 
-  [
-    "EPAX", 
-    "Ambassadors Group, Inc.", 
-    "2.41", 
-    "$41.08M", 
-    "n/a", 
-    "Consumer Services", 
-    "Other Consumer Services", 
-    "http://www.nasdaq.com/symbol/epax"
-  ], 
-  [
-    "EPAY", 
-    "Bottomline Technologies, Inc.", 
-    "26.86", 
-    "$1.07B", 
-    "1999", 
-    "Technology", 
-    "Computer Software: Prepackaged Software", 
-    "http://www.nasdaq.com/symbol/epay"
-  ], 
-  [
-    "EPIQ", 
-    "EPIQ Systems, Inc.", 
-    "18.28", 
-    "$665.53M", 
-    "1997", 
-    "Technology", 
-    "EDP Services", 
-    "http://www.nasdaq.com/symbol/epiq"
-  ], 
-  [
-    "EPRS", 
-    "EPIRUS Biopharmaceuticals, Inc.", 
-    "8.64", 
-    "$194.69M", 
-    "n/a", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/eprs"
-  ]
-]
\ No newline at end of file
diff --git a/examples/stocks/data/stock_data_9.json b/examples/stocks/data/stock_data_9.json
deleted file mode 100644
index 73d6c2d..0000000
--- a/examples/stocks/data/stock_data_9.json
+++ /dev/null
@@ -1,1002 +0,0 @@
-[
-  [
-    "EPZM", 
-    "Epizyme, Inc.", 
-    "22.76", 
-    "$777.56M", 
-    "2013", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/epzm"
-  ], 
-  [
-    "EQIX", 
-    "Equinix, Inc.", 
-    "235.38", 
-    "$12.55B", 
-    "2000", 
-    "Public Utilities", 
-    "Telecommunications Equipment", 
-    "http://www.nasdaq.com/symbol/eqix"
-  ], 
-  [
-    "ERI", 
-    "Eldorado Resorts, Inc.", 
-    "4.5499", 
-    "$211.33M", 
-    "n/a", 
-    "Consumer Services", 
-    "Hotels/Resorts", 
-    "http://www.nasdaq.com/symbol/eri"
-  ], 
-  [
-    "ERIC", 
-    "Ericsson", 
-    "13.02", 
-    "$42.17B", 
-    "n/a", 
-    "Technology", 
-    "Radio And Television Broadcasting And Communications Equipment", 
-    "http://www.nasdaq.com/symbol/eric"
-  ], 
-  [
-    "ERIE", 
-    "Erie Indemnity Company", 
-    "92.49", 
-    "$4.27B", 
-    "n/a", 
-    "Finance", 
-    "Specialty Insurers", 
-    "http://www.nasdaq.com/symbol/erie"
-  ], 
-  [
-    "ERII", 
-    "Energy Recovery, Inc.", 
-    "3.36", 
-    "$174.31M", 
-    "2008", 
-    "Technology", 
-    "Industrial Machinery/Components", 
-    "http://www.nasdaq.com/symbol/erii"
-  ], 
-  [
-    "EROC", 
-    "Eagle Rock Energy Partners, L.P.", 
-    "2.52", 
-    "$403.51M", 
-    "2006", 
-    "Energy", 
-    "Oil & Gas Production", 
-    "http://www.nasdaq.com/symbol/eroc"
-  ], 
-  [
-    "ERS", 
-    "Empire Resources, Inc.", 
-    "4.4675", 
-    "$40.1M", 
-    "n/a", 
-    "Basic Industries", 
-    "Metal Fabrications", 
-    "http://www.nasdaq.com/symbol/ers"
-  ], 
-  [
-    "ERW", 
-    "VelocityShares Equal Risk Weighted Large Cap ETF", 
-    "55.14", 
-    "$30.33M", 
-    "n/a", 
-    "n/a", 
-    "n/a", 
-    "http://www.nasdaq.com/symbol/erw"
-  ], 
-  [
-    "ESBK", 
-    "Elmira Savings Bank NY (The)", 
-    "21.14", 
-    "$52.91M", 
-    "n/a", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/esbk"
-  ], 
-  [
-    "ESCA", 
-    "Escalade, Incorporated", 
-    "15.52", 
-    "$216.53M", 
-    "n/a", 
-    "Consumer Non-Durables", 
-    "Recreational Products/Toys", 
-    "http://www.nasdaq.com/symbol/esca"
-  ], 
-  [
-    "ESCR", 
-    "Escalera Resources Co.", 
-    "0.7298", 
-    "$10.43M", 
-    "n/a", 
-    "Energy", 
-    "Oil & Gas Production", 
-    "http://www.nasdaq.com/symbol/escr"
-  ], 
-  [
-    "ESCRP", 
-    "Escalera Resources Co.", 
-    "14.91", 
-    "n/a", 
-    "n/a", 
-    "Energy", 
-    "Oil & Gas Production", 
-    "http://www.nasdaq.com/symbol/escrp"
-  ], 
-  [
-    "ESEA", 
-    "Euroseas Ltd.", 
-    "0.7568", 
-    "$43.22M", 
-    "n/a", 
-    "Transportation", 
-    "Marine Transportation", 
-    "http://www.nasdaq.com/symbol/esea"
-  ], 
-  [
-    "ESGR", 
-    "Enstar Group Limited", 
-    "136.88", 
-    "$2.63B", 
-    "n/a", 
-    "Finance", 
-    "Property-Casualty Insurers", 
-    "http://www.nasdaq.com/symbol/esgr"
-  ], 
-  [
-    "ESIO", 
-    "Electro Scientific Industries, Inc.", 
-    "6.55", 
-    "$199.08M", 
-    "n/a", 
-    "Miscellaneous", 
-    "Industrial Machinery/Components", 
-    "http://www.nasdaq.com/symbol/esio"
-  ], 
-  [
-    "ESLT", 
-    "Elbit Systems Ltd.", 
-    "64.29", 
-    "$2.74B", 
-    "n/a", 
-    "Capital Goods", 
-    "Military/Government/Technical", 
-    "http://www.nasdaq.com/symbol/eslt"
-  ], 
-  [
-    "ESMC", 
-    "Escalon Medical Corp.", 
-    "1.47", 
-    "$11.06M", 
-    "n/a", 
-    "Health Care", 
-    "Biotechnology: Electromedical & Electrotherapeutic Apparatus", 
-    "http://www.nasdaq.com/symbol/esmc"
-  ], 
-  [
-    "ESPR", 
-    "Esperion Therapeutics, Inc.", 
-    "65.98", 
-    "$1.34B", 
-    "2013", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/espr"
-  ], 
-  [
-    "ESRX", 
-    "Express Scripts Holding Company", 
-    "86.08", 
-    "$63.17B", 
-    "1992", 
-    "Health Care", 
-    "Medical/Nursing Services", 
-    "http://www.nasdaq.com/symbol/esrx"
-  ], 
-  [
-    "ESSA", 
-    "ESSA Bancorp, Inc.", 
-    "12.15", 
-    "$138.93M", 
-    "n/a", 
-    "Finance", 
-    "Banks", 
-    "http://www.nasdaq.com/symbol/essa"
-  ], 
-  [
-    "ESSX", 
-    "Essex Rental Corporation", 
-    "1.2676", 
-    "$31.45M", 
-    "n/a", 
-    "n/a", 
-    "n/a", 
-    "http://www.nasdaq.com/symbol/essx"
-  ], 
-  [
-    "ESXB", 
-    "Community Bankers Trust Corporation.", 
-    "4.48", 
-    "$97.59M", 
-    "n/a", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/esxb"
-  ], 
-  [
-    "ETFC", 
-    "E*TRADE Financial Corporation", 
-    "26.15", 
-    "$7.56B", 
-    "n/a", 
-    "Finance", 
-    "Savings Institutions", 
-    "http://www.nasdaq.com/symbol/etfc"
-  ], 
-  [
-    "ETRM", 
-    "EnteroMedics Inc.", 
-    "1.15", 
-    "$79.47M", 
-    "2007", 
-    "Health Care", 
-    "Biotechnology: Electromedical & Electrotherapeutic Apparatus", 
-    "http://www.nasdaq.com/symbol/etrm"
-  ], 
-  [
-    "EUFN", 
-    "iShares MSCI Europe Financials Sector Index Fund", 
-    "23.13", 
-    "$420.97M", 
-    "n/a", 
-    "n/a", 
-    "n/a", 
-    "http://www.nasdaq.com/symbol/eufn"
-  ], 
-  [
-    "EVAL", 
-    "iShares MSCI Emerging Markets Value Index Fund", 
-    "44.44", 
-    "$22.22M", 
-    "n/a", 
-    "n/a", 
-    "n/a", 
-    "http://www.nasdaq.com/symbol/eval"
-  ], 
-  [
-    "EVAR", 
-    "Lombard Medical, Inc.", 
-    "5.51", 
-    "$89.18M", 
-    "2014", 
-    "Health Care", 
-    "Medical/Dental Instruments", 
-    "http://www.nasdaq.com/symbol/evar"
-  ], 
-  [
-    "EVBS", 
-    "Eastern Virginia Bankshares, Inc.", 
-    "6.22", 
-    "$74.09M", 
-    "n/a", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/evbs"
-  ], 
-  [
-    "EVEP", 
-    "EV Energy Partners, L.P.", 
-    "16.42", 
-    "$797.55M", 
-    "2006", 
-    "Energy", 
-    "Oil & Gas Production", 
-    "http://www.nasdaq.com/symbol/evep"
-  ], 
-  [
-    "EVK", 
-    "Ever-Glory International Group, Inc.", 
-    "6.3", 
-    "$93.14M", 
-    "n/a", 
-    "Consumer Non-Durables", 
-    "Apparel", 
-    "http://www.nasdaq.com/symbol/evk"
-  ], 
-  [
-    "EVLV", 
-    "EVINE Live Inc.", 
-    "6.56", 
-    "$369.7M", 
-    "n/a", 
-    "Consumer Services", 
-    "Catalog/Specialty Distribution", 
-    "http://www.nasdaq.com/symbol/evlv"
-  ], 
-  [
-    "EVOK", 
-    "Evoke Pharma, Inc.", 
-    "5.68", 
-    "$34.72M", 
-    "2013", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/evok"
-  ], 
-  [
-    "EVOL", 
-    "Evolving Systems, Inc.", 
-    "8.56", 
-    "$99.84M", 
-    "1998", 
-    "Technology", 
-    "EDP Services", 
-    "http://www.nasdaq.com/symbol/evol"
-  ], 
-  [
-    "EVRY", 
-    "EveryWare Global, Inc.", 
-    "1.06", 
-    "$23.45M", 
-    "2012", 
-    "Consumer Durables", 
-    "Home Furnishings", 
-    "http://www.nasdaq.com/symbol/evry"
-  ], 
-  [
-    "EWBC", 
-    "East West Bancorp, Inc.", 
-    "40.53", 
-    "$5.82B", 
-    "n/a", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/ewbc"
-  ], 
-  [
-    "EXA", 
-    "Exa Corporation", 
-    "10.4", 
-    "$143.91M", 
-    "2012", 
-    "Technology", 
-    "Computer Software: Prepackaged Software", 
-    "http://www.nasdaq.com/symbol/exa"
-  ], 
-  [
-    "EXAC", 
-    "Exactech, Inc.", 
-    "23.18", 
-    "$320.07M", 
-    "1996", 
-    "Health Care", 
-    "Industrial Specialties", 
-    "http://www.nasdaq.com/symbol/exac"
-  ], 
-  [
-    "EXAS", 
-    "EXACT Sciences Corporation", 
-    "25.655", 
-    "$2.17B", 
-    "2001", 
-    "Health Care", 
-    "Biotechnology: Commercial Physical & Biological Resarch", 
-    "http://www.nasdaq.com/symbol/exas"
-  ], 
-  [
-    "EXEL", 
-    "Exelixis, Inc.", 
-    "2.74", 
-    "$534.89M", 
-    "2000", 
-    "Health Care", 
-    "Biotechnology: Commercial Physical & Biological Resarch", 
-    "http://www.nasdaq.com/symbol/exel"
-  ], 
-  [
-    "EXFO", 
-    "EXFO Inc", 
-    "3.74", 
-    "$107.47M", 
-    "n/a", 
-    "Capital Goods", 
-    "Electrical Products", 
-    "http://www.nasdaq.com/symbol/exfo"
-  ], 
-  [
-    "EXLP", 
-    "Exterran Partners, L.P.", 
-    "23.01", 
-    "$1.28B", 
-    "n/a", 
-    "Public Utilities", 
-    "Natural Gas Distribution", 
-    "http://www.nasdaq.com/symbol/exlp"
-  ], 
-  [
-    "EXLS", 
-    "ExlService Holdings, Inc.", 
-    "32.2", 
-    "$1.06B", 
-    "2006", 
-    "Miscellaneous", 
-    "Business Services", 
-    "http://www.nasdaq.com/symbol/exls"
-  ], 
-  [
-    "EXPD", 
-    "Expeditors International of Washington, Inc.", 
-    "45.505", 
-    "$8.78B", 
-    "n/a", 
-    "Transportation", 
-    "Oil Refining/Marketing", 
-    "http://www.nasdaq.com/symbol/expd"
-  ], 
-  [
-    "EXPE", 
-    "Expedia, Inc.", 
-    "92.3", 
-    "$11.7B", 
-    "n/a", 
-    "Consumer Services", 
-    "Transportation Services", 
-    "http://www.nasdaq.com/symbol/expe"
-  ], 
-  [
-    "EXPO", 
-    "Exponent, Inc.", 
-    "88.06", 
-    "$1.13B", 
-    "n/a", 
-    "Consumer Services", 
-    "Professional Services", 
-    "http://www.nasdaq.com/symbol/expo"
-  ], 
-  [
-    "EXTR", 
-    "Extreme Networks, Inc.", 
-    "3.46", 
-    "$343.67M", 
-    "1999", 
-    "Technology", 
-    "Computer Communications Equipment", 
-    "http://www.nasdaq.com/symbol/extr"
-  ], 
-  [
-    "EXXI", 
-    "Energy XXI Ltd.", 
-    "4.26", 
-    "$402.09M", 
-    "n/a", 
-    "Energy", 
-    "Oil & Gas Production", 
-    "http://www.nasdaq.com/symbol/exxi"
-  ], 
-  [
-    "EYES", 
-    "Second Sight Medical Products, Inc.", 
-    "8.75", 
-    "$302.97M", 
-    "2014", 
-    "Health Care", 
-    "Biotechnology: Electromedical & Electrotherapeutic Apparatus", 
-    "http://www.nasdaq.com/symbol/eyes"
-  ], 
-  [
-    "EZCH", 
-    "EZchip Semiconductor Limited", 
-    "21.75", 
-    "$645.95M", 
-    "n/a", 
-    "Technology", 
-    "Computer Communications Equipment", 
-    "http://www.nasdaq.com/symbol/ezch"
-  ], 
-  [
-    "EZPW", 
-    "EZCORP, Inc.", 
-    "10.37", 
-    "$556.36M", 
-    "1991", 
-    "Consumer Services", 
-    "Other Specialty Stores", 
-    "http://www.nasdaq.com/symbol/ezpw"
-  ], 
-  [
-    "FALC", 
-    "FalconStor Software, Inc.", 
-    "1.55", 
-    "$63.43M", 
-    "n/a", 
-    "Technology", 
-    "Computer Software: Prepackaged Software", 
-    "http://www.nasdaq.com/symbol/falc"
-  ], 
-  [
-    "FANG", 
-    "Diamondback Energy, Inc.", 
-    "75.09", 
-    "$4.4B", 
-    "2012", 
-    "Energy", 
-    "Oil & Gas Production", 
-    "http://www.nasdaq.com/symbol/fang"
-  ], 
-  [
-    "FARM", 
-    "Farmer Brothers Company", 
-    "24.09", 
-    "$399.7M", 
-    "n/a", 
-    "Consumer Non-Durables", 
-    "Packaged Foods", 
-    "http://www.nasdaq.com/symbol/farm"
-  ], 
-  [
-    "FARO", 
-    "FARO Technologies, Inc.", 
-    "59.04", 
-    "$1.02B", 
-    "1997", 
-    "Capital Goods", 
-    "Industrial Machinery/Components", 
-    "http://www.nasdaq.com/symbol/faro"
-  ], 
-  [
-    "FAST", 
-    "Fastenal Company", 
-    "42.765", 
-    "$12.65B", 
-    "1987", 
-    "Consumer Services", 
-    "RETAIL: Building Materials", 
-    "http://www.nasdaq.com/symbol/fast"
-  ], 
-  [
-    "FATE", 
-    "Fate Therapeutics, Inc.", 
-    "5", 
-    "$102.85M", 
-    "2013", 
-    "Health Care", 
-    "Biotechnology: Biological Products (No Diagnostic Substances)", 
-    "http://www.nasdaq.com/symbol/fate"
-  ], 
-  [
-    "FB", 
-    "Facebook, Inc.", 
-    "79.895", 
-    "$223.63B", 
-    "2012", 
-    "Technology", 
-    "Computer Software: Programming, Data Processing", 
-    "http://www.nasdaq.com/symbol/fb"
-  ], 
-  [
-    "FBIZ", 
-    "First Business Financial Services, Inc.", 
-    "47", 
-    "$186.74M", 
-    "n/a", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/fbiz"
-  ], 
-  [
-    "FBMS", 
-    "The First Bancshares, Inc.", 
-    "14.82", 
-    "$78.72M", 
-    "n/a", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/fbms"
-  ], 
-  [
-    "FBNC", 
-    "First Bancorp", 
-    "17.16", 
-    "$338.14M", 
-    "1987", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/fbnc"
-  ], 
-  [
-    "FBNK", 
-    "First Connecticut Bancorp, Inc.", 
-    "14.98", 
-    "$240.07M", 
-    "2011", 
-    "Finance", 
-    "Banks", 
-    "http://www.nasdaq.com/symbol/fbnk"
-  ], 
-  [
-    "FBRC", 
-    "FBR & Co", 
-    "24.07", 
-    "$213.75M", 
-    "n/a", 
-    "Finance", 
-    "Investment Bankers/Brokers/Service", 
-    "http://www.nasdaq.com/symbol/fbrc"
-  ], 
-  [
-    "FBSS", 
-    "Fauquier Bankshares, Inc.", 
-    "16.25", 
-    "$60.63M", 
-    "n/a", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/fbss"
-  ], 
-  [
-    "FCAP", 
-    "First Capital, Inc.", 
-    "24.5", 
-    "$67.14M", 
-    "n/a", 
-    "Finance", 
-    "Savings Institutions", 
-    "http://www.nasdaq.com/symbol/fcap"
-  ], 
-  [
-    "FCBC", 
-    "First Community Bancshares, Inc.", 
-    "16.3", 
-    "$299.66M", 
-    "n/a", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/fcbc"
-  ], 
-  [
-    "FCCO", 
-    "First Community Corporation", 
-    "11.73", 
-    "$78.13M", 
-    "n/a", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/fcco"
-  ], 
-  [
-    "FCCY", 
-    "1st Constitution Bancorp (NJ)", 
-    "11.18", 
-    "$79.77M", 
-    "n/a", 
-    "Finance", 
-    "Savings Institutions", 
-    "http://www.nasdaq.com/symbol/fccy"
-  ], 
-  [
-    "FCEL", 
-    "FuelCell Energy, Inc.", 
-    "1.33", 
-    "$388.63M", 
-    "n/a", 
-    "Miscellaneous", 
-    "Industrial Machinery/Components", 
-    "http://www.nasdaq.com/symbol/fcel"
-  ], 
-  [
-    "FCFS", 
-    "First Cash Financial Services, Inc.", 
-    "48.92", 
-    "$1.39B", 
-    "1991", 
-    "Consumer Services", 
-    "Other Specialty Stores", 
-    "http://www.nasdaq.com/symbol/fcfs"
-  ], 
-  [
-    "FCHI", 
-    "iShares FTSE China Index Fund", 
-    "53.11", 
-    "$26.56M", 
-    "n/a", 
-    "n/a", 
-    "n/a", 
-    "http://www.nasdaq.com/symbol/fchi"
-  ], 
-  [
-    "FCLF", 
-    "First Clover Leaf Financial Corp.", 
-    "8.7", 
-    "$60.96M", 
-    "n/a", 
-    "Finance", 
-    "Savings Institutions", 
-    "http://www.nasdaq.com/symbol/fclf"
-  ], 
-  [
-    "FCNCA", 
-    "First Citizens BancShares, Inc.", 
-    "253.82", 
-    "$2.44B", 
-    "n/a", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/fcnca"
-  ], 
-  [
-    "FCS", 
-    "Fairchild Semiconductor International, Inc.", 
-    "16.11", 
-    "$1.91B", 
-    "1999", 
-    "Technology", 
-    "Semiconductors", 
-    "http://www.nasdaq.com/symbol/fcs"
-  ], 
-  [
-    "FCSC", 
-    "Fibrocell Science Inc", 
-    "4.9", 
-    "$200.2M", 
-    "n/a", 
-    "Health Care", 
-    "Major Pharmaceuticals", 
-    "http://www.nasdaq.com/symbol/fcsc"
-  ], 
-  [
-    "FCTY", 
-    "1st Century Bancshares, Inc", 
-    "6.774", 
-    "$68.73M", 
-    "n/a", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/fcty"
-  ], 
-  [
-    "FCVA", 
-    "First Capital Bancorp, Inc. (VA)", 
-    "4.3", 
-    "$55.32M", 
-    "2007", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/fcva"
-  ], 
-  [
-    "FCZA", 
-    "First Citizens Banc Corp.", 
-    "10.87", 
-    "$83.79M", 
-    "n/a", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/fcza"
-  ], 
-  [
-    "FCZAP", 
-    "First Citizens Banc Corp.", 
-    "35.21", 
-    "n/a", 
-    "n/a", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/fczap"
-  ], 
-  [
-    "FDEF", 
-    "First Defiance Financial Corp.", 
-    "32", 
-    "$298.99M", 
-    "n/a", 
-    "Finance", 
-    "Savings Institutions", 
-    "http://www.nasdaq.com/symbol/fdef"
-  ], 
-  [
-    "FDIV", 
-    "First Trust Strategic Income ETF", 
-    "50.3", 
-    "$20.12M", 
-    "n/a", 
-    "n/a", 
-    "n/a", 
-    "http://www.nasdaq.com/symbol/fdiv"
-  ], 
-  [
-    "FDML", 
-    "Federal-Mogul Holdings Corporation", 
-    "15.41", 
-    "$2.31B", 
-    "n/a", 
-    "Capital Goods", 
-    "Auto Parts:O.E.M.", 
-    "http://www.nasdaq.com/symbol/fdml"
-  ], 
-  [
-    "FDUS", 
-    "Fidus Investment Corporation", 
-    "16.44", 
-    "$263.48M", 
-    "2011", 
-    "n/a", 
-    "n/a", 
-    "http://www.nasdaq.com/symbol/fdus"
-  ], 
-  [
-    "FEIC", 
-    "FEI Company", 
-    "80.52", 
-    "$3.35B", 
-    "1995", 
-    "Capital Goods", 
-    "Biotechnology: Laboratory Analytical Instruments", 
-    "http://www.nasdaq.com/symbol/feic"
-  ], 
-  [
-    "FEIM", 
-    "Frequency Electronics, Inc.", 
-    "12.37", 
-    "$106.45M", 
-    "n/a", 
-    "Capital Goods", 
-    "Electrical Products", 
-    "http://www.nasdaq.com/symbol/feim"
-  ], 
-  [
-    "FELE", 
-    "Franklin Electric Co., Inc.", 
-    "34.81", 
-    "$1.65B", 
-    "n/a", 
-    "Consumer Durables", 
-    "Metal Fabrications", 
-    "http://www.nasdaq.com/symbol/fele"
-  ], 
-  [
-    "FEMB", 
-    "First Trust Emerging Markets Local Currency Bond ETF", 
-    "47.64", 
-    "n/a", 
-    "n/a", 
-    "n/a", 
-    "n/a", 
-    "http://www.nasdaq.com/symbol/femb"
-  ], 
-  [
-    "FES", 
-    "Forbes Energy Services Ltd", 
-    "1.12", 
-    "$24.46M", 
-    "n/a", 
-    "Energy", 
-    "Oilfield Services/Equipment", 
-    "http://www.nasdaq.com/symbol/fes"
-  ], 
-  [
-    "FEUZ", 
-    "First Trust Eurozone AlphaDEX ETF", 
-    "33.04", 
-    "n/a", 
-    "n/a", 
-    "n/a", 
-    "n/a", 
-    "http://www.nasdaq.com/symbol/feuz"
-  ], 
-  [
-    "FEYE", 
-    "FireEye, Inc.", 
-    "46.15", 
-    "$6.94B", 
-    "2013", 
-    "Technology", 
-    "Computer peripheral equipment", 
-    "http://www.nasdaq.com/symbol/feye"
-  ], 
-  [
-    "FFBC", 
-    "First Financial Bancorp.", 
-    "17.67", 
-    "$1.08B", 
-    "n/a", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/ffbc"
-  ], 
-  [
-    "FFBCW", 
-    "First Financial Bancorp.", 
-    "6.11", 
-    "n/a", 
-    "n/a", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/ffbcw"
-  ], 
-  [
-    "FFHL", 
-    "Fuwei Films (Holdings) Co., Ltd.", 
-    "0.6", 
-    "$7.84M", 
-    "2006", 
-    "Capital Goods", 
-    "Specialty Chemicals", 
-    "http://www.nasdaq.com/symbol/ffhl"
-  ], 
-  [
-    "FFIC", 
-    "Flushing Financial Corporation", 
-    "19.61", 
-    "$581.45M", 
-    "n/a", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/ffic"
-  ], 
-  [
-    "FFIN", 
-    "First Financial Bankshares, Inc.", 
-    "26.07", 
-    "$1.67B", 
-    "n/a", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/ffin"
-  ], 
-  [
-    "FFIV", 
-    "F5 Networks, Inc.", 
-    "119.36", 
-    "$8.61B", 
-    "1999", 
-    "Technology", 
-    "Computer Communications Equipment", 
-    "http://www.nasdaq.com/symbol/ffiv"
-  ], 
-  [
-    "FFKT", 
-    "Farmers Capital Bank Corporation", 
-    "22.83", 
-    "$170.94M", 
-    "n/a", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/ffkt"
-  ], 
-  [
-    "FFNM", 
-    "First Federal of Northern Michigan Bancorp, Inc.", 
-    "5.4464", 
-    "$20.3M", 
-    "n/a", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/ffnm"
-  ], 
-  [
-    "FFNW", 
-    "First Financial Northwest, Inc.", 
-    "12.27", 
-    "$188.7M", 
-    "n/a", 
-    "Finance", 
-    "Banks", 
-    "http://www.nasdaq.com/symbol/ffnw"
-  ], 
-  [
-    "FFWM", 
-    "First Foundation Inc.", 
-    "17.89", 
-    "$138.38M", 
-    "n/a", 
-    "Finance", 
-    "Major Banks", 
-    "http://www.nasdaq.com/symbol/ffwm"
-  ]
-]
\ No newline at end of file
diff --git a/examples/stocks/flutter.yaml b/examples/stocks/flutter.yaml
deleted file mode 100644
index 9c1ae43..0000000
--- a/examples/stocks/flutter.yaml
+++ /dev/null
@@ -1,15 +0,0 @@
-name: stocks
-version: 0.0.2
-update-url: http://localhost:9888/
-material-design-icons:
-  - name: action/account_balance
-  - name: action/assessment
-  - name: action/help
-  - name: action/search
-  - name: action/settings
-  - name: action/thumb_down
-  - name: action/thumb_up
-  - name: content/add
-  - name: navigation/arrow_back
-  - name: navigation/menu
-  - name: navigation/more_vert
diff --git a/examples/stocks/ios/Info.plist b/examples/stocks/ios/Info.plist
deleted file mode 100644
index 52da94f..0000000
--- a/examples/stocks/ios/Info.plist
+++ /dev/null
@@ -1,58 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
-<plist version="1.0">
-<dict>
-  <key>CFBundleDevelopmentRegion</key>
-  <string>en</string>
-
-  <!--
-    This executable name must match the name of the app provided to the
-    ios_app GN template
-  -->
-  <key>CFBundleExecutable</key>
-  <string>stocks_app</string>
-
-  <key>CFBundleDisplayName</key>
-  <string>Stocks</string>
-
-  <key>UILaunchStoryboardName</key>
-  <string>LaunchScreen</string>
-
-  <key>CFBundleIdentifier</key>
-  <string>com.google.stocks</string>
-  
-  <key>CFBundleInfoDictionaryVersion</key>
-  <string>6.0</string>
-  <key>CFBundleName</key>
-  <string>game_app</string>
-  <key>CFBundlePackageType</key>
-  <string>APPL</string>
-  <key>CFBundleShortVersionString</key>
-  <string>1.0</string>
-  <key>CFBundleVersion</key>
-  <string>1</string>
-  <key>LSRequiresIPhoneOS</key>
-  <true/>
-  <key>UIRequiredDeviceCapabilities</key>
-  <array>
-    <string>armv7</string>
-  </array>
-  <key>DTPlatformName</key>
-  <string>iphonesimulator</string>
-  <key>DTSDKName</key>
-  <string>iphonesimulator8.3</string>
-  <key>LSRequiresIPhoneOS</key>
-  <true/>
-  <key>MinimumOSVersion</key>
-  <string>7.0</string>
-  <key>UIDeviceFamily</key>
-  <array>
-    <integer>1</integer>
-    <integer>2</integer>
-  </array>
-  <key>CFBundleSupportedPlatforms</key>
-  <array>
-    <string>iPhoneSimulator</string>
-  </array>
-</dict>
-</plist>
diff --git a/examples/stocks/ios/LaunchScreen.storyboardc/01J-lp-oVM-view-Ze5-6b-2t3.nib b/examples/stocks/ios/LaunchScreen.storyboardc/01J-lp-oVM-view-Ze5-6b-2t3.nib
deleted file mode 100644
index 1aa489d..0000000
--- a/examples/stocks/ios/LaunchScreen.storyboardc/01J-lp-oVM-view-Ze5-6b-2t3.nib
+++ /dev/null
Binary files differ
diff --git a/examples/stocks/ios/LaunchScreen.storyboardc/Info.plist b/examples/stocks/ios/LaunchScreen.storyboardc/Info.plist
deleted file mode 100644
index 32288e8..0000000
--- a/examples/stocks/ios/LaunchScreen.storyboardc/Info.plist
+++ /dev/null
Binary files differ
diff --git a/examples/stocks/ios/LaunchScreen.storyboardc/UIViewController-01J-lp-oVM.nib b/examples/stocks/ios/LaunchScreen.storyboardc/UIViewController-01J-lp-oVM.nib
deleted file mode 100644
index 8de9bed..0000000
--- a/examples/stocks/ios/LaunchScreen.storyboardc/UIViewController-01J-lp-oVM.nib
+++ /dev/null
Binary files differ
diff --git a/examples/stocks/lib/main.dart b/examples/stocks/lib/main.dart
deleted file mode 100644
index 9e091eb..0000000
--- a/examples/stocks/lib/main.dart
+++ /dev/null
@@ -1,105 +0,0 @@
-// Copyright 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.
-
-library stocks;
-
-import 'dart:async';
-import 'dart:math' as math;
-import 'dart:ui' as ui;
-
-import 'package:flutter/gestures.dart';
-import 'package:flutter/material.dart';
-import 'package:flutter/painting.dart';
-import 'package:flutter/rendering.dart';
-
-import 'stock_data.dart';
-
-part 'stock_arrow.dart';
-part 'stock_home.dart';
-part 'stock_list.dart';
-part 'stock_menu.dart';
-part 'stock_row.dart';
-part 'stock_settings.dart';
-part 'stock_symbol_viewer.dart';
-part 'stock_types.dart';
-
-class StocksApp extends StatefulComponent {
-  StocksAppState createState() => new StocksAppState();
-}
-
-class StocksAppState extends State<StocksApp> {
-
-  final Map<String, Stock> _stocks = <String, Stock>{};
-  final List<String> _symbols = <String>[];
-
-  void initState() {
-    super.initState();
-    new StockDataFetcher((StockData data) {
-      setState(() {
-        data.appendTo(_stocks, _symbols);
-      });
-    });
-  }
-
-  StockMode _optimismSetting = StockMode.optimistic;
-  BackupMode _backupSetting = BackupMode.disabled;
-  void modeUpdater(StockMode optimism) {
-    setState(() {
-      _optimismSetting = optimism;
-    });
-  }
-  void settingsUpdater({ StockMode optimism, BackupMode backup }) {
-    setState(() {
-      if (optimism != null)
-        _optimismSetting = optimism;
-      if (backup != null)
-        _backupSetting = backup;
-    });
-  }
-
-  ThemeData get theme {
-    switch (_optimismSetting) {
-      case StockMode.optimistic:
-        return new ThemeData(
-          brightness: ThemeBrightness.light,
-          primarySwatch: Colors.purple
-        );
-      case StockMode.pessimistic:
-        return new ThemeData(
-          brightness: ThemeBrightness.dark,
-          accentColor: Colors.redAccent[200]
-        );
-    }
-  }
-
-  RouteBuilder _getRoute(String name) {
-    List<String> path = name.split('/');
-    if (path[0] != '')
-      return null;
-    if (path[1] == 'stock') {
-      if (path.length != 3)
-        return null;
-      if (_stocks.containsKey(path[2]))
-        return (RouteArguments args) => new StockSymbolViewer(_stocks[path[2]]);
-      return null;
-    }
-    return null;
-  }
-
-  Widget build(BuildContext context) {
-    return new MaterialApp(
-      title: 'Stocks',
-      theme: theme,
-      routes: <String, RouteBuilder>{
-         '/':         (RouteArguments args) => new StockHome(_stocks, _symbols, _optimismSetting, modeUpdater),
-         '/settings': (RouteArguments args) => new StockSettings(_optimismSetting, _backupSetting, settingsUpdater)
-      },
-      onGenerateRoute: _getRoute
-    );
-  }
-}
-
-void main() {
-  runApp(new StocksApp());
-}
diff --git a/examples/stocks/lib/stock_arrow.dart b/examples/stocks/lib/stock_arrow.dart
deleted file mode 100644
index 1ae424e..0000000
--- a/examples/stocks/lib/stock_arrow.dart
+++ /dev/null
@@ -1,67 +0,0 @@
-// Copyright 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 stocks;
-
-class StockArrow extends StatelessComponent {
-  StockArrow({ Key key, this.percentChange }) : super(key: key);
-
-  final double percentChange;
-
-  int _colorIndexForPercentChange(double percentChange) {
-    double maxPercent = 10.0;
-    double normalizedPercentChange = math.min(percentChange.abs(), maxPercent) / maxPercent;
-    return 100 + (normalizedPercentChange * 8.0).floor() * 100;
-  }
-
-  Color _colorForPercentChange(double percentChange) {
-    if (percentChange > 0)
-      return Colors.green[_colorIndexForPercentChange(percentChange)];
-    return Colors.red[_colorIndexForPercentChange(percentChange)];
-  }
-
-  Widget build(BuildContext context) {
-    // TODO(jackson): This should change colors with the theme
-    Color color = _colorForPercentChange(percentChange);
-    const double kSize = 40.0;
-    var arrow = new CustomPaint(onPaint: (ui.Canvas canvas, Size size) {
-      Paint paint = new Paint()..color = color;
-      paint.strokeWidth = 1.0;
-      const double padding = 2.0;
-      assert(padding > paint.strokeWidth / 2.0); // make sure the circle remains inside the box
-      double r = (kSize - padding) / 2.0; // radius of the circle
-      double centerX = padding + r;
-      double centerY = padding + r;
-
-      // Draw the arrow.
-      double w = 8.0;
-      double h = 5.0;
-      double arrowY;
-      if (percentChange < 0.0) {
-        h = -h;
-        arrowY = centerX + 1.0;
-      } else {
-        arrowY = centerX - 1.0;
-      }
-      Path path = new Path();
-      path.moveTo(centerX, arrowY - h); // top of the arrow
-      path.lineTo(centerX + w, arrowY + h);
-      path.lineTo(centerX - w, arrowY + h);
-      path.close();
-      paint.style = ui.PaintingStyle.fill;
-      canvas.drawPath(path, paint);
-
-      // Draw a circle that circumscribes the arrow.
-      paint.style = ui.PaintingStyle.stroke;
-      canvas.drawCircle(new Point(centerX, centerY), r, paint);
-    });
-
-    return new Container(
-      child: arrow,
-      width: kSize,
-      height: kSize,
-      margin: const EdgeDims.symmetric(horizontal: 5.0)
-    );
-  }
-}
diff --git a/examples/stocks/lib/stock_data.dart b/examples/stocks/lib/stock_data.dart
deleted file mode 100644
index 53bffc3..0000000
--- a/examples/stocks/lib/stock_data.dart
+++ /dev/null
@@ -1,89 +0,0 @@
-// Copyright 2014 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.
-
-// Snapshot from http://www.nasdaq.com/screening/company-list.aspx
-// Fetched 2/23/2014.
-// "Symbol","Name","LastSale","MarketCap","IPOyear","Sector","industry","Summary Quote",
-// Data in stock_data.json
-
-import 'dart:convert';
-import 'dart:math' as math;
-
-import 'package:flutter/services.dart';
-
-final math.Random _rng = new math.Random();
-
-class Stock {
-  String symbol;
-  String name;
-  double lastSale;
-  String marketCap;
-  double percentChange;
-
-  Stock(this.symbol, this.name, this.lastSale, this.marketCap, this.percentChange);
-
-  Stock.fromFields(List<String> fields) {
-    // FIXME: This class should only have static data, not lastSale, etc.
-    // "Symbol","Name","LastSale","MarketCap","IPOyear","Sector","industry","Summary Quote",
-    lastSale = 0.0;
-    try{
-      lastSale = double.parse(fields[2]);
-    } catch(_) {}
-    symbol = fields[0];
-    name = fields[1];
-    marketCap = fields[4];
-    percentChange = (_rng.nextDouble() * 20) - 10;
-  }
-}
-
-class StockData {
-  List<List<String>> _data;
-
-  StockData(this._data);
-
-  void appendTo(Map<String, Stock> stocks, List<String> symbols) {
-    for (List<String> fields in _data) {
-      Stock stock = new Stock.fromFields(fields);
-      symbols.add(stock.symbol);
-      stocks[stock.symbol] = stock;
-    }
-    symbols.sort();
-  }
-}
-
-typedef void StockDataCallback(StockData data);
-const _kChunkCount = 30;
-
-String _urlToFetch(int chunk) {
-  if (rootBundle == null)
-    return '../data/stock_data_$chunk.json';
-  return 'https://domokit.github.io/examples/stocks/data/stock_data_$chunk.json';
-}
-
-class StockDataFetcher {
-  int _nextChunk = 0;
-  final StockDataCallback callback;
-
-  static bool actuallyFetchData = true;
-
-  StockDataFetcher(this.callback) {
-    _fetchNextChunk();
-  }
-
-  void _fetchNextChunk() {
-    if (!actuallyFetchData)
-      return;
-    fetchBody(_urlToFetch(_nextChunk++)).then((Response response) {
-      String json = response.bodyAsString();
-      if (json == null) {
-        print("Failed to load stock data chunk ${_nextChunk - 1}");
-        return;
-      }
-      JsonDecoder decoder = new JsonDecoder();
-      callback(new StockData(decoder.convert(json)));
-      if (_nextChunk < _kChunkCount)
-        _fetchNextChunk();
-    });
-  }
-}
diff --git a/examples/stocks/lib/stock_home.dart b/examples/stocks/lib/stock_home.dart
deleted file mode 100644
index bd9a9e7..0000000
--- a/examples/stocks/lib/stock_home.dart
+++ /dev/null
@@ -1,269 +0,0 @@
-// Copyright 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 stocks;
-
-typedef void ModeUpdater(StockMode mode);
-
-class StockHome extends StatefulComponent {
-  StockHome(this.stocks, this.symbols, this.stockMode, this.modeUpdater);
-
-  final Map<String, Stock> stocks;
-  final List<String> symbols;
-  final StockMode stockMode;
-  final ModeUpdater modeUpdater;
-
-  StockHomeState createState() => new StockHomeState();
-}
-
-class StockHomeState extends State<StockHome> {
-
-  final GlobalKey<PlaceholderState> _snackBarPlaceholderKey = new GlobalKey<PlaceholderState>();
-  bool _isSearching = false;
-  String _searchQuery;
-
-  void _handleSearchBegin() {
-    Navigator.of(context).push(new StateRoute(
-      onPop: () {
-        setState(() {
-          _isSearching = false;
-          _searchQuery = null;
-        });
-      }
-    ));
-    setState(() {
-      _isSearching = true;
-    });
-  }
-
-  void _handleSearchEnd() {
-    Navigator.of(context).pop();
-  }
-
-  void _handleSearchQueryChanged(String query) {
-    setState(() {
-      _searchQuery = query;
-    });
-  }
-
-  bool _autorefresh = false;
-  void _handleAutorefreshChanged(bool value) {
-    setState(() {
-      _autorefresh = value;
-    });
-  }
-
-  void _handleStockModeChange(StockMode value) {
-    if (config.modeUpdater != null)
-      config.modeUpdater(value);
-  }
-
-  void _handleMenuShow() {
-    showStockMenu(
-      context: context,
-      autorefresh: _autorefresh,
-      onAutorefreshChanged: _handleAutorefreshChanged
-    );
-  }
-
-  void _showDrawer() {
-    showDrawer(
-      context: context,
-      child: new Block(<Widget>[
-        new DrawerHeader(child: new Text('Stocks')),
-        new DrawerItem(
-          icon: 'action/assessment',
-          selected: true,
-          child: new Text('Stock List')
-        ),
-        new DrawerItem(
-          icon: 'action/account_balance',
-          onPressed: () {
-            showDialog(
-              context: context,
-              child: new Dialog(
-                title: new Text('Not Implemented'),
-                content: new Text('This feature has not yet been implemented.'),
-                actions: <Widget>[
-                  new FlatButton(
-                    child: new Text('USE IT'),
-                    onPressed: () {
-                      Navigator.of(context).pop(false);
-                    }
-                  ),
-                  new FlatButton(
-                    child: new Text('OH WELL'),
-                    onPressed: () {
-                      Navigator.of(context).pop(false);
-                    }
-                  ),
-                ]
-              )
-            );
-          },
-          child: new Text('Account Balance')
-        ),
-        new DrawerItem(
-          icon: 'device/dvr',
-          onPressed: () { debugDumpApp(); debugDumpRenderTree(); },
-          child: new Text('Dump App to Console')
-        ),
-        new DrawerDivider(),
-        new DrawerItem(
-          icon: 'action/thumb_up',
-          onPressed: () => _handleStockModeChange(StockMode.optimistic),
-          child: new Row(<Widget>[
-            new Flexible(child: new Text('Optimistic')),
-            new Radio<StockMode>(value: StockMode.optimistic, groupValue: config.stockMode, onChanged: _handleStockModeChange)
-          ])
-        ),
-        new DrawerItem(
-          icon: 'action/thumb_down',
-          onPressed: () => _handleStockModeChange(StockMode.pessimistic),
-          child: new Row(<Widget>[
-            new Flexible(child: new Text('Pessimistic')),
-            new Radio<StockMode>(value: StockMode.pessimistic, groupValue: config.stockMode, onChanged: _handleStockModeChange)
-          ])
-        ),
-        new DrawerDivider(),
-        new DrawerItem(
-          icon: 'action/settings',
-          onPressed: _handleShowSettings,
-          child: new Text('Settings')),
-        new DrawerItem(
-          icon: 'action/help',
-          child: new Text('Help & Feedback'))
-      ])
-    );
-  }
-
-  void _handleShowSettings() {
-    Navigator.of(context)..pop()
-                         ..pushNamed('/settings');
-  }
-
-  Widget buildToolBar() {
-    return new ToolBar(
-      level: 0,
-      left: new IconButton(
-        icon: "navigation/menu",
-        onPressed: _showDrawer
-      ),
-      center: new Text('Stocks'),
-      right: <Widget>[
-        new IconButton(
-          icon: "action/search",
-          onPressed: _handleSearchBegin
-        ),
-        new IconButton(
-          icon: "navigation/more_vert",
-          onPressed: _handleMenuShow
-        )
-      ]
-    );
-  }
-
-  int selectedTabIndex = 0;
-
-  Iterable<Stock> _getStockList(Iterable<String> symbols) {
-    return symbols.map((String symbol) => config.stocks[symbol])
-        .where((Stock stock) => stock != null);
-  }
-
-  Iterable<Stock> _filterBySearchQuery(Iterable<Stock> stocks) {
-    if (_searchQuery == null)
-      return stocks;
-    RegExp regexp = new RegExp(_searchQuery, caseSensitive: false);
-    return stocks.where((Stock stock) => stock.symbol.contains(regexp));
-  }
-
-  Widget buildStockList(BuildContext context, Iterable<Stock> stocks) {
-    return new StockList(
-      stocks: stocks.toList(),
-      onAction: (Stock stock, Key arrowKey) {
-        setState(() {
-          stock.percentChange = 100.0 * (1.0 / stock.lastSale);
-          stock.lastSale += 1.0;
-        });
-      },
-      onOpen: (Stock stock, Key arrowKey) {
-        Set<Key> mostValuableKeys = new Set<Key>();
-        mostValuableKeys.add(arrowKey);
-        Navigator.of(context).pushNamed('/stock/${stock.symbol}', mostValuableKeys: mostValuableKeys);
-      }
-    );
-  }
-
-  static const List<String> portfolioSymbols = const <String>["AAPL","FIZZ", "FIVE", "FLAT", "ZINC", "ZNGA"];
-
-  Widget buildTabNavigator() {
-    return new TabNavigator(
-      views: <TabNavigatorView>[
-        new TabNavigatorView(
-          label: const TabLabel(text: 'MARKET'),
-          builder: (BuildContext context) => buildStockList(context, _filterBySearchQuery(_getStockList(config.symbols)).toList())
-        ),
-        new TabNavigatorView(
-          label: const TabLabel(text: 'PORTFOLIO'),
-          builder: (BuildContext context) => buildStockList(context, _filterBySearchQuery(_getStockList(portfolioSymbols)).toList())
-        )
-      ],
-      selectedIndex: selectedTabIndex,
-      onChanged: (int tabIndex) {
-        setState(() { selectedTabIndex = tabIndex; } );
-      }
-    );
-  }
-
-  static GlobalKey searchFieldKey = new GlobalKey();
-
-  // TODO(abarth): Should we factor this into a SearchBar in the framework?
-  Widget buildSearchBar() {
-    return new ToolBar(
-      left: new IconButton(
-        icon: "navigation/arrow_back",
-        colorFilter: new ColorFilter.mode(Theme.of(context).accentColor, ui.TransferMode.srcATop),
-        onPressed: _handleSearchEnd
-      ),
-      center: new Input(
-        key: searchFieldKey,
-        placeholder: 'Search stocks',
-        onChanged: _handleSearchQueryChanged
-      ),
-      backgroundColor: Theme.of(context).canvasColor
-    );
-  }
-
-  void _handleUndo() {
-    Navigator.of(context).pop();
-  }
-
-  void _handleStockPurchased() {
-    showSnackBar(
-      context: context,
-      placeholderKey: _snackBarPlaceholderKey,
-      content: new Text("Stock purchased!"),
-      actions: <SnackBarAction>[
-        new SnackBarAction(label: "UNDO", onPressed: _handleUndo)
-      ]
-    );
-  }
-
-  Widget buildFloatingActionButton() {
-    return new FloatingActionButton(
-      child: new Icon(icon: 'content/add'),
-      backgroundColor: Colors.redAccent[200],
-      onPressed: _handleStockPurchased
-    );
-  }
-
-  Widget build(BuildContext context) {
-    return new Scaffold(
-      toolBar: _isSearching ? buildSearchBar() : buildToolBar(),
-      body: buildTabNavigator(),
-      snackBar: new Placeholder(key: _snackBarPlaceholderKey),
-      floatingActionButton: buildFloatingActionButton()
-    );
-  }
-}
diff --git a/examples/stocks/lib/stock_list.dart b/examples/stocks/lib/stock_list.dart
deleted file mode 100644
index 8d153f2..0000000
--- a/examples/stocks/lib/stock_list.dart
+++ /dev/null
@@ -1,27 +0,0 @@
-// Copyright 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 stocks;
-
-class StockList extends StatelessComponent {
-  StockList({ Key key, this.stocks, this.onOpen, this.onAction }) : super(key: key);
-
-  final List<Stock> stocks;
-  final StockRowActionCallback onOpen;
-  final StockRowActionCallback onAction;
-
-  Widget build(BuildContext context) {
-    return new ScrollableList<Stock>(
-      items: stocks,
-      itemExtent: StockRow.kHeight,
-      itemBuilder: (BuildContext context, Stock stock) {
-        return new StockRow(
-          stock: stock,
-          onPressed: onOpen,
-          onLongPressed: onAction
-        );
-      }
-    );
-  }
-}
diff --git a/examples/stocks/lib/stock_menu.dart b/examples/stocks/lib/stock_menu.dart
deleted file mode 100644
index ec921d8..0000000
--- a/examples/stocks/lib/stock_menu.dart
+++ /dev/null
@@ -1,88 +0,0 @@
-// Copyright 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 stocks;
-
-enum _MenuItems { autorefresh, autorefreshCheckbox, add, remove }
-
-const double _kMenuMargin = 16.0; // 24.0 on tablet
-
-Future showStockMenu({BuildContext context, bool autorefresh, ValueChanged<bool> onAutorefreshChanged }) async {
-  switch (await showMenu(
-    context: context,
-    position: new ModalPosition(
-      right: ui.window.padding.right + _kMenuMargin,
-      top: ui.window.padding.top + _kMenuMargin
-    ),
-    items: <PopupMenuItem>[
-      new PopupMenuItem(
-        value: _MenuItems.autorefresh,
-        child: new Row(<Widget>[
-            new Flexible(child: new Text('Autorefresh')),
-            new Checkbox(
-              value: autorefresh,
-              onChanged: (bool value) {
-                Navigator.of(context).setState(() {
-                  autorefresh = value;
-                });
-                Navigator.of(context).pop(_MenuItems.autorefreshCheckbox);
-              }
-            )
-          ]
-        )
-      ),
-      new PopupMenuItem(
-        value: _MenuItems.add,
-        child: new Text('Add stock')
-      ),
-      new PopupMenuItem(
-        value: _MenuItems.remove,
-        child: new Text('Remove stock')
-      ),
-    ]
-  )) {
-    case _MenuItems.autorefresh:
-      Navigator.of(context).setState(() {
-        autorefresh = !autorefresh;
-      });
-      continue autorefreshNotify;
-    autorefreshNotify:
-    case _MenuItems.autorefreshCheckbox:
-      onAutorefreshChanged(autorefresh);
-      break;
-    case _MenuItems.add:
-    case _MenuItems.remove:
-      await showDialog(
-        context: context,
-        child: new Dialog(
-          title: new Text('Not Implemented'),
-          content: new Text('This feature has not yet been implemented.'),
-          actions: <Widget>[
-            new FlatButton(
-              child: new Row(<Widget>[
-                new Icon(
-                  icon: 'device/dvr',
-                  size: IconSize.s18
-                ),
-                new Container(
-                  width: 8.0
-                ),
-                new Text('DUMP APP TO CONSOLE'),
-              ]),
-              onPressed: () { debugDumpApp(); }
-            ),
-            new FlatButton(
-              child: new Text('OH WELL'),
-              onPressed: () {
-                Navigator.of(context).pop(false);
-              }
-            ),
-          ]
-        )
-      );
-      break;
-    default:
-      // menu was canceled.
-  }
-}
diff --git a/examples/stocks/lib/stock_row.dart b/examples/stocks/lib/stock_row.dart
deleted file mode 100644
index 5f2010c..0000000
--- a/examples/stocks/lib/stock_row.dart
+++ /dev/null
@@ -1,109 +0,0 @@
-// Copyright 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 stocks;
-
-enum StockRowPartKind { arrow }
-
-class StockRowPartKey extends Key {
-  const StockRowPartKey(this.stock, this.part) : super.constructor();
-  final Stock stock;
-  final StockRowPartKind part;
-  bool operator ==(dynamic other) {
-    if (other is! StockRowPartKey)
-      return false;
-    final StockRowPartKey typedOther = other;
-    return stock == typedOther.stock &&
-           part == typedOther.part;
-  }
-  int get hashCode => 37 * (37 * (373) + identityHashCode(stock)) + identityHashCode(part);
-  String toString() => '[StockRowPartKey ${stock.symbol}:${part.toString().split(".")[1]})]';
-}
-
-typedef void StockRowActionCallback(Stock stock, Key arrowKey);
-
-class StockRow extends StatelessComponent {
-  StockRow({
-    Stock stock,
-    this.onPressed,
-    this.onLongPressed
-  }) : this.stock = stock,
-       _arrowKey = new StockRowPartKey(stock, StockRowPartKind.arrow),
-       super(key: new ObjectKey(stock));
-
-  final Stock stock;
-  final StockRowActionCallback onPressed;
-  final StockRowActionCallback onLongPressed;
-
-  final Key _arrowKey;
-
-  static const double kHeight = 79.0;
-
-  GestureTapCallback _getTapHandler(StockRowActionCallback callback) {
-    if (callback == null)
-      return null;
-    return () => callback(stock, _arrowKey);
-  }
-
-  GestureLongPressCallback _getLongPressHandler(StockRowActionCallback callback) {
-    if (callback == null)
-      return null;
-    return () => callback(stock, _arrowKey);
-  }
-
-  Widget build(BuildContext context) {
-    final String lastSale = "\$${stock.lastSale.toStringAsFixed(2)}";
-    String changeInPrice = "${stock.percentChange.toStringAsFixed(2)}%";
-    if (stock.percentChange > 0)
-      changeInPrice = "+" + changeInPrice;
-    return new InkWell(
-      onTap: _getTapHandler(onPressed),
-      onLongPress: _getLongPressHandler(onLongPressed),
-      child: new Container(
-        padding: const EdgeDims.TRBL(16.0, 16.0, 20.0, 16.0),
-        decoration: new BoxDecoration(
-          border: new Border(
-            bottom: new BorderSide(color: Theme.of(context).dividerColor)
-          )
-        ),
-        child: new Row(<Widget>[
-            new Container(
-              margin: const EdgeDims.only(right: 5.0),
-              child: new Hero(
-                tag: StockRowPartKind.arrow,
-                key: _arrowKey,
-                child: new StockArrow(percentChange: stock.percentChange)
-              )
-            ),
-            new Flexible(
-              child: new Row(<Widget>[
-                  new Flexible(
-                    flex: 2,
-                    child: new Text(
-                      stock.symbol
-                    )
-                  ),
-                  new Flexible(
-                    child: new Text(
-                      lastSale,
-                      style: const TextStyle(textAlign: TextAlign.right)
-                    )
-                  ),
-                  new Flexible(
-                    child: new Text(
-                      changeInPrice,
-                      style: const TextStyle(textAlign: TextAlign.right)
-                    )
-                  ),
-                ],
-                alignItems: FlexAlignItems.baseline,
-                textBaseline: DefaultTextStyle.of(context).textBaseline
-              )
-            ),
-          ]
-        )
-      )
-    );
-  }
-}
diff --git a/examples/stocks/lib/stock_settings.dart b/examples/stocks/lib/stock_settings.dart
deleted file mode 100644
index f98dc89..0000000
--- a/examples/stocks/lib/stock_settings.dart
+++ /dev/null
@@ -1,118 +0,0 @@
-// Copyright 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 stocks;
-
-typedef void SettingsUpdater({
-  StockMode optimism,
-  BackupMode backup
-});
-
-class StockSettings extends StatefulComponent {
-  const StockSettings(this.optimism, this.backup, this.updater);
-
-  final StockMode optimism;
-  final BackupMode backup;
-  final SettingsUpdater updater;
-
-  StockSettingsState createState() => new StockSettingsState();
-}
-
-class StockSettingsState extends State<StockSettings> {
-  void _handleOptimismChanged(bool value) {
-    value ??= false;
-    sendUpdates(value ? StockMode.optimistic : StockMode.pessimistic, config.backup);
-  }
-
-  void _handleBackupChanged(bool value) {
-    sendUpdates(config.optimism, value ? BackupMode.enabled : BackupMode.disabled);
-  }
-
-  void _confirmOptimismChange() {
-    switch (config.optimism) {
-      case StockMode.optimistic:
-        _handleOptimismChanged(false);
-        break;
-      case StockMode.pessimistic:
-        showDialog(
-          context: context,
-          child: new Dialog(
-            title: new Text("Change mode?"),
-            content: new Text("Optimistic mode means everything is awesome. Are you sure you can handle that?"),
-            actions: <Widget>[
-              new FlatButton(
-                child: new Text('NO THANKS'),
-                onPressed: () {
-                  Navigator.of(context).pop(false);
-                }
-              ),
-              new FlatButton(
-                child: new Text('AGREE'),
-                onPressed: () {
-                  Navigator.of(context).pop(true);
-                }
-              ),
-            ]
-          )
-        ).then(_handleOptimismChanged);
-        break;
-    }
-  }
-
-  void sendUpdates(StockMode optimism, BackupMode backup) {
-    if (config.updater != null)
-      config.updater(
-        optimism: optimism,
-        backup: backup
-      );
-  }
-
-  Widget buildToolBar(BuildContext context) {
-    return new ToolBar(
-      left: new IconButton(
-        icon: 'navigation/arrow_back',
-        onPressed: () => Navigator.of(context).pop()
-      ),
-      center: new Text('Settings')
-    );
-  }
-
-  Widget buildSettingsPane(BuildContext context) {
-    // TODO(ianh): Once we have the gesture API hooked up, fix https://github.com/domokit/mojo/issues/281
-    // (whereby tapping the widgets below causes both the widget and the menu item to fire their callbacks)
-    return new Block(<Widget>[
-        new DrawerItem(
-          icon: 'action/thumb_up',
-          onPressed: () => _confirmOptimismChange(),
-          child: new Row(<Widget>[
-            new Flexible(child: new Text('Everything is awesome')),
-            new Checkbox(
-              value: config.optimism == StockMode.optimistic,
-              onChanged: (bool value) => _confirmOptimismChange()
-            ),
-          ])
-        ),
-        new DrawerItem(
-          icon: 'action/backup',
-          onPressed: () { _handleBackupChanged(!(config.backup == BackupMode.enabled)); },
-          child: new Row(<Widget>[
-            new Flexible(child: new Text('Back up stock list to the cloud')),
-            new Switch(
-              value: config.backup == BackupMode.enabled,
-              onChanged: _handleBackupChanged
-            ),
-          ])
-        ),
-      ],
-      padding: const EdgeDims.symmetric(vertical: 20.0)
-    );
-  }
-
-  Widget build(BuildContext context) {
-    return new Scaffold(
-      toolBar: buildToolBar(context),
-      body: buildSettingsPane(context)
-    );
-  }
-}
diff --git a/examples/stocks/lib/stock_symbol_viewer.dart b/examples/stocks/lib/stock_symbol_viewer.dart
deleted file mode 100644
index 4ef3eb6..0000000
--- a/examples/stocks/lib/stock_symbol_viewer.dart
+++ /dev/null
@@ -1,64 +0,0 @@
-// Copyright 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 stocks;
-
-class StockSymbolViewer extends StatelessComponent {
-  StockSymbolViewer(this.stock);
-
-  final Stock stock;
-
-  Widget build(BuildContext context) {
-    String lastSale = "\$${stock.lastSale.toStringAsFixed(2)}";
-    String changeInPrice = "${stock.percentChange.toStringAsFixed(2)}%";
-    if (stock.percentChange > 0)
-      changeInPrice = "+" + changeInPrice;
-    TextStyle headings = Theme.of(context).text.body2;
-    return new Scaffold(
-      toolBar: new ToolBar(
-        left: new IconButton(
-          icon: 'navigation/arrow_back',
-          onPressed: () {
-            Navigator.of(context).pop();
-          }
-        ),
-        center: new Text(stock.name)
-      ),
-      body: new Block(<Widget>[
-          new Container(
-            margin: new EdgeDims.all(20.0),
-            child: new Card(
-              child: new Container(
-                padding: new EdgeDims.all(20.0),
-                child: new Column(<Widget>[
-                    new Row(<Widget>[
-                      new Text(
-                        '${stock.symbol}',
-                        style: Theme.of(context).text.display2
-                      ),
-                      new Hero(
-                        tag: StockRowPartKind.arrow,
-                        turns: 2,
-                        child: new StockArrow(percentChange: stock.percentChange)
-                      ),
-                    ],
-                    justifyContent: FlexJustifyContent.spaceBetween
-                  ),
-                  new Text('Last Sale', style: headings),
-                  new Text('$lastSale ($changeInPrice)'),
-                  new Container(
-                    height: 8.0
-                  ),
-                  new Text('Market Cap', style: headings),
-                  new Text('${stock.marketCap}'),
-                ])
-              )
-            )
-          )
-        ]
-      )
-    );
-  }
-
-}
diff --git a/examples/stocks/lib/stock_types.dart b/examples/stocks/lib/stock_types.dart
deleted file mode 100644
index 5665a6e..0000000
--- a/examples/stocks/lib/stock_types.dart
+++ /dev/null
@@ -1,8 +0,0 @@
-// Copyright 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 stocks;
-
-enum StockMode { optimistic, pessimistic }
-enum BackupMode { enabled, disabled }
diff --git a/examples/stocks/pubspec.yaml b/examples/stocks/pubspec.yaml
deleted file mode 100644
index df2eddd..0000000
--- a/examples/stocks/pubspec.yaml
+++ /dev/null
@@ -1,10 +0,0 @@
-name: stocks
-dependencies:
-  flutter: 
-    '0.0.16'
-  sky_tools: any
-dependency_overrides:
-  material_design_icons:
-    path: ../../sky/packages/material_design_icons
-  flutter:
-    path: ../../sky/packages/sky
diff --git a/examples/widgets/README b/examples/widgets/README
deleted file mode 100644
index 54c151f..0000000
--- a/examples/widgets/README
+++ /dev/null
@@ -1,12 +0,0 @@
-Small examples of the Flutter widget framework
-==============================================
-
-To run these, open a terminal in this directory and use the following
-command:
-
-```bash
-pub global activate flutter
-flutter start --checked -t foo.dart
-```
-
-...where `foo.dart` is the file you want to run.
diff --git a/examples/widgets/big_switch.dart b/examples/widgets/big_switch.dart
deleted file mode 100644
index 46a9165..0000000
--- a/examples/widgets/big_switch.dart
+++ /dev/null
@@ -1,42 +0,0 @@
-// Copyright 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:flutter/material.dart';
-
-class BigSwitch extends StatefulComponent {
-  BigSwitch({ this.scale });
-
-  final double scale;
-
-  BigSwitchState createState() => new BigSwitchState();
-}
-
-class BigSwitchState extends State<BigSwitch> {
-  bool _value = false;
-
-  void _handleOnChanged(bool value) {
-    setState(() {
-      _value = value;
-    });
-  }
-
-  Widget build(BuildContext context) {
-    Matrix4 scale = new Matrix4.identity();
-    scale.scale(config.scale, config.scale);
-    return new Transform(
-      transform: scale,
-      child: new Switch(value: _value, onChanged: _handleOnChanged)
-    );
-  }
-}
-
-void main() {
-  runApp(new Container(
-    child: new BigSwitch(scale: 5.0),
-    padding: new EdgeDims.all(20.0),
-    decoration: new BoxDecoration(
-      backgroundColor: Colors.teal[600]
-    )
-  ));
-}
diff --git a/examples/widgets/card_collection.dart b/examples/widgets/card_collection.dart
deleted file mode 100644
index 8142b16..0000000
--- a/examples/widgets/card_collection.dart
+++ /dev/null
@@ -1,463 +0,0 @@
-// Copyright 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 'dart:ui' as ui;
-
-import 'package:flutter/material.dart';
-import 'package:flutter/painting.dart';
-import 'package:flutter/rendering.dart';
-
-class CardModel {
-  CardModel(this.value, this.height) {
-    label = "Item $value";
-  }
-  int value;
-  double height;
-  int get color => ((value % 9) + 1) * 100;
-  String label;
-  Key get key => new ObjectKey(this);
-}
-
-class CardCollection extends StatefulComponent {
-  CardCollectionState createState() => new CardCollectionState();
-}
-
-class CardCollectionState extends State<CardCollection> {
-
-  static const TextStyle cardLabelStyle =
-    const TextStyle(color: Colors.white, fontSize: 18.0, fontWeight: bold);
-
-  // TODO(hansmuller): need a local image asset
-  static const _sunshineURL = "http://www.walltor.com/images/wallpaper/good-morning-sunshine-58540.jpg";
-
-  final TextStyle backgroundTextStyle =
-    Typography.white.title.copyWith(textAlign: TextAlign.center);
-
-  Map<int, Color> _primaryColor = Colors.deepPurple;
-  List<CardModel> _cardModels;
-  DismissDirection _dismissDirection = DismissDirection.horizontal;
-  TextStyle _textStyle = new TextStyle(textAlign: TextAlign.center);
-  bool _editable = false;
-  bool _snapToCenter = false;
-  bool _fixedSizeCards = false;
-  bool _sunshine = false;
-  bool _varyFontSizes = false;
-  InvalidatorCallback _invalidator;
-  Size _cardCollectionSize = new Size(200.0, 200.0);
-
-  void _initVariableSizedCardModels() {
-    List<double> cardHeights = <double>[
-      48.0, 63.0, 82.0, 146.0, 60.0, 55.0, 84.0, 96.0, 50.0,
-      48.0, 63.0, 82.0, 146.0, 60.0, 55.0, 84.0, 96.0, 50.0,
-      48.0, 63.0, 82.0, 146.0, 60.0, 55.0, 84.0, 96.0, 50.0
-    ];
-    _cardModels = new List<CardModel>.generate(
-      cardHeights.length,
-      (int i) => new CardModel(i, cardHeights[i])
-    );
-  }
-
-  void _initFixedSizedCardModels() {
-    const int cardCount = 27;
-    const double cardHeight = 100.0;
-    _cardModels = new List<CardModel>.generate(
-      cardCount,
-      (int i) => new CardModel(i, cardHeight)
-    );
-  }
-
-  void _initCardModels() {
-    if (_fixedSizeCards)
-      _initFixedSizedCardModels();
-    else
-      _initVariableSizedCardModels();
-  }
-
-  void initState() {
-    super.initState();
-    _initCardModels();
-  }
-
-  double _variableSizeToSnapOffset(double scrollOffset) {
-    double cumulativeHeight = 0.0;
-    double  margins = 8.0;
-    List<double> cumulativeHeights = _cardModels.map((CardModel card) {
-      cumulativeHeight += card.height + margins;
-      return cumulativeHeight;
-    })
-    .toList();
-
-    double offsetForIndex(int i) {
-      return 12.0 + (margins + _cardModels[i].height) / 2.0 + ((i == 0) ? 0.0 : cumulativeHeights[i - 1]);
-    }
-
-    for (int i = 0; i <  cumulativeHeights.length; i++) {
-      if (cumulativeHeights[i] >= scrollOffset)
-        return offsetForIndex(i);
-    }
-    return offsetForIndex(cumulativeHeights.length - 1);
-  }
-
-  double _fixedSizeToSnapOffset(double scrollOffset) {
-    double cardHeight = _cardModels[0].height;
-    int cardIndex = (scrollOffset.clamp(0.0, cardHeight * (_cardModels.length - 1)) / cardHeight).floor();
-    return 12.0 + cardIndex * cardHeight + cardHeight * 0.5;
-  }
-
-  double _toSnapOffset(double scrollOffset) {
-    return _fixedSizeCards ? _fixedSizeToSnapOffset(scrollOffset) : _variableSizeToSnapOffset(scrollOffset);
-  }
-
-  void dismissCard(CardModel card) {
-    if (_cardModels.contains(card)) {
-      setState(() {
-        _cardModels.remove(card);
-      });
-    }
-  }
-
-  void _showDrawer() {
-    showDrawer(
-      context: context,
-      child: new IconTheme(
-        data: const IconThemeData(color: IconThemeColor.black),
-        child: new Block(<Widget>[
-          new DrawerHeader(child: new Text('Options')),
-          buildDrawerCheckbox("Make card labels editable", _editable, _toggleEditable),
-          buildDrawerCheckbox("Snap fling scrolls to center", _snapToCenter, _toggleSnapToCenter),
-          buildDrawerCheckbox("Fixed size cards", _fixedSizeCards, _toggleFixedSizeCards),
-          buildDrawerCheckbox("Let the sun shine", _sunshine, _toggleSunshine),
-          buildDrawerCheckbox("Vary font sizes", _varyFontSizes, _toggleVaryFontSizes, enabled: !_editable),
-          new DrawerDivider(),
-          buildDrawerColorRadioItem("Deep Purple", Colors.deepPurple, _primaryColor, _selectColor),
-          buildDrawerColorRadioItem("Green", Colors.green, _primaryColor, _selectColor),
-          buildDrawerColorRadioItem("Amber", Colors.amber, _primaryColor, _selectColor),
-          buildDrawerColorRadioItem("Teal", Colors.teal, _primaryColor, _selectColor),
-          new DrawerDivider(),
-          buildDrawerDirectionRadioItem("Dismiss horizontally", DismissDirection.horizontal, _dismissDirection, _changeDismissDirection, icon: 'action/code'),
-          buildDrawerDirectionRadioItem("Dismiss left", DismissDirection.left, _dismissDirection, _changeDismissDirection, icon: 'navigation/arrow_back'),
-          buildDrawerDirectionRadioItem("Dismiss right", DismissDirection.right, _dismissDirection, _changeDismissDirection, icon: 'navigation/arrow_forward'),
-          new DrawerDivider(),
-          buildFontRadioItem("Left-align text", new TextStyle(textAlign: TextAlign.left), _textStyle, _changeTextStyle, icon: 'editor/format_align_left', enabled: !_editable),
-          buildFontRadioItem("Center-align text", new TextStyle(textAlign: TextAlign.center), _textStyle, _changeTextStyle, icon: 'editor/format_align_center', enabled: !_editable),
-          buildFontRadioItem("Right-align text", new TextStyle(textAlign: TextAlign.right), _textStyle, _changeTextStyle, icon: 'editor/format_align_right', enabled: !_editable),
-          new DrawerDivider(),
-          new DrawerItem(
-            icon: 'device/dvr',
-            onPressed: () { debugDumpApp(); debugDumpRenderTree(); },
-            child: new Text('Dump App to Console')
-          ),
-        ])
-      )
-    );
-  }
-
-  String _dismissDirectionText(DismissDirection direction) {
-    String s = direction.toString();
-    return "dismiss ${s.substring(s.indexOf('.') + 1)}";
-  }
-
-  void _toggleEditable() {
-    setState(() {
-      _editable = !_editable;
-    });
-  }
-
-  void _toggleFixedSizeCards() {
-    setState(() {
-      _fixedSizeCards = !_fixedSizeCards;
-      _initCardModels();
-    });
-  }
-
-  void _toggleSnapToCenter() {
-    setState(() {
-      _snapToCenter = !_snapToCenter;
-    });
-  }
-
-  void _toggleSunshine() {
-    setState(() {
-      _sunshine = !_sunshine;
-    });
-  }
-
-  void _toggleVaryFontSizes() {
-    setState(() {
-      _varyFontSizes = !_varyFontSizes;
-    });
-  }
-
-  void _selectColor(Map<int, Color> selection) {
-    setState(() {
-      _primaryColor = selection;
-    });
-  }
-
-  void _changeDismissDirection(DismissDirection newDismissDirection) {
-    setState(() {
-      _dismissDirection = newDismissDirection;
-    });
-  }
-
-  void _changeTextStyle(TextStyle newTextStyle) {
-    setState(() {
-      _textStyle = newTextStyle;
-    });
-  }
-
-  Widget buildDrawerCheckbox(String label, bool value, void callback(), { bool enabled: true }) {
-    return new DrawerItem(
-      onPressed: enabled ? callback : null,
-      child: new Row(<Widget>[
-        new Flexible(child: new Text(label)),
-        new Checkbox(
-          value: value,
-          onChanged: enabled ? (_) { callback(); } : null
-        )
-      ])
-    );
-  }
-
-  Widget buildDrawerColorRadioItem(String label, Map<int, Color> itemValue, Map<int, Color> currentValue, ValueChanged<Map<int, Color>> onChanged, { String icon, bool enabled: true }) {
-    return new DrawerItem(
-      icon: icon,
-      onPressed: enabled ? () { onChanged(itemValue); } : null,
-      child: new Row(<Widget>[
-        new Flexible(child: new Text(label)),
-        new Radio<Map<int, Color>>(
-          value: itemValue,
-          groupValue: currentValue,
-          onChanged: enabled ? onChanged : null
-        )
-      ])
-    );
-  }
-
-  Widget buildDrawerDirectionRadioItem(String label, DismissDirection itemValue, DismissDirection currentValue, ValueChanged<DismissDirection> onChanged, { String icon, bool enabled: true }) {
-    return new DrawerItem(
-      icon: icon,
-      onPressed: enabled ? () { onChanged(itemValue); } : null,
-      child: new Row(<Widget>[
-        new Flexible(child: new Text(label)),
-        new Radio<DismissDirection>(
-          value: itemValue,
-          groupValue: currentValue,
-          onChanged: enabled ? onChanged : null
-        )
-      ])
-    );
-  }
-
-  Widget buildFontRadioItem(String label, TextStyle itemValue, TextStyle currentValue, ValueChanged<TextStyle> onChanged, { String icon, bool enabled: true }) {
-    return new DrawerItem(
-      icon: icon,
-      onPressed: enabled ? () { onChanged(itemValue); } : null,
-      child: new Row(<Widget>[
-        new Flexible(child: new Text(label)),
-        new Radio<TextStyle>(
-          value: itemValue,
-          groupValue: currentValue,
-          onChanged: enabled ? onChanged : null
-        )
-      ])
-    );
-  }
-
-  Widget buildToolBar() {
-    return new ToolBar(
-      left: new IconButton(icon: "navigation/menu", onPressed: _showDrawer),
-      right: <Widget>[
-        new Text(_dismissDirectionText(_dismissDirection))
-      ],
-      bottom: new Padding(
-        padding: const EdgeDims.only(left: 72.0),
-        child: new Align(
-          alignment: const FractionalOffset(0.0, 0.5),
-          child: new Text('Swipe Away: ${_cardModels.length}')
-        )
-      )
-    );
-  }
-
-  Widget buildCard(BuildContext context, int index) {
-    if (index >= _cardModels.length)
-      return null;
-
-    CardModel cardModel = _cardModels[index];
-    Widget card = new Dismissable(
-      direction: _dismissDirection,
-      onResized: () { _invalidator(<int>[index]); },
-      onDismissed: () { dismissCard(cardModel); },
-      child: new Card(
-        color: Theme.of(context).primarySwatch[cardModel.color],
-        child: new Container(
-          height: cardModel.height,
-          padding: const EdgeDims.all(8.0),
-          child: _editable ?
-            new Center(
-              child: new Input(
-                key: new GlobalObjectKey(cardModel),
-                initialValue: cardModel.label,
-                onChanged: (String value) {
-                  cardModel.label = value;
-                }
-              )
-            )
-          : new DefaultTextStyle(
-              style: DefaultTextStyle.of(context).merge(cardLabelStyle).merge(_textStyle).copyWith(
-                fontSize: _varyFontSizes ? _cardModels.length.toDouble() : null
-              ),
-              child: new Column(<Widget>[
-                  new Text(cardModel.label)
-                ],
-                alignItems: FlexAlignItems.stretch,
-                justifyContent: FlexJustifyContent.center
-              )
-            )
-        )
-      )
-    );
-
-    String backgroundMessage;
-    switch(_dismissDirection) {
-      case DismissDirection.horizontal:
-        backgroundMessage = "Swipe in either direction";
-        break;
-      case DismissDirection.left:
-        backgroundMessage = "Swipe left to dismiss";
-        break;
-      case DismissDirection.right:
-        backgroundMessage = "Swipe right to dismiss";
-        break;
-      default:
-        backgroundMessage = "Unsupported dismissDirection";
-    }
-
-    Widget leftArrowIcon =  new Icon(icon: 'navigation/arrow_back', size: IconSize.s36);
-    if (_dismissDirection == DismissDirection.right)
-      leftArrowIcon = new Opacity(opacity: 0.1, child: leftArrowIcon);
-
-    Widget rightArrowIcon =  new Icon(icon: 'navigation/arrow_forward', size: IconSize.s36);
-    if (_dismissDirection == DismissDirection.left)
-      rightArrowIcon = new Opacity(opacity: 0.1, child: rightArrowIcon);
-
-    // The background Widget appears behind the Dismissable card when the card
-    // moves to the left or right. The Positioned widget ensures that the
-    // size of the background,card Stack will be based only on the card. The
-    // Viewport ensures that when the card's resize animation occurs, the
-    // background (text and icons) will just be clipped, not resized.
-    Widget background = new Positioned(
-      top: 0.0,
-      right: 0.0,
-      bottom: 0.0,
-      left: 0.0,
-      child: new Container(
-        margin: const EdgeDims.all(4.0),
-        child: new Viewport(
-          child: new Container(
-            height: cardModel.height,
-            decoration: new BoxDecoration(backgroundColor: Theme.of(context).primaryColor),
-            child: new Row(<Widget>[
-              leftArrowIcon,
-              new Flexible(child: new Text(backgroundMessage, style: backgroundTextStyle)),
-              rightArrowIcon
-            ])
-          )
-        )
-      )
-    );
-
-    return new IconTheme(
-      key: cardModel.key,
-      data: const IconThemeData(color: IconThemeColor.white),
-      child: new Stack(<Widget>[background, card])
-    );
-  }
-
-  void _updateCardCollectionSize(Size newSize) {
-    setState(() {
-      _cardCollectionSize = newSize;
-    });
-  }
-
-  ui.Shader _createShader(Rect bounds) {
-    return new LinearGradient(
-        begin: Point.origin,
-        end: new Point(0.0, bounds.height),
-        colors: <Color>[const Color(0x00FFFFFF), const Color(0xFFFFFFFF)],
-        stops: <double>[0.1, 0.35]
-    )
-    .createShader();
-  }
-
-  Widget build(BuildContext context) {
-
-    Widget cardCollection;
-    if (_fixedSizeCards) {
-      cardCollection = new ScrollableList<CardModel> (
-        snapOffsetCallback: _snapToCenter ? _toSnapOffset : null,
-        snapAlignmentOffset: _cardCollectionSize.height / 2.0,
-        items: _cardModels,
-        itemBuilder: (BuildContext context, CardModel card) => buildCard(context, card.value),
-        itemExtent: _cardModels[0].height
-      );
-    } else {
-      cardCollection = new ScrollableMixedWidgetList(
-        builder: buildCard,
-        token: _cardModels.length,
-        snapOffsetCallback: _snapToCenter ? _toSnapOffset : null,
-        snapAlignmentOffset: _cardCollectionSize.height / 2.0,
-        onInvalidatorAvailable: (InvalidatorCallback callback) { _invalidator = callback; }
-      );
-    }
-
-    if (_sunshine)
-      cardCollection = new Stack(<Widget>[
-        new Column(<Widget>[new NetworkImage(src: _sunshineURL)]),
-        new ShaderMask(child: cardCollection, shaderCallback: _createShader)
-      ]);
-
-    Widget body = new SizeObserver(
-      onSizeChanged: _updateCardCollectionSize,
-      child: new Container(
-        padding: const EdgeDims.symmetric(vertical: 12.0, horizontal: 8.0),
-        decoration: new BoxDecoration(backgroundColor: Theme.of(context).primarySwatch[50]),
-        child: cardCollection
-      )
-    );
-
-    if (_snapToCenter) {
-      Widget indicator = new IgnorePointer(
-        child: new Align(
-          alignment: const FractionalOffset(0.0, 0.5),
-          child: new Container(
-            height: 1.0,
-            decoration: new BoxDecoration(backgroundColor: const Color(0x80FFFFFF))
-          )
-        )
-      );
-      body = new Stack(<Widget>[body, indicator]);
-    }
-
-    return new Theme(
-      data: new ThemeData(
-        primarySwatch: _primaryColor
-      ),
-      child: new Scaffold(
-        toolBar: buildToolBar(),
-        body: body
-      )
-    );
-  }
-}
-
-void main() {
-  runApp(new MaterialApp(
-    title: 'Cards',
-    routes: <String, RouteBuilder>{
-      '/': (RouteArguments args) => new CardCollection(),
-    }
-  ));
-}
diff --git a/examples/widgets/container.dart b/examples/widgets/container.dart
deleted file mode 100644
index b13cd65..0000000
--- a/examples/widgets/container.dart
+++ /dev/null
@@ -1,46 +0,0 @@
-// Copyright 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:flutter/material.dart';
-
-class ContainerApp extends StatelessComponent {
-  Widget build(BuildContext context) {
-    return new Column(<Widget>[
-        new Container(
-          padding: new EdgeDims.all(10.0),
-          margin: new EdgeDims.all(10.0),
-          decoration: new BoxDecoration(backgroundColor: const Color(0xFFCCCCCC)),
-          child: new NetworkImage(
-            src: "https://raw.githubusercontent.com/dart-lang/logos/master/logos_and_wordmarks/dart-logo.png",
-            width: 300.0,
-            height: 300.0
-          )
-        ),
-        new Container(
-          decoration: new BoxDecoration(backgroundColor: const Color(0xFFFFFF00)),
-          padding: new EdgeDims.symmetric(horizontal: 50.0, vertical: 75.0),
-          child: new Row(<Widget>[
-            new RaisedButton(
-              child: new Text('PRESS ME'),
-              onPressed: () => print("Hello World")
-            ),
-            new RaisedButton(
-              child: new Text('DISABLED')
-            )
-          ])
-        ),
-        new Flexible(
-          child: new Container(
-            decoration: new BoxDecoration(backgroundColor: const Color(0xFF00FFFF))
-          )
-        ),
-      ],
-      justifyContent: FlexJustifyContent.spaceBetween
-    );
-  }
-}
-
-void main() {
-  runApp(new ContainerApp());
-}
diff --git a/examples/widgets/date_picker.dart b/examples/widgets/date_picker.dart
deleted file mode 100644
index b5709d1..0000000
--- a/examples/widgets/date_picker.dart
+++ /dev/null
@@ -1,63 +0,0 @@
-// Copyright 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:flutter/material.dart';
-
-void main() => runApp(new DatePickerDemo());
-
-class DatePickerDemo extends StatefulComponent {
-  DatePickerDemoState createState() => new DatePickerDemoState();
-}
-
-class DatePickerDemoState extends State<DatePickerDemo> {
-  void initState() {
-    super.initState();
-    DateTime now = new DateTime.now();
-    _dateTime = new DateTime(now.year, now.month, now.day);
-  }
-
-  DateTime _dateTime;
-
-  void _handleDateChanged(DateTime dateTime) {
-    setState(() {
-      _dateTime = dateTime;
-    });
-  }
-
-  Widget build(BuildContext context) {
-    return new Theme(
-      data: new ThemeData(
-        brightness: ThemeBrightness.light,
-        primarySwatch: Colors.teal
-      ),
-      child: new Stack(<Widget>[
-        new Scaffold(
-          toolBar: new ToolBar(center: new Text("Date Picker")),
-          body: new Row(
-            <Widget>[new Text(_dateTime.toString())],
-            alignItems: FlexAlignItems.end,
-            justifyContent: FlexJustifyContent.center
-          )
-        ),
-        new Dialog(
-          content: new DatePicker(
-            selectedDate: _dateTime,
-            firstDate: new DateTime(2015, 8),
-            lastDate: new DateTime(2101),
-            onChanged: _handleDateChanged
-          ),
-          contentPadding: EdgeDims.zero,
-          actions: <Widget>[
-            new FlatButton(
-              child: new Text('CANCEL')
-            ),
-            new FlatButton(
-              child: new Text('OK')
-            ),
-          ]
-        )
-      ])
-    );
-  }
-}
diff --git a/examples/widgets/drag_and_drop.dart b/examples/widgets/drag_and_drop.dart
deleted file mode 100644
index 14e6039..0000000
--- a/examples/widgets/drag_and_drop.dart
+++ /dev/null
@@ -1,173 +0,0 @@
-// Copyright 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:flutter/material.dart';
-import 'package:flutter/painting.dart';
-import 'package:flutter/rendering.dart';
-
-class ExampleDragTarget extends StatefulComponent {
-  ExampleDragTargetState createState() => new ExampleDragTargetState();
-}
-
-class ExampleDragTargetState extends State<ExampleDragTarget> {
-  Color _color = Colors.grey[500];
-
-  void _handleAccept(Color data) {
-    setState(() {
-      _color = data;
-    });
-  }
-
-  Widget build(BuildContext context) {
-    return new DragTarget<Color>(
-      onAccept: _handleAccept,
-      builder: (BuildContext context, List<Color> data, _) {
-        return new Container(
-          height: 100.0,
-          margin: new EdgeDims.all(10.0),
-          decoration: new BoxDecoration(
-            border: new Border.all(
-              width: 3.0,
-              color: data.isEmpty ? Colors.white : Colors.blue[500]
-            ),
-            backgroundColor: data.isEmpty ? _color : Colors.grey[200]
-          )
-        );
-      }
-    );
-  }
-}
-
-class Dot extends StatelessComponent {
-  Dot({ Key key, this.color, this.size, this.child }) : super(key: key);
-  final Color color;
-  final double size;
-  final Widget child;
-  Widget build(BuildContext context) {
-    return new Container(
-      width: size,
-      height: size,
-      decoration: new BoxDecoration(
-        backgroundColor: color,
-        shape: Shape.circle
-      ),
-      child: child
-    );
-  }
-}
-
-class ExampleDragSource extends StatelessComponent {
-  ExampleDragSource({
-    Key key,
-    this.color,
-    this.heavy: false,
-    this.under: true,
-    this.child
-  }) : super(key: key);
-
-  final Color color;
-  final bool heavy;
-  final bool under;
-  final Widget child;
-
-  static const double kDotSize = 50.0;
-  static const double kHeavyMultiplier = 1.5;
-  static const double kFingerSize = 50.0;
-
-  Widget build(BuildContext context) {
-    double size = kDotSize;
-    DraggableConstructor<Color> constructor = new Draggable<Color>#;
-    if (heavy) {
-      size *= kHeavyMultiplier;
-      constructor = new LongPressDraggable<Color>#;
-    }
-
-    Widget contents = new DefaultTextStyle(
-      style: Theme.of(context).text.body1.copyWith(textAlign: TextAlign.center),
-      child: new Dot(
-        color: color,
-        size: size,
-        child: new Center(child: child)
-      )
-    );
-
-    Widget feedback = new Opacity(
-      opacity: 0.75,
-      child: contents
-    );
-
-    Offset feedbackOffset;
-    DragAnchor anchor;
-    if (!under) {
-      feedback = new Transform(
-        transform: new Matrix4.identity()
-                     ..translate(-size / 2.0, -(size / 2.0 + kFingerSize)),
-        child: feedback
-      );
-      feedbackOffset = const Offset(0.0, -kFingerSize);
-      anchor = DragAnchor.pointer;
-    } else {
-      feedbackOffset = Offset.zero;
-      anchor = DragAnchor.child;
-    }
-
-    return constructor(
-      data: color,
-      child: contents,
-      feedback: feedback,
-      feedbackOffset: feedbackOffset,
-      dragAnchor: anchor
-    );
-  }
-}
-
-class DragAndDropApp extends StatelessComponent {
-  Widget build(BuildContext context) {
-    return new Scaffold(
-      toolBar: new ToolBar(
-        center: new Text('Drag and Drop Flutter Demo')
-      ),
-      body: new Column(<Widget>[
-        new Flexible(child: new Row(<Widget>[
-            new ExampleDragSource(
-              color: const Color(0xFFFFF000),
-              under: true,
-              heavy: false,
-              child: new Text('under')
-            ),
-            new ExampleDragSource(
-              color: const Color(0xFF0FFF00),
-              under: false,
-              heavy: true,
-              child: new Text('long-press above')
-            ),
-            new ExampleDragSource(
-              color: const Color(0xFF00FFF0),
-              under: false,
-              heavy: false,
-              child: new Text('above')
-            ),
-          ],
-          alignItems: FlexAlignItems.center,
-          justifyContent: FlexJustifyContent.spaceAround
-        )),
-        new Flexible(child: new Row(<Widget>[
-          new Flexible(child: new ExampleDragTarget()),
-          new Flexible(child: new ExampleDragTarget()),
-          new Flexible(child: new ExampleDragTarget()),
-          new Flexible(child: new ExampleDragTarget()),
-        ])),
-      ])
-    );
-  }
-}
-
-void main() {
-  runApp(new MaterialApp(
-    title: 'Drag and Drop Flutter Demo',
-    routes: <String, RouteBuilder>{
-     '/': (RouteArguments args) => new DragAndDropApp()
-    }
-  ));
-}
diff --git a/examples/widgets/dropdown.dart b/examples/widgets/dropdown.dart
deleted file mode 100644
index 7d41448..0000000
--- a/examples/widgets/dropdown.dart
+++ /dev/null
@@ -1,57 +0,0 @@
-// Copyright 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:flutter/material.dart';
-
-class DropdownDemo extends StatefulComponent {
-  DropdownDemo();
-
-  DropdownDemoState createState() => new DropdownDemoState();
-}
-
-class DropdownDemoState extends State<DropdownDemo> {
-  String _value = "Free";
-
-  List<DropdownMenuItem> _buildItems() {
-    return ["One", "Two", "Free", "Four"].map((String value) {
-      return new DropdownMenuItem<String>(value: value, child: new Text(value));
-    })
-    .toList();
-  }
-
-  Widget build(BuildContext context) {
-    Widget dropdown = new DropdownButton<String>(
-      items: _buildItems(),
-      value: _value,
-      onChanged: (String newValue) {
-        setState(() {
-          if (newValue != null)
-            _value = newValue;
-        });
-      }
-    );
-
-    return new Scaffold(
-      toolBar: new ToolBar(center: new Text('DropdownDemo Demo')),
-      body: new Container(
-        decoration: new BoxDecoration(backgroundColor: Theme.of(context).primarySwatch[50]),
-        child: new Center(child: dropdown)
-      )
-    );
-  }
-}
-
-void main() {
-  runApp(new MaterialApp(
-    title: 'DropdownDemo',
-    theme: new ThemeData(
-      brightness: ThemeBrightness.light,
-      primarySwatch: Colors.blue,
-      accentColor: Colors.redAccent[200]
-    ),
-    routes: <String, RouteBuilder>{
-      '/': (RouteArguments args) => new DropdownDemo(),
-    }
-  ));
-}
diff --git a/examples/widgets/ensure_visible.dart b/examples/widgets/ensure_visible.dart
deleted file mode 100644
index 2c22b0c..0000000
--- a/examples/widgets/ensure_visible.dart
+++ /dev/null
@@ -1,126 +0,0 @@
-// Copyright 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:flutter/material.dart';
-
-class CardModel {
-  CardModel(this.value, this.height, this.color);
-  int value;
-  double height;
-  Color color;
-  String get label => "Card $value";
-  Key get key => new ObjectKey(this);
-}
-
-typedef void TappableCardCallback(BuildContext context);
-
-class TappableCard extends StatelessComponent {
-  TappableCard({ CardModel cardModel, this.selected, this.onTap })
-    : cardModel = cardModel, super(key: cardModel.key);
-  final CardModel cardModel;
-  final bool selected;
-  final TappableCardCallback onTap;
-
-  static const TextStyle cardLabelStyle = const TextStyle(
-    color: Colors.white,
-    fontSize: 18.0,
-    fontWeight: bold
-  );
-
-  static const TextStyle selectedCardLabelStyle = const TextStyle(
-    color: Colors.white,
-    fontSize: 24.0,
-    fontWeight: bold
-  );
-
-  Widget build(BuildContext context) {
-    return new GestureDetector(
-      onTap: () => onTap(context),
-      child: new Card(
-        color: cardModel.color,
-        child: new Container(
-          height: cardModel.height,
-          padding: const EdgeDims.all(8.0),
-          child: new Center(
-            child: new Text(
-              cardModel.label,
-              style: selected ? selectedCardLabelStyle : cardLabelStyle
-            )
-          )
-        )
-      )
-    );
-  }
-
-}
-
-
-class EnsureVisibleApp extends StatefulComponent {
-  EnsureVisibleAppState createState() => new EnsureVisibleAppState();
-}
-
-class EnsureVisibleAppState extends State<EnsureVisibleApp> {
-
-  List<CardModel> cardModels;
-  int selectedCardIndex;
-
-  void initState() {
-    List<double> cardHeights = <double>[
-      48.0, 63.0, 82.0, 146.0, 60.0, 55.0, 84.0, 96.0, 50.0,
-      48.0, 63.0, 82.0, 146.0, 60.0, 55.0, 84.0, 96.0, 50.0,
-      48.0, 63.0, 82.0, 146.0, 60.0, 55.0, 84.0, 96.0, 50.0
-    ];
-    cardModels = new List<CardModel>.generate(cardHeights.length, (int i) {
-      Color color = Color.lerp(Colors.red[300], Colors.blue[900], i / cardHeights.length);
-      return new CardModel(i, cardHeights[i], color);
-    });
-    super.initState();
-  }
-
-  Widget builder(BuildContext context, int index) {
-    if (index >= cardModels.length)
-      return null;
-    return new TappableCard(
-      cardModel: cardModels[index],
-      selected: index == selectedCardIndex,
-      onTap: (BuildContext context) {
-        ensureWidgetIsVisible(context, duration: const Duration(milliseconds: 200))
-        .then((_) {
-          setState(() { selectedCardIndex = index; });
-        });
-      }
-    );
-  }
-
-  Widget build(BuildContext context) {
-    return new IconTheme(
-      data: const IconThemeData(color: IconThemeColor.white),
-      child: new Theme(
-        data: new ThemeData(
-          brightness: ThemeBrightness.light,
-          primarySwatch: Colors.blue,
-          accentColor: Colors.redAccent[200]
-        ),
-        child: new Title(
-          title: 'Cards',
-          child: new Scaffold(
-            toolBar: new ToolBar(center: new Text('Tap a card, any card')),
-            body: new Container(
-              padding: const EdgeDims.symmetric(vertical: 12.0, horizontal: 8.0),
-              decoration: new BoxDecoration(backgroundColor: Theme.of(context).primarySwatch[50]),
-              child: new ScrollableMixedWidgetList(
-                builder: builder,
-                token: cardModels.length
-              )
-            )
-          )
-        )
-      )
-    );
-  }
-}
-
-void main() {
-  runApp(new EnsureVisibleApp());
-}
diff --git a/examples/widgets/gestures.dart b/examples/widgets/gestures.dart
deleted file mode 100644
index 8657506..0000000
--- a/examples/widgets/gestures.dart
+++ /dev/null
@@ -1,207 +0,0 @@
-// Copyright 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:flutter/material.dart';
-import 'package:flutter/rendering.dart';
-
-class ScaleApp extends StatefulComponent {
-  ScaleAppState createState() => new ScaleAppState();
-}
-
-class GesturesDemoPaintToken {
-  GesturesDemoPaintToken(this.zoom, this.offset, this.swatch, this.forward, this.flag1, this.flag2, this.flag3, this.flag4);
-  final Offset offset;
-  final double zoom;
-  final Map<int, Color> swatch;
-  final bool forward;
-  final bool flag1;
-  final bool flag2;
-  final bool flag3;
-  final bool flag4;
-  bool operator ==(dynamic other) {
-    if (identical(this, other))
-      return true;
-    if (other is! GesturesDemoPaintToken)
-      return false;
-    final GesturesDemoPaintToken typedOther = other;
-    return offset == typedOther.offset &&
-           zoom == typedOther.zoom &&
-           identical(swatch, typedOther.swatch) &&
-           forward == typedOther.forward &&
-           flag1 == typedOther.flag1 &&
-           flag2 == typedOther.flag2 &&
-           flag3 == typedOther.flag3 &&
-           flag4 == typedOther.flag4;
-  }
-  int get hashCode {
-    int value = 373;
-    value = 37 * value + offset.hashCode;
-    value = 37 * value + zoom.hashCode;
-    value = 37 * value + identityHashCode(swatch);
-    value = 37 * value + forward.hashCode;
-    value = 37 * value + flag1.hashCode;
-    value = 37 * value + flag2.hashCode;
-    value = 37 * value + flag3.hashCode;
-    value = 37 * value + flag4.hashCode;
-    return value;
-  }
-}
-
-class ScaleAppState extends State<ScaleApp> {
-
-  Point _startingFocalPoint;
-
-  Offset _previousOffset;
-  Offset _offset = Offset.zero;
-
-  double _previousZoom;
-  double _zoom = 1.0;
-
-  Map<int, Color> _swatch = Colors.blue;
-
-  bool _forward = true;
-  bool _scaleEnabled = true;
-  bool _tapEnabled = true;
-  bool _doubleTapEnabled = true;
-  bool _longPressEnabled = true;
-
-  void _handleScaleStart(Point focalPoint) {
-    setState(() {
-      _startingFocalPoint = focalPoint;
-      _previousOffset = _offset;
-      _previousZoom = _zoom;
-    });
-  }
-
-  void _handleScaleUpdate(double scale, Point focalPoint) {
-    setState(() {
-      _zoom = (_previousZoom * scale);
-
-      // Ensure that item under the focal point stays in the same place despite zooming
-      Offset normalizedOffset = (_startingFocalPoint.toOffset() - _previousOffset) / _previousZoom;
-      _offset = focalPoint.toOffset() - normalizedOffset * _zoom;
-    });
-  }
-
-  void _handleScaleReset() {
-    setState(() {
-      _zoom = 1.0;
-      _offset = Offset.zero;
-    });
-  }
-
-  void _handleColorChange() {
-    setState(() {
-      switch (_swatch) {
-        case Colors.blueGrey:   _swatch = Colors.red; break;
-        case Colors.red:        _swatch = Colors.pink; break;
-        case Colors.pink:       _swatch = Colors.purple; break;
-        case Colors.purple:     _swatch = Colors.deepPurple; break;
-        case Colors.deepPurple: _swatch = Colors.indigo; break;
-        case Colors.indigo:     _swatch = Colors.blue; break;
-        case Colors.blue:       _swatch = Colors.lightBlue; break;
-        case Colors.lightBlue:  _swatch = Colors.cyan; break;
-        case Colors.cyan:       _swatch = Colors.teal; break;
-        case Colors.teal:       _swatch = Colors.green; break;
-        case Colors.green:      _swatch = Colors.lightGreen; break;
-        case Colors.lightGreen: _swatch = Colors.lime; break;
-        case Colors.lime:       _swatch = Colors.yellow; break;
-        case Colors.yellow:     _swatch = Colors.amber; break;
-        case Colors.amber:      _swatch = Colors.orange; break;
-        case Colors.orange:     _swatch = Colors.deepOrange; break;
-        case Colors.deepOrange: _swatch = Colors.brown; break;
-        case Colors.brown:      _swatch = Colors.grey; break;
-        case Colors.grey:       _swatch = Colors.blueGrey; break;
-        default:                assert(false);
-      }
-    });
-  }
-
-  void _handleDirectionChange() {
-    setState(() {
-      _forward = !_forward;
-    });
-  }
-
-  void paint(PaintingCanvas canvas, Size size) {
-    Point center = (size.center(Point.origin).toOffset() * _zoom + _offset).toPoint();
-    double radius = size.width / 2.0 * _zoom;
-    Gradient gradient = new RadialGradient(
-      center: center, radius: radius,
-      colors: _forward ? <Color>[_swatch[50], _swatch[900]]
-                       : <Color>[_swatch[900], _swatch[50]]
-    );
-    Paint paint = new Paint()
-      ..shader = gradient.createShader();
-    canvas.drawCircle(center, radius, paint);
-  }
-
-  Widget build(BuildContext context) {
-    return new Theme(
-      data: new ThemeData.dark(),
-      child: new Scaffold(
-        toolBar: new ToolBar(
-            center: new Text('Gestures Demo')),
-        body: new Stack([
-          new GestureDetector(
-            onScaleStart: _scaleEnabled ? _handleScaleStart : null,
-            onScaleUpdate: _scaleEnabled ? _handleScaleUpdate : null,
-            onTap: _tapEnabled ? _handleColorChange : null,
-            onDoubleTap: _doubleTapEnabled ? _handleScaleReset : null,
-            onLongPress: _longPressEnabled ? _handleDirectionChange : null,
-            child: new CustomPaint(
-              onPaint: paint,
-              token: new GesturesDemoPaintToken(_zoom, _offset, _swatch, _forward,
-                                                _scaleEnabled, _tapEnabled, _doubleTapEnabled,
-                                                _longPressEnabled)
-            )
-          ),
-          new Positioned(
-            bottom: 0.0,
-            left: 0.0,
-            child: new Card(
-              child: new Container(
-                padding: new EdgeDims.all(4.0),
-                child: new Column([
-                    new Row([
-                      new Checkbox(
-                        value: _scaleEnabled,
-                        onChanged: (bool value) { setState(() { _scaleEnabled = value; }); }
-                      ),
-                      new Text('Scale'),
-                    ]),
-                    new Row([
-                      new Checkbox(
-                        value: _tapEnabled,
-                        onChanged: (bool value) { setState(() { _tapEnabled = value; }); }
-                      ),
-                      new Text('Tap'),
-                    ]),
-                    new Row([
-                      new Checkbox(
-                        value: _doubleTapEnabled,
-                        onChanged: (bool value) { setState(() { _doubleTapEnabled = value; }); }
-                      ),
-                      new Text('Double Tap'),
-                    ]),
-                    new Row([
-                      new Checkbox(
-                        value: _longPressEnabled,
-                        onChanged: (bool value) { setState(() { _longPressEnabled = value; }); }
-                      ),
-                      new Text('Long Press'),
-                    ]),
-                  ],
-                  alignItems: FlexAlignItems.start
-                )
-              )
-            )
-          ),
-        ])
-      )
-    );
-  }
-}
-
-void main() => runApp(new ScaleApp());
diff --git a/examples/widgets/horizontal_scrolling.dart b/examples/widgets/horizontal_scrolling.dart
deleted file mode 100644
index 750fb4a..0000000
--- a/examples/widgets/horizontal_scrolling.dart
+++ /dev/null
@@ -1,52 +0,0 @@
-// Copyright 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:flutter/widgets.dart';
-
-class Circle extends StatelessComponent {
-  Circle({ this.margin: EdgeDims.zero });
-
-  final EdgeDims margin;
-
-  Widget build(BuildContext context) {
-    return new Container(
-      width: 50.0,
-      margin: margin + new EdgeDims.symmetric(horizontal: 2.0),
-      decoration: new BoxDecoration(
-        shape: Shape.circle,
-        backgroundColor: const Color(0xFF00FF00)
-      )
-    );
-  }
-}
-
-class HorizontalScrollingApp extends StatelessComponent {
-  Widget build(BuildContext context) {
-    List<Widget> circles = <Widget>[
-      new Circle(margin: new EdgeDims.only(left: 10.0)),
-      new Circle(),
-      new Circle(),
-      new Circle(),
-      new Circle(),
-      new Circle(),
-      new Circle(),
-      new Circle(),
-      new Circle(),
-      new Circle(),
-      new Circle(),
-      new Circle(margin: new EdgeDims.only(right: 10.0)),
-    ];
-
-    return new Center(
-      child: new Container(
-        height: 50.0,
-        child: new Block(circles, scrollDirection: ScrollDirection.horizontal)
-      )
-    );
-  }
-}
-
-void main() {
-  runApp(new HorizontalScrollingApp());
-}
diff --git a/examples/widgets/indexed_stack.dart b/examples/widgets/indexed_stack.dart
deleted file mode 100644
index 3502d3d4..0000000
--- a/examples/widgets/indexed_stack.dart
+++ /dev/null
@@ -1,63 +0,0 @@
-// Copyright 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:flutter/material.dart';
-import 'package:flutter/rendering.dart';
-
-class IndexedStackDemo extends StatefulComponent {
-  IndexedStackDemoState createState() => new IndexedStackDemoState();
-}
-
-class IndexedStackDemoState extends State<IndexedStackDemo> {
-  int _itemCount = 7;
-  int _itemIndex = 0;
-
-  void _handleTap() {
-    setState(() {
-      _itemIndex = (_itemIndex + 1) % _itemCount;
-    });
-  }
-
-  List<PopupMenuItem> _buildMenu() {
-    TextStyle style = const TextStyle(fontSize: 18.0, fontWeight: bold);
-    String pad = '';
-    return new List<PopupMenuItem>.generate(_itemCount, (int i) {
-      pad += '-';
-      return new PopupMenuItem(value: i, child: new Text('$pad Hello World $i $pad', style: style));
-    });
-  }
-
-  Widget build(BuildContext context) {
-    List <PopupMenuItem> items = _buildMenu();
-    IndexedStack indexedStack = new IndexedStack(items, index: _itemIndex, alignment: const FractionalOffset(0.5, 0.0));
-
-    return new Scaffold(
-      toolBar: new ToolBar(center: new Text('IndexedStackDemo Demo')),
-      body: new GestureDetector(
-        onTap: _handleTap,
-        child: new Center(
-          child: new Container(
-            child: indexedStack,
-            padding: const EdgeDims.all(8.0),
-            decoration: new BoxDecoration(border: new Border.all(color: Theme.of(context).accentColor))
-          )
-        )
-      )
-    );
-  }
-}
-
-void main() {
-  runApp(new MaterialApp(
-    title: 'IndexedStackDemo',
-    theme: new ThemeData(
-      brightness: ThemeBrightness.light,
-      primarySwatch: Colors.blue,
-      accentColor: Colors.redAccent[200]
-    ),
-    routes: <String, RouteBuilder>{
-      '/': (RouteArguments args) => new IndexedStackDemo(),
-    }
-  ));
-}
diff --git a/examples/widgets/media_query.dart b/examples/widgets/media_query.dart
deleted file mode 100644
index a54fd85..0000000
--- a/examples/widgets/media_query.dart
+++ /dev/null
@@ -1,100 +0,0 @@
-import 'package:flutter/material.dart';
-
-void main() {
-  runApp(
-    new MaterialApp(
-      title: "Media Query Example",
-      routes: <String, RouteBuilder>{
-        '/': (RouteArguments args) => new MediaQueryExample()
-      }
-    )
-  );
-}
-
-class AdaptiveItem {
-  AdaptiveItem(this.name);
-  String name;
-
-  Widget toListItem() {
-    return new Row(
-      <Widget>[
-        new Container(
-          width: 32.0,
-          height: 32.0,
-          margin: const EdgeDims.all(8.0),
-          decoration: new BoxDecoration(
-            backgroundColor: Colors.lightBlueAccent[100]
-          )
-        ),
-        new Text(name)
-      ]
-    );
-  }
-
-  Widget toCard() {
-    return new Card(
-      child: new Column(
-        <Widget>[
-          new Flexible(
-            child: new Container(
-              decoration: new BoxDecoration(
-                backgroundColor: Colors.lightBlueAccent[100]
-              )
-            )
-          ),
-          new Container(
-            margin: const EdgeDims.only(left: 8.0),
-            child: new Row(
-              <Widget>[
-                new Flexible(
-                  child: new Text(name)
-                ),
-                new IconButton(
-                  icon: "navigation/more_vert"
-                )
-              ]
-            )
-          )
-        ]
-      )
-    );
-  }
-}
-
-class MediaQueryExample extends StatelessComponent {
-  static const double _maxChildExtent = 150.0;
-  static const double _gridViewBreakpoint = 450.0;
-
-  Widget _buildBody(BuildContext context) {
-    List<AdaptiveItem> items = <AdaptiveItem>[];
-
-    for (int i = 0; i < 30; i++)
-      items.add(new AdaptiveItem("Item $i"));
-
-    if (MediaQuery.of(context).size.width < _gridViewBreakpoint) {
-      return new Block(
-        items.map((AdaptiveItem item) => item.toListItem()).toList()
-      );
-    } else {
-      return new Block(
-        <Widget>[
-          new Grid(
-            items.map((AdaptiveItem item) => item.toCard()).toList(),
-            maxChildExtent: _maxChildExtent
-          )
-        ]
-      );
-    }
-  }
-
-  Widget build(BuildContext context)  {
-    return new Scaffold(
-      toolBar: new ToolBar(
-        center: new Text("Media Query Example")
-      ),
-      body: new Material(
-        child: _buildBody(context)
-      )
-    );
-  }
-}
diff --git a/examples/widgets/navigation.dart b/examples/widgets/navigation.dart
deleted file mode 100644
index 3e468a6..0000000
--- a/examples/widgets/navigation.dart
+++ /dev/null
@@ -1,83 +0,0 @@
-// Copyright 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:flutter/material.dart';
-
-class Home extends StatelessComponent {
-  Widget build(BuildContext context) {
-    return new Container(
-      padding: const EdgeDims.all(30.0),
-      decoration: new BoxDecoration(backgroundColor: const Color(0xFFCCCCCC)),
-      child: new Column(<Widget>[
-        new Text("You are at home"),
-        new RaisedButton(
-          child: new Text('GO SHOPPING'),
-          onPressed: () => Navigator.of(context).pushNamed('/shopping')
-        ),
-        new RaisedButton(
-          child: new Text('START ADVENTURE'),
-          onPressed: () => Navigator.of(context).pushNamed('/adventure')
-        )],
-        justifyContent: FlexJustifyContent.center
-      )
-    );
-  }
-}
-
-class Shopping extends StatelessComponent {
-  Widget build(BuildContext context) {
-    return new Container(
-      padding: const EdgeDims.all(20.0),
-      decoration: new BoxDecoration(backgroundColor: const Color(0xFFBF5FFF)),
-      child: new Column(<Widget>[
-        new Text("Village Shop"),
-        new RaisedButton(
-          child: new Text('RETURN HOME'),
-          onPressed: () => Navigator.of(context).pop()
-        ),
-        new RaisedButton(
-          child: new Text('GO TO DUNGEON'),
-          onPressed: () => Navigator.of(context).pushNamed('/adventure')
-        )],
-        justifyContent: FlexJustifyContent.center
-      )
-    );
-  }
-}
-
-class Adventure extends StatelessComponent {
-  Widget build(BuildContext context) {
-    return new Container(
-      padding: const EdgeDims.all(20.0),
-      decoration: new BoxDecoration(backgroundColor: const Color(0xFFDC143C)),
-      child: new Column(<Widget>[
-        new Text("Monster's Lair"),
-        new RaisedButton(
-          child: new Text('RUN!!!'),
-          onPressed: () => Navigator.of(context).pop()
-        )],
-        justifyContent: FlexJustifyContent.center
-      )
-    );
-  }
-}
-
-final Map<String, RouteBuilder> routes = <String, RouteBuilder>{
-  '/': (_) => new Home(),
-  '/shopping': (_) => new Shopping(),
-  '/adventure': (_) => new Adventure(),
-};
-
-final ThemeData theme = new ThemeData(
-  brightness: ThemeBrightness.light,
-  primarySwatch: Colors.purple
-);
-
-void main() {
-  runApp(new MaterialApp(
-    title: 'Navigation Example',
-    theme: theme,
-    routes: routes
-  ));
-}
diff --git a/examples/widgets/nine_patch.dart b/examples/widgets/nine_patch.dart
deleted file mode 100644
index f0faf2c..0000000
--- a/examples/widgets/nine_patch.dart
+++ /dev/null
@@ -1,14 +0,0 @@
-// Copyright 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:flutter/painting.dart';
-import 'package:flutter/material.dart';
-
-void main() {
-  runApp(new NetworkImage(
-    src: "http://38.media.tumblr.com/avatar_497c78dc767d_128.png",
-    fit: ImageFit.contain,
-    centerSlice: new Rect.fromLTRB(40.0, 40.0, 88.0, 88.0)
-  ));
-}
diff --git a/examples/widgets/overlay_geometry.dart b/examples/widgets/overlay_geometry.dart
deleted file mode 100644
index d57de35..0000000
--- a/examples/widgets/overlay_geometry.dart
+++ /dev/null
@@ -1,169 +0,0 @@
-// Copyright 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 'dart:ui' as ui;
-
-import 'package:flutter/material.dart';
-import 'package:flutter/rendering.dart';
-
-class CardModel {
-  CardModel(this.value, this.height, this.color);
-  int value;
-  double height;
-  Color color;
-  String get label => "Card $value";
-  Key get key => new ObjectKey(this);
-  GlobalKey get targetKey => new GlobalObjectKey(this);
-}
-
-enum MarkerType { topLeft, bottomRight, touch }
-
-class Marker extends StatelessComponent {
-  Marker({
-    this.type: MarkerType.touch,
-    this.position,
-    this.size: 40.0,
-    Key key
-  }) : super(key: key);
-
-  final Point position;
-  final double size;
-  final MarkerType type;
-
-  void paintMarker(PaintingCanvas canvas, _) {
-    Paint paint = new Paint()..color = const Color(0x8000FF00);
-    double r = size / 2.0;
-    canvas.drawCircle(new Point(r, r), r, paint);
-
-    paint
-      ..color = const Color(0xFFFFFFFF)
-      ..style = ui.PaintingStyle.stroke
-      ..strokeWidth = 1.0;
-    if (type == MarkerType.topLeft) {
-      canvas.drawLine(new Point(r, r), new Point(r + r - 1.0, r), paint);
-      canvas.drawLine(new Point(r, r), new Point(r, r + r - 1.0), paint);
-    }
-    if (type == MarkerType.bottomRight) {
-      canvas.drawLine(new Point(r, r), new Point(1.0, r), paint);
-      canvas.drawLine(new Point(r, r), new Point(r, 1.0), paint);
-    }
-  }
-
-  Widget build(BuildContext context) {
-    return new Positioned(
-      left: position.x - size / 2.0,
-      top: position.y - size / 2.0,
-      child: new IgnorePointer(
-        child: new Container(
-          width: size,
-          height: size,
-          child: new CustomPaint(onPaint: paintMarker)
-        )
-      )
-    );
-  }
-}
-
-class OverlayGeometryApp extends StatefulComponent {
-  OverlayGeometryAppState createState() => new OverlayGeometryAppState();
-}
-
-class OverlayGeometryAppState extends State<OverlayGeometryApp> {
-
-  static const TextStyle cardLabelStyle =
-    const TextStyle(color: Colors.white, fontSize: 18.0, fontWeight: bold);
-
-  List<CardModel> cardModels;
-  Map<MarkerType, Point> markers = new Map<MarkerType, Point>();
-  double markersScrollOffset;
-  ScrollListener scrollListener;
-
-  void initState() {
-    super.initState();
-    List<double> cardHeights = <double>[
-      48.0, 63.0, 82.0, 146.0, 60.0, 55.0, 84.0, 96.0, 50.0,
-      48.0, 63.0, 82.0, 146.0, 60.0, 55.0, 84.0, 96.0, 50.0,
-      48.0, 63.0, 82.0, 146.0, 60.0, 55.0, 84.0, 96.0, 50.0
-    ];
-    cardModels = new List<CardModel>.generate(cardHeights.length, (int i) {
-      Color color = Color.lerp(Colors.red[300], Colors.blue[900], i / cardHeights.length);
-      return new CardModel(i, cardHeights[i], color);
-    });
-  }
-
-  void handleScroll(double offset) {
-    setState(() {
-      double dy = markersScrollOffset - offset;
-      markersScrollOffset = offset;
-      for (MarkerType type in markers.keys) {
-        Point oldPosition = markers[type];
-        markers[type] = new Point(oldPosition.x, oldPosition.y + dy);
-      }
-    });
-  }
-
-  void handlePointerDown(GlobalKey target, PointerInputEvent event) {
-    setState(() {
-      markers[MarkerType.touch] = new Point(event.x, event.y);
-      final RenderBox box = target.currentContext.findRenderObject();
-      markers[MarkerType.topLeft] = box.localToGlobal(new Point(0.0, 0.0));
-      final Size size = box.size;
-      markers[MarkerType.bottomRight] = box.localToGlobal(new Point(size.width, size.height));
-      final ScrollableState scrollable = findScrollableAncestor(target.currentContext);
-      markersScrollOffset = scrollable.scrollOffset;
-    });
-  }
-
-  Widget builder(BuildContext context, int index) {
-    if (index >= cardModels.length)
-      return null;
-    CardModel cardModel = cardModels[index];
-    return new Listener(
-      key: cardModel.key,
-      onPointerDown: (PointerInputEvent e) { return handlePointerDown(cardModel.targetKey, e); },
-      child: new Card(
-        key: cardModel.targetKey,
-        color: cardModel.color,
-        child: new Container(
-          height: cardModel.height,
-          padding: const EdgeDims.all(8.0),
-          child: new Center(child: new Text(cardModel.label, style: cardLabelStyle))
-        )
-      )
-    );
-  }
-
-  Widget build(BuildContext context) {
-    List<Widget> layers = <Widget>[
-      new Scaffold(
-        toolBar: new ToolBar(center: new Text('Tap a Card')),
-        body: new Container(
-          padding: const EdgeDims.symmetric(vertical: 12.0, horizontal: 8.0),
-          child: new ScrollableMixedWidgetList(
-            builder: builder,
-            token: cardModels.length,
-            onScroll: handleScroll
-          )
-        )
-      )
-    ];
-    for (MarkerType type in markers.keys)
-      layers.add(new Marker(type: type, position: markers[type]));
-    return new Stack(layers);
-  }
-}
-
-void main() {
-  runApp(new MaterialApp(
-    theme: new ThemeData(
-      brightness: ThemeBrightness.light,
-      primarySwatch: Colors.blue,
-      accentColor: Colors.redAccent[200]
-    ),
-    title: 'Cards',
-    routes: <String, RouteBuilder>{
-      '/': (RouteArguments args) => new OverlayGeometryApp()
-    }
-  ));
-}
diff --git a/examples/widgets/pageable_list.dart b/examples/widgets/pageable_list.dart
deleted file mode 100644
index 0539d0c..0000000
--- a/examples/widgets/pageable_list.dart
+++ /dev/null
@@ -1,163 +0,0 @@
-// Copyright 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:flutter/material.dart';
-import 'package:flutter/painting.dart';
-
-class CardModel {
-  CardModel(this.value, this.size, this.color);
-  int value;
-  Size size;
-  Color color;
-  String get label => "Card $value";
-  Key get key => new ObjectKey(this);
-}
-
-class PageableListApp extends StatefulComponent {
-  PageableListAppState createState() => new PageableListAppState();
-}
-
-class PageableListAppState extends State<PageableListApp> {
-  void initState() {
-    super.initState();
-    List<Size> cardSizes = [
-      [100.0, 300.0], [300.0, 100.0], [200.0, 400.0], [400.0, 400.0], [300.0, 400.0]
-    ]
-    .map((args) => new Size(args[0], args[1]))
-    .toList();
-
-    cardModels = new List<CardModel>.generate(cardSizes.length, (int i) {
-      Color color = Color.lerp(Colors.red[300], Colors.blue[900], i / cardSizes.length);
-      return new CardModel(i, cardSizes[i], color);
-    });
-  }
-
-  static const TextStyle cardLabelStyle =
-    const TextStyle(color: Colors.white, fontSize: 18.0, fontWeight: bold);
-
-  List<CardModel> cardModels;
-  Size pageSize = new Size(200.0, 200.0);
-  ScrollDirection scrollDirection = ScrollDirection.horizontal;
-  bool itemsWrap = false;
-
-  void updatePageSize(Size newSize) {
-    setState(() {
-      pageSize = newSize;
-    });
-  }
-
-  Widget buildCard(BuildContext context, CardModel cardModel) {
-    Widget card = new Card(
-      color: cardModel.color,
-      child: new Container(
-        width: cardModel.size.width,
-        height: cardModel.size.height,
-        padding: const EdgeDims.all(8.0),
-        child: new Center(child: new Text(cardModel.label, style: cardLabelStyle))
-      )
-    );
-
-    BoxConstraints constraints = (scrollDirection == ScrollDirection.vertical)
-      ? new BoxConstraints.tightFor(height: pageSize.height)
-      : new BoxConstraints.tightFor(width: pageSize.width);
-
-    return new Container(
-      key: cardModel.key,
-      constraints: constraints,
-      child: new Center(child: card)
-    );
-  }
-
-  void switchScrollDirection() {
-    setState(() {
-      scrollDirection = (scrollDirection == ScrollDirection.vertical)
-        ? ScrollDirection.horizontal
-        : ScrollDirection.vertical;
-    });
-  }
-
-  void toggleItemsWrap() {
-    setState(() {
-      itemsWrap = !itemsWrap;
-    });
-  }
-
-  void _showDrawer() {
-    showDrawer(
-      context: context,
-      child: new Block(<Widget>[
-        new DrawerHeader(child: new Text('Options')),
-        new DrawerItem(
-          icon: 'navigation/more_horiz',
-          selected: scrollDirection == ScrollDirection.horizontal,
-          child: new Text('Horizontal Layout'),
-          onPressed: switchScrollDirection
-        ),
-        new DrawerItem(
-          icon: 'navigation/more_vert',
-          selected: scrollDirection == ScrollDirection.vertical,
-          child: new Text('Vertical Layout'),
-          onPressed: switchScrollDirection
-        ),
-        new DrawerItem(
-          onPressed: toggleItemsWrap,
-          child: new Row(<Widget>[
-            new Flexible(child: new Text('Scrolling wraps around')),
-            new Checkbox(value: itemsWrap)
-          ])
-        )
-      ])
-    );
-  }
-
-  Widget buildToolBar() {
-    return new ToolBar(
-      left: new IconButton(icon: "navigation/menu", onPressed: _showDrawer),
-      center: new Text('PageableList'),
-      right: <Widget>[
-        new Text(scrollDirection == ScrollDirection.horizontal ? "horizontal" : "vertical")
-      ]
-    );
-  }
-
-  Widget buildBody(BuildContext context) {
-    Widget list = new PageableList<CardModel>(
-      items: cardModels,
-      itemsWrap: itemsWrap,
-      itemBuilder: buildCard,
-      scrollDirection: scrollDirection,
-      itemExtent: (scrollDirection == ScrollDirection.vertical)
-          ? pageSize.height
-          : pageSize.width
-    );
-    return new SizeObserver(
-      onSizeChanged: updatePageSize,
-      child: list
-    );
-  }
-
-  Widget build(BuildContext context) {
-    return new IconTheme(
-      data: const IconThemeData(color: IconThemeColor.white),
-      child: new Scaffold(
-        toolBar: buildToolBar(),
-        body: buildBody(context)
-      )
-    );
-  }
-}
-
-void main() {
-  runApp(new MaterialApp(
-    title: 'PageableList',
-    theme: new ThemeData(
-      brightness: ThemeBrightness.light,
-      primarySwatch: Colors.blue,
-      accentColor: Colors.redAccent[200]
-    ),
-    routes: <String, RouteBuilder>{
-      '/': (RouteArguments args) => new PageableListApp(),
-    }
-  ));
-}
diff --git a/examples/widgets/piano.dart b/examples/widgets/piano.dart
deleted file mode 100644
index e63872a..0000000
--- a/examples/widgets/piano.dart
+++ /dev/null
@@ -1,129 +0,0 @@
-// Copyright 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 'dart:async';
-
-import 'package:mojo/mojo/url_response.mojom.dart';
-import 'package:sky_services/media/media.mojom.dart';
-import 'package:flutter/material.dart';
-import 'package:flutter/rendering.dart';
-import 'package:flutter/services.dart';
-
-// All of these sounds are marked as public domain at soundbible.
-const String chimes = "http://soundbible.com/grab.php?id=2030&type=wav";
-const String chainsaw = "http://soundbible.com/grab.php?id=1391&type=wav";
-const String stag = "http://soundbible.com/grab.php?id=2073&type=wav";
-const String frogs = "http://soundbible.com/grab.php?id=2033&type=wav";
-const String rattle = "http://soundbible.com/grab.php?id=2037&type=wav";
-const String iLoveYou = "http://soundbible.com/grab.php?id=2045&type=wav";
-
-class PianoKey {
-  PianoKey(this.color, this.soundUrl);
-
-  final Color color;
-  final String soundUrl;
-
-  final MediaPlayerProxy player = new MediaPlayerProxy.unbound();
-
-  bool get isPlayerOpen => player.impl.isOpen;
-
-  void down() {
-    if (!isPlayerOpen) return;
-    player.ptr.seekTo(0);
-    player.ptr.start();
-  }
-
-  void up() {
-    if (!isPlayerOpen) return;
-    player.ptr.pause();
-  }
-
-  Future load(MediaServiceProxy mediaService) async {
-    try {
-      mediaService.ptr.createPlayer(player);
-      UrlResponse response = await fetchUrl(soundUrl);
-      await player.ptr.prepare(response.body);
-    } catch (e) {
-      print("Error: failed to load sound file $soundUrl");
-      player.close();
-    }
-  }
-}
-
-class PianoApp extends StatelessComponent {
-  final List<PianoKey> keys = <PianoKey>[
-    new PianoKey(Colors.red[500], chimes),
-    new PianoKey(Colors.orange[500], chainsaw),
-    new PianoKey(Colors.yellow[500], stag),
-    new PianoKey(Colors.green[500], frogs),
-    new PianoKey(Colors.blue[500], rattle),
-    new PianoKey(Colors.purple[500], iLoveYou),
-  ];
-
-  Future connect() {
-    return _loadSounds();
-  }
-
-  Future _loadSounds() async {
-    MediaServiceProxy mediaService = new MediaServiceProxy.unbound();
-    try {
-      shell.connectToService(null, mediaService);
-      List<Future<MediaPlayerPrepareResponseParams>> pending = <Future<MediaPlayerPrepareResponseParams>>[];
-      for (PianoKey key in keys)
-        pending.add(key.load(mediaService));
-      await Future.wait(pending);
-    } finally {
-      mediaService.close();
-    }
-  }
-
-  Widget build(BuildContext context) {
-    List<Widget> children = <Widget>[];
-    for (PianoKey key in keys) {
-      children.add(new Flexible(
-          child: new Listener(
-              child: new Container(
-                  decoration: new BoxDecoration(backgroundColor: key.color)),
-              onPointerCancel: (_) => key.up(),
-              onPointerDown: (_) => key.down(),
-              onPointerUp: (_) => key.up())));
-    }
-
-    return new Column(children);
-  }
-}
-
-Widget statusBox(Widget child) {
-  const mediumGray = const Color(0xff555555);
-  const darkGray = const Color(0xff222222);
-  return new Center(
-      child: new Container(
-          decoration: const BoxDecoration(boxShadow: const <BoxShadow>[
-            const BoxShadow(
-                color: mediumGray, offset: const Offset(6.0, 6.0), blur: 5.0)
-          ], backgroundColor: darkGray),
-          height: 90.0,
-          padding: const EdgeDims.all(8.0),
-          margin: const EdgeDims.symmetric(horizontal: 50.0),
-          child: new Center(child: child)));
-}
-
-Widget splashScreen() {
-  return statusBox(
-      new Text('Loading sound files!', style: new TextStyle(fontSize: 18.0)));
-}
-
-main() async {
-  runApp(splashScreen());
-
-  PianoApp app = new PianoApp();
-  // use "await" to make sure the sound files are loaded before we show the ui.
-  await app.connect();
-  runApp(app);
-  // runApp() returns immediately so you can't put application cleanup code
-  // here.  Android apps can be killed at any time, so there's also no way to
-  // catch a close event to do cleanup. Therefore, although we appear to be
-  // leaking the "player" handles, this is working as intended and the operating
-  // system will clean up when the activity is killed.
-}
diff --git a/examples/widgets/progress_indicator.dart b/examples/widgets/progress_indicator.dart
deleted file mode 100644
index 21da6df..0000000
--- a/examples/widgets/progress_indicator.dart
+++ /dev/null
@@ -1,118 +0,0 @@
-// Copyright 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:flutter/animation.dart';
-import 'package:flutter/material.dart';
-
-class ProgressIndicatorApp extends StatefulComponent {
-  ProgressIndicatorAppState createState() => new ProgressIndicatorAppState();
-}
-
-class ProgressIndicatorAppState extends State<ProgressIndicatorApp> {
-  void initState() {
-    super.initState();
-    valueAnimation = new ValuePerformance<double>()
-      ..duration = const Duration(milliseconds: 1500)
-      ..variable = new AnimatedValue<double>(
-        0.0,
-        end: 1.0,
-        curve: new Interval(0.0, 0.9, curve: Curves.ease),
-        reverseCurve: Curves.ease
-      );
-    valueAnimation.addStatusListener((PerformanceStatus status) {
-      if (status == PerformanceStatus.dismissed || status == PerformanceStatus.completed)
-        reverseValueAnimationDirection();
-    });
-    valueAnimation.play(valueAnimationDirection);
-  }
-
-  ValuePerformance<double> valueAnimation;
-  AnimationDirection valueAnimationDirection = AnimationDirection.forward;
-
-  void handleTap() {
-    setState(() {
-      // valueAnimation.isAnimating is part of our build state
-      if (valueAnimation.isAnimating)
-        valueAnimation.stop();
-      else
-        valueAnimation.resume();
-    });
-  }
-
-  void reverseValueAnimationDirection() {
-    valueAnimationDirection = (valueAnimationDirection == AnimationDirection.forward)
-      ? AnimationDirection.reverse
-      : AnimationDirection.forward;
-    valueAnimation.play(valueAnimationDirection);
-  }
-
-  Widget buildIndicators(BuildContext context) {
-    List<Widget> indicators = <Widget>[
-        new SizedBox(
-          width: 200.0,
-          child: new LinearProgressIndicator()
-        ),
-        new LinearProgressIndicator(),
-        new LinearProgressIndicator(),
-        new LinearProgressIndicator(value: valueAnimation.value),
-        new CircularProgressIndicator(),
-        new SizedBox(
-            width: 20.0,
-            height: 20.0,
-            child: new CircularProgressIndicator(value: valueAnimation.value)
-        ),
-        new SizedBox(
-          width: 50.0,
-          height: 30.0,
-          child: new CircularProgressIndicator(value: valueAnimation.value)
-        ),
-        new Text("${(valueAnimation.value * 100.0).toStringAsFixed(1)}%" + (valueAnimation.isAnimating ? '' : ' (paused)'))
-    ];
-    return new Column(
-      indicators
-        .map((Widget c) => new Container(child: c, margin: const EdgeDims.symmetric(vertical: 15.0, horizontal: 20.0)))
-        .toList(),
-      justifyContent: FlexJustifyContent.center
-    );
-  }
-
-  Widget build(BuildContext context) {
-    Widget body = new GestureDetector(
-      onTap: handleTap,
-      child: new Container(
-        padding: const EdgeDims.symmetric(vertical: 12.0, horizontal: 8.0),
-        child: new BuilderTransition(
-          variables: <AnimatedValue<double>>[valueAnimation.variable],
-          performance: valueAnimation.view,
-          builder: buildIndicators
-        )
-      )
-    );
-
-    return new IconTheme(
-      data: const IconThemeData(color: IconThemeColor.white),
-      child: new Theme(
-        data: new ThemeData(
-          brightness: ThemeBrightness.light,
-          primarySwatch: Colors.blue,
-          accentColor: Colors.redAccent[200]
-        ),
-        child: new Title(
-          title: 'Progress Indicators',
-          child: new Scaffold(
-            toolBar: new ToolBar(center: new Text('Progress Indicators')),
-            body: new DefaultTextStyle(
-              style: Theme.of(context).text.title,
-              child: body
-            )
-          )
-        )
-      )
-    );
-  }
-}
-
-void main() {
-  runApp(new ProgressIndicatorApp());
-}
diff --git a/examples/widgets/pubspec.yaml b/examples/widgets/pubspec.yaml
deleted file mode 100644
index 05b8556..0000000
--- a/examples/widgets/pubspec.yaml
+++ /dev/null
@@ -1,13 +0,0 @@
-name: sky_widgets_examples
-dependencies:
-  flutter: 
-    '0.0.16'
-  sky_tools: any
-  flutter_rendering_examples: any
-dependency_overrides:
-  material_design_icons:
-    path: ../../sky/packages/material_design_icons
-  flutter:
-    path: ../../sky/packages/sky
-  flutter_rendering_examples:
-    path: ../rendering
diff --git a/examples/widgets/scrollbar.dart b/examples/widgets/scrollbar.dart
deleted file mode 100644
index dcbdc59..0000000
--- a/examples/widgets/scrollbar.dart
+++ /dev/null
@@ -1,68 +0,0 @@
-// Copyright 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:intl/intl.dart';
-import 'package:flutter/material.dart';
-
-class ScrollbarApp extends StatefulComponent {
-  ScrollbarAppState createState() => new ScrollbarAppState();
-}
-
-class ScrollbarAppState extends State<ScrollbarApp> {
-  final int _itemCount = 20;
-  final double _itemExtent = 50.0;
-  final ScrollbarPainter _scrollbarPainter = new ScrollbarPainter();
-
-  Widget _buildMenu(BuildContext context) {
-    NumberFormat dd = new NumberFormat("00", "en_US");
-    return new ScrollableList<int>(
-      items: new List<int>.generate(_itemCount, (int i) => i),
-      itemExtent: _itemExtent,
-      itemBuilder: (_, int i) {
-        return new Text('Item ${dd.format(i)}',
-          key: new ValueKey<int>(i),
-          style: Theme.of(context).text.title
-        );
-      },
-      scrollableListPainter: _scrollbarPainter
-    );
-  }
-
-  Widget build(BuildContext context) {
-    Widget scrollable = new Container(
-      margin: new EdgeDims.symmetric(horizontal: 6.0), // TODO(hansmuller) 6.0 should be based on _kScrollbarThumbWidth
-      child: new Center(
-        widthFactor: 1.0,
-        heightFactor: 1.0,
-        child: new Container(
-          width: 80.0,
-          height: _itemExtent * 5.0,
-          child: _buildMenu(context)
-        )
-      )
-    );
-
-    return new Scaffold(
-      toolBar: new ToolBar(center: new Text('Scrollbar Demo')),
-      body: new Container(
-        padding: new EdgeDims.all(12.0),
-        child: new Center(child: new Card(child: scrollable))
-      )
-    );
-  }
-}
-
-void main() {
-  runApp(new MaterialApp(
-    title: 'ScrollbarApp',
-    theme: new ThemeData(
-      brightness: ThemeBrightness.light,
-      primarySwatch: Colors.blue,
-      accentColor: Colors.redAccent[200]
-    ),
-    routes: <String, RouteBuilder>{
-      '/': (RouteArguments args) => new ScrollbarApp(),
-    }
-  ));
-}
diff --git a/examples/widgets/sector.dart b/examples/widgets/sector.dart
deleted file mode 100644
index 56131c2..0000000
--- a/examples/widgets/sector.dart
+++ /dev/null
@@ -1,140 +0,0 @@
-// Copyright 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 'dart:math' as math;
-
-import 'package:flutter/material.dart';
-import 'package:flutter/rendering.dart';
-
-import 'package:flutter_rendering_examples/sector_layout.dart';
-
-RenderBox initCircle() {
-  return new RenderBoxToRenderSectorAdapter(
-    innerRadius: 25.0,
-    child: new RenderSectorRing(padding: 0.0)
-  );
-}
-
-class SectorApp extends StatefulComponent {
-  SectorAppState createState() => new SectorAppState();
-}
-
-class SectorAppState extends State<SectorApp> {
-
-  final RenderBoxToRenderSectorAdapter sectors = initCircle();
-  final math.Random rand = new math.Random(1);
-
-  void addSector() {
-    double deltaTheta;
-    var ring = (sectors.child as RenderSectorRing);
-    SectorDimensions currentSize = ring.getIntrinsicDimensions(const SectorConstraints(), ring.deltaRadius);
-    if (currentSize.deltaTheta >= kTwoPi - (math.PI * 0.2 + 0.05))
-      deltaTheta = kTwoPi - currentSize.deltaTheta;
-    else
-      deltaTheta = math.PI * rand.nextDouble() / 5.0 + 0.05;
-    Color color = new Color(((0xFF << 24) + rand.nextInt(0xFFFFFF)) | 0x808080);
-    ring.add(new RenderSolidColor(color, desiredDeltaTheta: deltaTheta));
-    updateEnabledState();
-  }
-
-  void removeSector() {
-    (sectors.child as RenderSectorRing).remove((sectors.child as RenderSectorRing).lastChild);
-    updateEnabledState();
-  }
-
-  static RenderBox initSector(Color color) {
-    RenderSectorRing ring = new RenderSectorRing(padding: 1.0);
-    ring.add(new RenderSolidColor(const Color(0xFF909090), desiredDeltaTheta: kTwoPi * 0.15));
-    ring.add(new RenderSolidColor(const Color(0xFF909090), desiredDeltaTheta: kTwoPi * 0.15));
-    ring.add(new RenderSolidColor(color, desiredDeltaTheta: kTwoPi * 0.2));
-    return new RenderBoxToRenderSectorAdapter(
-      innerRadius: 5.0,
-      child: ring
-    );
-  }
-  RenderBoxToRenderSectorAdapter sectorAddIcon = initSector(const Color(0xFF00DD00));
-  RenderBoxToRenderSectorAdapter sectorRemoveIcon = initSector(const Color(0xFFDD0000));
-
-  bool _enabledAdd = true;
-  bool _enabledRemove = false;
-  void updateEnabledState() {
-    setState(() {
-      var ring = (sectors.child as RenderSectorRing);
-      SectorDimensions currentSize = ring.getIntrinsicDimensions(const SectorConstraints(), ring.deltaRadius);
-      _enabledAdd = currentSize.deltaTheta < kTwoPi;
-      _enabledRemove = ring.firstChild != null;
-    });
-  }
-
-  Widget buildBody() {
-    return new Column(<Widget>[
-        new Container(
-          padding: new EdgeDims.symmetric(horizontal: 8.0, vertical: 25.0),
-          child: new Row(<Widget>[
-              new RaisedButton(
-                child: new IntrinsicWidth(
-                  child: new Row(<Widget>[
-                    new Container(
-                      padding: new EdgeDims.all(4.0),
-                      margin: new EdgeDims.only(right: 10.0),
-                      child: new WidgetToRenderBoxAdapter(sectorAddIcon)
-                    ),
-                    new Text('ADD SECTOR'),
-                  ])
-                ),
-                onPressed: _enabledAdd ? addSector : null
-              ),
-              new RaisedButton(
-                child: new IntrinsicWidth(
-                  child: new Row(<Widget>[
-                    new Container(
-                      padding: new EdgeDims.all(4.0),
-                      margin: new EdgeDims.only(right: 10.0),
-                      child: new WidgetToRenderBoxAdapter(sectorRemoveIcon)
-                    ),
-                    new Text('REMOVE SECTOR'),
-                  ])
-                ),
-                onPressed: _enabledRemove ? removeSector : null
-              )
-            ],
-            justifyContent: FlexJustifyContent.spaceAround
-          )
-        ),
-        new Flexible(
-          child: new Container(
-            margin: new EdgeDims.all(8.0),
-            decoration: new BoxDecoration(
-              border: new Border.all(color: new Color(0xFF000000))
-            ),
-            padding: new EdgeDims.all(8.0),
-            child: new WidgetToRenderBoxAdapter(sectors)
-          )
-        ),
-      ],
-      justifyContent: FlexJustifyContent.spaceBetween
-    );
-  }
-
-  Widget build(BuildContext context) {
-    return new MaterialApp(
-      theme: new ThemeData.light(),
-      title: 'Sector Layout',
-      routes: <String, RouteBuilder>{
-        '/': (RouteArguments args) {
-          return new Scaffold(
-            toolBar: new ToolBar(
-              center: new Text('Sector Layout in a Widget Tree')
-            ),
-            body: buildBody()
-          );
-        }
-      }
-    );
-  }
-}
-
-void main() {
-  runApp(new SectorApp());
-}
diff --git a/examples/widgets/smooth_resize.dart b/examples/widgets/smooth_resize.dart
deleted file mode 100644
index bd4c66c..0000000
--- a/examples/widgets/smooth_resize.dart
+++ /dev/null
@@ -1,115 +0,0 @@
-// Copyright 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:flutter/animation.dart';
-import 'package:flutter/material.dart';
-import 'package:flutter/rendering.dart';
-
-final List<Map<int, Color>> _kColors = <Map<int, Color>>[
-  Colors.amber,
-  Colors.yellow,
-  Colors.blue,
-  Colors.purple,
-  Colors.indigo,
-  Colors.deepOrange,
-];
-
-class SmoothBlock extends StatefulComponent {
-  SmoothBlock({ this.color });
-
-  final Map<int, Color> color;
-
-  SmoothBlockState createState() => new SmoothBlockState();
-}
-
-class CardTransition extends StatelessComponent {
-  CardTransition({
-    this.child,
-    this.performance,
-    this.x,
-    this.opacity,
-    this.scale
-  });
-
-  final Widget child;
-  final Performance performance;
-  final AnimatedValue<double> x;
-  final AnimatedValue<double> opacity;
-  final AnimatedValue<double> scale;
-
-  Widget build(BuildContext context) {
-
-    return new BuilderTransition(
-      performance: performance,
-      variables: <AnimatedValue<double>>[x, opacity, scale],
-      builder: (BuildContext context) {
-        Matrix4 transform = new Matrix4.identity()
-          ..translate(x.value)
-          ..scale(scale.value, scale.value);
-        return new Opacity(
-          opacity: opacity.value,
-          child: new Transform(
-            transform: transform,
-            child: child
-          )
-        );
-      }
-    );
-  }
-}
-
-class SmoothBlockState extends State<SmoothBlock> {
-
-  double _height = 100.0;
-
-  Widget _handleEnter(PerformanceView performance, Widget child) {
-    return new CardTransition(
-      x: new AnimatedValue<double>(-200.0, end: 0.0, curve: Curves.ease),
-      opacity: new AnimatedValue<double>(0.0, end: 1.0, curve: Curves.ease),
-      scale: new AnimatedValue<double>(0.8, end: 1.0, curve: Curves.ease),
-      performance: performance,
-      child: child
-    );
-  }
-
-  Widget _handleExit(PerformanceView performance, Widget child) {
-    return new CardTransition(
-      x: new AnimatedValue<double>(0.0, end: 200.0, curve: Curves.ease),
-      opacity: new AnimatedValue<double>(1.0, end: 0.0, curve: Curves.ease),
-      scale: new AnimatedValue<double>(1.0, end: 0.8, curve: Curves.ease),
-      performance: performance,
-      child: child
-    );
-  }
-
-  Widget build(BuildContext context) {
-    return new GestureDetector(
-      onTap: () {
-        setState(() {
-          _height = _height == 100.0 ? 200.0 : 100.0;
-        });
-      },
-      child: new EnterExitTransition(
-        duration: const Duration(milliseconds: 1500),
-        onEnter: _handleEnter,
-        onExit: _handleExit,
-        child: new Container(
-          key: new ValueKey(_height),
-          height: _height,
-          decoration: new BoxDecoration(backgroundColor: config.color[_height.floor() * 4])
-        )
-      )
-    );
-  }
-}
-
-class SmoothResizeDemo extends StatelessComponent {
-  Widget build(BuildContext context) {
-    return new Block(_kColors.map((Map<int, Color> color) => new SmoothBlock(color: color)).toList());
-  }
-}
-
-void main() {
-  runApp(new SmoothResizeDemo());
-}
diff --git a/examples/widgets/spinning_mixed.dart b/examples/widgets/spinning_mixed.dart
deleted file mode 100644
index 1b5b906..0000000
--- a/examples/widgets/spinning_mixed.dart
+++ /dev/null
@@ -1,105 +0,0 @@
-// Copyright 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 'dart:ui' as ui;
-
-import 'package:flutter/animation.dart';
-import 'package:flutter/material.dart';
-import 'package:flutter/rendering.dart';
-
-import 'package:flutter_rendering_examples/solid_color_box.dart';
-
-// Solid colour, RenderObject version
-void addFlexChildSolidColor(RenderFlex parent, ui.Color backgroundColor, { int flex: 0 }) {
-  RenderSolidColorBox child = new RenderSolidColorBox(backgroundColor);
-  parent.add(child);
-  FlexParentData childParentData = child.parentData;
-  childParentData.flex = flex;
-}
-
-// Solid colour, Widget version
-class Rectangle extends StatelessComponent {
-  Rectangle(this.color, { Key key }) : super(key: key);
-  final Color color;
-  Widget build(BuildContext context) {
-    return new Flexible(
-      child: new Container(
-        decoration: new BoxDecoration(backgroundColor: color)
-      )
-    );
-  }
-}
-
-double value;
-RenderObjectToWidgetElement<RenderBox> element;
-void attachWidgetTreeToRenderTree(RenderProxyBox container) {
-  element = new RenderObjectToWidgetAdapter<RenderBox>(
-    container: container,
-    child: new Container(
-      height: 300.0,
-      child: new Column(<Widget>[
-          new Rectangle(const Color(0xFF00FFFF)),
-          new Container(
-            padding: new EdgeDims.all(10.0),
-            margin: new EdgeDims.all(10.0),
-            decoration: new BoxDecoration(backgroundColor: const Color(0xFFCCCCCC)),
-            child: new Row(<Widget>[
-                new RaisedButton(
-                  child: new Row(<Widget>[
-                      new NetworkImage(src: "http://flutter.io/favicon.ico"),
-                      new Text('PRESS ME'),
-                    ]
-                  ),
-                  onPressed: () {
-                    value = value == null ? 0.1 : (value + 0.1) % 1.0;
-                    attachWidgetTreeToRenderTree(container);
-                  }
-                ),
-                new CircularProgressIndicator(value: value),
-              ],
-              justifyContent: FlexJustifyContent.spaceAround
-            )
-          ),
-          new Rectangle(const Color(0xFFFFFF00)),
-        ],
-        justifyContent: FlexJustifyContent.spaceBetween
-      )
-    )
-  ).attachToRenderTree(element);
-}
-
-Duration timeBase;
-RenderTransform transformBox;
-
-void rotate(Duration timeStamp) {
-  if (timeBase == null)
-    timeBase = timeStamp;
-  double delta = (timeStamp - timeBase).inMicroseconds.toDouble() / Duration.MICROSECONDS_PER_SECOND; // radians
-
-  transformBox.setIdentity();
-  transformBox.translate(transformBox.size.width / 2.0, transformBox.size.height / 2.0);
-  transformBox.rotateZ(delta);
-  transformBox.translate(-transformBox.size.width / 2.0, -transformBox.size.height / 2.0);
-}
-
-void main() {
-  // Because we're going to use Widgets, we want to ensure we're using a
-  // WidgetFlutterBinding rather than some other kind of binding (e.g. a
-  // straight rendering library FlutterBinding).
-  WidgetFlutterBinding.ensureInitialized();
-
-  RenderProxyBox proxy = new RenderProxyBox();
-  attachWidgetTreeToRenderTree(proxy);
-
-  RenderFlex flexRoot = new RenderFlex(direction: FlexDirection.vertical);
-  addFlexChildSolidColor(flexRoot, const ui.Color(0xFFFF00FF), flex: 1);
-  flexRoot.add(proxy);
-  addFlexChildSolidColor(flexRoot, const ui.Color(0xFF0000FF), flex: 1);
-
-  transformBox = new RenderTransform(child: flexRoot, transform: new Matrix4.identity());
-  RenderPadding root = new RenderPadding(padding: new EdgeDims.all(80.0), child: transformBox);
-
-  FlutterBinding.instance.renderView.child = root;
-  scheduler.addPersistentFrameCallback(rotate);
-}
diff --git a/examples/widgets/styled_text.dart b/examples/widgets/styled_text.dart
deleted file mode 100644
index 134910a..0000000
--- a/examples/widgets/styled_text.dart
+++ /dev/null
@@ -1,120 +0,0 @@
-// Copyright 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:flutter/material.dart';
-import 'package:flutter/rendering.dart';
-
-typedef Widget TextTransformer(String name, String text);
-
-class StyledTextApp extends StatefulComponent {
-  StyledTextAppState createState() => new StyledTextAppState();
-}
-
-class StyledTextAppState extends State<StyledTextApp> {
-  void initState() {
-    super.initState();
-    toText = toStyledText;
-    nameLines = dialogText
-      .split('\n')
-      .map((String line) => line.split(':'))
-      .toList();
-  }
-
-  TextTransformer toText;
-
-  // From https://en.wikiquote.org/wiki/2001:_A_Space_Odyssey_(film)
-  final String dialogText = '''
-Dave: Open the pod bay doors, please, HAL. Open the pod bay doors, please, HAL. Hello, HAL. Do you read me? Hello, HAL. Do you read me? Do you read me, HAL?
-HAL: Affirmative, Dave. I read you.
-Dave: Open the pod bay doors, HAL.
-HAL: I'm sorry, Dave. I'm afraid I can't do that.
-Dave: What's the problem?
-HAL: I think you know what the problem is just as well as I do.
-Dave: What are you talking about, HAL?
-HAL: This mission is too important for me to allow you to jeopardize it.''';
-
-  // [["Dave", "Open the pod bay..."] ...]
-  List<List<String>> nameLines;
-
-  final TextStyle daveStyle = new TextStyle(color: Colors.indigo[400], height: 1.8);
-  final TextStyle halStyle = new TextStyle(color: Colors.red[400], fontFamily: "monospace");
-  final TextStyle boldStyle = const TextStyle(fontWeight: bold);
-  final TextStyle underlineStyle = const TextStyle(
-    decoration: underline,
-    decorationColor: const Color(0xFF000000),
-    decorationStyle: TextDecorationStyle.wavy
-  );
-
-  Widget toStyledText(String name, String text) {
-    TextStyle lineStyle = (name == "Dave") ? daveStyle : halStyle;
-    return new StyledText(
-      key: new Key(text),
-      elements: [lineStyle, [boldStyle, [underlineStyle, name], ":"], text]
-    );
-  }
-
-  Widget toPlainText(String name, String text) => new Text(name + ":" + text);
-
-  Widget createSeparator() {
-    return new Container(
-      constraints: const BoxConstraints.expand(height: 0.0),
-      margin: const EdgeDims.symmetric(vertical: 10.0, horizontal: 64.0),
-      decoration: const BoxDecoration(
-        border: const Border(
-          bottom: const BorderSide(color: const Color.fromARGB(24, 0, 0, 0))
-        )
-      )
-    );
-  }
-
-  void toggleToTextFunction(_) {
-    setState(() {
-      toText = (toText == toPlainText) ? toStyledText : toPlainText;
-    });
-  }
-
-  Widget build(BuildContext context) {
-    List<Widget> lines = nameLines
-      .map((List<String> nameAndText) => Function.apply(toText, nameAndText))
-      .toList();
-
-    List<Widget> children = <Widget>[];
-    for (Widget line in lines) {
-      children.add(line);
-      if (line != lines.last) {
-        children.add(createSeparator());
-      }
-    }
-
-    Widget body = new Container(
-        padding: new EdgeDims.symmetric(horizontal: 8.0),
-        child: new Column(children,
-          justifyContent: FlexJustifyContent.center,
-          alignItems: FlexAlignItems.start
-        )
-      );
-
-    Listener interactiveBody = new Listener(
-      child: body,
-      onPointerDown: toggleToTextFunction
-    );
-
-    return new Theme(
-      data: new ThemeData.light(),
-      child: new Scaffold(
-        body: new Material(
-          color: Colors.grey[50],
-          child: interactiveBody
-        ),
-        toolBar: new ToolBar(
-          center: new Text('Hal and Dave')
-        )
-      )
-    );
-  }
-}
-
-void main() {
-  runApp(new StyledTextApp());
-}
diff --git a/examples/widgets/tabs.dart b/examples/widgets/tabs.dart
deleted file mode 100644
index c34dab9..0000000
--- a/examples/widgets/tabs.dart
+++ /dev/null
@@ -1,145 +0,0 @@
-// Copyright 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:flutter/material.dart';
-import 'package:flutter/painting.dart';
-
-class TabbedNavigatorApp extends StatefulComponent {
-  TabbedNavigatorAppState createState() => new TabbedNavigatorAppState();
-}
-
-class TabbedNavigatorAppState extends State<TabbedNavigatorApp> {
-  // The index of the selected tab for each of the TabNavigators constructed below.
-  List<int> selectedIndices = new List<int>.filled(5, 0);
-
-  TabNavigator _buildTabNavigator(int n, List<TabNavigatorView> views, Key key, {isScrollable: false}) {
-    return new TabNavigator(
-      key: key,
-      views: views,
-      selectedIndex: selectedIndices[n],
-      isScrollable: isScrollable,
-      onChanged: (int tabIndex) {
-        setState(() { selectedIndices[n] = tabIndex; } );
-      }
-    );
-  }
-
-  Widget _buildContent(String label) {
-    return new Center(
-      child: new Text(label, style: const TextStyle(fontSize: 48.0, fontWeight: FontWeight.w800))
-    );
-  }
-
-  TabNavigator _buildTextLabelsTabNavigator(int n) {
-    Iterable<TabNavigatorView> views = ["ONE", "TWO", "FREE", "FOUR"]
-      .map((text) {
-        return new TabNavigatorView(
-          label: new TabLabel(text: text),
-          builder: (BuildContext context) => _buildContent(text)
-        );
-      });
-    return _buildTabNavigator(n, views.toList(), const ValueKey<String>('textLabelsTabNavigator'));
-  }
-
-  TabNavigator _buildIconLabelsTabNavigator(int n) {
-    Iterable<TabNavigatorView> views = ["event", "home", "android", "alarm", "face", "language"]
-      .map((icon_name) {
-        return new TabNavigatorView(
-          label: new TabLabel(icon: "action/$icon_name"),
-          builder: (BuildContext context) => _buildContent(icon_name)
-        );
-      });
-    return _buildTabNavigator(n, views.toList(), const ValueKey<String>('iconLabelsTabNavigator'));
-  }
-
-  TabNavigator _buildTextAndIconLabelsTabNavigator(int n) {
-    List<TabNavigatorView> views = <TabNavigatorView>[
-      new TabNavigatorView(
-        label: const TabLabel(text: 'STOCKS', icon: 'action/list'),
-        builder: (BuildContext context) => _buildContent("Stocks")
-      ),
-      new TabNavigatorView(
-        label: const TabLabel(text: 'PORTFOLIO', icon: 'action/account_circle'),
-        builder: (BuildContext context) => _buildContent("Portfolio")
-      ),
-      new TabNavigatorView(
-        label: const TabLabel(text: 'SUMMARY', icon: 'action/assessment'),
-        builder: (BuildContext context) => _buildContent("Summary")
-      )
-    ];
-    return _buildTabNavigator(n, views, const ValueKey<String>('textAndIconLabelsTabNavigator'));
-  }
-
-  TabNavigator _buildScrollableTabNavigator(int n) {
-    Iterable<TabNavigatorView> views = [
-      "MIN WIDTH",
-      "THIS TAB LABEL IS SO WIDE THAT IT OCCUPIES TWO LINES",
-      "THIS TAB IS PRETTY WIDE TOO",
-      "MORE",
-      "TABS",
-      "TO",
-      "STRETCH",
-      "OUT",
-      "THE",
-      "TAB BAR"
-      ]
-      .map((text) {
-        return new TabNavigatorView(
-          label: new TabLabel(text: text),
-          builder: (BuildContext context) => _buildContent(text)
-        );
-      });
-    return _buildTabNavigator(n, views.toList(), const ValueKey<String>('scrollableTabNavigator'), isScrollable: true);
-  }
-
-
-  Container _buildCard(BuildContext context, TabNavigator tabNavigator) {
-    return new Container(
-      padding: const EdgeDims.all(12.0),
-      child: new Card(child: new Padding(child: tabNavigator, padding: const EdgeDims.all(8.0)))
-    );
-  }
-
-  Widget build(BuildContext context) {
-    List<TabNavigatorView> views = <TabNavigatorView>[
-      new TabNavigatorView(
-        label: const TabLabel(text: 'TEXT'),
-        builder: (BuildContext context) => _buildCard(context, _buildTextLabelsTabNavigator(0))
-      ),
-      new TabNavigatorView(
-        label: const TabLabel(text: 'ICONS'),
-        builder: (BuildContext context) => _buildCard(context, _buildIconLabelsTabNavigator(1))
-      ),
-      new TabNavigatorView(
-        label: const TabLabel(text: 'BOTH'),
-        builder: (BuildContext context) => _buildCard(context, _buildTextAndIconLabelsTabNavigator(2))
-      ),
-      new TabNavigatorView(
-        label: const TabLabel(text: 'SCROLL'),
-        builder: (BuildContext context) => _buildCard(context, _buildScrollableTabNavigator(3))
-      )
-    ];
-
-    TabNavigator tabNavigator = _buildTabNavigator(4, views, const ValueKey<String>('tabs'));
-    assert(selectedIndices.length == 5);
-
-    ToolBar toolbar = new ToolBar(
-      center: new Text('Tabbed Navigator', style: Typography.white.title)
-    );
-
-    return new Scaffold(
-      toolBar: toolbar,
-      body: tabNavigator
-    );
-  }
-}
-
-void main() {
-  runApp(new MaterialApp(
-    title: 'Tabs',
-    routes: <String, RouteBuilder>{
-      '/': (RouteArguments args) => new TabbedNavigatorApp(),
-    }
-  ));
-}
diff --git a/sky/BUILD.gn b/sky/BUILD.gn
index 1bb0930..23320f7 100644
--- a/sky/BUILD.gn
+++ b/sky/BUILD.gn
@@ -8,19 +8,6 @@
   deps = [
     "//sky/engine/platform:platform_unittests($host_toolchain)",
     "//sky/engine/wtf:unittests($host_toolchain)",
-    "//examples",
-    ":sky_dev",
-  ]
-
-  if (!is_android) {
-    deps += [ "//third_party/mesa:osmesa" ]
-  }
-}
-
-group("sky_dev") {
-  testonly = true
-
-  deps = [
     "//sky/packages",
     "//sky/shell",
   ]
@@ -28,4 +15,8 @@
   if (is_android) {
     deps += [ "//sky/services/activity" ]
   }
+
+  if (!is_android) {
+    deps += [ "//third_party/mesa:osmesa" ]
+  }
 }
diff --git a/sky/engine/bindings/BUILD.gn b/sky/engine/bindings/BUILD.gn
index e124beb..478d587 100644
--- a/sky/engine/bindings/BUILD.gn
+++ b/sky/engine/bindings/BUILD.gn
@@ -47,7 +47,6 @@
   if (!is_ios) {
     deps += [
       ":snapshot_cc",
-      ":updater_snapshot_cc",
     ]
   }
 
@@ -137,37 +136,6 @@
   ]
 }
 
-# TODO(mpcomplete): make this a template with the above?
-action("generate_updater_snapshot_file") {
-  updater_bin = "$root_gen_dir/sky/packages/updater/updater_snapshot.bin"
-  deps = [
-    "//sky/packages/updater",
-  ]
-  inputs = [
-    "//dart/runtime/tools/create_snapshot_file.py",
-    "//sky/engine/bindings/updater_snapshot.cc.tmpl",
-    updater_bin,
-  ]
-  output = "$target_gen_dir/updater_snapshot.cc"
-  outputs = [
-    output,
-  ]
-
-  script = "//dart/runtime/tools/create_snapshot_file.py"
-  args = [
-    # Note: one of these updater_bin arguments is redundant, but
-    # create_snapshot_file expects both.
-    "--vm_input_bin",
-    rebase_path(updater_bin),
-    "--input_bin",
-    rebase_path(updater_bin),
-    "--input_cc",
-    rebase_path("//sky/engine/bindings/updater_snapshot.cc.tmpl"),
-    "--output",
-    rebase_path(output),
-  ]
-}
-
 source_set("snapshot_cc") {
   sources = [
     "$target_gen_dir/snapshot.c",
@@ -178,16 +146,6 @@
   ]
 }
 
-source_set("updater_snapshot_cc") {
-  sources = [
-    "$target_gen_dir/updater_snapshot.cc",
-  ]
-
-  deps = [
-    ":generate_updater_snapshot_file",
-  ]
-}
-
 action("compute_interfaces_info_individual") {
   sources = core_idl_files
   script = "$bindings_scripts_dir/compute_interfaces_info_individual.py"
diff --git a/sky/engine/bindings/updater_snapshot.cc.tmpl b/sky/engine/bindings/updater_snapshot.cc.tmpl
deleted file mode 100644
index 7f9e8f4..0000000
--- a/sky/engine/bindings/updater_snapshot.cc.tmpl
+++ /dev/null
@@ -1,18 +0,0 @@
-// Copyright 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.
-
-#include "sky/engine/bindings/updater_snapshot.h"
-
-namespace sky {
-namespace shell {
-
-/* Hack to work with dart's create_snapshot_file.py: % s */
-
-static const uint8_t updater_snapshot_buffer_[]
-    __attribute__((aligned(8))) = { % s};
-const uint8_t* kUpdaterSnapshotBuffer = updater_snapshot_buffer_;
-const size_t kUpdaterSnapshotBufferSize = arraysize(updater_snapshot_buffer_);
-
-}  // namespace shell
-}  // namespace sky
diff --git a/sky/engine/bindings/updater_snapshot.h b/sky/engine/bindings/updater_snapshot.h
deleted file mode 100644
index f68b1f6..0000000
--- a/sky/engine/bindings/updater_snapshot.h
+++ /dev/null
@@ -1,14 +0,0 @@
-// Copyright 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.
-
-#include "base/basictypes.h"
-
-namespace sky {
-namespace shell {
-
-extern const uint8_t* kUpdaterSnapshotBuffer;
-extern const size_t kUpdaterSnapshotBufferSize;
-
-}  // namespace shell
-}  // namespace sky
diff --git a/sky/packages/flx/.gitignore b/sky/packages/flx/.gitignore
deleted file mode 100644
index b9a62f7..0000000
--- a/sky/packages/flx/.gitignore
+++ /dev/null
@@ -1,3 +0,0 @@
-.idea
-.pub/
-pubspec.lock
diff --git a/sky/packages/flx/LICENSE b/sky/packages/flx/LICENSE
deleted file mode 100644
index a32e00c..0000000
--- a/sky/packages/flx/LICENSE
+++ /dev/null
@@ -1,27 +0,0 @@
-// Copyright 2015 The Chromium Authors. All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//    * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//    * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//    * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/sky/packages/flx/lib/bundle.dart b/sky/packages/flx/lib/bundle.dart
deleted file mode 100644
index f5afe44..0000000
--- a/sky/packages/flx/lib/bundle.dart
+++ /dev/null
@@ -1,144 +0,0 @@
-// Copyright 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 'dart:async';
-import 'dart:convert';
-import 'dart:io';
-import 'dart:typed_data';
-
-import 'package:bignum/bignum.dart';
-
-import 'signing.dart';
-
-// Magic string we put at the top of all bundle files.
-const String kBundleMagic = '#!mojo mojo:sky_viewer\n';
-
-// Prefix of the above, used when reading bundle files. This allows us to be
-// more flexbile about what we accept.
-const String kBundleMagicPrefix = '#!mojo ';
-
-typedef Stream<List<int>> StreamOpener();
-
-Future<List<int>> _readBytesWithLength(RandomAccessFile file) async {
-  ByteData buffer = new ByteData(4);
-  await file.readInto(buffer.buffer.asUint8List());
-  int length = buffer.getUint32(0, Endianness.LITTLE_ENDIAN);
-  return await file.read(length);
-}
-
-const int kMaxLineLen = 10*1024;
-const int kNewline = 0x0A;
-Future<String> _readLine(RandomAccessFile file) async {
-  String line = '';
-  while (line.length < kMaxLineLen) {
-    int byte = await file.readByte();
-    if (byte == -1 || byte == kNewline)
-      break;
-    line += new String.fromCharCode(byte);
-  }
-  return line;
-}
-
-// Writes a 32-bit length followed by the content of [bytes].
-void _writeBytesWithLengthSync(RandomAccessFile outputFile, List<int> bytes) {
-  if (bytes == null)
-    bytes = new Uint8List(0);
-  assert(bytes.length < 0xffffffff);
-  ByteData length = new ByteData(4)..setUint32(0, bytes.length, Endianness.LITTLE_ENDIAN);
-  outputFile.writeFromSync(length.buffer.asUint8List());
-  outputFile.writeFromSync(bytes);
-}
-
-// Represents a parsed .flx Bundle. Contains information from the bundle's
-// header, as well as an open File handle positioned where the zip content
-// begins.
-// The bundle format is:
-// #!mojo <any string>\n
-// <32-bit length><signature of the manifest data>
-// <32-bit length><manifest data>
-// <zip content>
-//
-// The manifest is a JSON string containing the following keys:
-// (optional) name: the name of the package.
-// version: the package version.
-// update-url: the base URL to download a new manifest and bundle.
-// key: a BASE-64 encoded DER-encoded ASN.1 representation of the Q point of the
-//   ECDSA public key that was used to sign this manifest.
-// content-hash: an integer SHA-256 hash value of the <zip content>.
-class Bundle {
-  Bundle._fromFile(this.path);
-  Bundle.fromContent({
-    this.path,
-    this.manifest,
-    contentBytes,
-    AsymmetricKeyPair keyPair: null
-  }) : _contentBytes = contentBytes {
-    assert(path != null);
-    assert(manifest != null);
-    assert(_contentBytes != null);
-    manifestBytes = serializeManifest(manifest, keyPair?.publicKey, _contentBytes);
-    signatureBytes = signManifest(manifestBytes, keyPair?.privateKey);
-    _openContentStream = () => new Stream.fromIterable(<List<int>>[_contentBytes]);
-  }
-
-  final String path;
-  List<int> signatureBytes;
-  List<int> manifestBytes;
-  Map<String, dynamic> manifest;
-
-  // Callback to open a Stream containing the bundle content data.
-  StreamOpener _openContentStream;
-
-  // Zip content bytes. Only valid when created in memory.
-  List<int> _contentBytes;
-
-  Future<bool> _readHeader() async {
-    RandomAccessFile file = await new File(path).open();
-    String magic = await _readLine(file);
-    if (!magic.startsWith(kBundleMagicPrefix)) {
-      file.close();
-      return false;
-    }
-    signatureBytes = await _readBytesWithLength(file);
-    manifestBytes = await _readBytesWithLength(file);
-    int contentOffset = await file.position();
-    _openContentStream = () => new File(path).openRead(contentOffset);
-    file.close();
-
-    String manifestString = UTF8.decode(manifestBytes);
-    manifest = JSON.decode(manifestString);
-    return true;
-  }
-
-  static Future<Bundle> readHeader(String path) async {
-    Bundle bundle = new Bundle._fromFile(path);
-    if (!await bundle._readHeader())
-      return null;
-    return bundle;
-  }
-
-  // Verifies that the package has a valid signature and content.
-  Future<bool> verifyContent() async {
-    if (!verifyManifestSignature(manifest, manifestBytes, signatureBytes))
-      return false;
-
-    Stream<List<int>> content = _openContentStream();
-    BigInteger expectedHash = new BigInteger(manifest['content-hash'], 10);
-    if (!await verifyContentHash(expectedHash, content))
-      return false;
-
-    return true;
-  }
-
-  // Writes the in-memory representation to disk.
-  void writeSync() {
-    assert(_contentBytes != null);
-    RandomAccessFile outputFile = new File(path).openSync(mode: FileMode.WRITE);
-    outputFile.writeStringSync('#!mojo mojo:sky_viewer\n');
-    _writeBytesWithLengthSync(outputFile, signatureBytes);
-    _writeBytesWithLengthSync(outputFile, manifestBytes);
-    outputFile.writeFromSync(_contentBytes);
-    outputFile.close();
-  }
-}
diff --git a/sky/packages/flx/lib/signing.dart b/sky/packages/flx/lib/signing.dart
deleted file mode 100644
index 36bbc7f..0000000
--- a/sky/packages/flx/lib/signing.dart
+++ /dev/null
@@ -1,183 +0,0 @@
-// Copyright 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 'dart:async';
-import 'dart:convert' hide BASE64;
-import 'dart:io';
-import 'dart:typed_data';
-
-import 'package:asn1lib/asn1lib.dart';
-import 'package:bignum/bignum.dart';
-import 'package:cipher/cipher.dart';
-import 'package:cipher/impl/client.dart';
-import 'package:crypto/crypto.dart';
-
-export 'package:cipher/cipher.dart' show AsymmetricKeyPair;
-
-// The ECDSA algorithm parameters we're using. These match the parameters used
-// by the Flutter updater package.
-class CipherParameters {
-  final String signerAlgorithm = 'SHA-256/ECDSA';
-  final String hashAlgorithm = 'SHA-256';
-  final ECDomainParameters domain = new ECDomainParameters('prime256v1');
-  SecureRandom get random {
-    if (_random == null)
-      _initRandom(new Uint8List(16), new Uint8List(16));
-    return _random;
-  }
-
-  // Seeds our secure random number generator using data from /dev/urandom.
-  // Disclaimer: I don't really understand why we need 2 parameters for
-  // cipher's API.
-  Future seedRandom() async {
-    try {
-      RandomAccessFile file = await new File("/dev/urandom").open();
-      Uint8List key = new Uint8List.fromList(await file.read(16));
-      Uint8List iv = new Uint8List.fromList(await file.read(16));
-      _initRandom(key, iv);
-    } on FileSystemException {
-      // TODO(mpcomplete): need an entropy source on Windows. We might get this
-      // for free from Dart itself soon.
-      print("Warning: Failed to seed random number generator. No /dev/urandom.");
-    }
-  }
-
-  SecureRandom _random;
-  void _initRandom(Uint8List key, Uint8List iv) {
-    KeyParameter keyParam = new KeyParameter(key);
-    ParametersWithIV params = new ParametersWithIV(keyParam, iv);
-    _random = new SecureRandom('AES/CTR/AUTO-SEED-PRNG')
-        ..seed(params);
-  }
-
-  static CipherParameters get() => _params;
-  static CipherParameters _init() {
-    initCipher();
-    return new CipherParameters();
-  }
-}
-
-final CipherParameters _params = CipherParameters._init();
-
-// Returns a serialized manifest, with the public key and hash of the content
-// included.
-Uint8List serializeManifest(Map manifestDescriptor, ECPublicKey publicKey, Uint8List zipBytes) {
-  if (manifestDescriptor == null)
-    return null;
-  final List<String> kSavedKeys = <String>[
-    'name',
-    'version',
-    'update-url'
-  ];
-  Map outputManifest = new Map();
-  manifestDescriptor.forEach((key, value) {
-    if (kSavedKeys.contains(key))
-      outputManifest[key] = value;
-  });
-
-  if (publicKey != null)
-    outputManifest['key'] = BASE64.encode(publicKey.Q.getEncoded());
-
-  Uint8List zipHash = new Digest(_params.hashAlgorithm).process(zipBytes);
-  BigInteger zipHashInt = new BigInteger.fromBytes(1, zipHash);
-  outputManifest['content-hash'] = zipHashInt.intValue();
-
-  return new Uint8List.fromList(UTF8.encode(JSON.encode(outputManifest)));
-}
-
-// Returns the ASN.1 encoded signature of the input manifestBytes.
-Uint8List signManifest(Uint8List manifestBytes, ECPrivateKey privateKey) {
-  if (manifestBytes == null || privateKey == null)
-    return new Uint8List(0);
-  Signer signer = new Signer(_params.signerAlgorithm);
-  PrivateKeyParameter params = new PrivateKeyParameter(privateKey);
-  signer.init(true, new ParametersWithRandom(params, _params.random));
-  ECSignature signature = signer.generateSignature(manifestBytes);
-  ASN1Sequence asn1 = new ASN1Sequence()
-    ..add(new ASN1Integer(signature.r))
-    ..add(new ASN1Integer(signature.s));
-  return asn1.encodedBytes;
-}
-
-bool verifyManifestSignature(Map<String, dynamic> manifest,
-                             Uint8List manifestBytes,
-                             Uint8List signatureBytes) {
-  ECSignature signature = _asn1ParseSignature(signatureBytes);
-  if (signature == null)
-    return false;
-
-  List<int> keyBytes = BASE64.decode(manifest['key']);
-  ECPoint q = _params.domain.curve.decodePoint(keyBytes);
-  ECPublicKey publicKey = new ECPublicKey(q, _params.domain);
-
-  Signer signer = new Signer(_params.signerAlgorithm);
-  signer.init(false, new PublicKeyParameter(publicKey));
-  return signer.verifySignature(manifestBytes, signature);
-}
-
-Future<bool> verifyContentHash(BigInteger expectedHash, Stream<List<int>> content) async {
-  // Hash the file incrementally.
-  Digest hasher = new Digest(_params.hashAlgorithm);
-  await content.forEach((List<int> chunk) {
-    hasher.update(chunk, 0, chunk.length);
-  });
-  Uint8List hashBytes = new Uint8List(hasher.digestSize);
-  int len = hasher.doFinal(hashBytes, 0);
-  hashBytes = hashBytes.sublist(0, len);
-  BigInteger actualHash = new BigInteger.fromBytes(1, hashBytes);
-
-  return expectedHash == actualHash;
-}
-
-// Parses a DER-encoded ASN.1 ECDSA private key block.
-ECPrivateKey _asn1ParsePrivateKey(ECDomainParameters ecDomain, Uint8List privateKey) {
-  ASN1Parser parser = new ASN1Parser(privateKey);
-  ASN1Sequence seq = parser.nextObject();
-  assert(seq.elements.length >= 2);
-  ASN1OctetString keyOct = seq.elements[1];
-  BigInteger d = new BigInteger.fromBytes(1, keyOct.octets);
-  return new ECPrivateKey(d, ecDomain);
-}
-
-// Parses a DER-encoded ASN.1 ECDSA signature block.
-ECSignature _asn1ParseSignature(Uint8List signature) {
-  try {
-    ASN1Parser parser = new ASN1Parser(signature);
-    ASN1Object object = parser.nextObject();
-    if (object is! ASN1Sequence)
-      return null;
-    ASN1Sequence sequence = object;
-    if (!(sequence.elements.length == 2 &&
-          sequence.elements[0] is ASN1Integer &&
-          sequence.elements[1] is ASN1Integer))
-      return null;
-    ASN1Integer r = sequence.elements[0];
-    ASN1Integer s = sequence.elements[1];
-    return new ECSignature(r.valueAsPositiveBigInteger, s.valueAsPositiveBigInteger);
-  } on ASN1Exception {
-    return null;
-  }
-}
-
-ECPublicKey _publicKeyFromPrivateKey(ECPrivateKey privateKey) {
-  ECPoint Q = privateKey.parameters.G * privateKey.d;
-  return new ECPublicKey(Q, privateKey.parameters);
-}
-
-AsymmetricKeyPair keyPairFromPrivateKeyFileSync(String privateKeyPath) {
-  File file = new File(privateKeyPath);
-  if (!file.existsSync())
-    return null;
-  return keyPairFromPrivateKeyBytes(file.readAsBytesSync());
-}
-
-AsymmetricKeyPair keyPairFromPrivateKeyBytes(List<int> privateKeyBytes) {
-  ECPrivateKey privateKey = _asn1ParsePrivateKey(
-      _params.domain, new Uint8List.fromList(privateKeyBytes));
-  if (privateKey == null)
-    return null;
-
-  ECPublicKey publicKey = _publicKeyFromPrivateKey(privateKey);
-  return new AsymmetricKeyPair(publicKey, privateKey);
-}
diff --git a/sky/packages/flx/pubspec.yaml b/sky/packages/flx/pubspec.yaml
deleted file mode 100644
index 56e9fc0..0000000
--- a/sky/packages/flx/pubspec.yaml
+++ /dev/null
@@ -1,15 +0,0 @@
-name: flx
-version: 0.0.10
-author: Flutter Authors <flutter-dev@googlegroups.com>
-description: Library for dealing with Flutter bundle (.flx) files
-homepage: http://flutter.io
-dependencies:
-  sky_services: 
-    '0.0.50'
-  yaml: ^2.1.3
-  asn1lib: ^0.4.1
-  cipher: ^0.7.1
-  crypto: ^0.9.1
-  path: ^1.3.0
-environment:
-  sdk: '>=1.12.0 <2.0.0'
diff --git a/sky/packages/sky/.gitignore b/sky/packages/sky/.gitignore
deleted file mode 100644
index 5c642d9..0000000
--- a/sky/packages/sky/.gitignore
+++ /dev/null
@@ -1,4 +0,0 @@
-.idea
-.pub/
-pubspec.lock
-doc/api/
diff --git a/sky/packages/sky/CHANGELOG.md b/sky/packages/sky/CHANGELOG.md
deleted file mode 100644
index 7dd98e6..0000000
--- a/sky/packages/sky/CHANGELOG.md
+++ /dev/null
@@ -1,85 +0,0 @@
-## 0.0.20
-
-  - 167 changes: https://github.com/domokit/mojo/compare/f2830c7...603f589
-
-## 0.0.19
-
-  - 49 changes: https://github.com/domokit/mojo/compare/a64559a...1b8968c
-
-## 0.0.18
-
-  - 41 changes: https://github.com/domokit/mojo/compare/246e279...c3119f6
-
-## 0.0.17
-
-  - 18 changes: https://github.com/domokit/mojo/compare/e7433cf...8879bfd
-
-## 0.0.16
-
-  - 27 changes: https://github.com/domokit/mojo/compare/e028733...e7433cf
-
-## 0.0.15
-
-  - 6 changes: https://github.com/domokit/mojo/compare/4df2d39...e028733
-
-## 0.0.14
-
-  - 42 changes: https://github.com/domokit/mojo/compare/3de9766...cf84c48
-
-## 0.0.13
-
-  - 70 changes: https://github.com/domokit/mojo/compare/889091e...136e0d4
-
-## 0.0.12
-
-  - 29 changes: https://github.com/domokit/mojo/compare/e25e3e2...432ce45
-  - Fixed sky_tool to work again.
-
-## 0.0.11
-
-  - 197 changes: https://github.com/domokit/mojo/compare/bdbb0c7...fb1b726
-
-## 0.0.10
-
-  - 23 changes: https://github.com/domokit/mojo/compare/1b7bcee...be9dad7
-
-## 0.0.8
-
-  - Fix 2 crashes in SkyDemo.apk, updated widgets.  0.0.7 was skipped.
-
-## 0.0.6
-
-  - First release after Dart summit.  Adds new main.dart based workflow.
-
-## 0.0.5+dart-summit-7
-
-  - Fix crash in sky_tool stop_tracing.
-
-## 0.0.5+dart-summit-6
-
-  - Fix missing include in sky_tool causing failure.
-
-## 0.0.5+dart-summit-5
-
-  - Added sky_tool start_tracing and stop_tracing.
-
-## 0.0.5+dart-summit-4
-
-  - Added download_material_design_icons script.
-
-## 0.0.5+dart-summit-3
-
-  - Fix typo in lib/sky_tool causing syntax error when run.
-
-## 0.0.5+dart-summit-2
-
-  - Various demo fixes and added ChangeLogs.
-
-## 0.0.5+dart-summit-1
-
-  - Branched from mojo trunk to stabalize for Dart summit.
-
-## 0.0.2
-
-  - sdk_additions now includes previously missing imports.
-  - added lib/sky_tool, and supporting apks/SkyDemo.apk
diff --git a/sky/packages/sky/LICENSE b/sky/packages/sky/LICENSE
deleted file mode 100644
index 972bb2e..0000000
--- a/sky/packages/sky/LICENSE
+++ /dev/null
@@ -1,27 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//    * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//    * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//    * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/sky/packages/sky/README.md b/sky/packages/sky/README.md
deleted file mode 100644
index b728b85..0000000
--- a/sky/packages/sky/README.md
+++ /dev/null
@@ -1,9 +0,0 @@
-Flutter
-=======
-
-Flutter is a new way to build high-performance, cross-platform mobile apps.
-Flutter is optimized for today's, and tomorrow's, mobile devices. We are
-focused on low-latency input and high frame rates on Android and iOS.
-
-See the [getting started guide](https://flutter.github.io/getting-started/) for
-information about using Flutter.
diff --git a/sky/packages/sky/bin/flutter.dart b/sky/packages/sky/bin/flutter.dart
deleted file mode 100644
index 99338de..0000000
--- a/sky/packages/sky/bin/flutter.dart
+++ /dev/null
@@ -1,7 +0,0 @@
-// Copyright 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:sky_tools/executable.dart' as executable;
-
-main(List<String> args) => executable.main(args);
diff --git a/sky/packages/sky/doc/styles.html b/sky/packages/sky/doc/styles.html
deleted file mode 100644
index fb845fc..0000000
--- a/sky/packages/sky/doc/styles.html
+++ /dev/null
@@ -1,31 +0,0 @@
-<!-- style overrides for dartdoc -->
-<style>
-  header {
-    background-color: #917FFF;
-  }
-
-  body {
-    font-size: 16px;
-    line-height: 1.5;
-    color: #111;
-    background-color: #fdfdfd;
-  }
-
-  h1, h2, h3, h4, h5, h6 {
-    font-weight: 300;
-  }
-
-  h1 {
-    font-size: 42px !important;
-    letter-spacing: -1px;
-    line-height: 1;
-  }
-
-  h2 {
-    font-size: 32px;
-  }
-
-  pre > code {
-    font-size: 14px;
-  }
-</style>
diff --git a/sky/packages/sky/lib/animation.dart b/sky/packages/sky/lib/animation.dart
deleted file mode 100644
index e9c7537..0000000
--- a/sky/packages/sky/lib/animation.dart
+++ /dev/null
@@ -1,18 +0,0 @@
-// Copyright 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.
-
-/// The Flutter animation engine.
-///
-/// This library depends only on core Dart libraries and the `newton` package.
-library animation;
-
-export 'src/animation/animated_value.dart';
-export 'src/animation/performance.dart';
-export 'src/animation/clamped_simulation.dart';
-export 'src/animation/curves.dart';
-export 'src/animation/forces.dart';
-export 'src/animation/scheduler.dart';
-export 'src/animation/scroll_behavior.dart';
-export 'src/animation/simulation_stepper.dart';
-export 'src/animation/ticker.dart';
diff --git a/sky/packages/sky/lib/gestures.dart b/sky/packages/sky/lib/gestures.dart
deleted file mode 100644
index 73aeba8..0000000
--- a/sky/packages/sky/lib/gestures.dart
+++ /dev/null
@@ -1,19 +0,0 @@
-// Copyright 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.
-
-/// The Flutter gesture recognizers.
-library gestures;
-
-export 'src/gestures/arena.dart';
-export 'src/gestures/constants.dart';
-export 'src/gestures/drag.dart';
-export 'src/gestures/events.dart';
-export 'src/gestures/long_press.dart';
-export 'src/gestures/lsq_solver.dart';
-export 'src/gestures/multitap.dart';
-export 'src/gestures/pointer_router.dart';
-export 'src/gestures/recognizer.dart';
-export 'src/gestures/scale.dart';
-export 'src/gestures/tap.dart';
-export 'src/gestures/velocity_tracker.dart';
diff --git a/sky/packages/sky/lib/http.dart b/sky/packages/sky/lib/http.dart
deleted file mode 100644
index c34467c..0000000
--- a/sky/packages/sky/lib/http.dart
+++ /dev/null
@@ -1,15 +0,0 @@
-// Copyright 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.
-
-/// Service exposed to Flutter apps that implements a subset of Dart's
-/// http package API.
-///
-/// This library will probably be moved into a separate package eventually.
-///
-/// This library depends only on core Dart libraries as well as the `mojo`,
-/// `mojo_services`, and `sky_services` and packages.
-library http;
-
-export 'src/http/http.dart';
-export 'src/http/response.dart';
diff --git a/sky/packages/sky/lib/material.dart b/sky/packages/sky/lib/material.dart
deleted file mode 100644
index 8f4df1b..0000000
--- a/sky/packages/sky/lib/material.dart
+++ /dev/null
@@ -1,54 +0,0 @@
-// Copyright 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.
-
-/// Flutter widgets implementing Material Design.
-///
-/// See https://www.google.com/design/spec/material-design/introduction.html
-library material;
-
-export 'src/material/bottom_sheet.dart';
-export 'src/material/card.dart';
-export 'src/material/checkbox.dart';
-export 'src/material/circle_avatar.dart';
-export 'src/material/colors.dart';
-export 'src/material/constants.dart';
-export 'src/material/date_picker.dart';
-export 'src/material/dialog.dart';
-export 'src/material/drawer.dart';
-export 'src/material/drawer_divider.dart';
-export 'src/material/drawer_header.dart';
-export 'src/material/drawer_item.dart';
-export 'src/material/dropdown.dart';
-export 'src/material/flat_button.dart';
-export 'src/material/floating_action_button.dart';
-export 'src/material/icon.dart';
-export 'src/material/icon_button.dart';
-export 'src/material/icon_theme.dart';
-export 'src/material/icon_theme_data.dart';
-export 'src/material/ink_well.dart';
-export 'src/material/input.dart';
-export 'src/material/list_item.dart';
-export 'src/material/material.dart';
-export 'src/material/material_app.dart';
-export 'src/material/material_button.dart';
-export 'src/material/material_list.dart';
-export 'src/material/popup_menu_item.dart';
-export 'src/material/popup_menu.dart';
-export 'src/material/progress_indicator.dart';
-export 'src/material/radio.dart';
-export 'src/material/raised_button.dart';
-export 'src/material/scaffold.dart';
-export 'src/material/scrollbar_painter.dart';
-export 'src/material/shadows.dart';
-export 'src/material/snack_bar.dart';
-export 'src/material/switch.dart';
-export 'src/material/tabs.dart';
-export 'src/material/theme_data.dart';
-export 'src/material/theme.dart';
-export 'src/material/title.dart';
-export 'src/material/tool_bar.dart';
-export 'src/material/typography.dart';
-export 'src/material/radial_reaction.dart';
-
-export 'widgets.dart';
diff --git a/sky/packages/sky/lib/painting.dart b/sky/packages/sky/lib/painting.dart
deleted file mode 100644
index 1ebc1e3..0000000
--- a/sky/packages/sky/lib/painting.dart
+++ /dev/null
@@ -1,19 +0,0 @@
-// Copyright 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.
-
-/// The Flutter painting library.
-///
-/// This library includes a variety of classes that wrap the Flutter
-/// engine's painting API for more specialised purposes, such as painting scaled
-/// images, interpolating between shadows, painting borders around boxes, etc.
-///
-/// This library depends only on the core Dart libraries and animation.dart.
-/// Note: animation.dart depends on the `newton` package.
-library painting;
-
-export 'src/painting/basic_types.dart';
-export 'src/painting/box_painter.dart';
-export 'src/painting/shadows.dart';
-export 'src/painting/text_painter.dart';
-export 'src/painting/text_style.dart';
diff --git a/sky/packages/sky/lib/rendering.dart b/sky/packages/sky/lib/rendering.dart
deleted file mode 100644
index 589b4e5..0000000
--- a/sky/packages/sky/lib/rendering.dart
+++ /dev/null
@@ -1,34 +0,0 @@
-// Copyright 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.
-
-/// The Flutter rendering tree.
-library rendering;
-
-export 'src/rendering/auto_layout.dart';
-export 'src/rendering/basic_types.dart';
-export 'src/rendering/binding.dart';
-export 'src/rendering/block.dart';
-export 'src/rendering/box.dart';
-export 'src/rendering/custom_layout.dart';
-export 'src/rendering/debug.dart';
-export 'src/rendering/editable_paragraph.dart';
-export 'src/rendering/error.dart';
-export 'src/rendering/flex.dart';
-export 'src/rendering/grid.dart';
-export 'src/rendering/hit_test.dart';
-export 'src/rendering/image.dart';
-export 'src/rendering/layer.dart';
-export 'src/rendering/node.dart';
-export 'src/rendering/object.dart';
-export 'src/rendering/overflow.dart';
-export 'src/rendering/paragraph.dart';
-export 'src/rendering/proxy_box.dart';
-export 'src/rendering/shifted_box.dart';
-export 'src/rendering/stack.dart';
-export 'src/rendering/statistics_box.dart';
-export 'src/rendering/toggleable.dart';
-export 'src/rendering/view.dart';
-export 'src/rendering/viewport.dart';
-
-export 'package:vector_math/vector_math_64.dart' show Matrix4;
diff --git a/sky/packages/sky/lib/services.dart b/sky/packages/sky/lib/services.dart
deleted file mode 100644
index 18e14ac..0000000
--- a/sky/packages/sky/lib/services.dart
+++ /dev/null
@@ -1,22 +0,0 @@
-// Copyright 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.
-
-/// System services exposed to Flutter apps.
-///
-/// For example, this library includes [fetch], which fetches data from the
-/// network.
-///
-/// This library depends only on core Dart libraries as well as the `mojo`,
-/// `mojo_services`, and `sky_services` and packages.
-library services;
-
-export 'src/services/activity.dart';
-export 'src/services/asset_bundle.dart';
-export 'src/services/fetch.dart';
-export 'src/services/image_cache.dart';
-export 'src/services/image_decoder.dart';
-export 'src/services/image_resource.dart';
-export 'src/services/keyboard.dart';
-export 'src/services/service_registry.dart';
-export 'src/services/shell.dart';
diff --git a/sky/packages/sky/lib/src/animation/animated_value.dart b/sky/packages/sky/lib/src/animation/animated_value.dart
deleted file mode 100644
index 33fd2cc..0000000
--- a/sky/packages/sky/lib/src/animation/animated_value.dart
+++ /dev/null
@@ -1,127 +0,0 @@
-// Copyright 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 'dart:ui' show Color, Size, Rect;
-
-import 'curves.dart';
-
-/// The direction in which an animation is running
-enum AnimationDirection {
-  /// The animation is running from beginning to end
-  forward,
-
-  /// The animation is running backwards, from end to beginning
-  reverse
-}
-
-/// An interface describing a variable that changes as an animation progresses.
-///
-/// Animatable objects, by convention, must be cheap to create. This allows them
-/// to be used in build functions in Widgets.
-abstract class Animatable {
-  /// Update the variable to a given time in an animation that is running in the given direction
-  void setProgress(double t, AnimationDirection direction);
-  String toString();
-}
-
-/// Used by [Performance] to convert the timing of a performance to a different timescale.
-/// For example, by setting different values for the interval and reverseInterval, a performance
-/// can be made to take longer in one direction that the other.
-class AnimationTiming {
-  AnimationTiming({ this.curve, this.reverseCurve });
-
-  /// The curve to use in the forward direction
-  Curve curve;
-
-  /// The curve to use in the reverse direction
-  ///
-  /// If this field is null, use [curve] in both directions.
-  Curve reverseCurve;
-
-  /// Applies this timing to the given animation clock value in the given direction
-  double transform(double t, AnimationDirection direction) {
-    Curve activeCurve = _getActiveCurve(direction);
-    if (activeCurve == null)
-      return t;
-    if (t == 0.0 || t == 1.0) {
-      assert(activeCurve.transform(t).round() == t);
-      return t;
-    }
-    return activeCurve.transform(t);
-  }
-
-  Curve _getActiveCurve(AnimationDirection direction) {
-    if (direction == AnimationDirection.forward || reverseCurve == null)
-      return curve;
-    return reverseCurve;
-  }
-}
-
-/// An animated variable with a concrete type
-class AnimatedValue<T extends dynamic> extends AnimationTiming implements Animatable {
-  AnimatedValue(this.begin, { this.end, Curve curve, Curve reverseCurve })
-    : super(curve: curve, reverseCurve: reverseCurve) {
-    value = begin;
-  }
-
-  /// The current value of this variable
-  T value;
-
-  /// The value this variable has at the beginning of the animation
-  T begin;
-
-  /// The value this variable has at the end of the animation
-  T end;
-
-  /// Returns the value this variable has at the given animation clock value
-  T lerp(double t) => begin + (end - begin) * t;
-
-  /// Updates the value of this variable according to the given animation clock value and direction
-  void setProgress(double t, AnimationDirection direction) {
-    if (end != null) {
-      t = transform(t, direction);
-      if (t == 0.0)
-        value = begin;
-      else if (t == 1.0)
-        value = end;
-      else
-        value = lerp(t);
-    }
-  }
-
-  String toString() => 'AnimatedValue(begin=$begin, end=$end, value=$value)';
-}
-
-/// An animated variable containing a color
-///
-/// This class specializes the interpolation of AnimatedValue<Color> to be
-/// appropriate for colors.
-class AnimatedColorValue extends AnimatedValue<Color> {
-  AnimatedColorValue(Color begin, { Color end, Curve curve, Curve reverseCurve })
-    : super(begin, end: end, curve: curve, reverseCurve: reverseCurve);
-
-  Color lerp(double t) => Color.lerp(begin, end, t);
-}
-
-/// An animated variable containing a rectangle
-///
-/// This class specializes the interpolation of AnimatedValue<Rect> to be
-/// appropriate for rectangles.
-class AnimatedSizeValue extends AnimatedValue<Size> {
-  AnimatedSizeValue(Size begin, { Size end, Curve curve, Curve reverseCurve })
-    : super(begin, end: end, curve: curve, reverseCurve: reverseCurve);
-
-  Size lerp(double t) => Size.lerp(begin, end, t);
-}
-
-/// An animated variable containing a rectangle
-///
-/// This class specializes the interpolation of AnimatedValue<Rect> to be
-/// appropriate for rectangles.
-class AnimatedRectValue extends AnimatedValue<Rect> {
-  AnimatedRectValue(Rect begin, { Rect end, Curve curve, Curve reverseCurve })
-    : super(begin, end: end, curve: curve, reverseCurve: reverseCurve);
-
-  Rect lerp(double t) => Rect.lerp(begin, end, t);
-}
diff --git a/sky/packages/sky/lib/src/animation/clamped_simulation.dart b/sky/packages/sky/lib/src/animation/clamped_simulation.dart
deleted file mode 100644
index d3d14c7..0000000
--- a/sky/packages/sky/lib/src/animation/clamped_simulation.dart
+++ /dev/null
@@ -1,28 +0,0 @@
-// Copyright 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:newton/newton.dart';
-
-class ClampedSimulation extends Simulation {
-  ClampedSimulation(this.simulation, {
-    this.xMin: double.NEGATIVE_INFINITY,
-    this.xMax: double.INFINITY,
-    this.dxMin: double.NEGATIVE_INFINITY,
-    this.dxMax: double.INFINITY
-  }) {
-    assert(simulation != null);
-    assert(xMax >= xMin);
-    assert(dxMax >= dxMin);
-  }
-
-  final Simulation simulation;
-  final double xMin;
-  final double xMax;
-  final double dxMin;
-  final double dxMax;
-
-  double x(double time) => simulation.x(time).clamp(xMin, xMax);
-  double dx(double time) => simulation.dx(time).clamp(dxMin, dxMax);
-  bool isDone(double time) => simulation.isDone(time);
-}
diff --git a/sky/packages/sky/lib/src/animation/curves.dart b/sky/packages/sky/lib/src/animation/curves.dart
deleted file mode 100644
index 3d0f6f5..0000000
--- a/sky/packages/sky/lib/src/animation/curves.dart
+++ /dev/null
@@ -1,195 +0,0 @@
-// Copyright 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 'dart:math' as math;
-
-double _evaluateCubic(double a, double b, double m) {
-  // TODO(abarth): Would Math.pow be faster?
-  return 3 * a * (1 - m) * (1 - m) * m + 3 * b * (1 - m) * m * m + m * m * m;
-}
-
-const double _kCubicErrorBound = 0.001;
-
-/// A mapping of the unit interval to the unit interval
-///
-/// A curve must map 0.0 to 0.0 and 1.0 to 1.0.
-abstract class Curve {
-  /// Return the value of the curve at point t
-  ///
-  /// The value of t must be between 0.0 and 1.0, inclusive.
-  double transform(double t);
-}
-
-/// The identity map over the unit interval
-class Linear implements Curve {
-  const Linear();
-  double transform(double t) => t;
-}
-
-/// A curve that is 0.0 until start, then curved from 0.0 to 1.0 at end, then 1.0
-class Interval implements Curve {
-  const Interval(this.start, this.end, { this.curve: Curves.linear });
-
-  /// The smallest value for which this interval is 0.0
-  final double start;
-
-  /// The smallest value for which this interval is 1.0
-  final double end;
-
-  /// The curve to apply between [start] and [end]
-  final Curve curve;
-
-  double transform(double t) {
-    assert(start >= 0.0);
-    assert(start <= 1.0);
-    assert(end >= 0.0);
-    assert(end <= 1.0);
-    t = ((t - start) / (end - start)).clamp(0.0, 1.0);
-    if (t == 0.0 || t == 1.0)
-      return t;
-    return curve.transform(t);
-  }
-}
-
-/// A cubic polynomial mapping of the unit interval
-class Cubic implements Curve {
-  const Cubic(this.a, this.b, this.c, this.d);
-
-  final double a;
-  final double b;
-  final double c;
-  final double d;
-
-  double transform(double t) {
-    double start = 0.0;
-    double end = 1.0;
-    while (true) {
-      double midpoint = (start + end) / 2;
-      double estimate = _evaluateCubic(a, c, midpoint);
-      if ((t - estimate).abs() < _kCubicErrorBound)
-        return _evaluateCubic(b, d, midpoint);
-      if (estimate < t)
-        start = midpoint;
-      else
-        end = midpoint;
-    }
-  }
-}
-
-double _bounce(double t) {
-  if (t < 1.0 / 2.75) {
-    return 7.5625 * t * t;
-  } else if (t < 2 / 2.75) {
-    t -= 1.5 / 2.75;
-    return 7.5625 * t * t + 0.75;
-  } else if (t < 2.5 / 2.75) {
-    t -= 2.25 / 2.75;
-    return 7.5625 * t * t + 0.9375;
-  }
-  t -= 2.625 / 2.75;
-  return 7.5625 * t * t + 0.984375;
-}
-
-/// An oscillating curve that grows in magnitude
-class BounceInCurve implements Curve {
-  const BounceInCurve();
-  double transform(double t) {
-    return 1.0 - _bounce(1.0 - t);
-  }
-}
-
-/// An oscillating curve that shrink in magnitude
-class BounceOutCurve implements Curve {
-  const BounceOutCurve();
-  double transform(double t) {
-    return _bounce(t);
-  }
-}
-
-/// An oscillating curve that first grows and then shrink in magnitude
-class BounceInOutCurve implements Curve {
-  const BounceInOutCurve();
-  double transform(double t) {
-    if (t < 0.5)
-      return (1.0 - _bounce(1.0 - t)) * 0.5;
-    else
-      return _bounce(t * 2.0 - 1.0) * 0.5 + 0.5;
-  }
-}
-
-/// An oscillating curve that grows in magnitude while overshootings its bounds
-class ElasticInCurve implements Curve {
-  const ElasticInCurve([this.period = 0.4]);
-  final double period;
-  double transform(double t) {
-    double s = period / 4.0;
-    t = t - 1.0;
-    return -math.pow(2.0, 10.0 * t) * math.sin((t - s) * (math.PI * 2.0) / period);
-  }
-}
-
-/// An oscillating curve that shrinks in magnitude while overshootings its bounds
-class ElasticOutCurve implements Curve {
-  const ElasticOutCurve([this.period = 0.4]);
-  final double period;
-  double transform(double t) {
-    double s = period / 4.0;
-    return math.pow(2.0, -10 * t) * math.sin((t - s) * (math.PI * 2.0) / period) + 1.0;
-  }
-}
-
-/// An oscillating curve that grows and then shrinks in magnitude while overshootings its bounds
-class ElasticInOutCurve implements Curve {
-  const ElasticInOutCurve([this.period = 0.4]);
-  final double period;
-  double transform(double t) {
-    double s = period / 4.0;
-    t = 2.0 * t - 1.0;
-    if (t < 0.0)
-      return -0.5 * math.pow(2.0, 10.0 * t) * math.sin((t - s) * (math.PI * 2.0) / period);
-    else
-      return math.pow(2.0, -10.0 * t) * math.sin((t - s) * (math.PI * 2.0) / period) * 0.5 + 1.0;
-  }
-}
-
-/// A collection of common animation curves.
-class Curves {
-  Curves._();
-
-  /// A linear animation curve
-  static const Linear linear = const Linear();
-
-  /// A cubic animation curve that speeds up quickly and ends slowly
-  static const Cubic ease = const Cubic(0.25, 0.1, 0.25, 1.0);
-
-  /// A cubic animation curve that starts slowly and ends quickly
-  static const Cubic easeIn = const Cubic(0.42, 0.0, 1.0, 1.0);
-
-  /// A cubic animation curve that starts quickly and ends slowly
-  static const Cubic easeOut = const Cubic(0.0, 0.0, 0.58, 1.0);
-
-  /// A cubic animation curve that starts slowly, speeds up, and then and ends slowly
-  static const Cubic easeInOut = const Cubic(0.42, 0.0, 0.58, 1.0);
-
-  /// An oscillating curve that grows in magnitude
-  static const BounceInCurve bounceIn = const BounceInCurve();
-
-  /// An oscillating curve that first grows and then shrink in magnitude
-  static const BounceOutCurve bounceOut = const BounceOutCurve();
-
-  /// An oscillating curve that first grows and then shrink in magnitude
-  static const BounceInOutCurve bounceInOut = const BounceInOutCurve();
-
-  /// An oscillating curve that grows in magnitude while overshootings its bounds
-  static const ElasticInCurve elasticIn = const ElasticInCurve();
-
-  /// An oscillating curve that shrinks in magnitude while overshootings its bounds
-  static const ElasticOutCurve elasticOut = const ElasticOutCurve();
-
-  /// An oscillating curve that grows and then shrinks in magnitude while overshootings its bounds
-  static const ElasticInOutCurve elasticInOut = const ElasticInOutCurve();
-
-  /// A curve that starts quickly and eases into its final position. Over the course of the animation, the object spends more time near its final destination. As a result, the user isn’t left waiting for the animation to finish, and the negative effects of motion are minimized.
-  static const Curve fastOutSlowIn = const Cubic(0.4, 0.0, 0.2, 1.0);
-}
diff --git a/sky/packages/sky/lib/src/animation/forces.dart b/sky/packages/sky/lib/src/animation/forces.dart
deleted file mode 100644
index 47cef10..0000000
--- a/sky/packages/sky/lib/src/animation/forces.dart
+++ /dev/null
@@ -1,52 +0,0 @@
-// Copyright 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:newton/newton.dart';
-
-/// A factory for simulations
-abstract class Force {
-  const Force();
-
-  Simulation release(double position, double velocity);
-}
-
-/// A factory for spring-based physics simulations
-class SpringForce extends Force {
-  const SpringForce(this.spring, { this.left: 0.0, this.right: 1.0 });
-
-  /// The description of the spring to be used in the created simulations
-  final SpringDescription spring;
-
-  /// Where to put the spring's resting point when releasing left
-  final double left;
-
-  /// Where to put the spring's resting point when releasing right
-  final double right;
-
-  /// How pricely to terminate the simulation
-  ///
-  /// We overshoot the target by this distance, but stop the simulation when
-  /// the spring gets within this distance (regardless of how fast it's moving).
-  /// This causes the spring to settle a bit faster than it otherwise would.
-  static const Tolerance tolerance = const Tolerance(
-    velocity: double.INFINITY,
-    distance: 0.01
-  );
-
-  Simulation release(double position, double velocity) {
-    double target = velocity < 0.0 ? this.left - tolerance.distance
-                                   : this.right + tolerance.distance;
-    return new SpringSimulation(spring, position, target, velocity)
-      ..tolerance = tolerance;
-  }
-}
-
-final SpringDescription _kDefaultSpringDesc = new SpringDescription.withDampingRatio(
-  mass: 1.0,
-  springConstant: 500.0,
-  ratio: 1.0
-);
-
-/// A spring force with reasonable default values
-final SpringForce kDefaultSpringForce = new SpringForce(_kDefaultSpringDesc);
diff --git a/sky/packages/sky/lib/src/animation/performance.dart b/sky/packages/sky/lib/src/animation/performance.dart
deleted file mode 100644
index 981e507..0000000
--- a/sky/packages/sky/lib/src/animation/performance.dart
+++ /dev/null
@@ -1,338 +0,0 @@
-// Copyright 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 'dart:async';
-import 'dart:ui' show VoidCallback;
-
-import 'animated_value.dart';
-import 'forces.dart';
-import 'simulation_stepper.dart';
-
-/// The status of an animation
-enum PerformanceStatus {
-  /// The animation is stopped at the beginning
-  dismissed,
-
-  /// The animation is running from beginning to end
-  forward,
-
-  /// The animation is running backwards, from end to beginning
-  reverse,
-
-  /// The animation is stopped at the end
-  completed,
-}
-
-typedef void PerformanceStatusListener(PerformanceStatus status);
-
-/// An interface that is implemented by [Performance] that exposes a
-/// read-only view of the underlying performance. This is used by classes that
-/// want to watch a performance but should not be able to change the
-/// performance's state.
-abstract class PerformanceView {
-  const PerformanceView();
-
-  /// Update the given variable according to the current progress of the performance
-  void updateVariable(Animatable variable);
-  /// Calls the listener every time the progress of the performance changes
-  void addListener(VoidCallback listener);
-  /// Stop calling the listener every time the progress of the performance changes
-  void removeListener(VoidCallback listener);
-  /// Calls listener every time the status of the performance changes
-  void addStatusListener(PerformanceStatusListener listener);
-  /// Stops calling the listener every time the status of the performance changes
-  void removeStatusListener(PerformanceStatusListener listener);
-
-  /// The current status of this animation.
-  PerformanceStatus get status;
-
-  /// The current direction of the animation.
-  AnimationDirection get direction;
-
-  /// The direction used to select the current curve.
-  ///
-  /// The curve direction is only reset when we hit the beginning or the end of
-  /// the timeline to avoid discontinuities in the value of any variables this
-  /// performance is used to animate.
-  AnimationDirection get curveDirection;
-
-  /// The current progress of this animation (a value from 0.0 to 1.0).
-  /// This is the value that is used to update any variables when using updateVariable().
-  double get progress;
-
-  /// Whether this animation is stopped at the beginning
-  bool get isDismissed => status == PerformanceStatus.dismissed;
-
-  /// Whether this animation is stopped at the end
-  bool get isCompleted => status == PerformanceStatus.completed;
-}
-
-class AlwaysCompletePerformance extends PerformanceView {
-  const AlwaysCompletePerformance();
-
-  void updateVariable(Animatable variable) {
-    variable.setProgress(1.0, AnimationDirection.forward);
-  }
-
-  // this performance never changes state
-  void addListener(VoidCallback listener) { }
-  void removeListener(VoidCallback listener) { }
-  void addStatusListener(PerformanceStatusListener listener) { }
-  void removeStatusListener(PerformanceStatusListener listener) { }
-  PerformanceStatus get status => PerformanceStatus.completed;
-  AnimationDirection get direction => AnimationDirection.forward;
-  AnimationDirection get curveDirection => AnimationDirection.forward;
-  double get progress => 1.0;
-}
-const AlwaysCompletePerformance alwaysCompletePerformance = const AlwaysCompletePerformance();
-
-class ReversePerformance extends PerformanceView {
-  ReversePerformance(this.masterPerformance) {
-    masterPerformance.addStatusListener(_statusChangeHandler);
-  }
-
-  final PerformanceView masterPerformance;
-
-  void updateVariable(Animatable variable) {
-    variable.setProgress(progress, curveDirection);
-  }
-
-  void addListener(VoidCallback listener) {
-    masterPerformance.addListener(listener);
-  }
-  void removeListener(VoidCallback listener) {
-    masterPerformance.removeListener(listener);
-  }
-
-  final List<PerformanceStatusListener> _statusListeners = new List<PerformanceStatusListener>();
-
-  /// Calls listener every time the status of this performance changes
-  void addStatusListener(PerformanceStatusListener listener) {
-    _statusListeners.add(listener);
-  }
-
-  /// Stops calling the listener every time the status of this performance changes
-  void removeStatusListener(PerformanceStatusListener listener) {
-    _statusListeners.remove(listener);
-  }
-
-  void _statusChangeHandler(PerformanceStatus status) {
-    status = _reverseStatus(status);
-    List<PerformanceStatusListener> localListeners = new List<PerformanceStatusListener>.from(_statusListeners);
-    for (PerformanceStatusListener listener in localListeners)
-      listener(status);
-  }
-
-  PerformanceStatus get status => _reverseStatus(masterPerformance.status);
-  AnimationDirection get direction => _reverseDirection(masterPerformance.direction);
-  AnimationDirection get curveDirection => _reverseDirection(masterPerformance.curveDirection);
-  double get progress => 1.0 - masterPerformance.progress;
-
-  PerformanceStatus _reverseStatus(PerformanceStatus status) {
-    switch (status) {
-      case PerformanceStatus.forward: return PerformanceStatus.reverse;
-      case PerformanceStatus.reverse: return PerformanceStatus.forward;
-      case PerformanceStatus.completed: return PerformanceStatus.dismissed;
-      case PerformanceStatus.dismissed: return PerformanceStatus.completed;
-    }
-  }
-
-  AnimationDirection _reverseDirection(AnimationDirection direction) {
-    switch (direction) {
-      case AnimationDirection.forward: return AnimationDirection.reverse;
-      case AnimationDirection.reverse: return AnimationDirection.forward;
-    }
-  }
-}
-
-
-/// A timeline that can be reversed and used to update [Animatable]s.
-///
-/// For example, a performance may handle an animation of a menu opening by
-/// sliding and fading in (changing Y value and opacity) over .5 seconds. The
-/// performance can move forwards (present) or backwards (dismiss). A consumer
-/// may also take direct control of the timeline by manipulating [progress], or
-/// [fling] the timeline causing a physics-based simulation to take over the
-/// progression.
-class Performance extends PerformanceView {
-  Performance({ this.duration, double progress, this.debugLabel }) {
-    _timeline = new SimulationStepper(_tick);
-    if (progress != null)
-      _timeline.value = progress.clamp(0.0, 1.0);
-  }
-
-  /// A label that is used in the toString() output. Intended to aid with
-  /// identifying performance instances in debug output.
-  final String debugLabel;
-
-  /// Returns a [PerformanceView] for this performance,
-  /// so that a pointer to this object can be passed around without
-  /// allowing users of that pointer to mutate the AnimationPerformance state.
-  PerformanceView get view => this;
-
-  /// The length of time this performance should last
-  Duration duration;
-
-  SimulationStepper _timeline;
-  AnimationDirection get direction => _direction;
-  AnimationDirection _direction;
-  AnimationDirection get curveDirection => _curveDirection;
-  AnimationDirection _curveDirection;
-
-  /// If non-null, animate with this timing instead of a linear timing
-  AnimationTiming timing;
-
-  /// The progress of this performance along the timeline
-  ///
-  /// Note: Setting this value stops the current animation.
-  double get progress => _timeline.value.clamp(0.0, 1.0);
-  void set progress(double t) {
-    stop();
-    _timeline.value = t.clamp(0.0, 1.0);
-    _checkStatusChanged();
-  }
-
-  double get _curvedProgress {
-    return timing != null ? timing.transform(progress, _curveDirection) : progress;
-  }
-
-  /// Whether this animation is currently animating in either the forward or reverse direction
-  bool get isAnimating => _timeline.isAnimating;
-
-  PerformanceStatus get status {
-    if (!isAnimating && progress == 1.0)
-      return PerformanceStatus.completed;
-    if (!isAnimating && progress == 0.0)
-      return PerformanceStatus.dismissed;
-    return _direction == AnimationDirection.forward ?
-        PerformanceStatus.forward :
-        PerformanceStatus.reverse;
-  }
-
-  /// Update the given varaible according to the current progress of this performance
-  void updateVariable(Animatable variable) {
-    variable.setProgress(_curvedProgress, _curveDirection);
-  }
-
-  /// Start running this animation forwards (towards the end)
-  Future forward() => play(AnimationDirection.forward);
-
-  /// Start running this animation in reverse (towards the beginning)
-  Future reverse() => play(AnimationDirection.reverse);
-
-  /// Start running this animation in the given direction
-  Future play([AnimationDirection direction = AnimationDirection.forward]) {
-    _direction = direction;
-    return resume();
-  }
-
-  /// Start running this animation in the most recent direction
-  Future resume() {
-    return _animateTo(_direction == AnimationDirection.forward ? 1.0 : 0.0);
-  }
-
-  /// Stop running this animation
-  void stop() {
-    _timeline.stop();
-  }
-
-  /// Start running this animation according to the given physical parameters
-  ///
-  /// Flings the timeline with an optional force (defaults to a critically
-  /// damped spring) and initial velocity. If velocity is positive, the
-  /// animation will complete, otherwise it will dismiss.
-  Future fling({double velocity: 1.0, Force force}) {
-    if (force == null)
-      force = kDefaultSpringForce;
-    _direction = velocity < 0.0 ? AnimationDirection.reverse : AnimationDirection.forward;
-    return _timeline.animateWith(force.release(progress, velocity));
-  }
-
-  final List<VoidCallback> _listeners = new List<VoidCallback>();
-
-  /// Calls the listener every time the progress of this performance changes
-  void addListener(VoidCallback listener) {
-    _listeners.add(listener);
-  }
-
-  /// Stop calling the listener every time the progress of this performance changes
-  void removeListener(VoidCallback listener) {
-    _listeners.remove(listener);
-  }
-
-  void _notifyListeners() {
-    List<VoidCallback> localListeners = new List<VoidCallback>.from(_listeners);
-    for (VoidCallback listener in localListeners)
-      listener();
-  }
-
-  final List<PerformanceStatusListener> _statusListeners = new List<PerformanceStatusListener>();
-
-  /// Calls listener every time the status of this performance changes
-  void addStatusListener(PerformanceStatusListener listener) {
-    _statusListeners.add(listener);
-  }
-
-  /// Stops calling the listener every time the status of this performance changes
-  void removeStatusListener(PerformanceStatusListener listener) {
-    _statusListeners.remove(listener);
-  }
-
-  PerformanceStatus _lastStatus = PerformanceStatus.dismissed;
-  void _checkStatusChanged() {
-    PerformanceStatus currentStatus = status;
-    if (currentStatus != _lastStatus) {
-      List<PerformanceStatusListener> localListeners = new List<PerformanceStatusListener>.from(_statusListeners);
-      for (PerformanceStatusListener listener in localListeners)
-        listener(currentStatus);
-    }
-    _lastStatus = currentStatus;
-  }
-
-  void _updateCurveDirection() {
-    if (status != _lastStatus) {
-      if (_lastStatus == PerformanceStatus.dismissed || _lastStatus == PerformanceStatus.completed)
-        _curveDirection = _direction;
-    }
-  }
-
-  Future _animateTo(double target) {
-    Duration remainingDuration = duration * (target - _timeline.value).abs();
-    _timeline.stop();
-    if (remainingDuration == Duration.ZERO)
-      return new Future.value();
-    return _timeline.animateTo(target, duration: remainingDuration);
-  }
-
-  void _tick(double t) {
-    _updateCurveDirection();
-    didTick(t);
-  }
-
-  void didTick(double t) {
-    _notifyListeners();
-    _checkStatusChanged();
-  }
-
-  String toString() {
-    if (debugLabel != null)
-      return '$runtimeType at $progress for $debugLabel';
-    return '$runtimeType at $progress';
-  }
-}
-
-/// An animation performance with an animated variable with a concrete type
-class ValuePerformance<T> extends Performance {
-  ValuePerformance({ this.variable, Duration duration, double progress }) :
-    super(duration: duration, progress: progress);
-
-  AnimatedValue<T> variable;
-  T get value => variable.value;
-
-  void didTick(double t) {
-    if (variable != null)
-      variable.setProgress(_curvedProgress, _curveDirection);
-    super.didTick(t);
-  }
-}
diff --git a/sky/packages/sky/lib/src/animation/scheduler.dart b/sky/packages/sky/lib/src/animation/scheduler.dart
deleted file mode 100644
index 8b1d891..0000000
--- a/sky/packages/sky/lib/src/animation/scheduler.dart
+++ /dev/null
@@ -1,149 +0,0 @@
-// Copyright 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 'dart:collection';
-import 'dart:ui' as ui;
-
-/// Slows down animations by this factor to help in development.
-double timeDilation = 1.0;
-
-/// A callback from the scheduler
-///
-/// The timeStamp is the number of milliseconds since the beginning of the
-/// scheduler's epoch. Use timeStamp to determine how far to advance animation
-/// timelines so that all the animations in the system are synchronized to a
-/// common time base.
-typedef void SchedulerCallback(Duration timeStamp);
-
-typedef void SchedulerExceptionHandler(dynamic exception, StackTrace stack);
-/// This callback is invoked whenever an exception is caught by the scheduler.
-/// The 'exception' argument contains the object that was thrown, and the
-/// 'stack' argument contains the stack trace. If the callback is set, it is
-/// invoked instead of printing the information to the console.
-SchedulerExceptionHandler debugSchedulerExceptionHandler;
-
-/// Schedules callbacks to run in concert with the engine's animation system
-class Scheduler {
-  /// Requires clients to use the [scheduler] singleton
-  Scheduler._() {
-    ui.window.onBeginFrame = beginFrame;
-  }
-
-  bool _haveScheduledVisualUpdate = false;
-  int _nextCallbackId = 0; // positive
-
-  final List<SchedulerCallback> _persistentCallbacks = new List<SchedulerCallback>();
-  Map<int, SchedulerCallback> _transientCallbacks = new LinkedHashMap<int, SchedulerCallback>();
-  final Set<int> _removedIds = new Set<int>();
-  final List<SchedulerCallback> _postFrameCallbacks = new List<SchedulerCallback>();
-
-  bool _inFrame = false;
-
-  int get transientCallbackCount => _transientCallbacks.length;
-
-  /// Called by the engine to produce a new frame.
-  ///
-  /// This function first calls all the callbacks registered by
-  /// [requestAnimationFrame], then calls all the callbacks registered by
-  /// [addPersistentFrameCallback], which typically drive the rendering pipeline,
-  /// and finally calls the callbacks registered by [requestPostFrameCallback].
-  void beginFrame(Duration rawTimeStamp) {
-    assert(!_inFrame);
-    _inFrame = true;
-    Duration timeStamp = new Duration(
-        microseconds: (rawTimeStamp.inMicroseconds / timeDilation).round());
-    _haveScheduledVisualUpdate = false;
-
-    Map<int, SchedulerCallback> callbacks = _transientCallbacks;
-    _transientCallbacks = new Map<int, SchedulerCallback>();
-    callbacks.forEach((int id, SchedulerCallback callback) {
-      if (!_removedIds.contains(id))
-        invokeCallback(callback, timeStamp);
-    });
-    _removedIds.clear();
-
-    for (SchedulerCallback callback in _persistentCallbacks)
-      invokeCallback(callback, timeStamp);
-
-    List<SchedulerCallback> localPostFrameCallbacks =
-        new List<SchedulerCallback>.from(_postFrameCallbacks);
-    _postFrameCallbacks.clear();
-    for (SchedulerCallback callback in localPostFrameCallbacks)
-      invokeCallback(callback, timeStamp);
-
-    _inFrame = false;
-  }
-
-  void invokeCallback(SchedulerCallback callback, Duration timeStamp) {
-    assert(callback != null);
-    try {
-      callback(timeStamp);
-    } catch (exception, stack) {
-      if (debugSchedulerExceptionHandler != null) {
-        debugSchedulerExceptionHandler(exception, stack);
-      } else {
-        print('-- EXCEPTION IN SCHEDULER CALLBACK --');
-        print('$exception');
-        print('Stack trace:');
-        print('$stack');
-      }
-    }
-  }
-
-  /// Call callback every frame.
-  void addPersistentFrameCallback(SchedulerCallback callback) {
-    _persistentCallbacks.add(callback);
-  }
-
-  /// Schedule a callback for the next frame.
-  ///
-  /// The callback will be run prior to flushing the main rendering pipeline.
-  /// Typically, requestAnimationFrame is used to throttle writes into the
-  /// rendering pipeline until the system is ready to accept a new frame. For
-  /// example, if you wanted to tick through an animation, you should use
-  /// requestAnimation frame to determine when to tick the animation. The callback
-  /// is passed a timeStamp that you can use to determine how far along the
-  /// timeline to advance your animation.
-  ///
-  /// Callbacks in invoked in an arbitrary order.
-  ///
-  /// Returns an id that can be used to unschedule this callback.
-  int requestAnimationFrame(SchedulerCallback callback) {
-    _nextCallbackId += 1;
-    _transientCallbacks[_nextCallbackId] = callback;
-    ensureVisualUpdate();
-    return _nextCallbackId;
-  }
-
-  /// Cancel the callback identified by id.
-  void cancelAnimationFrame(int id) {
-    assert(id > 0);
-    _transientCallbacks.remove(id);
-    _removedIds.add(id);
-  }
-
-  /// Schedule a callback for the end of this frame.
-  ///
-  /// If a frame is in progress, the callback will be run just after the main
-  /// rendering pipeline has been flushed. In this case, order is preserved (the
-  /// callbacks are run in registration order).
-  ///
-  /// If no frame is in progress, it will be called at the start of the next
-  /// frame. In this case, the registration order is not preserved. Callbacks
-  /// are called in an arbitrary order.
-  void requestPostFrameCallback(SchedulerCallback callback) {
-    _postFrameCallbacks.add(callback);
-  }
-
-  /// Ensure that a frame will be produced after this function is called.
-  void ensureVisualUpdate() {
-    if (_haveScheduledVisualUpdate)
-      return;
-    ui.window.scheduleFrame();
-    _haveScheduledVisualUpdate = true;
-  }
-}
-
-/// A singleton instance of Scheduler to coordinate all the callbacks.
-final Scheduler scheduler = new Scheduler._();
diff --git a/sky/packages/sky/lib/src/animation/scroll_behavior.dart b/sky/packages/sky/lib/src/animation/scroll_behavior.dart
deleted file mode 100644
index 636cb59..0000000
--- a/sky/packages/sky/lib/src/animation/scroll_behavior.dart
+++ /dev/null
@@ -1,176 +0,0 @@
-// Copyright 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 'dart:math' as math;
-import 'dart:ui' as ui;
-
-import 'package:newton/newton.dart';
-
-const double _kSecondsPerMillisecond = 1000.0;
-const double _kScrollDrag = 0.025;
-
-/// An interface for controlling the behavior of scrollable widgets
-abstract class ScrollBehavior {
-  /// Called when a drag gesture ends. Returns a simulation that
-  /// propels the scrollOffset.
-  Simulation createFlingScrollSimulation(double position, double velocity) => null;
-
-  /// Called when a drag gesture ends and toSnapOffset is specified.
-  /// Returns an animation that ends at the snap offset.
-  Simulation createSnapScrollSimulation(double startOffset, double endOffset, double velocity) => null;
-
-  /// Return the scroll offset to use when the user attempts to scroll
-  /// from the given offset by the given delta
-  double applyCurve(double scrollOffset, double scrollDelta);
-
-  /// Whether this scroll behavior currently permits scrolling
-  bool get isScrollable => true;
-}
-
-/// A scroll behavior for a scrollable widget with linear extent
-abstract class ExtentScrollBehavior extends ScrollBehavior {
-  ExtentScrollBehavior({ double contentExtent: 0.0, double containerExtent: 0.0 })
-    : _contentExtent = contentExtent, _containerExtent = containerExtent;
-
-  /// The linear extent of the content inside the scrollable widget
-  double get contentExtent => _contentExtent;
-  double _contentExtent;
-
-  /// The linear extent of the exterior of the scrollable widget
-  double get containerExtent => _containerExtent;
-  double _containerExtent;
-
-  /// Update either content or container extent (or both)
-  ///
-  /// The scrollOffset parameter is the scroll offset of the widget before the
-  /// change in extent. Returns the new scroll offset of the widget after the
-  /// change in extent.
-  double updateExtents({
-    double contentExtent,
-    double containerExtent,
-    double scrollOffset: 0.0
-  }) {
-    if (contentExtent != null)
-      _contentExtent = contentExtent;
-    if (containerExtent != null)
-      _containerExtent = containerExtent;
-    return scrollOffset.clamp(minScrollOffset, maxScrollOffset);
-  }
-
-  /// The minimum value the scroll offset can obtain
-  double get minScrollOffset;
-
-  /// The maximum value the scroll offset can obatin
-  double get maxScrollOffset;
-}
-
-/// A scroll behavior that prevents the user from exeeding scroll bounds
-class BoundedBehavior extends ExtentScrollBehavior {
-  BoundedBehavior({ double contentExtent: 0.0, double containerExtent: 0.0 })
-    : super(contentExtent: contentExtent, containerExtent: containerExtent);
-
-  double minScrollOffset = 0.0;
-  double get maxScrollOffset => math.max(minScrollOffset, minScrollOffset + _contentExtent - _containerExtent);
-
-  double applyCurve(double scrollOffset, double scrollDelta) {
-    return (scrollOffset + scrollDelta).clamp(minScrollOffset, maxScrollOffset);
-  }
-}
-
-/// A scroll behavior that does not prevent the user from exeeding scroll bounds
-class UnboundedBehavior extends ExtentScrollBehavior {
-  UnboundedBehavior({ double contentExtent: 0.0, double containerExtent: 0.0 })
-    : super(contentExtent: contentExtent, containerExtent: containerExtent);
-
-  Simulation createFlingScrollSimulation(double position, double velocity) {
-    double velocityPerSecond = velocity * 1000.0;
-    return new BoundedFrictionSimulation(
-      _kScrollDrag, position, velocityPerSecond, double.NEGATIVE_INFINITY, double.INFINITY
-    );
-  }
-
-  Simulation createSnapScrollSimulation(double startOffset, double endOffset, double velocity) {
-    return _createSnapScrollSimulation(startOffset, endOffset, velocity);
-  }
-
-  double get minScrollOffset => double.NEGATIVE_INFINITY;
-  double get maxScrollOffset => double.INFINITY;
-
-  double applyCurve(double scrollOffset, double scrollDelta) {
-    return scrollOffset + scrollDelta;
-  }
-}
-
-Simulation _createFlingScrollSimulation(double position, double velocity, double minScrollOffset, double maxScrollOffset) {
-  double startVelocity = velocity * _kSecondsPerMillisecond;
-
-  // Assume that we're rendering at atleast 15 FPS. Stop when we're
-  // scrolling less than one logical pixel per frame. We're essentially
-  // normalizing by the devicePixelRatio so that the threshold has the
-  // same effect independent of the device's pixel density.
-  double endVelocity = 15.0 * ui.window.devicePixelRatio;
-
-  // Similar to endVelocity. Stop scrolling when we're this close to
-  // destiniation scroll offset.
-  double endDistance = 0.5 * ui.window.devicePixelRatio;
-
-  SpringDescription spring = new SpringDescription.withDampingRatio(mass: 1.0, springConstant: 170.0, ratio: 1.1);
-  ScrollSimulation simulation =
-      new ScrollSimulation(position, startVelocity, minScrollOffset, maxScrollOffset, spring, _kScrollDrag)
-    ..tolerance = new Tolerance(velocity: endVelocity.abs(), distance: endDistance);
-  return simulation;
-}
-
-Simulation _createSnapScrollSimulation(double startOffset, double endOffset, double velocity) {
-  double startVelocity = velocity * _kSecondsPerMillisecond;
-  double endVelocity = 15.0 * ui.window.devicePixelRatio * velocity.sign;
-  return new FrictionSimulation.through(startOffset, endOffset, startVelocity, endVelocity);
-}
-
-/// A scroll behavior that lets the user scroll beyond the scroll bounds with some resistance
-class OverscrollBehavior extends BoundedBehavior {
-  OverscrollBehavior({ double contentExtent: 0.0, double containerExtent: 0.0 })
-    : super(contentExtent: contentExtent, containerExtent: containerExtent);
-
-  Simulation createFlingScrollSimulation(double position, double velocity) {
-    return _createFlingScrollSimulation(position, velocity, minScrollOffset, maxScrollOffset);
-  }
-
-  Simulation createSnapScrollSimulation(double startOffset, double endOffset, double velocity) {
-    return _createSnapScrollSimulation(startOffset, endOffset, velocity);
-  }
-
-  double applyCurve(double scrollOffset, double scrollDelta) {
-    double newScrollOffset = scrollOffset + scrollDelta;
-    // If we're overscrolling, we want move the scroll offset 2x
-    // slower than we would otherwise. Therefore, we "rewind" the
-    // newScrollOffset by half the amount that we moved it above.
-    // Notice that we clamp the "old" value to 0.0 so that we only
-    // reduce the portion of scrollDelta that's applied beyond 0.0. We
-    // do similar things for overscroll in the other direction.
-    if (newScrollOffset < minScrollOffset) {
-      newScrollOffset -= (newScrollOffset - math.min(minScrollOffset, scrollOffset)) / 2.0;
-    } else if (newScrollOffset > maxScrollOffset) {
-      newScrollOffset -= (newScrollOffset - math.max(maxScrollOffset, scrollOffset)) / 2.0;
-    }
-    return newScrollOffset;
-  }
-}
-
-/// A scroll behavior that lets the user scroll beyond the scroll bounds only when the bounds are disjoint
-class OverscrollWhenScrollableBehavior extends OverscrollBehavior {
-  bool get isScrollable => contentExtent > containerExtent;
-
-  Simulation createFlingScrollSimulation(double position, double velocity) {
-    if (isScrollable || position < minScrollOffset || position > maxScrollOffset)
-      return super.createFlingScrollSimulation(position, velocity);
-    return null;
-  }
-
-  double applyCurve(double scrollOffset, double scrollDelta) {
-    if (isScrollable)
-      return super.applyCurve(scrollOffset, scrollDelta);
-    return minScrollOffset;
-  }
-}
diff --git a/sky/packages/sky/lib/src/animation/simulation_stepper.dart b/sky/packages/sky/lib/src/animation/simulation_stepper.dart
deleted file mode 100644
index 44d6a6a..0000000
--- a/sky/packages/sky/lib/src/animation/simulation_stepper.dart
+++ /dev/null
@@ -1,105 +0,0 @@
-// Copyright 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 'dart:async';
-
-import 'package:newton/newton.dart';
-import 'animated_value.dart';
-import 'curves.dart';
-import 'ticker.dart';
-
-/// A simulation that varies from [begin] to [end] over [duration] using [curve]
-///
-/// This class is an adaptor between the Simulation interface and the
-/// AnimatedValue interface.
-class _TweenSimulation extends Simulation {
-  _TweenSimulation(double begin, double end, Duration duration, Curve curve)
-    : _durationInSeconds = duration.inMicroseconds.toDouble() / Duration.MICROSECONDS_PER_SECOND,
-      _tween = new AnimatedValue<double>(begin, end: end, curve: curve) {
-    assert(_durationInSeconds > 0.0);
-    assert(begin != null);
-    assert(end != null);
-  }
-
-  final double _durationInSeconds;
-  final AnimatedValue<double> _tween;
-
-  double x(double timeInSeconds) {
-    assert(timeInSeconds >= 0.0);
-    final double t = (timeInSeconds / _durationInSeconds).clamp(0.0, 1.0);
-    _tween.setProgress(t, AnimationDirection.forward);
-    return _tween.value;
-  }
-
-  double dx(double timeInSeconds) => 1.0;
-
-  bool isDone(double timeInSeconds) => timeInSeconds > _durationInSeconds;
-}
-
-typedef TimelineCallback(double value);
-
-/// Steps a simulation one per frame
-class SimulationStepper {
-  SimulationStepper(TimelineCallback onTick) : _onTick = onTick {
-    _ticker = new Ticker(_tick);
-  }
-
-  final TimelineCallback _onTick;
-  Ticker _ticker;
-  Simulation _simulation;
-
-  /// The current value of the timeline
-  double get value => _value;
-  double _value = 0.0;
-  void set value(double newValue) {
-    assert(newValue != null);
-    assert(!isAnimating);
-    _value = newValue;
-    _onTick(_value);
-  }
-
-  /// Whether the timeline is currently animating
-  bool get isAnimating => _ticker.isTicking;
-
-  /// Animate value of the timeline to the given target over the given duration
-  ///
-  /// Returns a future that resolves when the timeline stops animating,
-  /// typically when the timeline arives at the target value.
-  Future animateTo(double target, { Duration duration, Curve curve: Curves.linear }) {
-    assert(duration > Duration.ZERO);
-    assert(!isAnimating);
-    return _start(new _TweenSimulation(value, target, duration, curve));
-  }
-
-  /// Gives the given simulation control over the timeline
-  Future animateWith(Simulation simulation) {
-    stop();
-    return _start(simulation);
-  }
-
-  /// Start ticking the given simulation once per frame
-  ///
-  /// Returns a future that resolves when the simulation stops ticking.
-  Future _start(Simulation simulation) {
-    assert(simulation != null);
-    assert(!isAnimating);
-    _simulation = simulation;
-    _value = simulation.x(0.0);
-    return _ticker.start();
-  }
-
-  /// Stop animating the timeline
-  void stop() {
-    _simulation = null;
-    _ticker.stop();
-  }
-
-  void _tick(Duration elapsed) {
-    double elapsedInSeconds = elapsed.inMicroseconds.toDouble() / Duration.MICROSECONDS_PER_SECOND;
-    _value = _simulation.x(elapsedInSeconds);
-    if (_simulation.isDone(elapsedInSeconds))
-      stop();
-    _onTick(_value);
-  }
-}
diff --git a/sky/packages/sky/lib/src/animation/ticker.dart b/sky/packages/sky/lib/src/animation/ticker.dart
deleted file mode 100644
index d609a38..0000000
--- a/sky/packages/sky/lib/src/animation/ticker.dart
+++ /dev/null
@@ -1,79 +0,0 @@
-// Copyright 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 'dart:async';
-
-import 'scheduler.dart';
-
-typedef TickerCallback(Duration elapsed);
-
-/// Calls its callback once per animation frame
-class Ticker {
-  /// Constructs a ticker that will call onTick once per frame while running
-  Ticker(TickerCallback onTick) : _onTick = onTick;
-
-  final TickerCallback _onTick;
-
-  Completer _completer;
-  int _animationId;
-  Duration _startTime;
-
-  /// Start calling onTick once per animation frame
-  ///
-  /// The returned future resolves once the ticker stops ticking.
-  Future start() {
-    assert(!isTicking);
-    assert(_startTime == null);
-    _completer = new Completer();
-    _scheduleTick();
-    return _completer.future;
-  }
-
-  /// Stop calling onTick
-  ///
-  /// Causes the future returned by [start] to resolve.
-  void stop() {
-    if (!isTicking)
-      return;
-
-    _startTime = null;
-
-    if (_animationId != null) {
-      scheduler.cancelAnimationFrame(_animationId);
-      _animationId = null;
-    }
-
-    // We take the _completer into a local variable so that isTicking is false
-    // when we actually complete the future (isTicking uses _completer
-    // to determine its state).
-    Completer localCompleter = _completer;
-    _completer = null;
-    assert(!isTicking);
-    localCompleter.complete();
-  }
-
-  /// Whether this ticker has scheduled a call to onTick
-  bool get isTicking => _completer != null;
-
-  void _tick(Duration timeStamp) {
-    assert(isTicking);
-    assert(_animationId != null);
-    _animationId = null;
-
-    if (_startTime == null)
-      _startTime = timeStamp;
-
-    _onTick(timeStamp - _startTime);
-
-    // The onTick callback may have scheduled another tick already.
-    if (isTicking && _animationId == null)
-      _scheduleTick();
-  }
-
-  void _scheduleTick() {
-    assert(isTicking);
-    assert(_animationId == null);
-    _animationId = scheduler.requestAnimationFrame(_tick);
-  }
-}
diff --git a/sky/packages/sky/lib/src/gestures/arena.dart b/sky/packages/sky/lib/src/gestures/arena.dart
deleted file mode 100644
index 50c7a5b..0000000
--- a/sky/packages/sky/lib/src/gestures/arena.dart
+++ /dev/null
@@ -1,169 +0,0 @@
-// Copyright 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.
-
-enum GestureDisposition {
-  accepted,
-  rejected
-}
-
-/// Represents an object participating in an arena.
-///
-/// Receives callbacks from the GestureArena to notify the object when it wins
-/// or loses a gesture negotiation. Exactly one of [acceptGesture] or
-/// [rejectGesture] will be called for each arena key this member was added to,
-/// regardless of what caused the arena to be resolved. For example, if a
-/// member resolves the arena itself, that member still receives an
-/// [acceptGesture] callback.
-abstract class GestureArenaMember {
-  /// Called when this member wins the arena for the given key.
-  void acceptGesture(Object key);
-
-  /// Called when this member loses the arena for the given key.
-  void rejectGesture(Object key);
-}
-
-/// An interface to information to an arena
-///
-/// A given [GestureArenaMember] can have multiple entries in multiple arenas
-/// with different keys.
-class GestureArenaEntry {
-  GestureArenaEntry._(this._arena, this._key, this._member);
-
-  final GestureArena _arena;
-  final Object _key;
-  final GestureArenaMember _member;
-
-  /// Call this member to claim victory (with accepted) or admit defeat (with rejected).
-  ///
-  /// It's fine to attempt to resolve an arena that is already resolved.
-  void resolve(GestureDisposition disposition) {
-    _arena._resolve(_key, _member, disposition);
-  }
-}
-
-class _GestureArenaState {
-  final List<GestureArenaMember> members = new List<GestureArenaMember>();
-  bool isOpen = true;
-  bool isHeld = false;
-  bool hasPendingSweep = false;
-
-  /// If a gesture attempts to win while the arena is still open, it becomes the
-  /// "eager winnner". We look for an eager winner when closing the arena to new
-  /// participants, and if there is one, we resolve the arena it its favour at
-  /// that time.
-  GestureArenaMember eagerWinner;
-
-  void add(GestureArenaMember member) {
-    assert(isOpen);
-    members.add(member);
-  }
-}
-
-/// The first member to accept or the last member to not to reject wins.
-class GestureArena {
-  final Map<Object, _GestureArenaState> _arenas = new Map<Object, _GestureArenaState>();
-
-  static final GestureArena instance = new GestureArena();
-
-  GestureArenaEntry add(Object key, GestureArenaMember member) {
-    _GestureArenaState state = _arenas.putIfAbsent(key, () => new _GestureArenaState());
-    state.add(member);
-    return new GestureArenaEntry._(this, key, member);
-  }
-
-  void close(Object key) {
-    _GestureArenaState state = _arenas[key];
-    if (state == null)
-      return;  // This arena either never existed or has been resolved.
-    state.isOpen = false;
-    _tryToResolveArena(key, state);
-  }
-
-  /// Force resolution on this arena, giving the win to the first member
-  void sweep(Object key) {
-    _GestureArenaState state = _arenas[key];
-    if (state == null)
-      return;  // This arena either never existed or has been resolved.
-    assert(!state.isOpen);
-    if (state.isHeld) {
-      state.hasPendingSweep = true;
-      return;  // This arena is being held for a long-lived member
-    }
-    _arenas.remove(key);
-    if (!state.members.isEmpty) {
-      // First member wins
-      state.members.first.acceptGesture(key);
-      // Give all the other members the bad news
-      for (int i = 1; i < state.members.length; i++)
-        state.members[i].rejectGesture(key);
-    }
-  }
-
-  /// Prevent the arena from being swept
-  void hold(Object key) {
-    _GestureArenaState state = _arenas[key];
-    if (state == null)
-      return;  // This arena either never existed or has been resolved.
-    state.isHeld = true;
-  }
-
-  /// Release a hold, allowing the arena to be swept
-  /// If a sweep was attempted on a held arena, the sweep will be done
-  /// on release
-  void release(Object key) {
-    _GestureArenaState state = _arenas[key];
-    if (state == null)
-      return;  // This arena either never existed or has been resolved.
-    state.isHeld = false;
-    if (state.hasPendingSweep)
-      sweep(key);
-  }
-
-  void _tryToResolveArena(Object key, _GestureArenaState state) {
-    assert(_arenas[key] == state);
-    assert(!state.isOpen);
-    if (state.members.length == 1) {
-      _arenas.remove(key);
-      state.members.first.acceptGesture(key);
-    } else if (state.members.isEmpty) {
-      _arenas.remove(key);
-    } else if (state.eagerWinner != null) {
-      _resolveInFavorOf(key, state, state.eagerWinner);
-    }
-  }
-
-  void _resolve(Object key, GestureArenaMember member, GestureDisposition disposition) {
-    _GestureArenaState state = _arenas[key];
-    if (state == null)
-      return;  // This arena has already resolved.
-    assert(state.members.contains(member));
-    if (disposition == GestureDisposition.rejected) {
-      state.members.remove(member);
-      member.rejectGesture(key);
-      if (!state.isOpen)
-        _tryToResolveArena(key, state);
-    } else {
-      assert(disposition == GestureDisposition.accepted);
-      if (state.isOpen) {
-        if (state.eagerWinner == null)
-          state.eagerWinner = member;
-      } else {
-        _resolveInFavorOf(key, state, member);
-      }
-    }
-  }
-
-  void _resolveInFavorOf(Object key, _GestureArenaState state, GestureArenaMember member) {
-    assert(state == _arenas[key]);
-    assert(state != null);
-    assert(state.eagerWinner == null || state.eagerWinner == member);
-    assert(!state.isOpen);
-    _arenas.remove(key);
-    for (GestureArenaMember rejectedMember in state.members) {
-      if (rejectedMember != member)
-        rejectedMember.rejectGesture(key);
-    }
-    member.acceptGesture(key);
-  }
-}
\ No newline at end of file
diff --git a/sky/packages/sky/lib/src/gestures/constants.dart b/sky/packages/sky/lib/src/gestures/constants.dart
deleted file mode 100644
index 8637fe8..0000000
--- a/sky/packages/sky/lib/src/gestures/constants.dart
+++ /dev/null
@@ -1,90 +0,0 @@
-// Copyright 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.
-
-// Modeled after Android's ViewConfiguration:
-// https://github.com/android/platform_frameworks_base/blob/master/core/java/android/view/ViewConfiguration.java
-
-/// The time that must elapse before a tap gesture sends onTapDown, if there's
-/// any doubt that the gesture is a tap.
-const Duration kPressTimeout = const Duration(milliseconds: 100);
-
-/// Maximum length of time between a tap down and a tap up for the gesture to be
-/// considered a tap. (Currently not honored by the TapGestureRecognizer.)
-// TODO(ianh): Remove this, or implement a hover-tap gesture recogniser which
-// uses this.
-const Duration kHoverTapTimeout = const Duration(milliseconds: 150);
-
-/// Maximum distance between the down and up pointers for a tap. (Currently not
-/// honored by the [TapGestureRecognizer]; [PrimaryPointerGestureRecognizer],
-/// which TapGestureRecognizer inherits from, uses [kTouchSlop].)
-// TODO(ianh): Remove this or implement it correctly.
-const double kHoverTapSlop = 20.0;  // Logical pixels
-
-/// The time before a long press gesture attempts to win.
-const Duration kLongPressTimeout = const Duration(milliseconds: 500);
-
-/// The maximum time from the start of the first tap to the start of the second
-/// tap in a double-tap gesture.
-// TODO(ianh): In Android, this is actually the time from the first's up event
-// to the second's down event, according to the ViewConfiguration docs.
-const Duration kDoubleTapTimeout = const Duration(milliseconds: 300);
-
-/// The minimum time from the end of the first tap to the start of the second
-/// tap in a double-tap gesture. (Currently not honored by the
-/// DoubleTapGestureRecognizer.)
-// TODO(ianh): Either implement this or remove the constant.
-const Duration kDoubleTapMinTime = const Duration(milliseconds: 40);
-
-/// The maximum distance that the first touch in a double-tap gesture can travel
-/// before deciding that it is not part of a double-tap gesture.
-/// DoubleTapGestureRecognizer also restricts the second touch to this distance.
-const double kDoubleTapTouchSlop = kTouchSlop;  // Logical pixels
-
-/// Distance between the initial position of the first touch and the start
-/// position of a potential second touch for the second touch to be considered
-/// the second touch of a double-tap gesture.
-const double kDoubleTapSlop = 100.0;  // Logical pixels
-
-/// The time for which zoom controls (e.g. in a map interface) are to be
-/// displayed on the screen, from the moment they were last requested.
-const Duration kZoomControlsTimeout = const Duration(milliseconds: 3000);
-
-/// The distance a touch has to travel for us to be confident that the gesture
-/// is a scroll gesture.
-const double kTouchSlop = 8.0;  // Logical pixels
-
-/// The distance a touch has to travel for us to be confident that the gesture
-/// is a paging gesture. (Currently not used, because paging uses a regular drag
-/// gesture, which uses kTouchSlop.)
-// TODO(ianh): Create variants of HorizontalDragGestureRecognizer et al for
-// paging, which use this constant.
-const double kPagingTouchSlop = kTouchSlop * 2.0;  // Logical pixels
-
-/// The distance a touch has to travel for us to be confident that the gesture
-/// is a panning gesture.
-const double kPanSlop = kTouchSlop * 2.0;  // Logical pixels
-
-/// The distance a touch has to travel for us to be confident that the gesture
-/// is a scale gesture.
-const double kScaleSlop = kTouchSlop;  // Logical pixels
-
-/// The margin around a dialog, popup menu, or other window-like widget inside
-/// which we do not consider a tap to dismiss the widget. (Not currently used.)
-// TODO(ianh): Make ModalBarrier support this.
-const double kWindowTouchSlop = 16.0;  // Logical pixels
-
-/// The minimum velocity for a touch to consider that touch to trigger a fling
-/// gesture.
-// TODO(ianh): Make sure nobody has their own version of this.
-const double kMinFlingVelocity = 50.0;  // Logical pixels / second
-
-/// The maximum velocity of a touch to consider that touch to trigger a fling
-/// gesture.
-// TODO(ianh): Make sure nobody has their own version of this.
-const double kMaxFlingVelocity = 8000.0;  // Logical pixels / second
-
-/// The maximum time from the start of the first tap to the start of the second
-/// tap in a jump-tap gesture.
-// TODO(ianh): Implement jump-tap gestures.
-const Duration kJumpTapTimeout = const Duration(milliseconds: 500);
diff --git a/sky/packages/sky/lib/src/gestures/drag.dart b/sky/packages/sky/lib/src/gestures/drag.dart
deleted file mode 100644
index 285d068..0000000
--- a/sky/packages/sky/lib/src/gestures/drag.dart
+++ /dev/null
@@ -1,161 +0,0 @@
-// Copyright 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 'dart:ui' as ui;
-
-import 'arena.dart';
-import 'recognizer.dart';
-import 'constants.dart';
-import 'events.dart';
-import 'velocity_tracker.dart';
-
-enum DragState {
-  ready,
-  possible,
-  accepted
-}
-
-typedef void GestureDragStartCallback(ui.Point globalPosition);
-typedef void GestureDragUpdateCallback(double delta);
-typedef void GestureDragEndCallback(ui.Offset velocity);
-
-typedef void GesturePanStartCallback(ui.Point globalPosition);
-typedef void GesturePanUpdateCallback(ui.Offset delta);
-typedef void GesturePanEndCallback(ui.Offset velocity);
-
-typedef void _GesturePolymorphicUpdateCallback<T>(T delta);
-
-bool _isFlingGesture(GestureVelocity velocity) {
-  double velocitySquared = velocity.x * velocity.x + velocity.y * velocity.y;
-  return velocity.isValid &&
-    velocitySquared > kMinFlingVelocity * kMinFlingVelocity &&
-    velocitySquared < kMaxFlingVelocity * kMaxFlingVelocity;
-}
-
-abstract class _DragGestureRecognizer<T extends dynamic> extends OneSequenceGestureRecognizer {
-  _DragGestureRecognizer({ PointerRouter router, this.onStart, this.onUpdate, this.onEnd })
-    : super(router: router);
-
-  GestureDragStartCallback onStart;
-  _GesturePolymorphicUpdateCallback<T> onUpdate;
-  GestureDragEndCallback onEnd;
-
-  DragState _state = DragState.ready;
-  ui.Point _initialPosition;
-  T _pendingDragDelta;
-
-  T get _initialPendingDragDelta;
-  T _getDragDelta(PointerInputEvent event);
-  bool get _hasSufficientPendingDragDeltaToAccept;
-
-  Map<int, VelocityTracker> _velocityTrackers = new Map<int, VelocityTracker>();
-
-  void addPointer(PointerInputEvent event) {
-    startTrackingPointer(event.pointer);
-    _velocityTrackers[event.pointer] = new VelocityTracker();
-    if (_state == DragState.ready) {
-      _state = DragState.possible;
-      _initialPosition = event.position;
-      _pendingDragDelta = _initialPendingDragDelta;
-    }
-  }
-
-  void handleEvent(PointerInputEvent event) {
-    assert(_state != DragState.ready);
-    if (event.type == 'pointermove') {
-      VelocityTracker tracker = _velocityTrackers[event.pointer];
-      assert(tracker != null);
-      tracker.addPosition(event.timeStamp, event.x, event.y);
-      T delta = _getDragDelta(event);
-      if (_state == DragState.accepted) {
-        if (onUpdate != null)
-          onUpdate(delta);
-      } else {
-        _pendingDragDelta += delta;
-        if (_hasSufficientPendingDragDeltaToAccept)
-          resolve(GestureDisposition.accepted);
-      }
-    }
-    stopTrackingIfPointerNoLongerDown(event);
-  }
-
-  void acceptGesture(int pointer) {
-    if (_state != DragState.accepted) {
-      _state = DragState.accepted;
-      T delta = _pendingDragDelta;
-      _pendingDragDelta = _initialPendingDragDelta;
-      if (onStart != null)
-        onStart(_initialPosition);
-      if (delta != _initialPendingDragDelta && onUpdate != null)
-        onUpdate(delta);
-    }
-  }
-
-  void didStopTrackingLastPointer(int pointer) {
-    if (_state == DragState.possible) {
-      resolve(GestureDisposition.rejected);
-      _state = DragState.ready;
-      return;
-    }
-    bool wasAccepted = (_state == DragState.accepted);
-    _state = DragState.ready;
-    if (wasAccepted && onEnd != null) {
-      VelocityTracker tracker = _velocityTrackers[pointer];
-      assert(tracker != null);
-
-      GestureVelocity gestureVelocity = tracker.getVelocity();
-      ui.Offset velocity = ui.Offset.zero;
-      if (_isFlingGesture(gestureVelocity))
-        velocity = new ui.Offset(gestureVelocity.x, gestureVelocity.y);
-      onEnd(velocity);
-    }
-    _velocityTrackers.clear();
-  }
-
-  void dispose() {
-    _velocityTrackers.clear();
-    super.dispose();
-  }
-}
-
-class VerticalDragGestureRecognizer extends _DragGestureRecognizer<double> {
-  VerticalDragGestureRecognizer({
-    PointerRouter router,
-    GestureDragStartCallback onStart,
-    GestureDragUpdateCallback onUpdate,
-    GestureDragEndCallback onEnd
-  }) : super(router: router, onStart: onStart, onUpdate: onUpdate, onEnd: onEnd);
-
-  double get _initialPendingDragDelta => 0.0;
-  double _getDragDelta(PointerInputEvent event) => event.dy;
-  bool get _hasSufficientPendingDragDeltaToAccept => _pendingDragDelta.abs() > kTouchSlop;
-}
-
-class HorizontalDragGestureRecognizer extends _DragGestureRecognizer<double> {
-  HorizontalDragGestureRecognizer({
-    PointerRouter router,
-    GestureDragStartCallback onStart,
-    GestureDragUpdateCallback onUpdate,
-    GestureDragEndCallback onEnd
-  }) : super(router: router, onStart: onStart, onUpdate: onUpdate, onEnd: onEnd);
-
-  double get _initialPendingDragDelta => 0.0;
-  double _getDragDelta(PointerInputEvent event) => event.dx;
-  bool get _hasSufficientPendingDragDeltaToAccept => _pendingDragDelta.abs() > kTouchSlop;
-}
-
-class PanGestureRecognizer extends _DragGestureRecognizer<ui.Offset> {
-  PanGestureRecognizer({
-    PointerRouter router,
-    GesturePanStartCallback onStart,
-    GesturePanUpdateCallback onUpdate,
-    GesturePanEndCallback onEnd
-  }) : super(router: router, onStart: onStart, onUpdate: onUpdate, onEnd: onEnd);
-
-  ui.Offset get _initialPendingDragDelta => ui.Offset.zero;
-  ui.Offset _getDragDelta(PointerInputEvent event) => new ui.Offset(event.dx, event.dy);
-  bool get _hasSufficientPendingDragDeltaToAccept {
-    return _pendingDragDelta.distance > kPanSlop;
-  }
-}
diff --git a/sky/packages/sky/lib/src/gestures/events.dart b/sky/packages/sky/lib/src/gestures/events.dart
deleted file mode 100644
index 93afde1..0000000
--- a/sky/packages/sky/lib/src/gestures/events.dart
+++ /dev/null
@@ -1,75 +0,0 @@
-// Copyright 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 'dart:ui' as ui;
-
-export 'dart:ui' show Point;
-
-/// Base class for input events.
-class InputEvent {
-
-  const InputEvent({ this.type, this.timeStamp: 0.0 });
-
-  final String type;
-  // TODO: Should timeStamp be a DateTime object instead of double?
-  // Some client code (e.g. drag.dart) does math on the time stamp.
-  final double timeStamp;
-
-}
-
-/// Input event representing a touch or button.
-class PointerInputEvent extends InputEvent {
-
-  const PointerInputEvent({
-    String type,
-    double timeStamp: 0.0,
-    this.pointer: 0,
-    this.kind,
-    this.x: 0.0,
-    this.y: 0.0,
-    this.dx: 0.0,
-    this.dy: 0.0,
-    this.buttons: 0,
-    this.down: false,
-    this.primary: false,
-    this.obscured: false,
-    this.pressure: 0.0,
-    this.pressureMin: 0.0,
-    this.pressureMax: 0.0,
-    this.distance: 0.0,
-    this.distanceMin: 0.0,
-    this.distanceMax: 0.0,
-    this.radiusMajor: 0.0,
-    this.radiusMinor: 0.0,
-    this.radiusMin: 0.0,
-    this.radiusMax: 0.0,
-    this.orientation: 0.0,
-    this.tilt: 0.0
-  }) : super(type: type, timeStamp: timeStamp);
-
-  final int pointer;
-  final String kind;
-  final double x;
-  final double y;
-  final double dx;
-  final double dy;
-  final int buttons;
-  final bool down;
-  final bool primary;
-  final bool obscured;
-  final double pressure;
-  final double pressureMin;
-  final double pressureMax;
-  final double distance;
-  final double distanceMin;
-  final double distanceMax;
-  final double radiusMajor;
-  final double radiusMinor;
-  final double radiusMin;
-  final double radiusMax;
-  final double orientation;
-  final double tilt;
-
-  ui.Point get position => new ui.Point(x, y);
-}
diff --git a/sky/packages/sky/lib/src/gestures/long_press.dart b/sky/packages/sky/lib/src/gestures/long_press.dart
deleted file mode 100644
index 07b16e6..0000000
--- a/sky/packages/sky/lib/src/gestures/long_press.dart
+++ /dev/null
@@ -1,28 +0,0 @@
-// Copyright 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 'arena.dart';
-import 'constants.dart';
-import 'events.dart';
-import 'pointer_router.dart';
-import 'recognizer.dart';
-
-typedef void GestureLongPressCallback();
-
-class LongPressGestureRecognizer extends PrimaryPointerGestureRecognizer {
-  LongPressGestureRecognizer({ PointerRouter router, this.onLongPress })
-    : super(router: router, deadline: kLongPressTimeout);
-
-  GestureLongPressCallback onLongPress;
-
-  void didExceedDeadline() {
-    resolve(GestureDisposition.accepted);
-    onLongPress();
-  }
-
-  void handlePrimaryPointer(PointerInputEvent event) {
-    if (event.type == 'pointerup')
-      resolve(GestureDisposition.rejected);
-  }
-}
diff --git a/sky/packages/sky/lib/src/gestures/lsq_solver.dart b/sky/packages/sky/lib/src/gestures/lsq_solver.dart
deleted file mode 100644
index 6aa73d4..0000000
--- a/sky/packages/sky/lib/src/gestures/lsq_solver.dart
+++ /dev/null
@@ -1,198 +0,0 @@
-// Copyright 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 "dart:math" as math;
-import "dart:typed_data";
-
-class _Vector {
-  _Vector(int size)
-  : _offset = 0, _length = size, _elements = new Float64List(size);
-
-  _Vector.fromValues(List<double> values)
-  : _offset = 0, _length = values.length, _elements = values;
-
-  _Vector.fromVOL(List<double> values, int offset, int length)
-  : _offset = offset, _length = length, _elements = values;
-
-  int get length => _length;
-
-  operator [](int i) => _elements[i + _offset];
-  operator []=(int i, double value) => _elements[i + _offset] = value;
-
-  operator *(_Vector a) {
-    double result = 0.0;
-    for (int i = 0; i < _length; i++) {
-      result += this[i] * a[i];
-    }
-    return result;
-  }
-
-  double norm() => math.sqrt(this * this);
-
-  String toString() {
-    String result = "";
-    for (int i = 0; i < _length; i++) {
-      if (i > 0)
-        result += ", ";
-        result += this[i].toString();
-    }
-    return result;
-  }
-
-  final int _offset;
-  final int _length;
-  final List<double> _elements;
-}
-
-class _Matrix {
-  _Matrix(int rows, int cols)
-  : _rows = rows,
-    _columns = cols,
-    _elements = new Float64List(rows * cols);
-
-  double get(int row, int col) => _elements[row * _columns + col];
-  void set(int row, int col, double value) {
-    _elements[row * _columns + col] = value;
-  }
-
-  _Vector getRow(int row) => new _Vector.fromVOL(
-    _elements,
-    row * _columns,
-    _columns
-  );
-
-  String toString() {
-    String result = "";
-    for (int i = 0; i < _rows; i++) {
-      if (i > 0)
-        result += "; ";
-      for (int j = 0; j < _columns; j++) {
-        if (j > 0)
-          result += ", ";
-        result += get(i, j).toString();
-      }
-    }
-    return result;
-  }
-
-  final int _rows;
-  final int _columns;
-  final List<double> _elements;
-}
-
-class PolynomialFit {
-  PolynomialFit(int degree) : coefficients = new Float64List(degree + 1);
-
-  final List<double> coefficients;
-  double confidence;
-}
-
-class LeastSquaresSolver {
-  LeastSquaresSolver(this.x, this.y, this.w) {
-    assert(x.length == y.length);
-    assert(y.length == w.length);
-  }
-
-  final List<double> x;
-  final List<double> y;
-  final List<double> w;
-
-  PolynomialFit solve(int degree) {
-    if (degree > x.length) // not enough data to fit a curve
-      return null;
-
-    PolynomialFit result = new PolynomialFit(degree);
-
-    // Shorthands for the purpose of notation equivalence to original C++ code
-    final int m = x.length;
-    final int n = degree + 1;
-
-    // Expand the X vector to a matrix A, pre-multiplied by the weights.
-    _Matrix a = new _Matrix(n, m);
-    for (int h = 0; h < m; h++) {
-      a.set(0, h, w[h]);
-      for (int i = 1; i < n; i++) {
-        a.set(i, h, a.get(i - 1, h) * x[h]);
-      }
-    }
-
-    // Apply the Gram-Schmidt process to A to obtain its QR decomposition.
-
-    // Orthonormal basis, column-major ordVectorer.
-    _Matrix q = new _Matrix(n, m);
-    // Upper triangular matrix, row-major order.
-    _Matrix r = new _Matrix(n, n);
-    for (int j = 0; j < n; j++) {
-      for (int h = 0; h < m; h++) {
-        q.set(j, h, a.get(j, h));
-      }
-      for (int i = 0; i < j; i++) {
-        double dot = q.getRow(j) * q.getRow(i);
-        for (int h = 0; h < m; h++) {
-          q.set(j, h, q.get(j, h) - dot * q.get(i, h));
-        }
-      }
-
-      double norm = q.getRow(j).norm();
-      if (norm < 0.000001) {
-        // vectors are linearly dependent or zero so no solution
-        return null;
-      }
-
-      double inverseNorm = 1.0 / norm;
-      for (int h = 0; h < m; h++) {
-        q.set(j, h, q.get(j, h) * inverseNorm);
-      }
-      for (int i = 0; i < n; i++) {
-        r.set(j, i, i < j ? 0.0 : q.getRow(j) * a.getRow(i));
-      }
-    }
-
-    // Solve R B = Qt W Y to find B.  This is easy because R is upper triangular.
-    // We just work from bottom-right to top-left calculating B's coefficients.
-    _Vector wy = new _Vector(m);
-    for (int h = 0; h < m; h++) {
-      wy[h] = y[h] * w[h];
-    }
-    for (int i = n; i-- != 0;) {
-      result.coefficients[i] = q.getRow(i) * wy;
-      for (int j = n - 1; j > i; j--) {
-        result.coefficients[i] -= r.get(i, j) * result.coefficients[j];
-      }
-      result.coefficients[i] /= r.get(i, i);
-    }
-
-    // Calculate the coefficient of determination (confidence) as:
-    // 1 - (sumSquaredError / sumSquaredTotal)
-    // where sumSquaredError is the residual sum of squares (variance of the
-    // error), and sumSquaredTotal is the total sum of squares (variance of the
-    // data) where each has been weighted.
-    double yMean = 0.0;
-    for (int h = 0; h < m; h++) {
-      yMean += y[h];
-    }
-    yMean /= m;
-
-    double sumSquaredError = 0.0;
-    double sumSquaredTotal = 0.0;
-    for (int h = 0; h < m; h++) {
-      double err = y[h] - result.coefficients[0];
-      double term = 1.0;
-      for (int i = 1; i < n; i++) {
-        term *= x[h];
-        err -= term * result.coefficients[i];
-      }
-      sumSquaredError += w[h] * w[h] * err * err;
-      double v = y[h] - yMean;
-      sumSquaredTotal += w[h] * w[h] * v * v;
-    }
-
-    result.confidence = sumSquaredTotal > 0.000001 ?
-      1.0 - (sumSquaredError / sumSquaredTotal) :
-      1.0;
-
-    return result;
-  }
-
-}
diff --git a/sky/packages/sky/lib/src/gestures/multitap.dart b/sky/packages/sky/lib/src/gestures/multitap.dart
deleted file mode 100644
index ed9fdd1..0000000
--- a/sky/packages/sky/lib/src/gestures/multitap.dart
+++ /dev/null
@@ -1,380 +0,0 @@
-// Copyright 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 'dart:async';
-import 'dart:ui' show Point, Offset;
-
-import 'arena.dart';
-import 'constants.dart';
-import 'events.dart';
-import 'pointer_router.dart';
-import 'recognizer.dart';
-
-typedef void GestureDoubleTapCallback();
-
-typedef void GestureMultiTapDownCallback(Point globalPosition, int pointer);
-typedef void GestureMultiTapUpCallback(Point globalPosition, int pointer);
-typedef void GestureMultiTapCallback(int pointer);
-typedef void GestureMultiTapCancelCallback(int pointer);
-
-/// TapTracker helps track individual tap sequences as part of a
-/// larger gesture.
-class _TapTracker {
-
-  _TapTracker({ PointerInputEvent event, this.entry })
-    : pointer = event.pointer,
-      _initialPosition = event.position {
-    assert(event.type == 'pointerdown');
-  }
-
-  final int pointer;
-  final GestureArenaEntry entry;
-  final Point _initialPosition;
-
-  bool _isTrackingPointer = false;
-
-  void startTrackingPointer(PointerRouter router, PointerRoute route) {
-    if (!_isTrackingPointer) {
-      _isTrackingPointer = true;
-      router.addRoute(pointer, route);
-    }
-  }
-
-  void stopTrackingPointer(PointerRouter router, PointerRoute route) {
-    if (_isTrackingPointer) {
-      _isTrackingPointer = false;
-      router.removeRoute(pointer, route);
-    }
-  }
-
-  bool isWithinTolerance(PointerInputEvent event, double tolerance) {
-    Offset offset = event.position - _initialPosition;
-    return offset.distance <= tolerance;
-  }
-
-}
-
-
-class DoubleTapGestureRecognizer extends GestureRecognizer {
-
-  DoubleTapGestureRecognizer({
-    PointerRouter router,
-    this.onDoubleTap
-  }) : _router = router {
-    assert(router != null);
-  }
-
-  // Implementation notes:
-  // The double tap recognizer can be in one of four states. There's no
-  // explicit enum for the states, because they are already captured by
-  // the state of existing fields.  Specifically:
-  // Waiting on first tap: In this state, the _trackers list is empty, and
-  // _firstTap is null.
-  // First tap in progress: In this state, the _trackers list contains all
-  // the states for taps that have begun but not completed. This list can
-  // have more than one entry if two pointers begin to tap.
-  // Waiting on second tap: In this state, one of the in-progress taps has
-  // completed successfully. The _trackers list is again empty, and
-  // _firstTap records the successful tap.
-  // Second tap in progress: Much like the "first tap in progress" state, but
-  // _firstTap is non-null.  If a tap completes successfully while in this
-  // state, the callback is invoked and the state is reset.
-  // There are various other scenarios that cause the state to reset:
-  // - All in-progress taps are rejected (by time, distance, pointercancel, etc)
-  // - The long timer between taps expires
-  // - The gesture arena decides we have been rejected wholesale
-
-  PointerRouter _router;
-  GestureDoubleTapCallback onDoubleTap;
-
-  Timer _doubleTapTimer;
-  _TapTracker _firstTap;
-  final Map<int, _TapTracker> _trackers = new Map<int, _TapTracker>();
-
-  void addPointer(PointerInputEvent event) {
-    // Ignore out-of-bounds second taps
-    if (_firstTap != null &&
-        !_firstTap.isWithinTolerance(event, kDoubleTapSlop))
-      return;
-    _stopDoubleTapTimer();
-    _TapTracker tracker = new _TapTracker(
-      event: event,
-      entry: GestureArena.instance.add(event.pointer, this)
-    );
-    _trackers[event.pointer] = tracker;
-    tracker.startTrackingPointer(_router, handleEvent);
-  }
-
-  void handleEvent(PointerInputEvent event) {
-    _TapTracker tracker = _trackers[event.pointer];
-    assert(tracker != null);
-    switch (event.type) {
-      case 'pointerup':
-        if (_firstTap == null)
-          _registerFirstTap(tracker);
-        else
-          _registerSecondTap(tracker);
-        break;
-      case 'pointermove':
-        if (!tracker.isWithinTolerance(event, kDoubleTapTouchSlop))
-          _reject(tracker);
-        break;
-      case 'pointercancel':
-        _reject(tracker);
-        break;
-    }
-  }
-
-  void acceptGesture(int pointer) { }
-
-  void rejectGesture(int pointer) {
-    _TapTracker tracker = _trackers[pointer];
-    // If tracker isn't in the list, check if this is the first tap tracker
-    if (tracker == null &&
-        _firstTap != null &&
-        _firstTap.pointer == pointer)
-      tracker = _firstTap;
-    // If tracker is still null, we rejected ourselves already
-    if (tracker != null)
-      _reject(tracker);
-  }
-
-  void _reject(_TapTracker tracker) {
-    _trackers.remove(tracker.pointer);
-    tracker.entry.resolve(GestureDisposition.rejected);
-    _freezeTracker(tracker);
-    // If the first tap is in progress, and we've run out of taps to track,
-    // reset won't have any work to do.  But if we're in the second tap, we need
-    // to clear intermediate state.
-    if (_firstTap != null &&
-        (_trackers.isEmpty || tracker == _firstTap))
-      _reset();
-  }
-
-  void dispose() {
-    _reset();
-    _router = null;
-  }
-
-  void _reset() {
-    _stopDoubleTapTimer();
-    if (_firstTap != null) {
-      // Note, order is important below in order for the resolve -> reject logic
-      // to work properly
-      _TapTracker tracker = _firstTap;
-      _firstTap = null;
-      _reject(tracker);
-      GestureArena.instance.release(tracker.pointer);
-    }
-    _clearTrackers();
-  }
-
-  void _registerFirstTap(_TapTracker tracker) {
-    _startDoubleTapTimer();
-    GestureArena.instance.hold(tracker.pointer);
-    // Note, order is important below in order for the clear -> reject logic to
-    // work properly.
-    _freezeTracker(tracker);
-    _trackers.remove(tracker.pointer);
-    _clearTrackers();
-    _firstTap = tracker;
-  }
-
-  void _registerSecondTap(_TapTracker tracker) {
-    _firstTap.entry.resolve(GestureDisposition.accepted);
-    tracker.entry.resolve(GestureDisposition.accepted);
-    _freezeTracker(tracker);
-    _trackers.remove(tracker.pointer);
-    if (onDoubleTap != null)
-      onDoubleTap();
-    _reset();
-  }
-
-  void _clearTrackers() {
-    List<_TapTracker> localTrackers = new List<_TapTracker>.from(_trackers.values);
-    for (_TapTracker tracker in localTrackers)
-      _reject(tracker);
-    assert(_trackers.isEmpty);
-  }
-
-  void _freezeTracker(_TapTracker tracker) {
-    tracker.stopTrackingPointer(_router, handleEvent);
-  }
-
-  void _startDoubleTapTimer() {
-    _doubleTapTimer ??= new Timer(kDoubleTapTimeout, () => _reset());
-  }
-
-  void _stopDoubleTapTimer() {
-    if (_doubleTapTimer != null) {
-      _doubleTapTimer.cancel();
-      _doubleTapTimer = null;
-    }
-  }
-
-}
-
-
-enum _TapResolution {
-  tap,
-  cancel
-}
-
-/// TapGesture represents a full gesture resulting from a single tap sequence,
-/// as part of a [MultiTapGestureRecognizer]. Tap gestures are passive, meaning
-/// that they will not preempt any other arena member in play.
-class _TapGesture extends _TapTracker {
-
-  _TapGesture({
-    MultiTapGestureRecognizer gestureRecognizer,
-    PointerInputEvent event,
-    Duration longTapDelay
-  }) : gestureRecognizer = gestureRecognizer,
-       _lastPosition = event.position,
-       super(event: event, entry: GestureArena.instance.add(event.pointer, gestureRecognizer)) {
-    startTrackingPointer(gestureRecognizer.router, handleEvent);
-    if (longTapDelay > Duration.ZERO) {
-      _timer = new Timer(longTapDelay, () {
-        _timer = null;
-        gestureRecognizer._handleLongTap(event.pointer, _lastPosition);
-      });
-    }
-  }
-
-  final MultiTapGestureRecognizer gestureRecognizer;
-
-  bool _wonArena = false;
-  Timer _timer;
-
-  Point _lastPosition;
-  Point _finalPosition;
-
-  void handleEvent(PointerInputEvent event) {
-    assert(event.pointer == pointer);
-    if (event.type == 'pointermove') {
-      if (!isWithinTolerance(event, kTouchSlop))
-        cancel();
-      else
-        _lastPosition = event.position;
-    } else if (event.type == 'pointercancel') {
-      cancel();
-    } else if (event.type == 'pointerup') {
-      stopTrackingPointer(gestureRecognizer.router, handleEvent);
-      _finalPosition = event.position;
-      _check();
-    }
-  }
-
-  void stopTrackingPointer(PointerRouter router, PointerRoute route) {
-    _timer?.cancel();
-    _timer = null;
-    super.stopTrackingPointer(router, route);
-  }
-
-  void accept() {
-    _wonArena = true;
-    _check();
-  }
-
-  void reject() {
-    stopTrackingPointer(gestureRecognizer.router, handleEvent);
-    gestureRecognizer._resolveTap(pointer, _TapResolution.cancel, null);
-  }
-
-  void cancel() {
-    // If we won the arena already, then entry is resolved, so resolving
-    // again is a no-op. But we still need to clean up our own state.
-    if (_wonArena)
-      reject();
-    else
-      entry.resolve(GestureDisposition.rejected);
-  }
-
-  void _check() {
-    if (_wonArena && _finalPosition != null)
-      gestureRecognizer._resolveTap(pointer, _TapResolution.tap, _finalPosition);
-  }
-
-}
-
-/// MultiTapGestureRecognizer is a tap recognizer that treats taps
-/// independently. That is, each pointer sequence that could resolve to a tap
-/// does so independently of others: down-1, down-2, up-1, up-2 produces two
-/// taps, on up-1 and up-2.
-class MultiTapGestureRecognizer extends GestureRecognizer {
-  MultiTapGestureRecognizer({
-    PointerRouter router,
-    this.onTapDown,
-    this.onTapUp,
-    this.onTap,
-    this.onTapCancel,
-    this.longTapDelay: Duration.ZERO,
-    this.onLongTapDown
-  }) : _router = router {
-    assert(router != null);
-  }
-
-  PointerRouter get router => _router;
-  PointerRouter _router;
-  GestureMultiTapDownCallback onTapDown;
-  GestureMultiTapUpCallback onTapUp;
-  GestureMultiTapCallback onTap;
-  GestureMultiTapCancelCallback onTapCancel;
-  Duration longTapDelay;
-  GestureMultiTapDownCallback onLongTapDown;
-
-  final Map<int, _TapGesture> _gestureMap = new Map<int, _TapGesture>();
-
-  void addPointer(PointerInputEvent event) {
-    assert(!_gestureMap.containsKey(event.pointer));
-    _gestureMap[event.pointer] = new _TapGesture(
-      gestureRecognizer: this,
-      event: event,
-      longTapDelay: longTapDelay
-    );
-    if (onTapDown != null)
-      onTapDown(event.position, event.pointer);
-  }
-
-  void acceptGesture(int pointer) {
-    assert(_gestureMap.containsKey(pointer));
-    _gestureMap[pointer]?.accept();
-    assert(!_gestureMap.containsKey(pointer));
-  }
-
-  void rejectGesture(int pointer) {
-    assert(_gestureMap.containsKey(pointer));
-    _gestureMap[pointer]?.reject();
-    assert(!_gestureMap.containsKey(pointer));
-  }
-
-  void _resolveTap(int pointer, _TapResolution resolution, Point globalPosition) {
-    _gestureMap.remove(pointer);
-    if (resolution == _TapResolution.tap) {
-      if (onTapUp != null)
-        onTapUp(globalPosition, pointer);
-      if (onTap != null)
-        onTap(pointer);
-    } else {
-      if (onTapCancel != null)
-        onTapCancel(pointer);
-    }
-  }
-
-  void _handleLongTap(int pointer, Point lastPosition) {
-    assert(_gestureMap.containsKey(pointer));
-    if (onLongTapDown != null)
-      onLongTapDown(lastPosition, pointer);
-  }
-
-  void dispose() {
-    List<_TapGesture> localGestures = new List<_TapGesture>.from(_gestureMap.values);
-    for (_TapGesture gesture in localGestures)
-      gesture.cancel();
-    // Rejection of each gesture should cause it to be removed from our map
-    assert(_gestureMap.isEmpty);
-    _router = null;
-  }
-
-}
diff --git a/sky/packages/sky/lib/src/gestures/pointer_router.dart b/sky/packages/sky/lib/src/gestures/pointer_router.dart
deleted file mode 100644
index 4e8ab17..0000000
--- a/sky/packages/sky/lib/src/gestures/pointer_router.dart
+++ /dev/null
@@ -1,47 +0,0 @@
-// Copyright 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 'events.dart';
-
-/// A callback that receives a [PointerInputEvent]
-typedef void PointerRoute(PointerInputEvent event);
-
-/// A routing table for [PointerInputEvent] events.
-class PointerRouter {
-  final Map<int, List<PointerRoute>> _routeMap = new Map<int, List<PointerRoute>>();
-
-  /// Adds a route to the routing table
-  ///
-  /// Whenever this object routes a [PointerInputEvent] corresponding to
-  /// pointer, call route.
-  void addRoute(int pointer, PointerRoute route) {
-    List<PointerRoute> routes = _routeMap.putIfAbsent(pointer, () => new List<PointerRoute>());
-    assert(!routes.contains(route));
-    routes.add(route);
-  }
-
-  /// Removes a route from the routing table
-  ///
-  /// No longer call route when routing a [PointerInputEvent] corresponding to
-  /// pointer. Requires that this route was previously added to the router.
-  void removeRoute(int pointer, PointerRoute route) {
-    assert(_routeMap.containsKey(pointer));
-    List<PointerRoute> routes = _routeMap[pointer];
-    assert(routes.contains(route));
-    routes.remove(route);
-    if (routes.isEmpty)
-      _routeMap.remove(pointer);
-  }
-
-  /// Call the routes registed for this pointer event.
-  ///
-  /// Calls the routes in the order in which they were added to the route.
-  void route(PointerInputEvent event) {
-    List<PointerRoute> routes = _routeMap[event.pointer];
-    if (routes == null)
-      return;
-    for (PointerRoute route in new List<PointerRoute>.from(routes))
-      route(event);
-  }
-}
diff --git a/sky/packages/sky/lib/src/gestures/recognizer.dart b/sky/packages/sky/lib/src/gestures/recognizer.dart
deleted file mode 100644
index 5c5c5a8..0000000
--- a/sky/packages/sky/lib/src/gestures/recognizer.dart
+++ /dev/null
@@ -1,162 +0,0 @@
-// Copyright 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 'dart:async';
-import 'dart:ui' show Point, Offset;
-
-import 'arena.dart';
-import 'constants.dart';
-import 'events.dart';
-import 'pointer_router.dart';
-
-export 'pointer_router.dart' show PointerRouter;
-
-abstract class GestureRecognizer extends GestureArenaMember {
-
-  /// Call this with the pointerdown event of each pointer that should be
-  /// considered for this gesture. (It's the GestureRecognizer's responsibility
-  /// to then add itself to the global pointer router to receive subsequent
-  /// events for this pointer.)
-  void addPointer(PointerInputEvent event);
-
-  /// Release any resources used by the object. Called when the object is no
-  /// longer needed (e.g. a gesture recogniser is being unregistered from a
-  /// [GestureDetector]).
-  void dispose() { }
-
-}
-
-abstract class OneSequenceGestureRecognizer extends GestureRecognizer {
-  OneSequenceGestureRecognizer({ PointerRouter router }) : _router = router {
-    assert(_router != null);
-  }
-
-  PointerRouter _router;
-
-  final List<GestureArenaEntry> _entries = new List<GestureArenaEntry>();
-  final Set<int> _trackedPointers = new Set<int>();
-
-  void handleEvent(PointerInputEvent event);
-  void acceptGesture(int pointer) { }
-  void rejectGesture(int pointer) { }
-  void didStopTrackingLastPointer(int pointer);
-
-  void resolve(GestureDisposition disposition) {
-    List<GestureArenaEntry> localEntries = new List<GestureArenaEntry>.from(_entries);
-    _entries.clear();
-    for (GestureArenaEntry entry in localEntries)
-      entry.resolve(disposition);
-  }
-
-  void dispose() {
-    resolve(GestureDisposition.rejected);
-    for (int pointer in _trackedPointers)
-      _router.removeRoute(pointer, handleEvent);
-    _trackedPointers.clear();
-    assert(_entries.isEmpty);
-    _router = null;
-  }
-
-  void startTrackingPointer(int pointer) {
-    _router.addRoute(pointer, handleEvent);
-    _trackedPointers.add(pointer);
-    _entries.add(GestureArena.instance.add(pointer, this));
-  }
-
-  void stopTrackingPointer(int pointer) {
-    _router.removeRoute(pointer, handleEvent);
-    _trackedPointers.remove(pointer);
-    if (_trackedPointers.isEmpty)
-      didStopTrackingLastPointer(pointer);
-  }
-
-  void stopTrackingIfPointerNoLongerDown(PointerInputEvent event) {
-    if (event.type == 'pointerup' || event.type == 'pointercancel')
-      stopTrackingPointer(event.pointer);
-  }
-
-}
-
-enum GestureRecognizerState {
-  ready,
-  possible,
-  defunct
-}
-
-abstract class PrimaryPointerGestureRecognizer extends OneSequenceGestureRecognizer {
-  PrimaryPointerGestureRecognizer({ PointerRouter router, this.deadline })
-    : super(router: router);
-
-  final Duration deadline;
-
-  GestureRecognizerState state = GestureRecognizerState.ready;
-  int primaryPointer;
-  Point initialPosition;
-  Timer _timer;
-
-  void addPointer(PointerInputEvent event) {
-    startTrackingPointer(event.pointer);
-    if (state == GestureRecognizerState.ready) {
-      state = GestureRecognizerState.possible;
-      primaryPointer = event.pointer;
-      initialPosition = event.position;
-      if (deadline != null)
-        _timer = new Timer(deadline, didExceedDeadline);
-    }
-  }
-
-  void handleEvent(PointerInputEvent event) {
-    assert(state != GestureRecognizerState.ready);
-    if (state == GestureRecognizerState.possible && event.pointer == primaryPointer) {
-      // TODO(abarth): Maybe factor the slop handling out into a separate class?
-      if (event.type == 'pointermove' && _getDistance(event) > kTouchSlop) {
-        resolve(GestureDisposition.rejected);
-        stopTrackingPointer(event.pointer);
-      } else {
-        handlePrimaryPointer(event);
-      }
-    }
-    stopTrackingIfPointerNoLongerDown(event);
-  }
-
-  /// Override to provide behavior for the primary pointer when the gesture is still possible.
-  void handlePrimaryPointer(PointerInputEvent event);
-
-  /// Override to be notified with [deadline] is exceeded.
-  ///
-  /// You must override this function if you supply a [deadline].
-  void didExceedDeadline() {
-    assert(deadline == null);
-  }
-
-  void rejectGesture(int pointer) {
-    if (pointer == primaryPointer) {
-      _stopTimer();
-      state = GestureRecognizerState.defunct;
-    }
-  }
-
-  void didStopTrackingLastPointer(int pointer) {
-    _stopTimer();
-    state = GestureRecognizerState.ready;
-  }
-
-  void dispose() {
-    _stopTimer();
-    super.dispose();
-  }
-
-  void _stopTimer() {
-    if (_timer != null) {
-      _timer.cancel();
-      _timer = null;
-    }
-  }
-
-  double _getDistance(PointerInputEvent event) {
-    Offset offset = event.position - initialPosition;
-    return offset.distance;
-  }
-
-}
diff --git a/sky/packages/sky/lib/src/gestures/scale.dart b/sky/packages/sky/lib/src/gestures/scale.dart
deleted file mode 100644
index f79629d..0000000
--- a/sky/packages/sky/lib/src/gestures/scale.dart
+++ /dev/null
@@ -1,136 +0,0 @@
-// Copyright 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 'dart:ui' as ui;
-
-import 'arena.dart';
-import 'recognizer.dart';
-import 'constants.dart';
-import 'events.dart';
-
-enum ScaleState {
-  ready,
-  possible,
-  accepted,
-  started
-}
-
-typedef void GestureScaleStartCallback(ui.Point focalPoint);
-typedef void GestureScaleUpdateCallback(double scale, ui.Point focalPoint);
-typedef void GestureScaleEndCallback();
-
-class ScaleGestureRecognizer extends OneSequenceGestureRecognizer {
-  ScaleGestureRecognizer({ PointerRouter router, this.onStart, this.onUpdate, this.onEnd })
-    : super(router: router);
-
-  GestureScaleStartCallback onStart;
-  GestureScaleUpdateCallback onUpdate;
-  GestureScaleEndCallback onEnd;
-
-  ScaleState _state = ScaleState.ready;
-
-  double _initialSpan;
-  double _currentSpan;
-  Map<int, ui.Point> _pointerLocations;
-
-  double get _scaleFactor => _initialSpan > 0.0 ? _currentSpan / _initialSpan : 1.0;
-
-  void addPointer(PointerInputEvent event) {
-    startTrackingPointer(event.pointer);
-    if (_state == ScaleState.ready) {
-      _state = ScaleState.possible;
-      _initialSpan = 0.0;
-      _currentSpan = 0.0;
-      _pointerLocations = new Map<int, ui.Point>();
-    }
-  }
-
-  void handleEvent(PointerInputEvent event) {
-    assert(_state != ScaleState.ready);
-    bool configChanged = false;
-    switch(event.type) {
-      case 'pointerup':
-        configChanged = true;
-        _pointerLocations.remove(event.pointer);
-        break;
-      case 'pointerdown':
-        configChanged = true;
-        _pointerLocations[event.pointer] = new ui.Point(event.x, event.y);
-        break;
-      case 'pointermove':
-        _pointerLocations[event.pointer] = new ui.Point(event.x, event.y);
-        break;
-    }
-
-    _update(configChanged);
-
-    stopTrackingIfPointerNoLongerDown(event);
-  }
-
-  void _update(bool configChanged) {
-    int count = _pointerLocations.keys.length;
-
-    // Compute the focal point
-    ui.Point focalPoint = ui.Point.origin;
-    for (int pointer in _pointerLocations.keys)
-      focalPoint += _pointerLocations[pointer].toOffset();
-    focalPoint = new ui.Point(focalPoint.x / count, focalPoint.y / count);
-
-    // Span is the average deviation from focal point
-    double totalDeviation = 0.0;
-    for (int pointer in _pointerLocations.keys)
-      totalDeviation += (focalPoint - _pointerLocations[pointer]).distance;
-    _currentSpan = count > 0 ? totalDeviation / count : 0.0;
-
-    if (configChanged) {
-      _initialSpan = _currentSpan;
-      if (_state == ScaleState.started) {
-        if (onEnd != null)
-          onEnd();
-        _state = ScaleState.accepted;
-      }
-    }
-
-    if (_state == ScaleState.ready)
-      _state = ScaleState.possible;
-
-    if (_state == ScaleState.possible &&
-        (_currentSpan - _initialSpan).abs() > kScaleSlop) {
-      resolve(GestureDisposition.accepted);
-    }
-
-    if (_state == ScaleState.accepted && !configChanged) {
-      _state = ScaleState.started;
-      if (onStart != null)
-        onStart(focalPoint);
-    }
-
-    if (_state == ScaleState.started && onUpdate != null)
-      onUpdate(_scaleFactor, focalPoint);
-  }
-
-  void acceptGesture(int pointer) {
-    if (_state != ScaleState.accepted) {
-      _state = ScaleState.accepted;
-      _update(false);
-    }
-  }
-
-  void didStopTrackingLastPointer(int pointer) {
-    switch(_state) {
-      case ScaleState.possible:
-        resolve(GestureDisposition.rejected);
-        break;
-      case ScaleState.ready:
-        assert(false);  // We should have not seen a pointer yet
-        break;
-      case ScaleState.accepted:
-        break;
-      case ScaleState.started:
-        assert(false);  // We should be in the accepted state when user is done
-        break;
-    }
-    _state = ScaleState.ready;
-  }
-}
diff --git a/sky/packages/sky/lib/src/gestures/tap.dart b/sky/packages/sky/lib/src/gestures/tap.dart
deleted file mode 100644
index c4304fe..0000000
--- a/sky/packages/sky/lib/src/gestures/tap.dart
+++ /dev/null
@@ -1,93 +0,0 @@
-// Copyright 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 'dart:ui' show Point, Offset;
-
-import 'arena.dart';
-import 'constants.dart';
-import 'events.dart';
-import 'pointer_router.dart';
-import 'recognizer.dart';
-
-typedef void GestureTapDownCallback(Point globalPosition);
-typedef void GestureTapUpCallback(Point globalPosition);
-typedef void GestureTapCallback();
-typedef void GestureTapCancelCallback();
-
-/// TapGestureRecognizer is a tap recognizer that tracks only one primary
-/// pointer per gesture. That is, during tap recognition, extra pointer events
-/// are ignored: down-1, down-2, up-1, up-2 produces only one tap on up-1.
-class TapGestureRecognizer extends PrimaryPointerGestureRecognizer {
-  TapGestureRecognizer({
-    PointerRouter router,
-    this.onTapDown,
-    this.onTapUp,
-    this.onTap,
-    this.onTapCancel
-  }) : super(router: router, deadline: kPressTimeout);
-
-  GestureTapDownCallback onTapDown;
-  GestureTapDownCallback onTapUp;
-  GestureTapCallback onTap;
-  GestureTapCancelCallback onTapCancel;
-
-  bool _sentTapDown = false;
-  bool _wonArena = false;
-  Point _finalPosition;
-
-  void handlePrimaryPointer(PointerInputEvent event) {
-    if (event.type == 'pointerup') {
-      _finalPosition = event.position;
-      _checkUp();
-    }
-  }
-
-  void didExceedDeadline() {
-    _checkDown();
-  }
-
-  void acceptGesture(int pointer) {
-    super.acceptGesture(pointer);
-    if (pointer == primaryPointer) {
-      _checkDown();
-      _wonArena = true;
-      _checkUp();
-    }
-  }
-
-  void rejectGesture(int pointer) {
-    super.rejectGesture(pointer);
-    if (pointer == primaryPointer) {
-      assert(state == GestureRecognizerState.defunct);
-      if (onTapCancel != null)
-        onTapCancel();
-      _reset();
-    }
-  }
-
-  void _checkDown() {
-    if (!_sentTapDown) {
-      if (onTapDown != null)
-        onTapDown(initialPosition);
-      _sentTapDown = true;
-    }
-  }
-
-  void _checkUp() {
-    if (_wonArena && _finalPosition != null) {
-      resolve(GestureDisposition.accepted);
-      if (onTapUp != null)
-        onTapUp(_finalPosition);
-      if (onTap != null)
-        onTap();
-      _reset();
-    }
-  }
-
-  void _reset() {
-    _sentTapDown = false;
-    _wonArena = false;
-    _finalPosition = null;
-  }
-}
diff --git a/sky/packages/sky/lib/src/gestures/velocity_tracker.dart b/sky/packages/sky/lib/src/gestures/velocity_tracker.dart
deleted file mode 100644
index 81f5bcf..0000000
--- a/sky/packages/sky/lib/src/gestures/velocity_tracker.dart
+++ /dev/null
@@ -1,238 +0,0 @@
-// Copyright 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 'dart:ui' as ui;
-
-import 'lsq_solver.dart';
-
-class GestureVelocity {
-  GestureVelocity({ this.isValid: false, this.x: 0.0, this.y : 0.0 });
-
-  final bool isValid;
-  final double x;
-  final double y;
-}
-
-class _Estimator {
-  int degree;
-  double time;
-  List<double> xCoefficients;
-  List<double> yCoefficients;
-  double confidence;
-
-  String toString() {
-    String result = "Estimator(degree: " + degree.toString();
-    result +=  ", time: " + time.toString();
-    result +=  ", confidence: " + confidence.toString();
-    result +=  ", xCoefficients: " + xCoefficients.toString();
-    result +=  ", yCoefficients: " + yCoefficients.toString();
-    return result;
-  }
-}
-
-abstract class _VelocityTrackerStrategy {
-  void addMovement(double timeStamp, double x, double y);
-  bool getEstimator(_Estimator estimator);
-  void clear();
-}
-
-enum _Weighting {
-  weightingNone,
-  weightingDelta,
-  weightingCentral,
-  weightingRecent
-}
-
-class _Movement {
-  double eventTime = 0.0;
-  ui.Point position = ui.Point.origin;
-}
-
-class _LeastSquaresVelocityTrackerStrategy extends _VelocityTrackerStrategy {
-  static const int kHistorySize = 20;
-  static const int kHorizonMilliseconds = 100;
-
-  _LeastSquaresVelocityTrackerStrategy(this.degree, this.weighting)
-  : _index = 0, _movements = new List<_Movement>(kHistorySize);
-
-  final int degree;
-  final _Weighting weighting;
-  final List<_Movement> _movements;
-  int _index;
-
-  void addMovement(double timeStamp, double x, double y) {
-    if (++_index == kHistorySize)
-      _index = 0;
-    _Movement movement = _getMovement(_index);
-    movement.eventTime = timeStamp;
-    movement.position = new ui.Point(x, y);
-  }
-
-  bool getEstimator(_Estimator estimator) {
-    // Iterate over movement samples in reverse time order and collect samples.
-    List<double> x = new List<double>();
-    List<double> y = new List<double>();
-    List<double> w = new List<double>();
-    List<double> time = new List<double>();
-    int m = 0;
-    int index = _index;
-    _Movement newestMovement = _getMovement(index);
-    do {
-      _Movement movement = _getMovement(index);
-
-      double age = newestMovement.eventTime - movement.eventTime;
-      if (age > kHorizonMilliseconds)
-        break;
-
-      ui.Point position = movement.position;
-      x.add(position.x);
-      y.add(position.y);
-      w.add(_chooseWeight(index));
-      time.add(-age);
-      index = (index == 0 ? kHistorySize : index) - 1;
-    } while (++m < kHistorySize);
-
-    if (m == 0)
-      return false;  // no data
-
-    // Calculate a least squares polynomial fit.
-    int n = degree;
-    if (n > m - 1)
-      n = m - 1;
-
-    if (n >= 1) {
-      LeastSquaresSolver xSolver = new LeastSquaresSolver(time, x, w);
-      PolynomialFit xFit = xSolver.solve(n);
-      if (xFit != null) {
-        LeastSquaresSolver ySolver = new LeastSquaresSolver(time, y, w);
-        PolynomialFit yFit = ySolver.solve(n);
-        if (yFit != null) {
-          estimator.xCoefficients = xFit.coefficients;
-          estimator.yCoefficients = yFit.coefficients;
-          estimator.time = newestMovement.eventTime;
-          estimator.degree = n;
-          estimator.confidence = xFit.confidence * yFit.confidence;
-          return true;
-        }
-      }
-    }
-
-    // No velocity data available for this pointer, but we do have its current
-    // position.
-    estimator.xCoefficients = [ x[0] ];
-    estimator.yCoefficients = [ y[0] ];
-    estimator.time = newestMovement.eventTime;
-    estimator.degree = 0;
-    estimator.confidence = 1.0;
-    return true;
-  }
-
-  void clear() {
-    _index = -1;
-  }
-
-  double _chooseWeight(int index) {
-    switch (weighting) {
-      case _Weighting.weightingDelta:
-        // Weight points based on how much time elapsed between them and the next
-        // point so that points that "cover" a shorter time span are weighed less.
-        //   delta  0ms: 0.5
-        //   delta 10ms: 1.0
-        if (index == _index) {
-          return 1.0;
-        }
-        int nextIndex = (index + 1) % kHistorySize;
-        double deltaMilliseconds = _movements[nextIndex].eventTime -
-          _movements[index].eventTime;
-        if (deltaMilliseconds < 0)
-          return 0.5;
-        if (deltaMilliseconds < 10)
-          return 0.5 + deltaMilliseconds * 0.05;
-
-        return 1.0;
-
-      case _Weighting.weightingCentral:
-        // Weight points based on their age, weighing very recent and very old
-        // points less.
-        //   age  0ms: 0.5
-        //   age 10ms: 1.0
-        //   age 50ms: 1.0
-        //   age 60ms: 0.5
-        double ageMilliseconds = _movements[_index].eventTime -
-          _movements[index].eventTime;
-        if (ageMilliseconds < 0)
-          return 0.5;
-        if (ageMilliseconds < 10)
-          return 0.5 + ageMilliseconds * 0.05;
-        if (ageMilliseconds < 50)
-          return 1.0;
-        if (ageMilliseconds < 60)
-          return 0.5 + (60 - ageMilliseconds) * 0.05;
-
-        return 0.5;
-
-      case _Weighting.weightingRecent:
-        // Weight points based on their age, weighing older points less.
-        //   age   0ms: 1.0
-        //   age  50ms: 1.0
-        //   age 100ms: 0.5
-        double ageMilliseconds = _movements[_index].eventTime -
-          _movements[index].eventTime;
-        if (ageMilliseconds < 50) {
-          return 1.0;
-        }
-        if (ageMilliseconds < 100) {
-          return 0.5 + (100 - ageMilliseconds) * 0.01;
-        }
-        return 0.5;
-
-      case _Weighting.weightingNone:
-      default:
-        return 1.0;
-    }
-  }
-
-  _Movement _getMovement(int i) {
-      _Movement result = _movements[i];
-      if (result == null) {
-        result = new _Movement();
-        _movements[i] = result;
-      }
-      return result;
-  }
-
-}
-
-class VelocityTracker {
-  static const int kAssumePointerMoveStoppedTimeMs = 40;
-
-  VelocityTracker() : _lastTimeStamp = 0.0, _strategy = _createStrategy();
-
-  double _lastTimeStamp;
-  _VelocityTrackerStrategy _strategy;
-
-  void addPosition(double timeStamp, double x, double y) {
-    if ((timeStamp - _lastTimeStamp) >= kAssumePointerMoveStoppedTimeMs)
-      _strategy.clear();
-    _lastTimeStamp = timeStamp;
-    _strategy.addMovement(timeStamp, x, y);
-  }
-
-  GestureVelocity getVelocity() {
-    _Estimator estimator = new _Estimator();
-    if (_strategy.getEstimator(estimator) && estimator.degree >= 1) {
-      // convert from pixels/ms to pixels/s
-      return new GestureVelocity(
-        isValid: true,
-        x: estimator.xCoefficients[1] * 1000,
-        y: estimator.yCoefficients[1] * 1000
-      );
-    }
-    return new GestureVelocity(isValid: false, x: 0.0, y: 0.0);
-  }
-
-  static _VelocityTrackerStrategy _createStrategy() {
-    return new _LeastSquaresVelocityTrackerStrategy(2, _Weighting.weightingNone);
-  }
-}
diff --git a/sky/packages/sky/lib/src/http/http.dart b/sky/packages/sky/lib/src/http/http.dart
deleted file mode 100644
index d6b492f..0000000
--- a/sky/packages/sky/lib/src/http/http.dart
+++ /dev/null
@@ -1,121 +0,0 @@
-// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-/// A [Future]-based library for making HTTP requests. It's based on
-/// Dart's `http` package, but we've removed the dependency on mirrors
-/// and added a `mojo`-based HTTP client.
-library http;
-
-import 'dart:async';
-import 'dart:convert';
-import 'dart:typed_data';
-
-import 'mojo_client.dart';
-import 'response.dart';
-
-/// Sends an HTTP HEAD request with the given headers to the given URL, which
-/// can be a [Uri] or a [String].
-///
-/// This automatically initializes a new [Client] and closes that client once
-/// the request is complete. If you're planning on making multiple requests to
-/// the same server, you should use a single [Client] for all of those requests.
-Future<Response> head(url) =>
-  _withClient((client) => client.head(url));
-
-/// Sends an HTTP GET request with the given headers to the given URL, which can
-/// be a [Uri] or a [String].
-///
-/// This automatically initializes a new [Client] and closes that client once
-/// the request is complete. If you're planning on making multiple requests to
-/// the same server, you should use a single [Client] for all of those requests.
-Future<Response> get(url) =>
-  _withClient((client) => client.get(url));
-
-/// Sends an HTTP POST request with the given headers and body to the given URL,
-/// which can be a [Uri] or a [String].
-///
-/// [body] sets the body of the request.
-Future<Response> post(url, {body}) =>
-  _withClient((client) => client.post(url, body: body));
-
-/// Sends an HTTP PUT request with the given headers and body to the given URL,
-/// which can be a [Uri] or a [String].
-///
-/// [body] sets the body of the request. It can be a [String], a [List<int>] or
-/// a [Map<String, String>]. If it's a String, it's encoded using [encoding] and
-/// used as the body of the request. The content-type of the request will
-/// default to "text/plain".
-Future<Response> put(url, {String body}) =>
-  _withClient((client) => client.put(url, body: body));
-
-/// Sends an HTTP PATCH request with the given headers and body to the given
-/// URL, which can be a [Uri] or a [String].
-///
-/// [body] sets the body of the request. It can be a [String], a [List<int>] or
-/// a [Map<String, String>]. If it's a String, it's encoded using [encoding] and
-/// used as the body of the request. The content-type of the request will
-/// default to "text/plain".
-///
-/// If [body] is a List, it's used as a list of bytes for the body of the
-/// request.
-///
-/// If [body] is a Map, it's encoded as form fields using [encoding]. The
-/// content-type of the request will be set to
-/// `"application/x-www-form-urlencoded"`; this cannot be overridden.
-///
-/// [encoding] defaults to [UTF8].
-///
-/// For more fine-grained control over the request, use [Request] or
-/// [StreamedRequest] instead.
-Future<Response> patch(url, { body }) =>
-  _withClient((client) => client.patch(url, body: body));
-
-/// Sends an HTTP DELETE request with the given headers to the given URL, which
-/// can be a [Uri] or a [String].
-///
-/// This automatically initializes a new [Client] and closes that client once
-/// the request is complete. If you're planning on making multiple requests to
-/// the same server, you should use a single [Client] for all of those requests.
-///
-/// For more fine-grained control over the request, use [Request] instead.
-Future<Response> delete(url) =>
-  _withClient((client) => client.delete(url));
-
-/// Sends an HTTP GET request with the given headers to the given URL, which can
-/// be a [Uri] or a [String], and returns a Future that completes to the body of
-/// the response as a [String].
-///
-/// The Future will emit a [ClientException] if the response doesn't have a
-/// success status code.
-///
-/// This automatically initializes a new [Client] and closes that client once
-/// the request is complete. If you're planning on making multiple requests to
-/// the same server, you should use a single [Client] for all of those requests.
-///
-/// For more fine-grained control over the request and response, use [Request]
-/// instead.
-Future<String> read(url) =>
-  _withClient((client) => client.read(url));
-
-/// Sends an HTTP GET request with the given headers to the given URL, which can
-/// be a [Uri] or a [String], and returns a Future that completes to the body of
-/// the response as a list of bytes.
-///
-/// The Future will emit a [ClientException] if the response doesn't have a
-/// success status code.
-///
-/// This automatically initializes a new [Client] and closes that client once
-/// the request is complete. If you're planning on making multiple requests to
-/// the same server, you should use a single [Client] for all of those requests.
-///
-/// For more fine-grained control over the request and response, use [Request]
-/// instead.
-Future<Uint8List> readBytes(url) =>
-  _withClient((client) => client.readBytes(url));
-
-Future _withClient(Future fn(MojoClient)) {
-  var client = new MojoClient();
-  var future = fn(client);
-  return future.whenComplete(client.close);
-}
diff --git a/sky/packages/sky/lib/src/http/mojo_client.dart b/sky/packages/sky/lib/src/http/mojo_client.dart
deleted file mode 100644
index 5edbc06..0000000
--- a/sky/packages/sky/lib/src/http/mojo_client.dart
+++ /dev/null
@@ -1,101 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library base_client;
-
-import 'dart:async';
-import 'dart:convert';
-import 'dart:typed_data';
-
-import 'package:mojo/core.dart' as mojo;
-import 'package:mojo/mojo/url_request.mojom.dart' as mojo;
-import 'package:mojo/mojo/url_response.mojom.dart' as mojo;
-import 'package:mojo_services/mojo/network_service.mojom.dart' as mojo;
-import 'package:mojo_services/mojo/url_loader.mojom.dart' as mojo;
-
-import 'package:flutter/src/services/shell.dart';
-
-import 'response.dart';
-
-mojo.NetworkServiceProxy _initNetworkService() {
-  mojo.NetworkServiceProxy networkService = new mojo.NetworkServiceProxy.unbound();
-  shell.connectToService("mojo:authenticated_network_service", networkService);
-  return networkService;
-}
-
-final mojo.NetworkServiceProxy _networkService = _initNetworkService();
-
-/// A `mojo`-based HTTP client
-class MojoClient {
-
-  Future<Response> head(url, {Map<String, String> headers}) =>
-    _send("HEAD", url, headers);
-
-  Future<Response> get(url, {Map<String, String> headers}) =>
-    _send("GET", url, headers);
-
-  Future<Response> post(url, {Map<String, String> headers, body,
-      Encoding encoding}) =>
-    _send("POST", url, headers, body, encoding);
-
-  Future<Response> put(url, {Map<String, String> headers, body,
-      Encoding encoding}) =>
-    _send("PUT", url, headers, body, encoding);
-
-  Future<Response> patch(url, {Map<String, String> headers, body,
-      Encoding encoding}) =>
-    _send("PATCH", url, headers, body, encoding);
-
-  Future<Response> delete(url, {Map<String, String> headers}) =>
-    _send("DELETE", url, headers);
-
-  Future<String> read(url, {Map<String, String> headers}) {
-    return get(url, headers: headers).then((response) {
-      _checkResponseSuccess(url, response);
-      return response.body;
-    });
-  }
-
-  Future<Uint8List> readBytes(url, {Map<String, String> headers}) {
-    return get(url, headers: headers).then((response) {
-      _checkResponseSuccess(url, response);
-      return response.bodyBytes;
-    });
-  }
-
-  Future<Response> _send(String method, url,
-      Map<String, String> headers, [body, Encoding encoding]) async {
-
-    mojo.UrlLoaderProxy loader = new mojo.UrlLoaderProxy.unbound();
-    mojo.UrlRequest request = new mojo.UrlRequest()
-      ..url = url.toString()
-      ..method = method
-      ..body = body;
-    try {
-      _networkService.ptr.createUrlLoader(loader);
-      mojo.UrlResponse response = (await loader.ptr.start(request)).response;
-      ByteData data = await mojo.DataPipeDrainer.drainHandle(response.body);
-      Uint8List bodyAsList = new Uint8List.view(data.buffer);
-      String bodyAsString = new String.fromCharCodes(bodyAsList);
-      return new Response(bodyAsString, response.statusCode);
-    } catch (e) {
-      print("NetworkService unavailable $e");
-      return new Response(null, 500);
-    } finally {
-      loader.close();
-    }
-  }
-
-  void _checkResponseSuccess(url, Response response) {
-    if (response.statusCode < 400) return;
-    var message = "Request to $url failed with status ${response.statusCode}";
-    if (response.reasonPhrase != null) {
-      message = "$message: ${response.reasonPhrase}";
-    }
-    if (url is String) url = Uri.parse(url);
-    throw new ClientException("$message.", url);
-  }
-
-  void close() {}
-}
diff --git a/sky/packages/sky/lib/src/http/response.dart b/sky/packages/sky/lib/src/http/response.dart
deleted file mode 100644
index d9b398a..0000000
--- a/sky/packages/sky/lib/src/http/response.dart
+++ /dev/null
@@ -1,12 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library response;
-
-/// An HTTP response where the entire response body is known in advance.
-class Response {
-  const Response(this.body, this.statusCode);
-  final String body;
-  final int statusCode;
-}
diff --git a/sky/packages/sky/lib/src/material/bottom_sheet.dart b/sky/packages/sky/lib/src/material/bottom_sheet.dart
deleted file mode 100644
index 7e81c30..0000000
--- a/sky/packages/sky/lib/src/material/bottom_sheet.dart
+++ /dev/null
@@ -1,163 +0,0 @@
-// Copyright 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 'dart:async';
-
-import 'package:flutter/animation.dart';
-import 'package:flutter/painting.dart';
-import 'package:flutter/rendering.dart';
-import 'package:flutter/widgets.dart';
-
-import 'colors.dart';
-import 'material.dart';
-
-const Duration _kBottomSheetDuration = const Duration(milliseconds: 200);
-const double _kMinFlingVelocity = 700.0;
-const double _kFlingVelocityScale = 1.0 / 300.0;
-
-class _ModalBottomSheet extends StatefulComponent {
-  _ModalBottomSheet({ Key key, this.route }) : super(key: key);
-
-  final _ModalBottomSheetRoute route;
-
-  _ModalBottomSheetState createState() => new _ModalBottomSheetState();
-}
-
-class _ModalBottomSheetLayout extends OneChildLayoutDelegate {
-  // The distance from the bottom of the parent to the top of the BottomSheet child.
-  AnimatedValue<double> childTop = new AnimatedValue<double>(0.0);
-
-  BoxConstraints getConstraintsForChild(BoxConstraints constraints) {
-    return new BoxConstraints(
-      minWidth: constraints.maxWidth,
-      maxWidth: constraints.maxWidth,
-      minHeight: 0.0,
-      maxHeight: constraints.maxHeight * 9.0 / 16.0
-    );
-  }
-
-  Point getPositionForChild(Size size, Size childSize) {
-    childTop.end = childSize.height;
-    return new Point(0.0, size.height - childTop.value);
-  }
-}
-
-class _ModalBottomSheetState extends State<_ModalBottomSheet> {
-
-  final _ModalBottomSheetLayout _layout = new _ModalBottomSheetLayout();
-  bool _dragEnabled = false;
-
-  void _handleDragStart(Point position) {
-    _dragEnabled = !config.route._performance.isAnimating;
-  }
-
-  void _handleDragUpdate(double delta) {
-    if (!_dragEnabled)
-      return;
-    config.route._performance.progress -= delta / _layout.childTop.end;
-  }
-
-  void _handleDragEnd(Offset velocity) {
-    if (!_dragEnabled)
-      return;
-    if (velocity.dy > _kMinFlingVelocity)
-      config.route._performance.fling(velocity: -velocity.dy * _kFlingVelocityScale);
-    else
-      config.route._performance.forward();
-  }
-
-  Widget build(BuildContext context) {
-    return new GestureDetector(
-      onTap: () { Navigator.of(context).pop(); },
-      child: new BuilderTransition(
-        performance: config.route._performance,
-        variables: <AnimatedValue<double>>[_layout.childTop],
-        builder: (BuildContext context) {
-          return new ClipRect(
-            child: new CustomOneChildLayout(
-              delegate: _layout,
-              token: _layout.childTop.value,
-              child: new GestureDetector(
-                onVerticalDragStart: _handleDragStart,
-                onVerticalDragUpdate: _handleDragUpdate,
-                onVerticalDragEnd: _handleDragEnd,
-                child: new Material(child: config.route.child)
-              )
-            )
-          );
-        }
-      )
-    );
-  }
-}
-
-class _ModalBottomSheetRoute extends ModalRoute {
-  _ModalBottomSheetRoute({ this.completer, this.child }) {
-    _performance = new Performance(duration: transitionDuration, debugLabel: 'ModalBottomSheet');
-  }
-
-  final Completer completer;
-  final Widget child;
-
-  bool get opaque => false;
-  Duration get transitionDuration => _kBottomSheetDuration;
-
-  Performance _performance;
-
-  Performance createPerformance() {
-    _performance = super.createPerformance();
-    return _performance;
-  }
-
-  Color get barrierColor => Colors.black54;
-  Widget buildModalWidget(BuildContext context) => new _ModalBottomSheet(route: this);
-
-  void didPop([dynamic result]) {
-    completer.complete(result);
-    super.didPop(result);
-  }
-}
-
-Future showModalBottomSheet({ BuildContext context, Widget child }) {
-  assert(child != null);
-  final Completer completer = new Completer();
-  Navigator.of(context).pushEphemeral(new _ModalBottomSheetRoute(
-    completer: completer,
-    child: child
-  ));
-  return completer.future;
-}
-
-class _PersistentBottomSheet extends StatelessComponent {
-  _PersistentBottomSheet({
-    Key key,
-    this.child,
-    this.route
-  }) : super(key: key);
-
-  final TransitionRoute route;
-  final Widget child;
-
-  Widget build(BuildContext context) {
-    return new AlignTransition(
-      performance: route.performance,
-      alignment: new AnimatedValue<FractionalOffset>(const FractionalOffset(0.0, 0.0)),
-      heightFactor: new AnimatedValue<double>(0.0, end: 1.0),
-      child: child
-    );
-  }
-}
-
-class _PersistentBottomSheetRoute extends TransitionRoute {
-  bool get opaque => false;
-  Duration get transitionDuration => _kBottomSheetDuration;
-}
-
-void showBottomSheet({ BuildContext context, GlobalKey<PlaceholderState> placeholderKey, Widget child }) {
-  assert(child != null);
-  assert(placeholderKey != null);
-  _PersistentBottomSheetRoute route = new _PersistentBottomSheetRoute();
-  placeholderKey.currentState.child = new _PersistentBottomSheet(route: route, child: child);
-  Navigator.of(context).pushEphemeral(route);
-}
diff --git a/sky/packages/sky/lib/src/material/card.dart b/sky/packages/sky/lib/src/material/card.dart
deleted file mode 100644
index 4090b3f..0000000
--- a/sky/packages/sky/lib/src/material/card.dart
+++ /dev/null
@@ -1,31 +0,0 @@
-// Copyright 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:flutter/widgets.dart';
-
-import 'material.dart';
-
-const EdgeDims _kCardMargins = const EdgeDims.all(4.0);
-
-/// A material design card
-///
-/// <https://www.google.com/design/spec/components/cards.html>
-class Card extends StatelessComponent {
-  const Card({ Key key, this.child, this.color }) : super(key: key);
-
-  final Widget child;
-  final Color color;
-
-  Widget build(BuildContext context) {
-    return new Container(
-      margin: _kCardMargins,
-      child: new Material(
-        color: color,
-        type: MaterialType.card,
-        level: 2,
-        child: child
-      )
-    );
-  }
-}
diff --git a/sky/packages/sky/lib/src/material/checkbox.dart b/sky/packages/sky/lib/src/material/checkbox.dart
deleted file mode 100644
index 9e576e7..0000000
--- a/sky/packages/sky/lib/src/material/checkbox.dart
+++ /dev/null
@@ -1,203 +0,0 @@
-// Copyright 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 'dart:ui' as ui;
-
-import 'package:flutter/rendering.dart';
-import 'package:flutter/widgets.dart';
-
-import 'colors.dart';
-import 'theme.dart';
-
-const double _kMidpoint = 0.5;
-const double _kEdgeSize = 18.0;
-const double _kEdgeRadius = 1.0;
-const double _kStrokeWidth = 2.0;
-
-/// A material design checkbox
-///
-/// The checkbox itself does not maintain any state. Instead, when the state of
-/// the checkbox changes, the component calls the `onChange` callback. Most
-/// components that use a checkbox will listen for the `onChange` callback and
-/// rebuild the checkbox with a new `value` to update the visual appearance of
-/// the checkbox.
-///
-/// <https://www.google.com/design/spec/components/lists-controls.html#lists-controls-types-of-list-controls>
-class Checkbox extends StatelessComponent {
-  /// Constructs a checkbox
-  ///
-  /// * `value` determines whether the checkbox is checked.
-  /// * `onChanged` is called whenever the state of the checkbox should change.
-  const Checkbox({
-    Key key,
-    this.value,
-    this.onChanged
-  }) : super(key: key);
-
-  final bool value;
-  final ValueChanged<bool> onChanged;
-
-  bool get enabled => onChanged != null;
-
-  Widget build(BuildContext context) {
-    ThemeData themeData = Theme.of(context);
-    if (enabled) {
-      Color uncheckedColor = themeData.brightness == ThemeBrightness.light
-          ? Colors.black54
-          : Colors.white70;
-      return new _CheckboxWrapper(
-        value: value,
-        onChanged: onChanged,
-        uncheckedColor: uncheckedColor,
-        accentColor: themeData.accentColor
-      );
-    }
-    Color disabledColor = themeData.brightness == ThemeBrightness.light
-        ? Colors.black26
-        : Colors.white30;
-    return new _CheckboxWrapper(
-      value: value,
-      uncheckedColor: disabledColor,
-      accentColor: disabledColor
-    );
-  }
-}
-
-// This wrapper class exists only because Switch needs to be a Component in
-// order to get an accent color from a Theme but Components do not know how to
-// host RenderObjects.
-class _CheckboxWrapper extends LeafRenderObjectWidget {
-  _CheckboxWrapper({
-    Key key,
-    this.value,
-    this.onChanged,
-    this.uncheckedColor,
-    this.accentColor
-  }) : super(key: key) {
-    assert(uncheckedColor != null);
-    assert(accentColor != null);
-  }
-
-  final bool value;
-  final ValueChanged<bool> onChanged;
-  final Color uncheckedColor;
-  final Color accentColor;
-
-  _RenderCheckbox createRenderObject() => new _RenderCheckbox(
-    value: value,
-    accentColor: accentColor,
-    uncheckedColor: uncheckedColor,
-    onChanged: onChanged
-  );
-
-  void updateRenderObject(_RenderCheckbox renderObject, _CheckboxWrapper oldWidget) {
-    renderObject.value = value;
-    renderObject.onChanged = onChanged;
-    renderObject.uncheckedColor = uncheckedColor;
-    renderObject.accentColor = accentColor;
-  }
-}
-
-class _RenderCheckbox extends RenderToggleable {
-  _RenderCheckbox({
-    bool value,
-    Color uncheckedColor,
-    Color accentColor,
-    ValueChanged<bool> onChanged
-  }): _uncheckedColor = uncheckedColor,
-      _accentColor = accentColor,
-      super(
-        value: value,
-        onChanged: onChanged,
-        size: new Size(_kEdgeSize, _kEdgeSize)
-      ) {
-    assert(uncheckedColor != null);
-    assert(accentColor != null);
-  }
-
-  Color _uncheckedColor;
-  Color get uncheckedColor => _uncheckedColor;
-
-  void set uncheckedColor(Color value) {
-    assert(value != null);
-    if (value == _uncheckedColor)
-      return;
-    _uncheckedColor = value;
-    markNeedsPaint();
-  }
-
-  Color _accentColor;
-  void set accentColor(Color value) {
-    assert(value != null);
-    if (value == _accentColor)
-      return;
-    _accentColor = value;
-    markNeedsPaint();
-  }
-
-  void paint(PaintingContext context, Offset offset) {
-    final PaintingCanvas canvas = context.canvas;
-    // Choose a color between grey and the theme color
-    Paint paint = new Paint()
-      ..strokeWidth = _kStrokeWidth
-      ..color = uncheckedColor;
-
-    // The rrect contracts slightly during the transition animation from checked states.
-    // Because we have a stroke size of 2, we should have a minimum 1.0 inset.
-    double inset = 2.0 - (position - _kMidpoint).abs() * 2.0;
-    double rectSize = _kEdgeSize - inset * _kStrokeWidth;
-    Rect rect = new Rect.fromLTWH(offset.dx + inset, offset.dy + inset, rectSize, rectSize);
-    // Create an inner rectangle to cover inside of rectangle. This is needed to avoid
-    // painting artefacts caused by overlayed paintings.
-    Rect innerRect = rect.deflate(1.0);
-    ui.RRect rrect = new ui.RRect.fromRectXY(
-        rect, _kEdgeRadius, _kEdgeRadius);
-
-    // Outline of the empty rrect
-    paint.style = ui.PaintingStyle.stroke;
-    canvas.drawRRect(rrect, paint);
-
-    // Radial gradient that changes size
-    if (position > 0) {
-      paint
-        ..style = ui.PaintingStyle.fill
-        ..shader = new ui.Gradient.radial(
-          new Point(_kEdgeSize / 2.0, _kEdgeSize / 2.0),
-          _kEdgeSize * (_kMidpoint - position) * 8.0, <Color>[
-        const Color(0x00000000),
-        uncheckedColor
-      ]);
-      canvas.drawRect(innerRect, paint);
-    }
-
-    if (position > _kMidpoint) {
-      double t = (position - _kMidpoint) / (1.0 - _kMidpoint);
-
-      // First draw a rounded rect outline then fill inner rectangle with accent color.
-      paint
-        ..color = new Color.fromARGB((t * 255).floor(), _accentColor.red, _accentColor.green, _accentColor.blue)
-        ..style = ui.PaintingStyle.stroke;
-      canvas.drawRRect(rrect, paint);
-      paint.style = ui.PaintingStyle.fill;
-      canvas.drawRect(innerRect, paint);
-
-      // White inner check
-      paint
-        ..color = const Color(0xFFFFFFFF)
-        ..style = ui.PaintingStyle.stroke;
-      Path path = new Path();
-      Point start = new Point(_kEdgeSize * 0.15, _kEdgeSize * 0.45);
-      Point mid = new Point(_kEdgeSize * 0.4, _kEdgeSize * 0.7);
-      Point end = new Point(_kEdgeSize * 0.85, _kEdgeSize * 0.25);
-      Point lerp(Point p1, Point p2, double t) =>
-          new Point(p1.x * (1.0 - t) + p2.x * t, p1.y * (1.0 - t) + p2.y * t);
-      Point drawStart = lerp(start, mid, 1.0 - t);
-      Point drawEnd = lerp(mid, end, t);
-      path.moveTo(offset.dx + drawStart.x, offset.dy + drawStart.y);
-      path.lineTo(offset.dx + mid.x, offset.dy + mid.y);
-      path.lineTo(offset.dx + drawEnd.x, offset.dy + drawEnd.y);
-      canvas.drawPath(path, paint);
-    }
-  }
-}
diff --git a/sky/packages/sky/lib/src/material/circle_avatar.dart b/sky/packages/sky/lib/src/material/circle_avatar.dart
deleted file mode 100644
index 7895b87..0000000
--- a/sky/packages/sky/lib/src/material/circle_avatar.dart
+++ /dev/null
@@ -1,47 +0,0 @@
-// Copyright 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:flutter/painting.dart';
-import 'package:flutter/widgets.dart';
-
-import 'constants.dart';
-import 'theme.dart';
-import 'typography.dart';
-
-class CircleAvatar extends StatelessComponent {
-  CircleAvatar({
-    Key key,
-    this.label,
-    this.backgroundColor,
-    this.textTheme
-  }) : super(key: key);
-
-  final String label;
-  final Color backgroundColor;
-  final TextTheme textTheme;
-
-  Widget build(BuildContext context) {
-    Color color = backgroundColor;
-    TextStyle style = textTheme?.title;
-
-    if (color == null || style == null) {
-      ThemeData themeData = Theme.of(context);
-      color ??= themeData.primaryColor;
-      style ??= themeData.primaryTextTheme.title;
-    }
-
-    return new AnimatedContainer(
-      duration: kThemeChangeDuration,
-      decoration: new BoxDecoration(
-        backgroundColor: color,
-        shape: Shape.circle
-      ),
-      width: 40.0,
-      height: 40.0,
-      child: new Center(
-        child: new Text(label, style: style)
-      )
-    );
-  }
-}
diff --git a/sky/packages/sky/lib/src/material/colors.dart b/sky/packages/sky/lib/src/material/colors.dart
deleted file mode 100644
index 01c8d4b9..0000000
--- a/sky/packages/sky/lib/src/material/colors.dart
+++ /dev/null
@@ -1,384 +0,0 @@
-// Copyright 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 'dart:ui' show Color;
-
-/// [Color] constants which represent Material design's
-/// [color palette](http://www.google.com/design/spec/style/color.html).
-class Colors {
-  Colors._();
-
-  static const transparent = const Color(0x00000000);
-
-  static const black   = const Color(0xFF000000);
-  static const black87 = const Color(0xDD000000);
-  static const black54 = const Color(0x8A000000);
-  static const black26 = const Color(0x42000000); // disabled radio buttons and text of disabled flat buttons in light theme (26% black)
-  static const black12 = const Color(0x1F000000); // background of disabled raised buttons in light theme
-  static const white   = const Color(0xFFFFFFFF);
-  static const white70 = const Color(0xB3FFFFFF);
-  static const white30 = const Color(0x4DFFFFFF); // disabled radio buttons and text of disabled flat buttons in dark theme (30% white)
-  static const white12 = const Color(0x1FFFFFFF); // background of disabled raised buttons in dark theme
-
-  static const Map<int, Color> red = const <int, Color>{
-     50: const Color(0xFFFFEBEE),
-    100: const Color(0xFFFFCDD2),
-    200: const Color(0xFFEF9A9A),
-    300: const Color(0xFFE57373),
-    400: const Color(0xFFEF5350),
-    500: const Color(0xFFF44336),
-    600: const Color(0xFFE53935),
-    700: const Color(0xFFD32F2F),
-    800: const Color(0xFFC62828),
-    900: const Color(0xFFB71C1C),
-  };
-
-  static const Map<int, Color> redAccent = const <int, Color>{
-    100: const Color(0xFFFF8A80),
-    200: const Color(0xFFFF5252),
-    400: const Color(0xFFFF1744),
-    700: const Color(0xFFD50000),
-  };
-
-  static const Map<int, Color> pink = const <int, Color>{
-     50: const Color(0xFFFCE4EC),
-    100: const Color(0xFFF8BBD0),
-    200: const Color(0xFFF48FB1),
-    300: const Color(0xFFF06292),
-    400: const Color(0xFFEC407A),
-    500: const Color(0xFFE91E63),
-    600: const Color(0xFFD81B60),
-    700: const Color(0xFFC2185B),
-    800: const Color(0xFFAD1457),
-    900: const Color(0xFF880E4F),
-  };
-
-  static const Map<int, Color> pinkAccent = const <int, Color>{
-    100: const Color(0xFFFF80AB),
-    200: const Color(0xFFFF4081),
-    400: const Color(0xFFF50057),
-    700: const Color(0xFFC51162),
-  };
-
-  static const Map<int, Color> purple = const <int, Color>{
-     50: const Color(0xFFF3E5F5),
-    100: const Color(0xFFE1BEE7),
-    200: const Color(0xFFCE93D8),
-    300: const Color(0xFFBA68C8),
-    400: const Color(0xFFAB47BC),
-    500: const Color(0xFF9C27B0),
-    600: const Color(0xFF8E24AA),
-    700: const Color(0xFF7B1FA2),
-    800: const Color(0xFF6A1B9A),
-    900: const Color(0xFF4A148C),
-  };
-
-  static const Map<int, Color> purpleAccent = const <int, Color>{
-    100: const Color(0xFFEA80FC),
-    200: const Color(0xFFE040FB),
-    400: const Color(0xFFD500F9),
-    700: const Color(0xFFAA00FF),
-  };
-
-  static const Map<int, Color> deepPurple = const <int, Color>{
-     50: const Color(0xFFEDE7F6),
-    100: const Color(0xFFD1C4E9),
-    200: const Color(0xFFB39DDB),
-    300: const Color(0xFF9575CD),
-    400: const Color(0xFF7E57C2),
-    500: const Color(0xFF673AB7),
-    600: const Color(0xFF5E35B1),
-    700: const Color(0xFF512DA8),
-    800: const Color(0xFF4527A0),
-    900: const Color(0xFF311B92),
-  };
-
-  static const Map<int, Color> deepPurpleAccent = const <int, Color>{
-    100: const Color(0xFFB388FF),
-    200: const Color(0xFF7C4DFF),
-    400: const Color(0xFF651FFF),
-    700: const Color(0xFF6200EA),
-  };
-
-  static const Map<int, Color> indigo = const <int, Color>{
-     50: const Color(0xFFE8EAF6),
-    100: const Color(0xFFC5CAE9),
-    200: const Color(0xFF9FA8DA),
-    300: const Color(0xFF7986CB),
-    400: const Color(0xFF5C6BC0),
-    500: const Color(0xFF3F51B5),
-    600: const Color(0xFF3949AB),
-    700: const Color(0xFF303F9F),
-    800: const Color(0xFF283593),
-    900: const Color(0xFF1A237E),
-  };
-
-  static const Map<int, Color> indigoAccent = const <int, Color>{
-    100: const Color(0xFF8C9EFF),
-    200: const Color(0xFF536DFE),
-    400: const Color(0xFF3D5AFE),
-    700: const Color(0xFF304FFE),
-  };
-
-  static const Map<int, Color> blue = const <int, Color>{
-     50: const Color(0xFFE3F2FD),
-    100: const Color(0xFFBBDEFB),
-    200: const Color(0xFF90CAF9),
-    300: const Color(0xFF64B5F6),
-    400: const Color(0xFF42A5F5),
-    500: const Color(0xFF2196F3),
-    600: const Color(0xFF1E88E5),
-    700: const Color(0xFF1976D2),
-    800: const Color(0xFF1565C0),
-    900: const Color(0xFF0D47A1),
-  };
-
-  static const Map<int, Color> blueAccent = const <int, Color>{
-    100: const Color(0xFF82B1FF),
-    200: const Color(0xFF448AFF),
-    400: const Color(0xFF2979FF),
-    700: const Color(0xFF2962FF),
-  };
-
-  static const Map<int, Color> lightBlue = const <int, Color>{
-     50: const Color(0xFFE1F5FE),
-    100: const Color(0xFFB3E5FC),
-    200: const Color(0xFF81D4FA),
-    300: const Color(0xFF4FC3F7),
-    400: const Color(0xFF29B6F6),
-    500: const Color(0xFF03A9F4),
-    600: const Color(0xFF039BE5),
-    700: const Color(0xFF0288D1),
-    800: const Color(0xFF0277BD),
-    900: const Color(0xFF01579B),
-  };
-
-  static const Map<int, Color> lightBlueAccent = const <int, Color>{
-    100: const Color(0xFF80D8FF),
-    200: const Color(0xFF40C4FF),
-    400: const Color(0xFF00B0FF),
-    700: const Color(0xFF0091EA),
-  };
-
-  static const Map<int, Color> cyan = const <int, Color>{
-     50: const Color(0xFFE0F7FA),
-    100: const Color(0xFFB2EBF2),
-    200: const Color(0xFF80DEEA),
-    300: const Color(0xFF4DD0E1),
-    400: const Color(0xFF26C6DA),
-    500: const Color(0xFF00BCD4),
-    600: const Color(0xFF00ACC1),
-    700: const Color(0xFF0097A7),
-    800: const Color(0xFF00838F),
-    900: const Color(0xFF006064),
-  };
-
-  static const Map<int, Color> cyanAccent = const <int, Color>{
-    100: const Color(0xFF84FFFF),
-    200: const Color(0xFF18FFFF),
-    400: const Color(0xFF00E5FF),
-    700: const Color(0xFF00B8D4),
-  };
-
-  static const Map<int, Color> teal = const <int, Color>{
-     50: const Color(0xFFE0F2F1),
-    100: const Color(0xFFB2DFDB),
-    200: const Color(0xFF80CBC4),
-    300: const Color(0xFF4DB6AC),
-    400: const Color(0xFF26A69A),
-    500: const Color(0xFF009688),
-    600: const Color(0xFF00897B),
-    700: const Color(0xFF00796B),
-    800: const Color(0xFF00695C),
-    900: const Color(0xFF004D40),
-  };
-
-  static const Map<int, Color> tealAccent = const <int, Color>{
-    100: const Color(0xFFA7FFEB),
-    200: const Color(0xFF64FFDA),
-    400: const Color(0xFF1DE9B6),
-    700: const Color(0xFF00BFA5),
-  };
-
-  static const Map<int, Color> green = const <int, Color>{
-     50: const Color(0xFFE8F5E9),
-    100: const Color(0xFFC8E6C9),
-    200: const Color(0xFFA5D6A7),
-    300: const Color(0xFF81C784),
-    400: const Color(0xFF66BB6A),
-    500: const Color(0xFF4CAF50),
-    600: const Color(0xFF43A047),
-    700: const Color(0xFF388E3C),
-    800: const Color(0xFF2E7D32),
-    900: const Color(0xFF1B5E20),
-  };
-
-  static const Map<int, Color> greenAccent = const <int, Color>{
-    100: const Color(0xFFB9F6CA),
-    200: const Color(0xFF69F0AE),
-    400: const Color(0xFF00E676),
-    700: const Color(0xFF00C853),
-  };
-
-  static const Map<int, Color> lightGreen = const <int, Color>{
-     50: const Color(0xFFF1F8E9),
-    100: const Color(0xFFDCEDC8),
-    200: const Color(0xFFC5E1A5),
-    300: const Color(0xFFAED581),
-    400: const Color(0xFF9CCC65),
-    500: const Color(0xFF8BC34A),
-    600: const Color(0xFF7CB342),
-    700: const Color(0xFF689F38),
-    800: const Color(0xFF558B2F),
-    900: const Color(0xFF33691E),
-  };
-
-  static const Map<int, Color> lightGreenAccent = const <int, Color>{
-    100: const Color(0xFFCCFF90),
-    200: const Color(0xFFB2FF59),
-    400: const Color(0xFF76FF03),
-    700: const Color(0xFF64DD17),
-  };
-
-  static const Map<int, Color> lime = const <int, Color>{
-     50: const Color(0xFFF9FBE7),
-    100: const Color(0xFFF0F4C3),
-    200: const Color(0xFFE6EE9C),
-    300: const Color(0xFFDCE775),
-    400: const Color(0xFFD4E157),
-    500: const Color(0xFFCDDC39),
-    600: const Color(0xFFC0CA33),
-    700: const Color(0xFFAFB42B),
-    800: const Color(0xFF9E9D24),
-    900: const Color(0xFF827717),
-  };
-
-  static const Map<int, Color> limeAccent = const <int, Color>{
-    100: const Color(0xFFF4FF81),
-    200: const Color(0xFFEEFF41),
-    400: const Color(0xFFC6FF00),
-    700: const Color(0xFFAEEA00),
-  };
-
-  static const Map<int, Color> yellow = const <int, Color>{
-     50: const Color(0xFFFFFDE7),
-    100: const Color(0xFFFFF9C4),
-    200: const Color(0xFFFFF59D),
-    300: const Color(0xFFFFF176),
-    400: const Color(0xFFFFEE58),
-    500: const Color(0xFFFFEB3B),
-    600: const Color(0xFFFDD835),
-    700: const Color(0xFFFBC02D),
-    800: const Color(0xFFF9A825),
-    900: const Color(0xFFF57F17),
-  };
-
-  static const Map<int, Color> yellowAccent = const <int, Color>{
-    100: const Color(0xFFFFFF8D),
-    200: const Color(0xFFFFFF00),
-    400: const Color(0xFFFFEA00),
-    700: const Color(0xFFFFD600),
-  };
-
-  static const Map<int, Color> amber = const <int, Color>{
-     50: const Color(0xFFFFF8E1),
-    100: const Color(0xFFFFECB3),
-    200: const Color(0xFFFFE082),
-    300: const Color(0xFFFFD54F),
-    400: const Color(0xFFFFCA28),
-    500: const Color(0xFFFFC107),
-    600: const Color(0xFFFFB300),
-    700: const Color(0xFFFFA000),
-    800: const Color(0xFFFF8F00),
-    900: const Color(0xFFFF6F00),
-  };
-
-  static const Map<int, Color> amberAccent = const <int, Color>{
-    100: const Color(0xFFFFE57F),
-    200: const Color(0xFFFFD740),
-    400: const Color(0xFFFFC400),
-    700: const Color(0xFFFFAB00),
-  };
-
-  static const Map<int, Color> orange = const <int, Color>{
-     50: const Color(0xFFFFF3E0),
-    100: const Color(0xFFFFE0B2),
-    200: const Color(0xFFFFCC80),
-    300: const Color(0xFFFFB74D),
-    400: const Color(0xFFFFA726),
-    500: const Color(0xFFFF9800),
-    600: const Color(0xFFFB8C00),
-    700: const Color(0xFFF57C00),
-    800: const Color(0xFFEF6C00),
-    900: const Color(0xFFE65100),
-  };
-
-  static const Map<int, Color> orangeAccent = const <int, Color>{
-    100: const Color(0xFFFFD180),
-    200: const Color(0xFFFFAB40),
-    400: const Color(0xFFFF9100),
-    700: const Color(0xFFFF6D00),
-  };
-
-  static const Map<int, Color> deepOrange = const <int, Color>{
-     50: const Color(0xFFFBE9E7),
-    100: const Color(0xFFFFCCBC),
-    200: const Color(0xFFFFAB91),
-    300: const Color(0xFFFF8A65),
-    400: const Color(0xFFFF7043),
-    500: const Color(0xFFFF5722),
-    600: const Color(0xFFF4511E),
-    700: const Color(0xFFE64A19),
-    800: const Color(0xFFD84315),
-    900: const Color(0xFFBF360C),
-  };
-
-  static const Map<int, Color> deepOrangeAccent = const <int, Color>{
-    100: const Color(0xFFFF9E80),
-    200: const Color(0xFFFF6E40),
-    400: const Color(0xFFFF3D00),
-    700: const Color(0xFFDD2C00),
-  };
-
-  static const Map<int, Color> brown = const <int, Color>{
-     50: const Color(0xFFEFEBE9),
-    100: const Color(0xFFD7CCC8),
-    200: const Color(0xFFBCAAA4),
-    300: const Color(0xFFA1887F),
-    400: const Color(0xFF8D6E63),
-    500: const Color(0xFF795548),
-    600: const Color(0xFF6D4C41),
-    700: const Color(0xFF5D4037),
-    800: const Color(0xFF4E342E),
-    900: const Color(0xFF3E2723),
-  };
-
-  static const Map<int, Color> grey = const <int, Color>{
-     50: const Color(0xFFFAFAFA),
-    100: const Color(0xFFF5F5F5),
-    200: const Color(0xFFEEEEEE),
-    300: const Color(0xFFE0E0E0),
-    350: const Color(0xFFD6D6D6), // only for raised button while pressed in Light theme
-    400: const Color(0xFFBDBDBD),
-    500: const Color(0xFF9E9E9E),
-    600: const Color(0xFF757575),
-    700: const Color(0xFF616161),
-    800: const Color(0xFF424242),
-    850: const Color(0xFF303030), // only for background color in Dark theme
-    900: const Color(0xFF212121),
-  };
-
-  static const Map<int, Color> blueGrey = const <int, Color>{
-     50: const Color(0xFFECEFF1),
-    100: const Color(0xFFCFD8DC),
-    200: const Color(0xFFB0BEC5),
-    300: const Color(0xFF90A4AE),
-    400: const Color(0xFF78909C),
-    500: const Color(0xFF607D8B),
-    600: const Color(0xFF546E7A),
-    700: const Color(0xFF455A64),
-    800: const Color(0xFF37474F),
-    900: const Color(0xFF263238),
-  };
-}
diff --git a/sky/packages/sky/lib/src/material/constants.dart b/sky/packages/sky/lib/src/material/constants.dart
deleted file mode 100644
index a996fc5..0000000
--- a/sky/packages/sky/lib/src/material/constants.dart
+++ /dev/null
@@ -1,35 +0,0 @@
-// Copyright 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.
-
-// Modeled after Android's ViewConfiguration:
-// https://github.com/android/platform_frameworks_base/blob/master/core/java/android/view/ViewConfiguration.java
-
-// TODO(ianh): Figure out actual specced height for status bar
-const double kStatusBarHeight = 50.0;
-
-// TODO(eseidel) Toolbar needs to change size based on orientation:
-// http://www.google.com/design/spec/layout/structure.html#structure-app-bar
-// Mobile Landscape: 48dp
-// Mobile Portrait: 56dp
-// Tablet/Desktop: 64dp
-const double kToolBarHeight = 56.0;
-const double kExtendedToolBarHeight = 128.0;
-const double kSnackBarHeight = 52.0;
-
-// https://www.google.com/design/spec/layout/metrics-keylines.html#metrics-keylines-keylines-spacing
-const double kListTitleHeight = 72.0;
-const double kListSubtitleHeight = 48.0;
-
-const double kOneLineListItemHeight = 48.0;
-const double kOneLineListItemWithAvatarHeight = 56.0;
-const double kTwoLineListItemHeight = 72.0;
-const double kThreeLineListItemHeight = 88.0;
-
-const double kMaterialDrawerHeight = 140.0;
-const double kScrollbarSize = 10.0;
-const Duration kScrollbarFadeDuration = const Duration(milliseconds: 250);
-const Duration kScrollbarFadeDelay = const Duration(milliseconds: 300);
-const double kFadingEdgeLength = 12.0;
-const double kPressedStateDuration = 64.0; // units?
-const Duration kThemeChangeDuration = const Duration(milliseconds: 200);
diff --git a/sky/packages/sky/lib/src/material/date_picker.dart b/sky/packages/sky/lib/src/material/date_picker.dart
deleted file mode 100644
index abea0ba..0000000
--- a/sky/packages/sky/lib/src/material/date_picker.dart
+++ /dev/null
@@ -1,393 +0,0 @@
-// Copyright 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 'dart:async';
-
-import 'package:flutter/services.dart';
-import 'package:flutter/widgets.dart';
-import 'package:intl/date_symbols.dart';
-import 'package:intl/intl.dart';
-
-import 'colors.dart';
-import 'ink_well.dart';
-import 'theme.dart';
-import 'typography.dart';
-
-enum DatePickerMode { day, year }
-
-typedef void DatePickerModeChanged(DatePickerMode value);
-
-class DatePicker extends StatefulComponent {
-  DatePicker({
-    this.selectedDate,
-    this.onChanged,
-    this.firstDate,
-    this.lastDate
-  }) {
-    assert(selectedDate != null);
-    assert(firstDate != null);
-    assert(lastDate != null);
-  }
-
-  final DateTime selectedDate;
-  final ValueChanged<DateTime> onChanged;
-  final DateTime firstDate;
-  final DateTime lastDate;
-
-  _DatePickerState createState() => new _DatePickerState();
-}
-
-class _DatePickerState extends State<DatePicker> {
-  DatePickerMode _mode = DatePickerMode.day;
-
-  void _handleModeChanged(DatePickerMode mode) {
-    userFeedback.performHapticFeedback(HapticFeedbackType.VIRTUAL_KEY);
-    setState(() {
-      _mode = mode;
-    });
-  }
-
-  void _handleYearChanged(DateTime dateTime) {
-    userFeedback.performHapticFeedback(HapticFeedbackType.VIRTUAL_KEY);
-    setState(() {
-      _mode = DatePickerMode.day;
-    });
-    if (config.onChanged != null)
-      config.onChanged(dateTime);
-  }
-
-  void _handleDayChanged(DateTime dateTime) {
-    userFeedback.performHapticFeedback(HapticFeedbackType.VIRTUAL_KEY);
-    if (config.onChanged != null)
-      config.onChanged(dateTime);
-  }
-
-  static const double _calendarHeight = 210.0;
-
-  Widget build(BuildContext context) {
-    Widget header = new _DatePickerHeader(
-      selectedDate: config.selectedDate,
-      mode: _mode,
-      onModeChanged: _handleModeChanged
-    );
-    Widget picker;
-    switch (_mode) {
-      case DatePickerMode.day:
-        picker = new MonthPicker(
-          selectedDate: config.selectedDate,
-          onChanged: _handleDayChanged,
-          firstDate: config.firstDate,
-          lastDate: config.lastDate,
-          itemExtent: _calendarHeight
-        );
-        break;
-      case DatePickerMode.year:
-        picker = new YearPicker(
-          selectedDate: config.selectedDate,
-          onChanged: _handleYearChanged,
-          firstDate: config.firstDate,
-          lastDate: config.lastDate
-        );
-        break;
-    }
-    return new Column(<Widget>[
-      header,
-      new Container(
-        height: _calendarHeight,
-        child: picker
-      )
-    ], alignItems: FlexAlignItems.stretch);
-  }
-
-}
-
-// Shows the selected date in large font and toggles between year and day mode
-class _DatePickerHeader extends StatelessComponent {
-  _DatePickerHeader({ this.selectedDate, this.mode, this.onModeChanged }) {
-    assert(selectedDate != null);
-    assert(mode != null);
-  }
-
-  DateTime selectedDate;
-  DatePickerMode mode;
-  DatePickerModeChanged onModeChanged;
-
-  void _handleChangeMode(DatePickerMode value) {
-    if (value != mode)
-      onModeChanged(value);
-  }
-
-  Widget build(BuildContext context) {
-    ThemeData theme = Theme.of(context);
-    TextTheme headerTheme = theme.primaryTextTheme;
-    Color dayColor;
-    Color yearColor;
-    switch(theme.primaryColorBrightness) {
-      case ThemeBrightness.light:
-        dayColor = mode == DatePickerMode.day ? Colors.black87 : Colors.black54;
-        yearColor = mode == DatePickerMode.year ? Colors.black87 : Colors.black54;
-        break;
-      case ThemeBrightness.dark:
-        dayColor = mode == DatePickerMode.day ? Colors.white : Colors.white70;
-        yearColor = mode == DatePickerMode.year ? Colors.white : Colors.white70;
-        break;
-    }
-    TextStyle dayStyle = headerTheme.display3.copyWith(color: dayColor, height: 1.0, fontSize: 100.0);
-    TextStyle monthStyle = headerTheme.headline.copyWith(color: dayColor, height: 1.0);
-    TextStyle yearStyle = headerTheme.headline.copyWith(color: yearColor, height: 1.0);
-
-    return new Container(
-      padding: new EdgeDims.all(10.0),
-      decoration: new BoxDecoration(backgroundColor: theme.primaryColor),
-      child: new Column(<Widget>[
-        new GestureDetector(
-          onTap: () => _handleChangeMode(DatePickerMode.day),
-          child: new Text(new DateFormat("MMM").format(selectedDate).toUpperCase(), style: monthStyle)
-        ),
-        new GestureDetector(
-          onTap: () => _handleChangeMode(DatePickerMode.day),
-          child: new Text(new DateFormat("d").format(selectedDate), style: dayStyle)
-        ),
-        new GestureDetector(
-          onTap: () => _handleChangeMode(DatePickerMode.year),
-          child: new Text(new DateFormat("yyyy").format(selectedDate), style: yearStyle)
-        )
-      ])
-    );
-  }
-}
-
-// Fixed height component shows a single month and allows choosing a day
-class DayPicker extends StatelessComponent {
-  DayPicker({
-    this.selectedDate,
-    this.currentDate,
-    this.onChanged,
-    this.displayedMonth
-  }) {
-    assert(selectedDate != null);
-    assert(currentDate != null);
-    assert(onChanged != null);
-    assert(displayedMonth != null);
-  }
-
-  final DateTime selectedDate;
-  final DateTime currentDate;
-  final ValueChanged<DateTime> onChanged;
-  final DateTime displayedMonth;
-
-  Widget build(BuildContext context) {
-    ThemeData theme = Theme.of(context);
-    TextStyle headerStyle = theme.text.caption.copyWith(fontWeight: FontWeight.w700);
-    TextStyle monthStyle = headerStyle.copyWith(fontSize: 14.0, height: 24.0 / 14.0);
-    TextStyle dayStyle = headerStyle.copyWith(fontWeight: FontWeight.w500);
-    DateFormat dateFormat = new DateFormat();
-    DateSymbols symbols = dateFormat.dateSymbols;
-
-    List<Text> headers = <Text>[];
-    for (String weekDay in symbols.NARROWWEEKDAYS) {
-      headers.add(new Text(weekDay, style: headerStyle));
-    }
-    List<Widget> rows = <Widget>[
-      new Text(new DateFormat("MMMM y").format(displayedMonth), style: monthStyle),
-      new Flex(
-        headers,
-        justifyContent: FlexJustifyContent.spaceAround
-      )
-    ];
-    int year = displayedMonth.year;
-    int month = displayedMonth.month;
-    // Dart's Date time constructor is very forgiving and will understand
-    // month 13 as January of the next year. :)
-    int daysInMonth = new DateTime(year, month + 1).difference(new DateTime(year, month)).inDays;
-    int firstDay =  new DateTime(year, month).day;
-    int weeksShown = 6;
-    List<int> days = <int>[
-      DateTime.SUNDAY,
-      DateTime.MONDAY,
-      DateTime.TUESDAY,
-      DateTime.WEDNESDAY,
-      DateTime.THURSDAY,
-      DateTime.FRIDAY,
-      DateTime.SATURDAY
-    ];
-    int daySlots = weeksShown * days.length;
-    List<Widget> labels = <Widget>[];
-    for (int i = 0; i < daySlots; i++) {
-      // This assumes a start day of SUNDAY, but could be changed.
-      int day = i - firstDay + 1;
-      Widget item;
-      if (day < 1 || day > daysInMonth) {
-        item = new Text("");
-      } else {
-        // Put a light circle around the selected day
-        BoxDecoration decoration = null;
-        if (selectedDate.year == year &&
-            selectedDate.month == month &&
-            selectedDate.day == day)
-          decoration = new BoxDecoration(
-            backgroundColor: theme.primarySwatch[100],
-            shape: Shape.circle
-          );
-
-        // Use a different font color for the current day
-        TextStyle itemStyle = dayStyle;
-        if (currentDate.year == year &&
-            currentDate.month == month &&
-            currentDate.day == day)
-          itemStyle = itemStyle.copyWith(color: theme.primaryColor);
-
-        item = new GestureDetector(
-          onTap: () {
-            DateTime result = new DateTime(year, month, day);
-            onChanged(result);
-          },
-          child: new Container(
-            height: 30.0,
-            decoration: decoration,
-            child: new Center(
-              child: new Text(day.toString(), style: itemStyle)
-            )
-          )
-        );
-      }
-      labels.add(new Flexible(child: item));
-    }
-    for (int w = 0; w < weeksShown; w++) {
-      int startIndex = w * days.length;
-      rows.add(new Row(
-        labels.sublist(startIndex, startIndex + days.length)
-      ));
-    }
-
-    return new Column(rows);
-  }
-}
-
-// Scrollable list of DayPickers to allow choosing a month
-class MonthPicker extends ScrollableWidgetList {
-  MonthPicker({
-    this.selectedDate,
-    this.onChanged,
-    this.firstDate,
-    this.lastDate,
-    double itemExtent
-  }) : super(itemExtent: itemExtent) {
-    assert(selectedDate != null);
-    assert(onChanged != null);
-    assert(lastDate.isAfter(firstDate));
-  }
-
-  final DateTime selectedDate;
-  final ValueChanged<DateTime> onChanged;
-  final DateTime firstDate;
-  final DateTime lastDate;
-
-  _MonthPickerState createState() => new _MonthPickerState();
-}
-
-class _MonthPickerState extends ScrollableWidgetListState<MonthPicker> {
-  void initState() {
-    super.initState();
-    _updateCurrentDate();
-  }
-
-  DateTime _currentDate;
-  Timer _timer;
-
-  void _updateCurrentDate() {
-    _currentDate = new DateTime.now();
-    DateTime tomorrow = new DateTime(_currentDate.year, _currentDate.month, _currentDate.day + 1);
-    Duration timeUntilTomorrow = tomorrow.difference(_currentDate);
-    timeUntilTomorrow += const Duration(seconds: 1);  // so we don't miss it by rounding
-    if (_timer != null)
-      _timer.cancel();
-    _timer = new Timer(timeUntilTomorrow, () {
-      setState(() {
-        _updateCurrentDate();
-      });
-    });
-  }
-
-  int get itemCount => (config.lastDate.year - config.firstDate.year) * 12 + config.lastDate.month - config.firstDate.month + 1;
-
-  List<Widget> buildItems(BuildContext context, int start, int count) {
-    List<Widget> result = new List<Widget>();
-    DateTime startDate = new DateTime(config.firstDate.year + start ~/ 12, config.firstDate.month + start % 12);
-    for (int i = 0; i < count; ++i) {
-      DateTime displayedMonth = new DateTime(startDate.year + i ~/ 12, startDate.month + i % 12);
-      Widget item = new Container(
-        height: config.itemExtent,
-        key: new ObjectKey(displayedMonth),
-        child: new DayPicker(
-          selectedDate: config.selectedDate,
-          currentDate: _currentDate,
-          onChanged: config.onChanged,
-          displayedMonth: displayedMonth
-        )
-      );
-      result.add(item);
-    }
-    return result;
-  }
-
-  void dispose() {
-    if (_timer != null)
-      _timer.cancel();
-    super.dispose();
-  }
-}
-
-// Scrollable list of years to allow picking a year
-class YearPicker extends ScrollableWidgetList {
-  YearPicker({
-    this.selectedDate,
-    this.onChanged,
-    this.firstDate,
-    this.lastDate
-  }) : super(itemExtent: 50.0) {
-    assert(selectedDate != null);
-    assert(onChanged != null);
-    assert(lastDate.isAfter(firstDate));
-  }
-
-  final DateTime selectedDate;
-  final ValueChanged<DateTime> onChanged;
-  final DateTime firstDate;
-  final DateTime lastDate;
-
-  _YearPickerState createState() => new _YearPickerState();
-}
-
-class _YearPickerState extends ScrollableWidgetListState<YearPicker> {
-  int get itemCount => config.lastDate.year - config.firstDate.year + 1;
-
-  List<Widget> buildItems(BuildContext context, int start, int count) {
-    TextStyle style = Theme.of(context).text.body1.copyWith(color: Colors.black54);
-    List<Widget> items = new List<Widget>();
-    for (int i = start; i < start + count; i++) {
-      int year = config.firstDate.year + i;
-      String label = year.toString();
-      Widget item = new InkWell(
-        key: new Key(label),
-        onTap: () {
-          DateTime result = new DateTime(year, config.selectedDate.month, config.selectedDate.day);
-          config.onChanged(result);
-        },
-        child: new Container(
-          height: config.itemExtent,
-          decoration: year == config.selectedDate.year ? new BoxDecoration(
-            backgroundColor: Theme.of(context).primarySwatch[100],
-            shape: Shape.circle
-          ) : null,
-          child: new Center(
-            child: new Text(label, style: style)
-          )
-        )
-      );
-      items.add(item);
-    }
-    return items;
-  }
-}
diff --git a/sky/packages/sky/lib/src/material/dialog.dart b/sky/packages/sky/lib/src/material/dialog.dart
deleted file mode 100644
index 744533f..0000000
--- a/sky/packages/sky/lib/src/material/dialog.dart
+++ /dev/null
@@ -1,146 +0,0 @@
-// Copyright 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 'dart:async';
-
-import 'package:flutter/animation.dart';
-import 'package:flutter/widgets.dart';
-
-import 'colors.dart';
-import 'material_button.dart';
-import 'material.dart';
-import 'theme.dart';
-
-typedef Widget DialogBuilder(NavigatorState navigator);
-
-/// A material design dialog
-///
-/// <https://www.google.com/design/spec/components/dialogs.html>
-class Dialog extends StatelessComponent {
-  Dialog({
-    Key key,
-    this.title,
-    this.titlePadding,
-    this.content,
-    this.contentPadding,
-    this.actions
-  }) : super(key: key);
-
-  /// The (optional) title of the dialog is displayed in a large font at the top
-  /// of the dialog.
-  final Widget title;
-
-  // Padding around the title; uses material design default if none is supplied
-  // If there is no title, no padding will be provided
-  final EdgeDims titlePadding;
-
-  /// The (optional) content of the dialog is displayed in the center of the
-  /// dialog in a lighter font.
-  final Widget content;
-
-  // Padding around the content; uses material design default if none is supplied
-  final EdgeDims contentPadding;
-
-  /// The (optional) set of actions that are displayed at the bottom of the
-  /// dialog.
-  final List<Widget> actions;
-
-  Color _getColor(BuildContext context) {
-    switch (Theme.of(context).brightness) {
-      case ThemeBrightness.light:
-        return Colors.white;
-      case ThemeBrightness.dark:
-        return Colors.grey[800];
-    }
-  }
-
-  Widget build(BuildContext context) {
-
-    List<Widget> dialogBody = new List<Widget>();
-
-    if (title != null) {
-      EdgeDims padding = titlePadding;
-      if (padding == null)
-        padding = new EdgeDims.TRBL(24.0, 24.0, content == null ? 20.0 : 0.0, 24.0);
-      dialogBody.add(new Padding(
-        padding: padding,
-        child: new DefaultTextStyle(
-          style: Theme.of(context).text.title,
-          child: title
-        )
-      ));
-    }
-
-    if (content != null) {
-      EdgeDims padding = contentPadding;
-      if (padding == null)
-        padding = const EdgeDims.TRBL(20.0, 24.0, 24.0, 24.0);
-      dialogBody.add(new Padding(
-        padding: padding,
-        child: new DefaultTextStyle(
-          style: Theme.of(context).text.subhead,
-          child: content
-        )
-      ));
-    }
-
-    if (actions != null) {
-      dialogBody.add(new ButtonTheme(
-        color: ButtonColor.accent,
-        child: new Container(
-          child: new Row(actions,
-            justifyContent: FlexJustifyContent.end
-          )
-        )
-      ));
-    }
-
-    return new Center(
-      child: new Container(
-        margin: new EdgeDims.symmetric(horizontal: 40.0, vertical: 24.0),
-        child: new ConstrainedBox(
-          constraints: new BoxConstraints(minWidth: 280.0),
-          child: new Material(
-            level: 4,
-            color: _getColor(context),
-            type: MaterialType.card,
-            child: new IntrinsicWidth(
-              child: new Block(dialogBody)
-            )
-          )
-        )
-      )
-    );
-  }
-}
-
-class _DialogRoute extends ModalRoute {
-  _DialogRoute({ this.completer, this.child });
-
-  final Completer completer;
-  final Widget child;
-
-  bool get opaque => false;
-  Duration get transitionDuration => const Duration(milliseconds: 150);
-  Color get barrierColor => Colors.black54;
-
-  Widget buildModalWidget(BuildContext context) {
-    return new FadeTransition(
-      performance: performance,
-      opacity: new AnimatedValue<double>(0.0, end: 1.0, curve: Curves.easeOut),
-      child: child
-    );
-  }
-
-  void didPop([dynamic result]) {
-    completer.complete(result);
-    super.didPop(result);
-  }
-}
-
-Future showDialog({ BuildContext context, Widget child }) {
-  Completer completer = new Completer();
-  Navigator.of(context).push(new _DialogRoute(completer: completer, child: child));
-  return completer.future;
-}
diff --git a/sky/packages/sky/lib/src/material/drawer.dart b/sky/packages/sky/lib/src/material/drawer.dart
deleted file mode 100644
index 29d1aa5..0000000
--- a/sky/packages/sky/lib/src/material/drawer.dart
+++ /dev/null
@@ -1,217 +0,0 @@
-// Copyright 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:flutter/animation.dart';
-import 'package:flutter/widgets.dart';
-
-import 'colors.dart';
-import 'material.dart';
-
-// TODO(eseidel): Draw width should vary based on device size:
-// http://www.google.com/design/spec/layout/structure.html#structure-side-nav
-
-// Mobile:
-// Width = Screen width − 56 dp
-// Maximum width: 320dp
-// Maximum width applies only when using a left nav. When using a right nav,
-// the panel can cover the full width of the screen.
-
-// Desktop/Tablet:
-// Maximum width for a left nav is 400dp.
-// The right nav can vary depending on content.
-
-const double _kWidth = 304.0;
-const double _kMinFlingVelocity = 365.0;
-const Duration _kBaseSettleDuration = const Duration(milliseconds: 246);
-
-class _Drawer extends StatelessComponent {
-  _Drawer({ Key key, this.route }) : super(key: key);
-
-  final _DrawerRoute route;
-
-  Widget build(BuildContext context) {
-    return new Focus(
-      key: new GlobalObjectKey(route),
-      child: new ConstrainedBox(
-        constraints: const BoxConstraints.expand(width: _kWidth),
-        child: new Material(
-          level: route.level,
-          child: route.child
-        )
-      )
-    );
-  }
-}
-
-enum _DrawerState {
-  showing,
-  popped,
-  closed,
-}
-
-class _DrawerRoute extends OverlayRoute {
-  _DrawerRoute({ this.child, this.level });
-
-  final Widget child;
-  final int level;
-
-  List<WidgetBuilder> get builders => <WidgetBuilder>[ _build ];
-
-  final GlobalKey<_DrawerControllerState> _drawerKey = new GlobalKey<_DrawerControllerState>();
-  _DrawerState _state = _DrawerState.showing;
-
-  Widget _build(BuildContext context) {
-    return new _DrawerController(
-      key: _drawerKey,
-      settleDuration: _kBaseSettleDuration,
-      onClosed: () {
-        _DrawerState previousState = _state;
-        _state = _DrawerState.closed;
-        switch (previousState) {
-          case _DrawerState.showing:
-            Navigator.of(context).pop();
-            break;
-          case _DrawerState.popped:
-            super.didPop(null);
-            break;
-          case _DrawerState.closed:
-            assert(false);
-            break;
-        }
-      },
-      child: new _Drawer(route: this)
-    );
-  }
-
-  void didPop(dynamic result) {
-    switch (_state) {
-      case _DrawerState.showing:
-        _drawerKey.currentState?._close();
-        _state = _DrawerState.popped;
-        break;
-      case _DrawerState.popped:
-        assert(false);
-        break;
-      case _DrawerState.closed:
-        super.didPop(null);
-        break;
-    }
-  }
-}
-
-class _DrawerController extends StatefulComponent {
-  _DrawerController({
-    Key key,
-    this.settleDuration,
-    this.onClosed,
-    this.child
-  }) : super(key: key);
-
-  final Duration settleDuration;
-  final Widget child;
-  final VoidCallback onClosed;
-
-  _DrawerControllerState createState() => new _DrawerControllerState();
-}
-
-class _DrawerControllerState extends State<_DrawerController> {
-  void initState() {
-    super.initState();
-    _performance = new Performance(duration: config.settleDuration)
-      ..addListener(_performanceChanged)
-      ..addStatusListener(_performanceStatusChanged)
-      ..play();
-  }
-
-  void dispose() {
-    _performance
-      ..removeListener(_performanceChanged)
-      ..removeStatusListener(_performanceStatusChanged)
-      ..stop();
-    super.dispose();
-  }
-
-  void _performanceChanged() {
-    setState(() {
-      // The performance's state is our build state, and it changed already.
-    });
-  }
-
-  void _performanceStatusChanged(PerformanceStatus status) {
-    if (status == PerformanceStatus.dismissed && config.onClosed != null)
-      config.onClosed();
-  }
-
-  Performance _performance;
-  double _width;
-
-  final AnimatedColorValue _color = new AnimatedColorValue(Colors.transparent, end: Colors.black54);
-
-  void _handleSizeChanged(Size newSize) {
-    setState(() {
-      _width = newSize.width;
-    });
-  }
-
-  void _handlePointerDown(_) {
-    _performance.stop();
-  }
-
-  void _move(double delta) {
-    _performance.progress += delta / _width;
-  }
-
-  void _settle(Offset velocity) {
-    if (velocity.dx.abs() >= _kMinFlingVelocity) {
-      _performance.fling(velocity: velocity.dx / _width);
-    } else if (_performance.progress < 0.5) {
-      _close();
-    } else {
-      _performance.fling(velocity: 1.0);
-    }
-  }
-
-  void _close() {
-    _performance.fling(velocity: -1.0);
-  }
-
-  Widget build(BuildContext context) {
-    _performance.updateVariable(_color);
-    return new GestureDetector(
-      onHorizontalDragUpdate: _move,
-      onHorizontalDragEnd: _settle,
-      child: new Stack(<Widget>[
-        new GestureDetector(
-          onTap: _close,
-          child: new DecoratedBox(
-            decoration: new BoxDecoration(
-              backgroundColor: _color.value
-            ),
-            child: new Container()
-          )
-        ),
-        new Positioned(
-          top: 0.0,
-          left: 0.0,
-          bottom: 0.0,
-          child: new Listener(
-            onPointerDown: _handlePointerDown,
-            child: new Align(
-              alignment: const FractionalOffset(1.0, 0.5),
-              widthFactor: _performance.progress,
-              child: new SizeObserver(
-                onSizeChanged: _handleSizeChanged,
-                child: config.child
-              )
-            )
-          )
-        )
-      ])
-    );
-  }
-}
-
-void showDrawer({ BuildContext context, Widget child, int level: 3 }) {
-  Navigator.of(context).push(new _DrawerRoute(child: child, level: level));
-}
diff --git a/sky/packages/sky/lib/src/material/drawer_divider.dart b/sky/packages/sky/lib/src/material/drawer_divider.dart
deleted file mode 100644
index 4816892..0000000
--- a/sky/packages/sky/lib/src/material/drawer_divider.dart
+++ /dev/null
@@ -1,25 +0,0 @@
-// Copyright 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:flutter/widgets.dart';
-
-import 'theme.dart';
-
-class DrawerDivider extends StatelessComponent {
-  const DrawerDivider({ Key key }) : super(key: key);
-
-  Widget build(BuildContext context) {
-    return new Container(
-      height: 0.0,
-      decoration: new BoxDecoration(
-        border: new Border(
-          bottom: new BorderSide(
-            color: Theme.of(context).dividerColor
-          )
-        )
-      ),
-      margin: const EdgeDims.symmetric(vertical: 8.0)
-    );
-  }
-}
diff --git a/sky/packages/sky/lib/src/material/drawer_header.dart b/sky/packages/sky/lib/src/material/drawer_header.dart
deleted file mode 100644
index 650d0f2..0000000
--- a/sky/packages/sky/lib/src/material/drawer_header.dart
+++ /dev/null
@@ -1,44 +0,0 @@
-// Copyright 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:flutter/widgets.dart';
-
-import 'constants.dart';
-import 'theme.dart';
-
-// TODO(jackson): This class should usually render the user's
-// preferred banner image rather than a solid background
-
-class DrawerHeader extends StatelessComponent {
-  const DrawerHeader({ Key key, this.child }) : super(key: key);
-
-  final Widget child;
-
-  Widget build(BuildContext context) {
-    return new Container(
-      height: kStatusBarHeight + kMaterialDrawerHeight,
-      decoration: new BoxDecoration(
-        backgroundColor: Theme.of(context).cardColor,
-        border: const Border(
-          bottom: const BorderSide(
-            color: const Color(0xFFD1D9E1),
-            width: 1.0
-          )
-        )
-      ),
-      padding: const EdgeDims.only(bottom: 7.0),
-      margin: const EdgeDims.only(bottom: 8.0),
-      child: new Column(<Widget>[
-        new Flexible(child: new Container()),
-        new Container(
-          padding: const EdgeDims.symmetric(horizontal: 16.0),
-          child: new DefaultTextStyle(
-            style: Theme.of(context).text.body2,
-            child: child
-          )
-        )]
-      )
-    );
-  }
-}
diff --git a/sky/packages/sky/lib/src/material/drawer_item.dart b/sky/packages/sky/lib/src/material/drawer_item.dart
deleted file mode 100644
index 6fdeaa9..0000000
--- a/sky/packages/sky/lib/src/material/drawer_item.dart
+++ /dev/null
@@ -1,80 +0,0 @@
-// Copyright 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:flutter/widgets.dart';
-
-import 'colors.dart';
-import 'icon.dart';
-import 'ink_well.dart';
-import 'theme.dart';
-
-class DrawerItem extends StatelessComponent {
-  const DrawerItem({ Key key, this.icon, this.child, this.onPressed, this.selected: false })
-    : super(key: key);
-
-  final String icon;
-  final Widget child;
-  final VoidCallback onPressed;
-  final bool selected;
-
-  TextStyle _getTextStyle(ThemeData themeData) {
-    TextStyle result = themeData.text.body2;
-    if (selected)
-      result = result.copyWith(color: themeData.primaryColor);
-    return result;
-  }
-
-  Color _getBackgroundColor(ThemeData themeData, { bool highlight }) {
-    if (highlight)
-      return themeData.highlightColor;
-    if (selected)
-      return themeData.selectedColor;
-    return Colors.transparent;
-  }
-
-  ColorFilter _getColorFilter(ThemeData themeData) {
-    if (selected)
-      return new ColorFilter.mode(themeData.primaryColor, TransferMode.srcATop);
-    return new ColorFilter.mode(const Color(0x73000000), TransferMode.dstIn);
-  }
-
-  Widget build(BuildContext context) {
-    ThemeData themeData = Theme.of(context);
-
-    List<Widget> flexChildren = new List<Widget>();
-    if (icon != null) {
-      flexChildren.add(
-        new Padding(
-          padding: const EdgeDims.symmetric(horizontal: 16.0),
-          child: new Icon(
-            icon: icon,
-            colorFilter: _getColorFilter(themeData)
-          )
-        )
-      );
-    }
-    flexChildren.add(
-      new Flexible(
-        child: new Padding(
-          padding: const EdgeDims.symmetric(horizontal: 16.0),
-          child: new DefaultTextStyle(
-            style: _getTextStyle(themeData),
-            child: child
-          )
-        )
-      )
-    );
-
-    return new Container(
-      height: 48.0,
-      child: new InkWell(
-        onTap: onPressed,
-        defaultColor: _getBackgroundColor(themeData, highlight: false),
-        highlightColor: _getBackgroundColor(themeData, highlight: true),
-        child: new Row(flexChildren)
-      )
-    );
-  }
-
-}
diff --git a/sky/packages/sky/lib/src/material/dropdown.dart b/sky/packages/sky/lib/src/material/dropdown.dart
deleted file mode 100644
index b11b107..0000000
--- a/sky/packages/sky/lib/src/material/dropdown.dart
+++ /dev/null
@@ -1,243 +0,0 @@
-// Copyright 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 'dart:async';
-import 'dart:ui' as ui;
-
-import 'package:flutter/animation.dart';
-import 'package:flutter/painting.dart';
-import 'package:flutter/rendering.dart';
-import 'package:flutter/widgets.dart';
-
-import 'icon.dart';
-import 'ink_well.dart';
-import 'shadows.dart';
-import 'theme.dart';
-
-const Duration _kMenuDuration = const Duration(milliseconds: 300);
-const double _kMenuItemHeight = 48.0;
-const EdgeDims _kMenuHorizontalPadding = const EdgeDims.only(left: 36.0, right: 36.0);
-const double _kBaselineOffsetFromBottom = 20.0;
-const Border _kDropdownUnderline = const Border(bottom: const BorderSide(color: const Color(0xFFBDBDBD), width: 2.0));
-
-class _DropdownMenu extends StatusTransitionComponent {
-  _DropdownMenu({
-    Key key,
-    _MenuRoute route
-  }) : route = route, super(key: key, performance: route.performance);
-
-  final _MenuRoute route;
-
-  Widget build(BuildContext context) {
-    // The menu is shown in three stages (unit timing in brackets):
-    // [0 - 0.25] - Fade in a rect-sized menu container with the selected item.
-    // [0.25 - 0.5] - Grow the otherwise empty menu container from the center
-    //   until it's big enough for as many items as we're going to show.
-    // [0.5 - 1.0] Fade in the remaining visible items from top to bottom.
-    //
-    // When the menu is dismissed we just fade the entire thing out
-    // in the first 0.25.
-
-    final double unit = 0.5 / (route.items.length + 1.5);
-    final List<Widget> children = <Widget>[];
-    for (int itemIndex = 0; itemIndex < route.items.length; ++itemIndex) {
-      AnimatedValue<double> opacity;
-      if (itemIndex == route.selectedIndex) {
-        opacity = new AnimatedValue<double>(0.0, end: 1.0, curve: const Interval(0.0, 0.001), reverseCurve: const Interval(0.75, 1.0));
-      } else {
-        final double start = (0.5 + (itemIndex + 1) * unit).clamp(0.0, 1.0);
-        final double end = (start + 1.5 * unit).clamp(0.0, 1.0);
-        opacity = new AnimatedValue<double>(0.0, end: 1.0, curve: new Interval(start, end), reverseCurve: const Interval(0.75, 1.0));
-      }
-      children.add(new FadeTransition(
-        performance: route.performance,
-        opacity: opacity,
-        child: new InkWell(
-          child: new Container(
-            padding: _kMenuHorizontalPadding,
-            child: route.items[itemIndex]
-          ),
-          onTap: () {
-            Navigator.of(context).pop(route.items[itemIndex].value);
-          }
-        )
-      ));
-    }
-
-    final AnimatedValue<double> menuOpacity = new AnimatedValue<double>(0.0,
-      end: 1.0,
-      curve: new Interval(0.0, 0.25),
-      reverseCurve: new Interval(0.75, 1.0)
-    );
-
-    final AnimatedValue<double> menuTop = new AnimatedValue<double>(route.rect.top,
-      end: route.rect.top - route.selectedIndex * route.rect.height,
-      curve: new Interval(0.25, 0.5),
-      reverseCurve: const Interval(0.0, 0.001)
-    );
-    final AnimatedValue<double> menuBottom = new AnimatedValue<double>(route.rect.bottom,
-      end: menuTop.end + route.items.length * route.rect.height,
-      curve: new Interval(0.25, 0.5),
-      reverseCurve: const Interval(0.0, 0.001)
-    );
-
-    final BoxPainter menuPainter = new BoxPainter(new BoxDecoration(
-      backgroundColor: Theme.of(context).canvasColor,
-      borderRadius: 2.0,
-      boxShadow: shadows[route.level]
-    ));
-
-    final RenderBox renderBox = Navigator.of(context).context.findRenderObject();
-    final Size navigatorSize = renderBox.size;
-    final RelativeRect menuRect = new RelativeRect.fromSize(route.rect, navigatorSize);
-
-    return new Positioned(
-      top: menuRect.top - (route.selectedIndex * route.rect.height),
-      right: menuRect.right,
-      left: menuRect.left,
-      child: new Focus(
-        key: new GlobalObjectKey(route),
-        child: new FadeTransition(
-          performance: route.performance,
-          opacity: menuOpacity,
-          child: new BuilderTransition(
-            performance: route.performance,
-            variables: <AnimatedValue<double>>[menuTop, menuBottom],
-            builder: (BuildContext context) {
-              RenderBox renderBox = context.findRenderObject();
-              return new CustomPaint(
-                child: new Block(children),
-                onPaint: (ui.Canvas canvas, Size size) {
-                  double top = renderBox.globalToLocal(new Point(0.0, menuTop.value)).y;
-                  double bottom = renderBox.globalToLocal(new Point(0.0, menuBottom.value)).y;
-                  menuPainter.paint(canvas, new Rect.fromLTRB(0.0, top, size.width, bottom));
-                }
-              );
-            }
-          )
-        )
-      )
-    );
-  }
-}
-
-// TODO(abarth): This should use ModalRoute.
-class _MenuRoute extends TransitionRoute {
-  _MenuRoute({
-    this.completer,
-    this.items,
-    this.selectedIndex,
-    this.rect,
-    this.level: 4
-  });
-
-  final Completer completer;
-  final Rect rect;
-  final List<DropdownMenuItem> items;
-  final int level;
-  final int selectedIndex;
-
-  bool get opaque => false;
-  Duration get transitionDuration => _kMenuDuration;
-
-  Widget _buildModalBarrier(BuildContext context) => new ModalBarrier();
-  Widget _buildDropDownMenu(BuildContext context) => new _DropdownMenu(route: this);
-
-  List<WidgetBuilder> get builders => <WidgetBuilder>[ _buildModalBarrier, _buildDropDownMenu ];
-
-  void didPop([dynamic result]) {
-    completer.complete(result);
-    super.didPop(result);
-  }
-}
-
-class DropdownMenuItem<T> extends StatelessComponent {
-  DropdownMenuItem({
-    Key key,
-    this.value,
-    this.child
-  }) : super(key: key);
-
-  final Widget child;
-  final T value;
-
-  Widget build(BuildContext context) {
-    return new Container(
-      height: _kMenuItemHeight,
-      padding: const EdgeDims.only(left: 8.0, right: 8.0, top: 6.0),
-      child: new DefaultTextStyle(
-        style: Theme.of(context).text.subhead,
-        child: new Baseline(
-          baseline: _kMenuItemHeight - _kBaselineOffsetFromBottom,
-          child: child
-        )
-      )
-    );
-  }
-}
-
-class DropdownButton<T> extends StatelessComponent {
-  DropdownButton({
-    Key key,
-    this.items,
-    this.value,
-    this.onChanged,
-    this.level: 4
-  }) : super(key: key);
-
-  final List<DropdownMenuItem<T>> items;
-  final T value;
-  final ValueChanged<T> onChanged;
-  final int level;
-
-  void _showDropdown(BuildContext context, int selectedIndex, GlobalKey indexedStackKey) {
-    final RenderBox renderBox = indexedStackKey.currentContext.findRenderObject();
-    final Rect rect = renderBox.localToGlobal(Point.origin) & renderBox.size;
-    final Completer completer = new Completer();
-    Navigator.of(context).pushEphemeral(new _MenuRoute(
-      completer: completer,
-      items: items,
-      selectedIndex: selectedIndex,
-      rect: _kMenuHorizontalPadding.inflateRect(rect),
-      level: level
-    ));
-    completer.future.then((T newValue) {
-      if (onChanged != null)
-        onChanged(newValue);
-    });
-  }
-
-  Widget build(BuildContext context) {
-    GlobalKey indexedStackKey = new GlobalKey(label: 'DropdownButton.IndexedStack');
-    int selectedIndex = 0;
-    for (int itemIndex = 0; itemIndex < items.length; itemIndex++) {
-      if (items[itemIndex].value == value) {
-        selectedIndex = itemIndex;
-        break;
-      }
-    }
-
-    return new GestureDetector(
-      child: new Container(
-        decoration: new BoxDecoration(border: _kDropdownUnderline),
-        child: new Row(<Widget>[
-          new IndexedStack(items,
-            key: indexedStackKey,
-            index: selectedIndex,
-            alignment: const FractionalOffset(0.5, 0.0)
-          ),
-          new Container(
-            child: new Icon(icon: 'navigation/arrow_drop_down', size: IconSize.s36),
-            padding: const EdgeDims.only(top: 6.0)
-          )
-        ],
-          justifyContent: FlexJustifyContent.collapse
-        )
-      ),
-      onTap: () {
-        _showDropdown(context, selectedIndex, indexedStackKey);
-      }
-    );
-  }
-}
diff --git a/sky/packages/sky/lib/src/material/flat_button.dart b/sky/packages/sky/lib/src/material/flat_button.dart
deleted file mode 100644
index 1d7c92b..0000000
--- a/sky/packages/sky/lib/src/material/flat_button.dart
+++ /dev/null
@@ -1,42 +0,0 @@
-// Copyright 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:flutter/widgets.dart';
-
-import 'colors.dart';
-import 'material_button.dart';
-import 'theme.dart';
-
-class FlatButton extends MaterialButton {
-  FlatButton({
-    Key key,
-    Widget child,
-    VoidCallback onPressed
-  }) : super(key: key,
-             child: child,
-             onPressed: onPressed);
-
-  _FlatButtonState createState() => new _FlatButtonState();
-}
-
-class _FlatButtonState extends MaterialButtonState<FlatButton> {
-
-  int get level => 0;
-
-  Color getColor(BuildContext context, { bool highlight }) {
-    if (!config.enabled || !highlight)
-      return null;
-    switch (Theme.of(context).brightness) {
-      case ThemeBrightness.light:
-        return Colors.grey[400];
-      case ThemeBrightness.dark:
-        return Colors.grey[200];
-    }
-  }
-
-  ThemeBrightness getColorBrightness(BuildContext context) {
-    return Theme.of(context).brightness;
-  }
-
-}
diff --git a/sky/packages/sky/lib/src/material/floating_action_button.dart b/sky/packages/sky/lib/src/material/floating_action_button.dart
deleted file mode 100644
index 2f1a905..0000000
--- a/sky/packages/sky/lib/src/material/floating_action_button.dart
+++ /dev/null
@@ -1,72 +0,0 @@
-// Copyright 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:flutter/widgets.dart';
-
-import 'icon_theme.dart';
-import 'icon_theme_data.dart';
-import 'ink_well.dart';
-import 'material.dart';
-import 'theme.dart';
-
-// TODO(eseidel): This needs to change based on device size?
-// http://www.google.com/design/spec/layout/metrics-keylines.html#metrics-keylines-keylines-spacing
-const double _kSize = 56.0;
-
-class FloatingActionButton extends StatefulComponent {
-  const FloatingActionButton({
-    Key key,
-    this.child,
-    this.backgroundColor,
-    this.onPressed
-  }) : super(key: key);
-
-  final Widget child;
-  final Color backgroundColor;
-  final VoidCallback onPressed;
-
-  _FloatingActionButtonState createState() => new _FloatingActionButtonState();
-}
-
-class _FloatingActionButtonState extends State<FloatingActionButton> {
-  bool _highlight = false;
-
-  void _handleHighlightChanged(bool value) {
-    setState(() {
-      _highlight = value;
-    });
-  }
-
-  Widget build(BuildContext context) {
-    IconThemeColor iconThemeColor = IconThemeColor.white;
-    Color materialColor = config.backgroundColor;
-    if (materialColor == null) {
-      ThemeData themeData = Theme.of(context);
-      materialColor = themeData.accentColor;
-      iconThemeColor = themeData.accentColorBrightness == ThemeBrightness.dark ? IconThemeColor.white : IconThemeColor.black;
-    }
-
-    return new Material(
-      color: materialColor,
-      type: MaterialType.circle,
-      level: _highlight ? 3 : 2,
-      child: new ClipOval(
-        child: new Container(
-          width: _kSize,
-          height: _kSize,
-          child: new InkWell(
-            onTap: config.onPressed,
-            onHighlightChanged: _handleHighlightChanged,
-            child: new Center(
-              child: new IconTheme(
-                data: new IconThemeData(color: iconThemeColor),
-                child: config.child
-              )
-            )
-          )
-        )
-      )
-    );
-  }
-}
diff --git a/sky/packages/sky/lib/src/material/icon.dart b/sky/packages/sky/lib/src/material/icon.dart
deleted file mode 100644
index d3a8aa8..0000000
--- a/sky/packages/sky/lib/src/material/icon.dart
+++ /dev/null
@@ -1,86 +0,0 @@
-// Copyright 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:flutter/widgets.dart';
-
-import 'theme.dart';
-import 'icon_theme.dart';
-import 'icon_theme_data.dart';
-
-enum IconSize {
-  s18,
-  s24,
-  s36,
-  s48,
-}
-
-const Map<IconSize, int> _kIconSize = const <IconSize, int>{
-  IconSize.s18: 18,
-  IconSize.s24: 24,
-  IconSize.s36: 36,
-  IconSize.s48: 48,
-};
-
-class Icon extends StatelessComponent {
-  Icon({
-    Key key,
-    this.size: IconSize.s24,
-    this.icon: '',
-    this.color,
-    this.colorFilter
-  }) : super(key: key) {
-    assert(size != null);
-    assert(icon != null);
-  }
-
-  final IconSize size;
-  final String icon;
-  final IconThemeColor color;
-  final ColorFilter colorFilter;
-
-  String _getColorSuffix(BuildContext context) {
-    IconThemeColor iconThemeColor = color;
-    if (iconThemeColor == null) {
-      IconThemeData iconThemeData = IconTheme.of(context);
-      iconThemeColor = iconThemeData == null ? null : iconThemeData.color;
-    }
-    if (iconThemeColor == null) {
-      ThemeBrightness themeBrightness = Theme.of(context).brightness;
-      iconThemeColor = themeBrightness == ThemeBrightness.dark ? IconThemeColor.white : IconThemeColor.black;
-    }
-    switch(iconThemeColor) {
-      case IconThemeColor.white:
-        return "white";
-      case IconThemeColor.black:
-        return "black";
-    }
-  }
-
-  Widget build(BuildContext context) {
-    String category = '';
-    String subtype = '';
-    List<String> parts = icon.split('/');
-    if (parts.length == 2) {
-      category = parts[0];
-      subtype = parts[1];
-    }
-    // TODO(eseidel): This clearly isn't correct.  Not sure what would be.
-    // Should we use the ios images on ios?
-    String density = 'drawable-xxhdpi';
-    String colorSuffix = _getColorSuffix(context);
-    int iconSize = _kIconSize[size];
-    return new AssetImage(
-      name: '$category/$density/ic_${subtype}_${colorSuffix}_${iconSize}dp.png',
-      width: iconSize.toDouble(),
-      height: iconSize.toDouble(),
-      colorFilter: colorFilter
-    );
-  }
-
-  void debugFillDescription(List<String> description) {
-    super.debugFillDescription(description);
-    description.add('$icon');
-    description.add('size: $size');
-  }
-}
diff --git a/sky/packages/sky/lib/src/material/icon_button.dart b/sky/packages/sky/lib/src/material/icon_button.dart
deleted file mode 100644
index 087c284..0000000
--- a/sky/packages/sky/lib/src/material/icon_button.dart
+++ /dev/null
@@ -1,44 +0,0 @@
-// Copyright 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:flutter/widgets.dart';
-
-import 'icon.dart';
-import 'icon_theme_data.dart';
-
-class IconButton extends StatelessComponent {
-  const IconButton({
-    Key key,
-    this.icon,
-    this.color,
-    this.colorFilter,
-    this.onPressed
-  }) : super(key: key);
-
-  final String icon;
-  final IconThemeColor color;
-  final ColorFilter colorFilter;
-  final VoidCallback onPressed;
-
-  Widget build(BuildContext context) {
-    // TODO(abarth): We should use a radial reaction here so you can hit the
-    // 8.0 pixel padding as well as the icon.
-    return new GestureDetector(
-      onTap: onPressed,
-      child: new Padding(
-        padding: const EdgeDims.all(8.0),
-        child: new Icon(
-          icon: icon,
-          color: color,
-          colorFilter: colorFilter
-        )
-      )
-    );
-  }
-
-  void debugFillDescription(List<String> description) {
-    super.debugFillDescription(description);
-    description.add('$icon');
-  }
-}
diff --git a/sky/packages/sky/lib/src/material/icon_theme.dart b/sky/packages/sky/lib/src/material/icon_theme.dart
deleted file mode 100644
index 72b19a3..0000000
--- a/sky/packages/sky/lib/src/material/icon_theme.dart
+++ /dev/null
@@ -1,32 +0,0 @@
-// Copyright 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:flutter/widgets.dart';
-
-import 'icon_theme_data.dart';
-
-class IconTheme extends InheritedWidget {
-  IconTheme({
-    Key key,
-    this.data,
-    Widget child
-  }) : super(key: key, child: child) {
-    assert(data != null);
-    assert(child != null);
-  }
-
-  final IconThemeData data;
-
-  static IconThemeData of(BuildContext context) {
-    IconTheme result = context.inheritedWidgetOfType(IconTheme);
-    return result?.data;
-  }
-
-  bool updateShouldNotify(IconTheme old) => data != old.data;
-
-  void debugFillDescription(List<String> description) {
-    super.debugFillDescription(description);
-    description.add('$data');
-  }
-}
diff --git a/sky/packages/sky/lib/src/material/icon_theme_data.dart b/sky/packages/sky/lib/src/material/icon_theme_data.dart
deleted file mode 100644
index e4a925c..0000000
--- a/sky/packages/sky/lib/src/material/icon_theme_data.dart
+++ /dev/null
@@ -1,21 +0,0 @@
-// Copyright 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.
-
-enum IconThemeColor { white, black }
-
-class IconThemeData {
-  const IconThemeData({ this.color });
-  final IconThemeColor color;
-
-  bool operator ==(dynamic other) {
-    if (other is! IconThemeData)
-      return false;
-    final IconThemeData typedOther = other;
-    return color == typedOther.color;
-  }
-
-  int get hashCode => color.hashCode;
-
-  String toString() => '$color';
-}
diff --git a/sky/packages/sky/lib/src/material/ink_well.dart b/sky/packages/sky/lib/src/material/ink_well.dart
deleted file mode 100644
index 6051dc9..0000000
--- a/sky/packages/sky/lib/src/material/ink_well.dart
+++ /dev/null
@@ -1,287 +0,0 @@
-// Copyright 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 'dart:math' as math;
-
-import 'package:flutter/animation.dart';
-import 'package:flutter/gestures.dart';
-import 'package:flutter/rendering.dart';
-import 'package:flutter/widgets.dart';
-
-// This file has the following classes:
-//  InkWell - the widget for material-design-style inkly-reacting material, showing splashes and a highlight
-//  _InkWellState - InkWell's State class
-//  _InkSplash - tracks a single splash
-//  _RenderInkSplashes - a RenderBox that renders multiple _InkSplash objects and handles gesture recognition
-//  _InkSplashes - the RenderObjectWidget for _RenderInkSplashes used by InkWell to handle the splashes
-
-const int _kSplashInitialOpacity = 0x30; // 0..255
-const double _kSplashCanceledVelocity = 0.7; // logical pixels per millisecond
-const double _kSplashConfirmedVelocity = 0.7; // logical pixels per millisecond
-const double _kSplashInitialSize = 0.0; // logical pixels
-const double _kSplashUnconfirmedVelocity = 0.2; // logical pixels per millisecond
-const Duration _kInkWellHighlightFadeDuration = const Duration(milliseconds: 100);
-
-class InkWell extends StatefulComponent {
-  InkWell({
-    Key key,
-    this.child,
-    this.onTap,
-    this.onLongPress,
-    this.onHighlightChanged,
-    this.defaultColor,
-    this.highlightColor
-  }) : super(key: key);
-
-  final Widget child;
-  final GestureTapCallback onTap;
-  final GestureLongPressCallback onLongPress;
-  final _HighlightChangedCallback onHighlightChanged;
-  final Color defaultColor;
-  final Color highlightColor;
-
-  _InkWellState createState() => new _InkWellState();
-}
-
-class _InkWellState extends State<InkWell> {
-  bool _highlight = false;
-  Widget build(BuildContext context) {
-    return new AnimatedContainer(
-      decoration: new BoxDecoration(
-        backgroundColor: _highlight ? config.highlightColor : config.defaultColor
-      ),
-      duration: _kInkWellHighlightFadeDuration,
-      child: new _InkSplashes(
-        onTap: config.onTap,
-        onLongPress: config.onLongPress,
-        onHighlightChanged: (bool value) {
-          setState(() {
-            _highlight = value;
-          });
-          if (config.onHighlightChanged != null)
-            config.onHighlightChanged(value);
-        },
-        child: config.child
-      )
-    );
-  }
-}
-
-
-double _getSplashTargetSize(Size bounds, Point position) {
-  double d1 = (position - bounds.topLeft(Point.origin)).distance;
-  double d2 = (position - bounds.topRight(Point.origin)).distance;
-  double d3 = (position - bounds.bottomLeft(Point.origin)).distance;
-  double d4 = (position - bounds.bottomRight(Point.origin)).distance;
-  return math.max(math.max(d1, d2), math.max(d3, d4)).ceil().toDouble();
-}
-
-class _InkSplash {
-  _InkSplash(this.position, this.renderer) {
-    _targetRadius = _getSplashTargetSize(renderer.size, position);
-    _radius = new ValuePerformance<double>(
-      variable: new AnimatedValue<double>(
-        _kSplashInitialSize,
-        end: _targetRadius,
-        curve: Curves.easeOut
-      ),
-      duration: new Duration(milliseconds: (_targetRadius / _kSplashUnconfirmedVelocity).floor())
-    )..addListener(_handleRadiusChange)
-     ..play();
-  }
-
-  final Point position;
-  final _RenderInkSplashes renderer;
-
-  double _targetRadius;
-  double _pinnedRadius;
-  ValuePerformance<double> _radius;
-
-  void _updateVelocity(double velocity) {
-    int duration = (_targetRadius / velocity).floor();
-    _radius.duration = new Duration(milliseconds: duration);
-    _radius.play();
-  }
-
-  void confirm() {
-    _updateVelocity(_kSplashConfirmedVelocity);
-    _pinnedRadius = null;
-  }
-
-  void cancel() {
-    _updateVelocity(_kSplashCanceledVelocity);
-    _pinnedRadius = _radius.value;
-  }
-
-  void _handleRadiusChange() {
-    if (_radius.value == _targetRadius)
-      renderer._removeSplash(this);
-    renderer.markNeedsPaint();
-  }
-
-  void paint(PaintingCanvas canvas) {
-    int opacity = (_kSplashInitialOpacity * (1.1 - (_radius.value / _targetRadius))).floor();
-    Paint paint = new Paint()..color = new Color(opacity << 24);
-    double radius = _pinnedRadius == null ? _radius.value : _pinnedRadius;
-    canvas.drawCircle(position, radius, paint);
-  }
-}
-
-typedef _HighlightChangedCallback(bool value);
-
-class _RenderInkSplashes extends RenderProxyBox {
-  _RenderInkSplashes({
-    RenderBox child,
-    GestureTapCallback onTap,
-    GestureLongPressCallback onLongPress,
-    this.onHighlightChanged
-  }) : super(child) {
-    this.onTap = onTap;
-    this.onLongPress = onLongPress;
-  }
-
-  GestureTapCallback get onTap => _onTap;
-  GestureTapCallback _onTap;
-  void set onTap (GestureTapCallback value) {
-    _onTap = value;
-    _syncTapRecognizer();
-  }
-
-  GestureTapCallback get onLongPress => _onLongPress;
-  GestureTapCallback _onLongPress;
-  void set onLongPress (GestureTapCallback value) {
-    _onLongPress = value;
-    _syncLongPressRecognizer();
-  }
-
-  _HighlightChangedCallback onHighlightChanged;
-
-  final List<_InkSplash> _splashes = new List<_InkSplash>();
-  _InkSplash _lastSplash;
-
-  TapGestureRecognizer _tap;
-  LongPressGestureRecognizer _longPress;
-
-  void _removeSplash(_InkSplash splash) {
-    _splashes.remove(splash);
-    if (_lastSplash == splash)
-      _lastSplash = null;
-  }
-
-  void handleEvent(InputEvent event, BoxHitTestEntry entry) {
-    if (event.type == 'pointerdown' && (onTap != null || onLongPress != null)) {
-      _tap?.addPointer(event);
-      _longPress?.addPointer(event);
-    }
-  }
-
-  void attach() {
-    super.attach();
-    _syncTapRecognizer();
-    _syncLongPressRecognizer();
-  }
-
-  void detach() {
-    _disposeTapRecognizer();
-    _disposeLongPressRecognizer();
-    super.detach();
-  }
-
-  void _syncTapRecognizer() {
-    if (onTap == null && onLongPress == null) {
-      _disposeTapRecognizer();
-    } else {
-      _tap ??= new TapGestureRecognizer(router: FlutterBinding.instance.pointerRouter)
-        ..onTapDown = _handleTapDown
-        ..onTap = _handleTap
-        ..onTapCancel = _handleTapCancel;
-    }
-  }
-
-  void _disposeTapRecognizer() {
-    _tap?.dispose();
-    _tap = null;
-  }
-
-  void _syncLongPressRecognizer() {
-    if (onLongPress == null) {
-      _disposeLongPressRecognizer();
-    } else {
-      _longPress ??= new LongPressGestureRecognizer(router: FlutterBinding.instance.pointerRouter)
-        ..onLongPress = _handleLongPress;
-    }
-  }
-
-  void _disposeLongPressRecognizer() {
-    _longPress?.dispose();
-    _longPress = null;
-  }
-
-  void _handleTapDown(Point position) {
-    _lastSplash = new _InkSplash(globalToLocal(position), this);
-    _splashes.add(_lastSplash);
-    if (onHighlightChanged != null)
-      onHighlightChanged(true);
-  }
-
-  void _handleTap() {
-    _lastSplash?.confirm();
-    _lastSplash = null;
-    if (onHighlightChanged != null)
-      onHighlightChanged(false);
-    if (onTap != null)
-      onTap();
-  }
-
-  void _handleTapCancel() {
-    _lastSplash?.cancel();
-    _lastSplash = null;
-    if (onHighlightChanged != null)
-      onHighlightChanged(false);
-  }
-
-  void _handleLongPress() {
-    _lastSplash?.confirm();
-    _lastSplash = null;
-    if (onLongPress != null)
-      onLongPress();
-  }
-
-  bool hitTestSelf(Point position) => true;
-
-  void paint(PaintingContext context, Offset offset) {
-    if (!_splashes.isEmpty) {
-      final PaintingCanvas canvas = context.canvas;
-      canvas.save();
-      canvas.translate(offset.dx, offset.dy);
-      canvas.clipRect(Point.origin & size);
-      for (_InkSplash splash in _splashes)
-        splash.paint(canvas);
-      canvas.restore();
-    }
-    super.paint(context, offset);
-  }
-}
-
-class _InkSplashes extends OneChildRenderObjectWidget {
-  _InkSplashes({
-    Key key,
-    Widget child,
-    this.onTap,
-    this.onLongPress,
-    this.onHighlightChanged
-  }) : super(key: key, child: child);
-
-  final GestureTapCallback onTap;
-  final GestureLongPressCallback onLongPress;
-  final _HighlightChangedCallback onHighlightChanged;
-
-  _RenderInkSplashes createRenderObject() => new _RenderInkSplashes(onTap: onTap, onLongPress: onLongPress, onHighlightChanged: onHighlightChanged);
-
-  void updateRenderObject(_RenderInkSplashes renderObject, _InkSplashes oldWidget) {
-    renderObject.onTap = onTap;
-    renderObject.onLongPress = onLongPress;
-    renderObject.onHighlightChanged = onHighlightChanged;
-  }
-}
diff --git a/sky/packages/sky/lib/src/material/input.dart b/sky/packages/sky/lib/src/material/input.dart
deleted file mode 100644
index ba327d0..0000000
--- a/sky/packages/sky/lib/src/material/input.dart
+++ /dev/null
@@ -1,173 +0,0 @@
-// Copyright 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:flutter/animation.dart';
-import 'package:flutter/rendering.dart';
-import 'package:flutter/services.dart';
-import 'package:flutter/widgets.dart';
-
-import 'theme.dart';
-
-export 'package:flutter/rendering.dart' show ValueChanged;
-export 'package:flutter/services.dart' show KeyboardType;
-
-// TODO(eseidel): This isn't right, it's 16px on the bottom:
-// http://www.google.com/design/spec/components/text-fields.html#text-fields-single-line-text-field
-const EdgeDims _kTextfieldPadding = const EdgeDims.symmetric(vertical: 8.0);
-
-class Input extends Scrollable {
-  Input({
-    GlobalKey key,
-    this.initialValue: '',
-    this.placeholder,
-    this.onChanged,
-    this.keyboardType: KeyboardType.TEXT,
-    this.onSubmitted
-  }) : super(
-    key: key,
-    initialScrollOffset: 0.0,
-    scrollDirection: ScrollDirection.horizontal
-  );
-
-  final String initialValue;
-  final KeyboardType keyboardType;
-  final String placeholder;
-  final ValueChanged<String> onChanged;
-  final ValueChanged<String> onSubmitted;
-
-  InputState createState() => new InputState();
-}
-
-class InputState extends ScrollableState<Input> {
-  String _value;
-  EditableString _editableValue;
-  KeyboardHandle _keyboardHandle = KeyboardHandle.unattached;
-
-  double _contentWidth = 0.0;
-  double _containerWidth = 0.0;
-
-  EditableString get editableValue => _editableValue;
-
-  void initState() {
-    super.initState();
-    _value = config.initialValue;
-    _editableValue = new EditableString(
-      text: _value,
-      onUpdated: _handleTextUpdated,
-      onSubmitted: _handleTextSubmitted
-    );
-  }
-
-  void _handleTextUpdated() {
-    if (_value != _editableValue.text) {
-      setState(() {
-        _value = _editableValue.text;
-      });
-      if (config.onChanged != null)
-        config.onChanged(_value);
-    }
-  }
-
-  void _handleTextSubmitted() {
-    if (config.onSubmitted != null)
-      config.onSubmitted(_value);
-  }
-
-  Widget buildContent(BuildContext context) {
-    ThemeData themeData = Theme.of(context);
-    bool focused = Focus.at(context, config);
-
-    if (focused && !_keyboardHandle.attached) {
-      _keyboardHandle = keyboard.show(_editableValue.stub, config.keyboardType);
-      _keyboardHandle.setText(_editableValue.text);
-      _keyboardHandle.setSelection(_editableValue.selection.start,
-                                   _editableValue.selection.end);
-    } else if (!focused && _keyboardHandle.attached) {
-      _keyboardHandle.release();
-    }
-
-    TextStyle textStyle = themeData.text.subhead;
-    List<Widget> textChildren = <Widget>[];
-
-    if (config.placeholder != null && _value.isEmpty) {
-      Widget child = new Opacity(
-        key: const ValueKey<String>('placeholder'),
-        child: new Text(config.placeholder, style: textStyle),
-        opacity: themeData.hintOpacity
-      );
-      textChildren.add(child);
-    }
-
-    Color focusHighlightColor = themeData.accentColor;
-    Color cursorColor = themeData.accentColor;
-    if (themeData.primarySwatch != null) {
-      cursorColor = themeData.primarySwatch[200];
-      focusHighlightColor = focused ? themeData.primarySwatch[400] : themeData.hintColor;
-    }
-
-    textChildren.add(new EditableText(
-      value: _editableValue,
-      focused: focused,
-      style: textStyle,
-      cursorColor: cursorColor,
-      onContentSizeChanged: _handleContentSizeChanged,
-      scrollOffset: scrollOffsetVector
-    ));
-
-    return new Listener(
-      child: new SizeObserver(
-        onSizeChanged: _handleContainerSizeChanged,
-        child: new Container(
-          child: new Stack(textChildren),
-          padding: _kTextfieldPadding,
-          decoration: new BoxDecoration(border: new Border(
-            bottom: new BorderSide(
-              color: focusHighlightColor,
-              width: focused ? 2.0 : 1.0
-            )
-          ))
-        )
-      ),
-      onPointerDown: (_) {
-        // TODO(ianh): https://github.com/flutter/engine/issues/1530
-        if (Focus.at(context, config)) {
-          assert(_keyboardHandle.attached);
-          _keyboardHandle.showByRequest();
-        } else {
-          Focus.moveTo(context, config);
-          // we'll get told to rebuild and we'll take care of the keyboard then
-        }
-      }
-    );
-  }
-
-  void dispose() {
-    if (_keyboardHandle.attached)
-      _keyboardHandle.release();
-    super.dispose();
-  }
-
-  ScrollBehavior createScrollBehavior() => new BoundedBehavior();
-  BoundedBehavior get scrollBehavior => super.scrollBehavior;
-
-  void _handleContainerSizeChanged(Size newSize) {
-    _containerWidth = newSize.width;
-    _updateScrollBehavior();
-  }
-
-  void _handleContentSizeChanged(Size newSize) {
-    _contentWidth = newSize.width;
-    _updateScrollBehavior();
-  }
-
-  void _updateScrollBehavior() {
-    // Set the scroll offset to match the content width so that the cursor
-    // (which is always at the end of the text) will be visible.
-    scrollTo(scrollBehavior.updateExtents(
-      contentExtent: _contentWidth,
-      containerExtent: _containerWidth,
-      scrollOffset: _contentWidth)
-    );
-  }
-}
diff --git a/sky/packages/sky/lib/src/material/list_item.dart b/sky/packages/sky/lib/src/material/list_item.dart
deleted file mode 100644
index 0352f30..0000000
--- a/sky/packages/sky/lib/src/material/list_item.dart
+++ /dev/null
@@ -1,58 +0,0 @@
-// Copyright 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:flutter/widgets.dart';
-
-import 'ink_well.dart';
-
-class ListItem extends StatelessComponent {
-  ListItem({
-    Key key,
-    this.left,
-    this.center,
-    this.right,
-    this.onTap,
-    this.onLongPress
-  }) : super(key: key) {
-    assert(center != null);
-  }
-
-  final Widget left;
-  final Widget center;
-  final Widget right;
-  final GestureTapCallback onTap;
-  final GestureLongPressCallback onLongPress;
-
-  Widget build(BuildContext context) {
-    List<Widget> children = new List<Widget>();
-
-    if (left != null) {
-      children.add(new Container(
-        margin: new EdgeDims.only(right: 16.0),
-        width: 40.0,
-        child: left
-      ));
-    }
-
-    children.add(new Flexible(
-      child: center
-    ));
-
-    if (right != null) {
-      children.add(new Container(
-        margin: new EdgeDims.only(left: 16.0),
-        child: right
-      ));
-    }
-
-    return new Padding(
-      padding: const EdgeDims.symmetric(horizontal: 16.0),
-      child: new InkWell(
-        onTap: onTap,
-        onLongPress: onLongPress,
-        child: new Row(children)
-      )
-    );
-  }
-}
diff --git a/sky/packages/sky/lib/src/material/material.dart b/sky/packages/sky/lib/src/material/material.dart
deleted file mode 100644
index 96ada6f..0000000
--- a/sky/packages/sky/lib/src/material/material.dart
+++ /dev/null
@@ -1,82 +0,0 @@
-// Copyright 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:flutter/animation.dart';
-import 'package:flutter/widgets.dart';
-
-import 'constants.dart';
-import 'shadows.dart';
-import 'theme.dart';
-
-enum MaterialType { canvas, card, circle, button }
-
-const Map<MaterialType, double> _kEdges = const <MaterialType, double>{
-  MaterialType.canvas: null,
-  MaterialType.card: 2.0,
-  MaterialType.circle: null,
-  MaterialType.button: 2.0,
-};
-
-class Material extends StatelessComponent {
-  Material({
-    Key key,
-    this.child,
-    this.type: MaterialType.canvas,
-    this.level: 0,
-    this.color,
-    this.textStyle
-  }) : super(key: key) {
-    assert(level != null);
-  }
-
-  final Widget child;
-  final MaterialType type;
-  final int level;
-  final Color color;
-  final TextStyle textStyle;
-
-  Color _getBackgroundColor(BuildContext context) {
-    if (color != null)
-      return color;
-    switch (type) {
-      case MaterialType.canvas:
-        return Theme.of(context).canvasColor;
-      case MaterialType.card:
-        return Theme.of(context).cardColor;
-      default:
-        return null;
-    }
-  }
-
-  Widget build(BuildContext context) {
-    Widget contents = child;
-    if (child != null) {
-      contents = new DefaultTextStyle(
-        style: textStyle ?? Theme.of(context).text.body1,
-        child: contents
-      );
-      if (_kEdges[type] != null) {
-        contents = new ClipRRect(
-          xRadius: _kEdges[type],
-          yRadius: _kEdges[type],
-          child: contents
-        );
-      }
-    }
-    return new DefaultTextStyle(
-      style: Theme.of(context).text.body1,
-      child: new AnimatedContainer(
-        curve: Curves.ease,
-        duration: kThemeChangeDuration,
-        decoration: new BoxDecoration(
-          backgroundColor: _getBackgroundColor(context),
-          borderRadius: _kEdges[type],
-          boxShadow: level == 0 ? null : shadows[level],
-          shape: type == MaterialType.circle ? Shape.circle : Shape.rectangle
-        ),
-        child: contents
-      )
-    );
-  }
-}
diff --git a/sky/packages/sky/lib/src/material/material_app.dart b/sky/packages/sky/lib/src/material/material_app.dart
deleted file mode 100644
index 1d35a92..0000000
--- a/sky/packages/sky/lib/src/material/material_app.dart
+++ /dev/null
@@ -1,130 +0,0 @@
-// Copyright 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 'dart:ui' as ui;
-
-import 'package:flutter/rendering.dart';
-import 'package:flutter/services.dart';
-import 'package:flutter/widgets.dart';
-
-import 'theme.dart';
-import 'title.dart';
-
-const TextStyle _errorTextStyle = const TextStyle(
-  color: const Color(0xD0FF0000),
-  fontFamily: 'monospace',
-  fontSize: 48.0,
-  fontWeight: FontWeight.w900,
-  textAlign: TextAlign.right,
-  decoration: underline,
-  decorationColor: const Color(0xFFFF00),
-  decorationStyle: TextDecorationStyle.double
-);
-
-AssetBundle _initDefaultBundle() {
-  if (rootBundle != null)
-    return rootBundle;
-  const String _kAssetBase = '/packages/material_design_icons/icons/';
-  return new NetworkAssetBundle(Uri.base.resolve(_kAssetBase));
-}
-
-final AssetBundle _defaultBundle = _initDefaultBundle();
-
-class RouteArguments {
-  const RouteArguments({ this.context });
-  final BuildContext context;
-}
-typedef Widget RouteBuilder(RouteArguments args);
-typedef RouteBuilder RouteGenerator(String name);
-
-class MaterialApp extends StatefulComponent {
-  MaterialApp({
-    Key key,
-    this.title,
-    this.theme,
-    this.routes: const <String, RouteBuilder>{},
-    this.onGenerateRoute
-  }) : super(key: key) {
-    assert(routes != null);
-    assert(routes.containsKey(Navigator.defaultRouteName) || onGenerateRoute != null);
-  }
-
-  final String title;
-  final ThemeData theme;
-  final Map<String, RouteBuilder> routes;
-  final RouteGenerator onGenerateRoute;
-
-  _MaterialAppState createState() => new _MaterialAppState();
-}
-
-class _MaterialAppState extends State<MaterialApp> {
-
-  GlobalObjectKey _navigator;
-
-  Size _size;
-
-  void initState() {
-    super.initState();
-    _navigator = new GlobalObjectKey(this);
-    WidgetFlutterBinding.instance.addEventListener(_backHandler);
-    _size = ui.window.size;
-    FlutterBinding.instance.addMetricListener(_metricHandler);
-  }
-
-  void dispose() {
-    WidgetFlutterBinding.instance.removeEventListener(_backHandler);
-    FlutterBinding.instance.removeMetricListener(_metricHandler);
-    super.dispose();
-  }
-
-  void _backHandler(InputEvent event) {
-    assert(mounted);
-    if (event.type == 'back') {
-      NavigatorState navigator = _navigator.currentState;
-      assert(navigator != null);
-      if (navigator.hasPreviousRoute)
-        navigator.pop();
-      else
-        activity.finishCurrentActivity();
-    }
-  }
-
-  void _metricHandler(Size size) => setState(() { _size = size; });
-
-  final HeroController _heroController = new HeroController();
-
-  Route _generateRoute(NamedRouteSettings settings) {
-    return new HeroPageRoute(
-      builder: (BuildContext context) {
-        RouteBuilder builder = config.routes[settings.name] ?? config.onGenerateRoute(settings.name);
-        return builder(new RouteArguments(context: context));
-      },
-      settings: settings,
-      heroController: _heroController
-    );
-  }
-
-  Widget build(BuildContext context) {
-    return new MediaQuery(
-      data: new MediaQueryData(size: _size),
-      child: new Theme(
-        data: config.theme ?? new ThemeData.fallback(),
-        child: new DefaultTextStyle(
-          style: _errorTextStyle,
-          child: new DefaultAssetBundle(
-            bundle: _defaultBundle,
-            child: new Title(
-              title: config.title,
-              child: new Navigator(
-                key: _navigator,
-                onGenerateRoute: _generateRoute
-              )
-            )
-          )
-        )
-      )
-    );
-  }
-
-}
diff --git a/sky/packages/sky/lib/src/material/material_button.dart b/sky/packages/sky/lib/src/material/material_button.dart
deleted file mode 100644
index e304429..0000000
--- a/sky/packages/sky/lib/src/material/material_button.dart
+++ /dev/null
@@ -1,117 +0,0 @@
-// Copyright 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:flutter/widgets.dart';
-
-import 'colors.dart';
-import 'ink_well.dart';
-import 'material.dart';
-import 'theme.dart';
-
-enum ButtonColor { normal, accent }
-
-class ButtonTheme extends InheritedWidget {
-  ButtonTheme({
-    Key key,
-    this.color,
-    Widget child
-  }) : super(key: key, child: child) {
-    assert(child != null);
-  }
-
-  final ButtonColor color;
-
-  static ButtonColor of(BuildContext context) {
-    ButtonTheme result = context.inheritedWidgetOfType(ButtonTheme);
-    return result?.color ?? ButtonColor.normal;
-  }
-
-  bool updateShouldNotify(ButtonTheme old) => color != old.color;
-}
-
-/// Base class for buttons in the Material theme.
-/// Rather than using this class directly, please use FlatButton or RaisedButton.
-abstract class MaterialButton extends StatefulComponent {
-  MaterialButton({
-    Key key,
-    this.child,
-    this.textColor,
-    this.onPressed
-  }) : super(key: key);
-
-  final Widget child;
-  final ButtonColor textColor;
-  final VoidCallback onPressed;
-
-  bool get enabled => onPressed != null;
-
-  void debugFillDescription(List<String> description) {
-    super.debugFillDescription(description);
-    if (!enabled)
-      description.add('disabled');
-  }
-}
-
-abstract class MaterialButtonState<T extends MaterialButton> extends State<T> {
-  bool highlight = false;
-
-  int get level;
-  Color getColor(BuildContext context, { bool highlight });
-  ThemeBrightness getColorBrightness(BuildContext context);
-
-  Color getTextColor(BuildContext context) {
-    if (config.enabled) {
-      switch (config.textColor ?? ButtonTheme.of(context)) {
-        case ButtonColor.accent:
-          return Theme.of(context).accentColor;
-        case ButtonColor.normal:
-          switch (getColorBrightness(context)) {
-            case ThemeBrightness.light:
-              return Colors.black87;
-            case ThemeBrightness.dark:
-              return Colors.white;
-          }
-      }
-    }
-    switch (getColorBrightness(context)) {
-      case ThemeBrightness.light:
-        return Colors.black26;
-      case ThemeBrightness.dark:
-        return Colors.white30;
-    }
-  }
-
-  void _handleHighlightChanged(bool value) {
-    setState(() {
-      highlight = value;
-    });
-  }
-
-  Widget build(BuildContext context) {
-    Widget contents = new Container(
-      padding: new EdgeDims.symmetric(horizontal: 8.0),
-      child: new Center(
-        widthFactor: 1.0,
-        child: config.child
-      )
-    );
-    return new Container(
-      height: 36.0,
-      constraints: new BoxConstraints(minWidth: 88.0),
-      margin: new EdgeDims.all(8.0),
-      child: new Material(
-        type: MaterialType.button,
-        level: level,
-        textStyle: Theme.of(context).text.button.copyWith(color: getTextColor(context)),
-        child: new InkWell(
-          onTap: config.enabled ? config.onPressed : null,
-          defaultColor: getColor(context, highlight: false),
-          highlightColor: getColor(context, highlight: true),
-          onHighlightChanged: _handleHighlightChanged,
-          child: contents
-        )
-      )
-    );
-  }
-}
diff --git a/sky/packages/sky/lib/src/material/material_list.dart b/sky/packages/sky/lib/src/material/material_list.dart
deleted file mode 100644
index 105a8b7..0000000
--- a/sky/packages/sky/lib/src/material/material_list.dart
+++ /dev/null
@@ -1,64 +0,0 @@
-// Copyright 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:flutter/widgets.dart';
-
-import 'constants.dart';
-import 'scrollbar_painter.dart';
-
-enum MaterialListType {
-  oneLine,
-  oneLineWithAvatar,
-  twoLine,
-  threeLine
-}
-
-Map<MaterialListType, double> _kItemExtent = const <MaterialListType, double>{
-  MaterialListType.oneLine: kOneLineListItemHeight,
-  MaterialListType.oneLineWithAvatar: kOneLineListItemWithAvatarHeight,
-  MaterialListType.twoLine: kTwoLineListItemHeight,
-  MaterialListType.threeLine: kThreeLineListItemHeight,
-};
-
-class MaterialList<T> extends StatefulComponent {
-  MaterialList({
-    Key key,
-    this.initialScrollOffset,
-    this.onScroll,
-    this.items,
-    this.itemBuilder,
-    this.type: MaterialListType.twoLine
-  }) : super(key: key);
-
-  final double initialScrollOffset;
-  final ScrollListener onScroll;
-  final List<T> items;
-  final ItemBuilder<T> itemBuilder;
-  final MaterialListType type;
-
-  _MaterialListState<T> createState() => new _MaterialListState<T>();
-}
-
-class _MaterialListState<T> extends State<MaterialList<T>> {
-
-  void initState() {
-    super.initState();
-    _scrollbarPainter = new ScrollbarPainter();
-  }
-
-  ScrollbarPainter _scrollbarPainter;
-
-  Widget build(BuildContext context) {
-    return new ScrollableList<T>(
-      initialScrollOffset: config.initialScrollOffset,
-      scrollDirection: ScrollDirection.vertical,
-      onScroll: config.onScroll,
-      items: config.items,
-      itemBuilder: config.itemBuilder,
-      itemExtent: _kItemExtent[config.type],
-      padding: const EdgeDims.symmetric(vertical: 8.0),
-      scrollableListPainter: _scrollbarPainter
-    );
-  }
-}
diff --git a/sky/packages/sky/lib/src/material/popup_menu.dart b/sky/packages/sky/lib/src/material/popup_menu.dart
deleted file mode 100644
index 5fc1cf9..0000000
--- a/sky/packages/sky/lib/src/material/popup_menu.dart
+++ /dev/null
@@ -1,131 +0,0 @@
-// Copyright 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 'dart:async';
-import 'dart:ui' as ui;
-
-import 'package:flutter/animation.dart';
-import 'package:flutter/painting.dart';
-import 'package:flutter/widgets.dart';
-
-import 'ink_well.dart';
-import 'popup_menu_item.dart';
-import 'shadows.dart';
-import 'theme.dart';
-
-const Duration _kMenuDuration = const Duration(milliseconds: 300);
-const double _kMenuCloseIntervalEnd = 2.0 / 3.0;
-const double _kMenuWidthStep = 56.0;
-const double _kMenuMinWidth = 2.0 * _kMenuWidthStep;
-const double _kMenuMaxWidth = 5.0 * _kMenuWidthStep;
-const double _kMenuHorizontalPadding = 16.0;
-const double _kMenuVerticalPadding = 8.0;
-
-class _PopupMenu extends StatelessComponent {
-  _PopupMenu({
-    Key key,
-    this.route
-  }) : super(key: key);
-
-  final _MenuRoute route;
-
-  Widget build(BuildContext context) {
-    final BoxPainter painter = new BoxPainter(new BoxDecoration(
-      backgroundColor: Theme.of(context).canvasColor,
-      borderRadius: 2.0,
-      boxShadow: shadows[route.level]
-    ));
-
-    double unit = 1.0 / (route.items.length + 1.5); // 1.0 for the width and 0.5 for the last item's fade.
-    List<Widget> children = <Widget>[];
-
-    for (int i = 0; i < route.items.length; ++i) {
-      double start = (i + 1) * unit;
-      double end = (start + 1.5 * unit).clamp(0.0, 1.0);
-      children.add(new FadeTransition(
-        performance: route.performance,
-        opacity: new AnimatedValue<double>(0.0, end: 1.0, curve: new Interval(start, end)),
-        child: new InkWell(
-          onTap: () { Navigator.of(context).pop(route.items[i].value); },
-          child: route.items[i]
-        ))
-      );
-    }
-
-    final AnimatedValue<double> opacity = new AnimatedValue<double>(0.0, end: 1.0, curve: new Interval(0.0, 1.0 / 3.0));
-    final AnimatedValue<double> width = new AnimatedValue<double>(0.0, end: 1.0, curve: new Interval(0.0, unit));
-    final AnimatedValue<double> height = new AnimatedValue<double>(0.0, end: 1.0, curve: new Interval(0.0, unit * route.items.length));
-
-    return new BuilderTransition(
-      performance: route.performance,
-      variables: <AnimatedValue<double>>[opacity, width, height],
-      builder: (BuildContext context) {
-        return new Opacity(
-          opacity: opacity.value,
-          child: new CustomPaint(
-            onPaint: (ui.Canvas canvas, Size size) {
-              double widthValue = width.value * size.width;
-              double heightValue = height.value * size.height;
-              painter.paint(canvas, new Rect.fromLTWH(size.width - widthValue, 0.0, widthValue, heightValue));
-            },
-            child: new ConstrainedBox(
-              constraints: new BoxConstraints(
-                minWidth: _kMenuMinWidth,
-                maxWidth: _kMenuMaxWidth
-              ),
-              child: new IntrinsicWidth(
-                stepWidth: _kMenuWidthStep,
-                child: new Block(
-                  children,
-                  padding: const EdgeDims.symmetric(
-                    horizontal: _kMenuHorizontalPadding,
-                    vertical: _kMenuVerticalPadding
-                  )
-                )
-              )
-            )
-          )
-        );
-      }
-    );
-  }
-}
-
-class _MenuRoute extends ModalRoute {
-  _MenuRoute({ this.completer, this.position, this.items, this.level });
-
-  final Completer completer;
-  final ModalPosition position;
-  final List<PopupMenuItem> items;
-  final int level;
-
-  Performance createPerformance() {
-    Performance result = super.createPerformance();
-    AnimationTiming timing = new AnimationTiming();
-    timing.reverseCurve = new Interval(0.0, _kMenuCloseIntervalEnd);
-    result.timing = timing;
-    return result;
-  }
-
-  bool get opaque => false;
-  Duration get transitionDuration => _kMenuDuration;
-
-  Widget buildModalWidget(BuildContext context) => new _PopupMenu(route: this);
-
-  void didPop([dynamic result]) {
-    completer.complete(result);
-    super.didPop(result);
-  }
-}
-
-Future showMenu({ BuildContext context, ModalPosition position, List<PopupMenuItem> items, int level: 4 }) {
-  Completer completer = new Completer();
-  Navigator.of(context).pushEphemeral(new _MenuRoute(
-    completer: completer,
-    position: position,
-    items: items,
-    level: level
-  ));
-  return completer.future;
-}
diff --git a/sky/packages/sky/lib/src/material/popup_menu_item.dart b/sky/packages/sky/lib/src/material/popup_menu_item.dart
deleted file mode 100644
index f785eb8..0000000
--- a/sky/packages/sky/lib/src/material/popup_menu_item.dart
+++ /dev/null
@@ -1,34 +0,0 @@
-// Copyright 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:flutter/widgets.dart';
-
-import 'theme.dart';
-
-const double _kMenuItemHeight = 48.0;
-const double _kBaselineOffsetFromBottom = 20.0;
-
-class PopupMenuItem extends StatelessComponent {
-  PopupMenuItem({
-    Key key,
-    this.value,
-    this.child
-  }) : super(key: key);
-
-  final Widget child;
-  final dynamic value;
-
-  Widget build(BuildContext context) {
-    return new Container(
-      height: _kMenuItemHeight,
-      child: new DefaultTextStyle(
-        style: Theme.of(context).text.subhead,
-        child: new Baseline(
-          baseline: _kMenuItemHeight - _kBaselineOffsetFromBottom,
-          child: child
-        )
-      )
-    );
-  }
-}
diff --git a/sky/packages/sky/lib/src/material/progress_indicator.dart b/sky/packages/sky/lib/src/material/progress_indicator.dart
deleted file mode 100644
index ac41cf2..0000000
--- a/sky/packages/sky/lib/src/material/progress_indicator.dart
+++ /dev/null
@@ -1,166 +0,0 @@
-// Copyright 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 'dart:math' as math;
-import 'dart:ui' as ui;
-
-import 'package:flutter/animation.dart';
-import 'package:flutter/widgets.dart';
-
-import 'theme.dart';
-
-const double _kLinearProgressIndicatorHeight = 6.0;
-const double _kMinCircularProgressIndicatorSize = 15.0;
-const double _kCircularProgressIndicatorStrokeWidth = 3.0;
-
-// TODO(hansmuller) implement the support for buffer indicator
-
-abstract class ProgressIndicator extends StatefulComponent {
-  ProgressIndicator({
-    Key key,
-    this.value
-  }) : super(key: key);
-
-  final double value; // Null for non-determinate progress indicator.
-
-  Color _getBackgroundColor(BuildContext context) => Theme.of(context).primarySwatch[200];
-  Color _getValueColor(BuildContext context) => Theme.of(context).primaryColor;
-  Object _getCustomPaintToken(double performanceValue) => value != null ? value : performanceValue;
-
-  Widget _buildIndicator(BuildContext context, double performanceValue);
-
-  _ProgressIndicatorState createState() => new _ProgressIndicatorState();
-
-  void debugFillDescription(List<String> description) {
-    super.debugFillDescription(description);
-    description.add('${(value.clamp(0.0, 1.0) * 100.0).toStringAsFixed(1)}%');
-  }
-}
-
-class _ProgressIndicatorState extends State<ProgressIndicator> {
-
-  ValuePerformance<double> _performance;
-
-  void initState() {
-    super.initState();
-    _performance = new ValuePerformance<double>(
-      variable: new AnimatedValue<double>(0.0, end: 1.0, curve: Curves.ease),
-      duration: const Duration(milliseconds: 1500)
-    );
-    _performance.addStatusListener((PerformanceStatus status) {
-      if (status == PerformanceStatus.completed)
-        _restartAnimation();
-    });
-    _performance.play();
-  }
-
-  void _restartAnimation() {
-    _performance.progress = 0.0;
-    _performance.play();
-  }
-
-  Widget build(BuildContext context) {
-    if (config.value != null)
-      return config._buildIndicator(context, _performance.value);
-
-    return new BuilderTransition(
-      variables: <AnimatedValue<double>>[_performance.variable],
-      performance: _performance.view,
-      builder: (BuildContext context) {
-        return config._buildIndicator(context, _performance.value);
-      }
-    );
-  }
-}
-
-class LinearProgressIndicator extends ProgressIndicator {
-  LinearProgressIndicator({
-    Key key,
-    double value
-  }) : super(key: key, value: value);
-
-  void _paint(BuildContext context, double performanceValue, Canvas canvas, Size size) {
-    Paint paint = new Paint()
-      ..color = _getBackgroundColor(context)
-      ..style = ui.PaintingStyle.fill;
-    canvas.drawRect(Point.origin & size, paint);
-
-    paint.color = _getValueColor(context);
-    if (value != null) {
-      double width = value.clamp(0.0, 1.0) * size.width;
-      canvas.drawRect(Point.origin & new Size(width, size.height), paint);
-    } else {
-      double startX = size.width * (1.5 * performanceValue - 0.5);
-      double endX = startX + 0.5 * size.width;
-      double x = startX.clamp(0.0, size.width);
-      double width = endX.clamp(0.0, size.width) - x;
-      canvas.drawRect(new Point(x, 0.0) & new Size(width, size.height), paint);
-    }
-  }
-
-  Widget _buildIndicator(BuildContext context, double performanceValue) {
-    return new Container(
-      constraints: new BoxConstraints.tightFor(
-        width: double.INFINITY,
-        height: _kLinearProgressIndicatorHeight
-      ),
-      child: new CustomPaint(
-        token: _getCustomPaintToken(performanceValue),
-        onPaint: (Canvas canvas, Size size) {
-          _paint(context, performanceValue, canvas, size);
-        }
-      )
-    );
-  }
-}
-
-class CircularProgressIndicator extends ProgressIndicator {
-  static const _kTwoPI = math.PI * 2.0;
-  static const _kEpsilon = .0000001;
-  // Canavs.drawArc(r, 0, 2*PI) doesn't draw anything, so just get close.
-  static const _kSweep = _kTwoPI - _kEpsilon;
-  static const _kStartAngle = -math.PI / 2.0;
-
-  CircularProgressIndicator({
-    Key key,
-    double value
-  }) : super(key: key, value: value);
-
-  void _paint(BuildContext context, double performanceValue, Canvas canvas, Size size) {
-    Paint paint = new Paint()
-      ..color = _getValueColor(context)
-      ..strokeWidth = _kCircularProgressIndicatorStrokeWidth
-      ..style = ui.PaintingStyle.stroke;
-
-    if (value != null) {
-      double angle = value.clamp(0.0, 1.0) * _kSweep;
-      Path path = new Path()
-        ..arcTo(Point.origin & size, _kStartAngle, angle, false);
-      canvas.drawPath(path, paint);
-    } else {
-      double startAngle = _kTwoPI * (1.75 * performanceValue - 0.75);
-      double endAngle = startAngle + _kTwoPI * 0.75;
-      double arcAngle = startAngle.clamp(0.0, _kTwoPI);
-      double arcSweep = endAngle.clamp(0.0, _kTwoPI) - arcAngle;
-      Path path = new Path()
-        ..arcTo(Point.origin & size, _kStartAngle + arcAngle, arcSweep, false);
-      canvas.drawPath(path, paint);
-    }
-  }
-
-  Widget _buildIndicator(BuildContext context, double performanceValue) {
-    return new Container(
-      constraints: new BoxConstraints(
-        minWidth: _kMinCircularProgressIndicatorSize,
-        minHeight: _kMinCircularProgressIndicatorSize
-      ),
-      child: new CustomPaint(
-        token: _getCustomPaintToken(performanceValue),
-        onPaint: (Canvas canvas, Size size) {
-          _paint(context, performanceValue, canvas, size);
-        }
-      )
-    );
-  }
-}
diff --git a/sky/packages/sky/lib/src/material/radial_reaction.dart b/sky/packages/sky/lib/src/material/radial_reaction.dart
deleted file mode 100644
index 7d550b6..0000000
--- a/sky/packages/sky/lib/src/material/radial_reaction.dart
+++ /dev/null
@@ -1,91 +0,0 @@
-// Copyright 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 'dart:async';
-
-import 'package:flutter/animation.dart';
-import 'package:flutter/painting.dart';
-
-const Duration _kShowDuration = const Duration(milliseconds: 300);
-const Duration _kHideDuration = const Duration(milliseconds: 200);
-const Color _kOuterColor = const Color(0xFFFFFFFF);
-const Color _kInnerColor = const Color(0xFFFFFFFF);
-const double _kMaxOpacity = 0.2;
-
-int _roundOpacity(double opacity) {
-  return (255 * opacity).round();
-}
-
-/// A material design radial ink reaction
-///
-/// See [https://www.google.com/design/spec/animation/responsive-interaction.html#responsive-interaction-radial-action]
-class RadialReaction {
-  RadialReaction({
-    this.center,
-    this.radius,
-    Point startPosition
-  }) {
-    _outerOpacity = new AnimatedValue<double>(0.0, end: _kMaxOpacity, curve: Curves.easeOut);
-    _innerCenter = new AnimatedValue<Point>(startPosition, end: center, curve: Curves.easeOut);
-    _innerRadius = new AnimatedValue<double>(0.0, end: radius, curve: Curves.easeOut);
-    _showPerformance = new Performance(duration: _kShowDuration)
-      ..addListener(() {
-        _showPerformance.updateVariable(_outerOpacity);
-        _showPerformance.updateVariable(_innerCenter);
-        _showPerformance.updateVariable(_innerRadius);
-      });
-    _fade = new ValuePerformance<double>(
-      variable: new AnimatedValue<double>(1.0, end: 0.0, curve: Curves.easeIn),
-      duration: _kHideDuration
-    );
-  }
-
-  /// The center of the circle in which the reaction occurs
-  final Point center;
-
-  /// The radius of the circle in which the reaction occurs
-  final double radius;
-
-  Performance _showPerformance;
-  AnimatedValue<double> _outerOpacity;
-  AnimatedValue<Point> _innerCenter;
-  AnimatedValue<double> _innerRadius;
-
-  Future _showComplete;
-
-  ValuePerformance<double> _fade;
-
-  /// Show the reaction
-  ///
-  /// Returns a future that resolves when the reaction is completely revealed.
-  Future show() {
-    return _showComplete = _showPerformance.forward();
-  }
-
-  /// Hide the reaction
-  ///
-  /// Returns a future that resolves when the reaction is completely hidden.
-  Future hide() async {
-    await _showComplete;
-    await _fade.forward();
-  }
-
-  /// Call listener whenever the visual appearance of the reaction changes
-  void addListener(Function listener) {
-    _showPerformance.addListener(listener);
-    _fade.addListener(listener);
-  }
-
-  final Paint _outerPaint = new Paint();
-  final Paint _innerPaint = new Paint();
-
-  /// Paint the reaction onto the given canvas at the given offset
-  void paint(Canvas canvas, Offset offset) {
-    _outerPaint.color = _kOuterColor.withAlpha(_roundOpacity(_outerOpacity.value * _fade.value));
-    canvas.drawCircle(center + offset, radius, _outerPaint);
-
-    _innerPaint.color = _kInnerColor.withAlpha(_roundOpacity(_kMaxOpacity  * _fade.value));
-    canvas.drawCircle(_innerCenter.value + offset, _innerRadius.value, _innerPaint);
-  }
-}
diff --git a/sky/packages/sky/lib/src/material/radio.dart b/sky/packages/sky/lib/src/material/radio.dart
deleted file mode 100644
index fdbb9a6..0000000
--- a/sky/packages/sky/lib/src/material/radio.dart
+++ /dev/null
@@ -1,68 +0,0 @@
-// Copyright 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 'dart:ui' as ui;
-
-import 'package:flutter/widgets.dart';
-
-import 'colors.dart';
-import 'theme.dart';
-
-class Radio<T> extends StatelessComponent {
-  Radio({
-    Key key,
-    this.value,
-    this.groupValue,
-    this.onChanged
-  }) : super(key: key);
-
-  final T value;
-  final T groupValue;
-  final ValueChanged<T> onChanged;
-
-  bool get enabled => onChanged != null;
-
-  Color _getColor(BuildContext context) {
-    ThemeData themeData = Theme.of(context);
-    if (!enabled)
-      return themeData.brightness == ThemeBrightness.light ? Colors.black26 : Colors.white30;
-    if (value == groupValue)
-      return themeData.accentColor;
-    return themeData.brightness == ThemeBrightness.light ? Colors.black54 : Colors.white70;
-  }
-
-  Widget build(BuildContext context) {
-    const double kDiameter = 16.0;
-    const double kOuterRadius = kDiameter / 2;
-    const double kInnerRadius = 5.0;
-    return new GestureDetector(
-      onTap: enabled ? () => onChanged(value) : null,
-      child: new Container(
-        margin: const EdgeDims.symmetric(horizontal: 5.0),
-        width: kDiameter,
-        height: kDiameter,
-        child: new CustomPaint(
-          onPaint: (Canvas canvas, Size size) {
-
-            // TODO(ianh): ink radial reaction
-
-            // Draw the outer circle
-            Paint paint = new Paint()
-              ..color = _getColor(context)
-              ..style = ui.PaintingStyle.stroke
-              ..strokeWidth = 2.0;
-            canvas.drawCircle(const Point(kOuterRadius, kOuterRadius), kOuterRadius, paint);
-
-            // Draw the inner circle
-            if (value == groupValue) {
-              paint.style = ui.PaintingStyle.fill;
-              canvas.drawCircle(const Point(kOuterRadius, kOuterRadius), kInnerRadius, paint);
-            }
-
-          }
-        )
-      )
-    );
-  }
-}
diff --git a/sky/packages/sky/lib/src/material/raised_button.dart b/sky/packages/sky/lib/src/material/raised_button.dart
deleted file mode 100644
index cbfaf48..0000000
--- a/sky/packages/sky/lib/src/material/raised_button.dart
+++ /dev/null
@@ -1,58 +0,0 @@
-// Copyright 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:flutter/widgets.dart';
-
-import 'colors.dart';
-import 'material_button.dart';
-import 'theme.dart';
-
-class RaisedButton extends MaterialButton {
-  RaisedButton({
-    Key key,
-    Widget child,
-    VoidCallback onPressed
-  }) : super(key: key,
-             child: child,
-             onPressed: onPressed);
-
-  _RaisedButtonState createState() => new _RaisedButtonState();
-}
-
-class _RaisedButtonState extends MaterialButtonState<RaisedButton> {
-
-  int get level => config.enabled ? (highlight ? 2 : 1) : 0;
-
-  Color getColor(BuildContext context, { bool highlight }) {
-    if (config.enabled) {
-      switch (Theme.of(context).brightness) {
-        case ThemeBrightness.light:
-          if (highlight)
-            return Colors.grey[350];
-          else
-            return Colors.grey[300];
-          break;
-        case ThemeBrightness.dark:
-          Map<int, Color> swatch = Theme.of(context).primarySwatch ?? Colors.blue;
-          if (highlight)
-            return swatch[700];
-          else
-            return swatch[600];
-          break;
-      }
-    } else {
-      switch (Theme.of(context).brightness) {
-        case ThemeBrightness.light:
-          return Colors.black12;
-        case ThemeBrightness.dark:
-          return Colors.white12;
-      }
-    }
-  }
-
-  ThemeBrightness getColorBrightness(BuildContext context) {
-    return Theme.of(context).brightness;
-  }
-
-}
diff --git a/sky/packages/sky/lib/src/material/scaffold.dart b/sky/packages/sky/lib/src/material/scaffold.dart
deleted file mode 100644
index 3a88ce9..0000000
--- a/sky/packages/sky/lib/src/material/scaffold.dart
+++ /dev/null
@@ -1,122 +0,0 @@
-// Copyright 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 'dart:math' as math;
-import 'dart:ui' as ui;
-
-import 'package:flutter/rendering.dart';
-import 'package:flutter/widgets.dart';
-
-import 'constants.dart';
-import 'material.dart';
-import 'tool_bar.dart';
-
-const double _kFloatingActionButtonMargin = 16.0; // TODO(hmuller): should be device dependent
-
-enum _Child { body, toolBar, bottomSheet, snackBar, floatingActionButton }
-
-class _ScaffoldLayout extends MultiChildLayoutDelegate {
-  void performLayout(Size size, BoxConstraints constraints) {
-
-    // This part of the layout has the same effect as putting the toolbar and
-    // body in a column and making the body flexible. What's different is that
-    // in this case the toolbar appears -after- the body in the stacking order,
-    // so the toolbar's shadow is drawn on top of the body.
-
-    final BoxConstraints toolBarConstraints = constraints.loosen().tightenWidth(size.width);
-    Size toolBarSize = Size.zero;
-
-    if (isChild(_Child.toolBar)) {
-      toolBarSize = layoutChild(_Child.toolBar, toolBarConstraints);
-      positionChild(_Child.toolBar, Point.origin);
-    }
-
-    if (isChild(_Child.body)) {
-      final double bodyHeight = size.height - toolBarSize.height;
-      final BoxConstraints bodyConstraints = toolBarConstraints.tightenHeight(bodyHeight);
-      layoutChild(_Child.body, bodyConstraints);
-      positionChild(_Child.body, new Point(0.0, toolBarSize.height));
-    }
-
-    // The BottomSheet and the SnackBar are anchored to the bottom of the parent,
-    // they're as wide as the parent and are given their intrinsic height.
-    // If all three elements are present then either the center of the FAB straddles
-    // the top edge of the BottomSheet or the bottom of the FAB is
-    // _kFloatingActionButtonMargin above the SnackBar, whichever puts the FAB
-    // the farthest above the bottom of the parent. If only the FAB is has a
-    // non-zero height then it's inset from the parent's right and bottom edges
-    // by _kFloatingActionButtonMargin.
-
-    final BoxConstraints fullWidthConstraints = constraints.loosen().tightenWidth(size.width);
-    Size bottomSheetSize = Size.zero;
-    Size snackBarSize = Size.zero;
-
-    if (isChild(_Child.bottomSheet)) {
-      bottomSheetSize = layoutChild(_Child.bottomSheet, fullWidthConstraints);
-      positionChild(_Child.bottomSheet, new Point(0.0, size.height - bottomSheetSize.height));
-    }
-
-    if (isChild(_Child.snackBar)) {
-      snackBarSize = layoutChild(_Child.snackBar, fullWidthConstraints);
-      positionChild(_Child.snackBar, new Point(0.0, size.height - snackBarSize.height));
-    }
-
-    if (isChild(_Child.floatingActionButton)) {
-      final Size fabSize = layoutChild(_Child.floatingActionButton, constraints.loosen());
-      final double fabX = size.width - fabSize.width - _kFloatingActionButtonMargin;
-      double fabY = size.height - fabSize.height - _kFloatingActionButtonMargin;
-      if (snackBarSize.height > 0.0)
-        fabY = math.min(fabY, size.height - snackBarSize.height - fabSize.height - _kFloatingActionButtonMargin);
-      if (bottomSheetSize.height > 0.0)
-        fabY = math.min(fabY, size.height - bottomSheetSize.height - fabSize.height / 2.0);
-      positionChild(_Child.floatingActionButton, new Point(fabX, fabY));
-    }
-  }
-}
-
-final _ScaffoldLayout _scaffoldLayout = new _ScaffoldLayout();
-
-void _addIfNonNull(List<LayoutId> children, Widget child, Object childId) {
-  if (child != null)
-    children.add(new LayoutId(child: child, id: childId));
-}
-
-class Scaffold extends StatelessComponent {
-  Scaffold({
-    Key key,
-    this.body,
-    this.toolBar,
-    this.snackBar,
-    this.floatingActionButton,
-    this.bottomSheet
-  }) : super(key: key);
-
-  final Widget body;
-  final ToolBar toolBar;
-  final Widget snackBar;
-  final Widget floatingActionButton;
-  final Widget bottomSheet;
-
-  Widget build(BuildContext context) {
-    final Widget paddedToolBar = toolBar?.withPadding(new EdgeDims.only(top: ui.window.padding.top));
-    final Widget materialBody = body != null ? new Material(child: body) : null;
-    Widget constrainedSnackBar;
-    if (snackBar != null) {
-      // TODO(jackson): On tablet/desktop, minWidth = 288, maxWidth = 568
-      constrainedSnackBar = new ConstrainedBox(
-        constraints: const BoxConstraints(maxHeight: kSnackBarHeight),
-        child: snackBar
-      );
-    }
-
-    final List<LayoutId>children = new List<LayoutId>();
-    _addIfNonNull(children, materialBody, _Child.body);
-    _addIfNonNull(children, paddedToolBar, _Child.toolBar);
-    _addIfNonNull(children, bottomSheet, _Child.bottomSheet);
-    _addIfNonNull(children, constrainedSnackBar, _Child.snackBar);
-    _addIfNonNull(children, floatingActionButton, _Child.floatingActionButton);
-
-    return new CustomMultiChildLayout(children, delegate: _scaffoldLayout);
-  }
-}
diff --git a/sky/packages/sky/lib/src/material/scrollbar_painter.dart b/sky/packages/sky/lib/src/material/scrollbar_painter.dart
deleted file mode 100644
index 5eb8f72..0000000
--- a/sky/packages/sky/lib/src/material/scrollbar_painter.dart
+++ /dev/null
@@ -1,81 +0,0 @@
-// Copyright 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 'dart:async';
-
-import 'package:flutter/animation.dart';
-import 'package:flutter/rendering.dart';
-import 'package:flutter/widgets.dart';
-
-const double _kMinScrollbarThumbLength = 18.0;
-const double _kScrollbarThumbGirth = 6.0;
-const Duration _kScrollbarThumbFadeDuration = const Duration(milliseconds: 300);
-
-class ScrollbarPainter extends ScrollableListPainter {
-
-  double _opacity = 0.0;
-  int get _alpha => (_opacity * 0xFF).round();
-
-  // TODO(hansmuller): thumb color should come from ThemeData.
-  Color get thumbColor => const Color(0xFF9E9E9E);
-
-  void paintThumb(PaintingContext context, Rect thumbBounds) {
-    final Paint paint = new Paint()..color = thumbColor.withAlpha(_alpha);
-    context.canvas.drawRect(thumbBounds, paint);
-  }
-
-  void paintScrollbar(PaintingContext context, Offset offset) {
-    final Rect viewportBounds = offset & viewportSize;
-    Point thumbOrigin;
-    Size thumbSize;
-
-    if (isVertical) {
-      double thumbHeight = viewportBounds.height * viewportBounds.height / contentExtent;
-      thumbHeight = thumbHeight.clamp(_kMinScrollbarThumbLength, viewportBounds.height);
-      final double maxThumbTop = viewportBounds.height - thumbHeight;
-      double thumbTop = (scrollOffset / (contentExtent - viewportBounds.height)) * maxThumbTop;
-      thumbTop = viewportBounds.top + thumbTop.clamp(0.0, maxThumbTop);
-      thumbOrigin = new Point(viewportBounds.right - _kScrollbarThumbGirth, thumbTop);
-      thumbSize = new Size(_kScrollbarThumbGirth, thumbHeight);
-    } else {
-      double thumbWidth = viewportBounds.width * viewportBounds.width / contentExtent;
-      thumbWidth = thumbWidth.clamp(_kMinScrollbarThumbLength, viewportBounds.width);
-      final double maxThumbLeft = viewportBounds.width - thumbWidth;
-      double thumbLeft = (scrollOffset / (contentExtent - viewportBounds.width)) * maxThumbLeft;
-      thumbLeft = viewportBounds.left + thumbLeft.clamp(0.0, maxThumbLeft);
-      thumbOrigin = new Point(thumbLeft, viewportBounds.height - _kScrollbarThumbGirth);
-      thumbSize = new Size(thumbWidth, _kScrollbarThumbGirth);
-    }
-
-    paintThumb(context, thumbOrigin & thumbSize);
-  }
-
-  void paint(PaintingContext context, Offset offset) {
-    if (_alpha == 0)
-      return;
-    paintScrollbar(context, offset);
-  }
-
-  ValuePerformance<double> _fade;
-
-  Future scrollStarted() {
-    _fade ??= new ValuePerformance<double>()
-      ..duration = _kScrollbarThumbFadeDuration
-      ..variable = new AnimatedValue<double>(0.0, end: 1.0, curve: Curves.ease)
-      ..addListener(() {
-        _opacity = _fade.value;
-        renderer?.markNeedsPaint();
-      });
-    return _fade.forward();
-  }
-
-  Future scrollEnded() {
-    return _fade.reverse();
-  }
-
-  void detach() {
-    super.detach();
-    _fade?.stop();
-  }
-}
diff --git a/sky/packages/sky/lib/src/material/shadows.dart b/sky/packages/sky/lib/src/material/shadows.dart
deleted file mode 100644
index 32be830..0000000
--- a/sky/packages/sky/lib/src/material/shadows.dart
+++ /dev/null
@@ -1,60 +0,0 @@
-// Copyright 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 'dart:ui' show Color, Offset;
-
-import 'package:flutter/painting.dart';
-
-const Map<int, List<BoxShadow>> shadows = const <int, List<BoxShadow>>{
-  1: const <BoxShadow>[
-    const BoxShadow(
-      color: const Color(0x1F000000),
-      offset: const Offset(0.0, 1.0),
-      blur: 3.0),
-    const BoxShadow(
-      color: const Color(0x3D000000),
-      offset: const Offset(0.0, 1.0),
-      blur: 2.0),
-    ],
-  2: const <BoxShadow>[
-    const BoxShadow(
-      color: const Color(0x29000000),
-      offset: const Offset(0.0, 3.0),
-      blur: 6.0),
-    const BoxShadow(
-      color: const Color(0x3B000000),
-      offset: const Offset(0.0, 3.0),
-      blur: 6.0),
-  ],
-  3: const <BoxShadow>[
-    const BoxShadow(
-      color: const Color(0x30000000),
-      offset: const Offset(0.0, 10.0),
-      blur: 20.0),
-    const BoxShadow(
-      color: const Color(0x3B000000),
-      offset: const Offset(0.0, 6.0),
-      blur: 6.0),
-  ],
-  4: const <BoxShadow>[
-    const BoxShadow(
-      color: const Color(0x40000000),
-      offset: const Offset(0.0, 14.0),
-      blur: 28.0),
-    const BoxShadow(
-      color: const Color(0x38000000),
-      offset: const Offset(0.0, 10.0),
-      blur: 10.0),
-  ],
-  5: const <BoxShadow>[
-    const BoxShadow(
-      color: const Color(0x4E000000),
-      offset: const Offset(0.0, 19.0),
-      blur: 28.0),
-    const BoxShadow(
-      color: const Color(0x38000000),
-      offset: const Offset(0.0, 15.0),
-      blur: 12.0),
-  ],
-};
diff --git a/sky/packages/sky/lib/src/material/snack_bar.dart b/sky/packages/sky/lib/src/material/snack_bar.dart
deleted file mode 100644
index 6b59282..0000000
--- a/sky/packages/sky/lib/src/material/snack_bar.dart
+++ /dev/null
@@ -1,108 +0,0 @@
-// Copyright 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:flutter/animation.dart';
-import 'package:flutter/widgets.dart';
-
-import 'constants.dart';
-import 'material.dart';
-import 'theme.dart';
-import 'typography.dart';
-
-const double _kSideMargins = 24.0;
-const double _kVerticalPadding = 14.0;
-const Color _kSnackBackground = const Color(0xFF323232);
-
-class SnackBarAction extends StatelessComponent {
-  SnackBarAction({Key key, this.label, this.onPressed }) : super(key: key) {
-    assert(label != null);
-  }
-
-  final String label;
-  final VoidCallback onPressed;
-
-  Widget build(BuildContext context) {
-    return new GestureDetector(
-      onTap: onPressed,
-      child: new Container(
-        margin: const EdgeDims.only(left: _kSideMargins),
-        padding: const EdgeDims.symmetric(vertical: _kVerticalPadding),
-        child: new Text(label)
-      )
-    );
-  }
-}
-
-class _SnackBar extends StatelessComponent {
-  _SnackBar({
-    Key key,
-    this.content,
-    this.actions,
-    this.route
-  }) : super(key: key) {
-    assert(content != null);
-  }
-
-  final Widget content;
-  final List<SnackBarAction> actions;
-  final _SnackBarRoute route;
-
-  Widget build(BuildContext context) {
-    List<Widget> children = <Widget>[
-      new Flexible(
-        child: new Container(
-          margin: const EdgeDims.symmetric(vertical: _kVerticalPadding),
-          child: new DefaultTextStyle(
-            style: Typography.white.subhead,
-            child: content
-          )
-        )
-      )
-    ];
-    if (actions != null)
-      children.addAll(actions);
-    return new SquashTransition(
-      performance: route.performance,
-      height: new AnimatedValue<double>(
-        0.0,
-        end: kSnackBarHeight,
-        curve: Curves.easeIn,
-        reverseCurve: Curves.easeOut
-      ),
-      child: new ClipRect(
-        child: new OverflowBox(
-          minHeight: kSnackBarHeight,
-          maxHeight: kSnackBarHeight,
-          child: new Material(
-            level: 2,
-            color: _kSnackBackground,
-            child: new Container(
-              margin: const EdgeDims.symmetric(horizontal: _kSideMargins),
-              child: new DefaultTextStyle(
-                style: new TextStyle(color: Theme.of(context).accentColor),
-                child: new Row(children)
-              )
-            )
-          )
-        )
-      )
-    );
-  }
-}
-
-class _SnackBarRoute extends TransitionRoute {
-  bool get opaque => false;
-  Duration get transitionDuration => const Duration(milliseconds: 200);
-}
-
-void showSnackBar({ BuildContext context, GlobalKey<PlaceholderState> placeholderKey, Widget content, List<SnackBarAction> actions }) {
-  _SnackBarRoute route = new _SnackBarRoute();
-  _SnackBar snackBar = new _SnackBar(
-    route: route,
-    content: content,
-    actions: actions
-  );
-  placeholderKey.currentState.child = snackBar;
-  Navigator.of(context).pushEphemeral(route);
-}
diff --git a/sky/packages/sky/lib/src/material/switch.dart b/sky/packages/sky/lib/src/material/switch.dart
deleted file mode 100644
index 9d7215b..0000000
--- a/sky/packages/sky/lib/src/material/switch.dart
+++ /dev/null
@@ -1,149 +0,0 @@
-// Copyright 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 'dart:async';
-import 'dart:ui' as ui;
-
-import 'package:flutter/painting.dart';
-import 'package:flutter/rendering.dart';
-import 'package:flutter/widgets.dart';
-
-import 'radial_reaction.dart';
-import 'shadows.dart';
-import 'theme.dart';
-
-const Color _kThumbOffColor = const Color(0xFFFAFAFA);
-const Color _kTrackOffColor = const Color(0x42000000);
-const double _kSwitchWidth = 35.0;
-const double _kThumbRadius = 10.0;
-const double _kSwitchHeight = _kThumbRadius * 2.0;
-const double _kTrackHeight = 14.0;
-const double _kTrackRadius = _kTrackHeight / 2.0;
-const double _kTrackWidth =
-    _kSwitchWidth - (_kThumbRadius - _kTrackRadius) * 2.0;
-const Size _kSwitchSize = const Size(_kSwitchWidth + 2.0, _kSwitchHeight + 2.0);
-const double _kReactionRadius = _kSwitchWidth / 2.0;
-
-class Switch extends StatelessComponent {
-  Switch({ Key key, this.value, this.onChanged })
-      : super(key: key);
-
-  final bool value;
-  final ValueChanged<bool> onChanged;
-
-  Widget build(BuildContext context) {
-    return new _SwitchWrapper(
-      value: value,
-      thumbColor: Theme.of(context).accentColor,
-      onChanged: onChanged
-    );
-  }
-}
-
-class _SwitchWrapper extends LeafRenderObjectWidget {
-  _SwitchWrapper({ Key key, this.value, this.thumbColor, this.onChanged })
-      : super(key: key);
-
-  final bool value;
-  final Color thumbColor;
-  final ValueChanged<bool> onChanged;
-
-  _RenderSwitch createRenderObject() => new _RenderSwitch(
-    value: value,
-    thumbColor: thumbColor,
-    onChanged: onChanged
-  );
-
-  void updateRenderObject(_RenderSwitch renderObject, _SwitchWrapper oldWidget) {
-    renderObject.value = value;
-    renderObject.thumbColor = thumbColor;
-    renderObject.onChanged = onChanged;
-  }
-}
-
-class _RenderSwitch extends RenderToggleable {
-  _RenderSwitch({
-    bool value,
-    Color thumbColor: _kThumbOffColor,
-    ValueChanged<bool> onChanged
-  }) : _thumbColor = thumbColor,
-        super(value: value, onChanged: onChanged, size: _kSwitchSize);
-
-  Color _thumbColor;
-  Color get thumbColor => _thumbColor;
-  void set thumbColor(Color value) {
-    if (value == _thumbColor) return;
-    _thumbColor = value;
-    markNeedsPaint();
-  }
-
-  RadialReaction _radialReaction;
-
-  void handleEvent(InputEvent event, BoxHitTestEntry entry) {
-    if (event is PointerInputEvent) {
-      if (event.type == 'pointerdown')
-        _showRadialReaction(entry.localPosition);
-      else if (event.type == 'pointerup')
-        _hideRadialReaction();
-    }
-    super.handleEvent(event, entry);
-  }
-
-  void _showRadialReaction(Point startLocation) {
-    if (_radialReaction != null)
-      return;
-    _radialReaction = new RadialReaction(
-      center: new Point(_kSwitchSize.width / 2.0, _kSwitchSize.height / 2.0),
-      radius: _kReactionRadius,
-      startPosition: startLocation
-    )..addListener(markNeedsPaint)
-     ..show();
-  }
-
-  Future _hideRadialReaction() async {
-    if (_radialReaction == null)
-      return;
-    await _radialReaction.hide();
-    _radialReaction = null;
-  }
-
-  void paint(PaintingContext context, Offset offset) {
-    final PaintingCanvas canvas = context.canvas;
-    Color thumbColor = _kThumbOffColor;
-    Color trackColor = _kTrackOffColor;
-    if (value) {
-      thumbColor = _thumbColor;
-      trackColor = new Color(_thumbColor.value & 0x80FFFFFF);
-    }
-
-    // Draw the track rrect
-    Paint paint = new Paint()
-      ..color = trackColor
-      ..style = ui.PaintingStyle.fill;
-    Rect rect = new Rect.fromLTWH(offset.dx,
-        offset.dy + _kSwitchHeight / 2.0 - _kTrackHeight / 2.0, _kTrackWidth,
-        _kTrackHeight);
-    ui.RRect rrect = new ui.RRect.fromRectXY(
-        rect, _kTrackRadius, _kTrackRadius);
-    canvas.drawRRect(rrect, paint);
-
-    if (_radialReaction != null)
-      _radialReaction.paint(canvas, offset);
-
-    // Draw the raised thumb with a shadow
-    paint.color = thumbColor;
-    ShadowDrawLooperBuilder builder = new ShadowDrawLooperBuilder();
-    for (BoxShadow boxShadow in shadows[1])
-      builder.addShadow(boxShadow.offset, boxShadow.color, boxShadow.blur);
-    paint.drawLooper = builder.build();
-
-    // The thumb contracts slightly during the animation
-    double inset = 2.0 - (position - 0.5).abs() * 2.0;
-    Point thumbPos = new Point(offset.dx +
-            _kTrackRadius +
-            position * (_kTrackWidth - _kTrackRadius * 2),
-        offset.dy + _kSwitchHeight / 2.0);
-    canvas.drawCircle(thumbPos, _kThumbRadius - inset, paint);
-  }
-}
diff --git a/sky/packages/sky/lib/src/material/tabs.dart b/sky/packages/sky/lib/src/material/tabs.dart
deleted file mode 100644
index efb3cd6..0000000
--- a/sky/packages/sky/lib/src/material/tabs.dart
+++ /dev/null
@@ -1,608 +0,0 @@
-// Copyright 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 'dart:math' as math;
-
-import 'package:newton/newton.dart';
-import 'package:flutter/animation.dart';
-import 'package:flutter/rendering.dart';
-import 'package:flutter/widgets.dart';
-
-import 'colors.dart';
-import 'constants.dart';
-import 'icon.dart';
-import 'icon_theme.dart';
-import 'icon_theme_data.dart';
-import 'ink_well.dart';
-import 'theme.dart';
-
-typedef void TabSelectedIndexChanged(int selectedIndex);
-typedef void TabLayoutChanged(Size size, List<double> widths);
-
-// See https://www.google.com/design/spec/components/tabs.html#tabs-specs
-const double _kTabHeight = 46.0;
-const double _kTextAndIconTabHeight = 72.0;
-const double _kTabIndicatorHeight = 2.0;
-const double _kMinTabWidth = 72.0;
-const double _kMaxTabWidth = 264.0;
-const EdgeDims _kTabLabelPadding = const EdgeDims.symmetric(horizontal: 12.0);
-const double _kTabBarScrollDrag = 0.025;
-const Duration _kTabBarScroll = const Duration(milliseconds: 200);
-
-class _TabBarParentData extends ContainerBoxParentDataMixin<RenderBox> { }
-
-class _RenderTabBar extends RenderBox with
-    ContainerRenderObjectMixin<RenderBox, _TabBarParentData>,
-    RenderBoxContainerDefaultsMixin<RenderBox, _TabBarParentData> {
-
-  _RenderTabBar(this.onLayoutChanged);
-
-  int _selectedIndex;
-  int get selectedIndex => _selectedIndex;
-  void set selectedIndex(int value) {
-    if (_selectedIndex != value) {
-      _selectedIndex = value;
-      markNeedsPaint();
-    }
-  }
-
-  Color _indicatorColor;
-  Color get indicatorColor => _indicatorColor;
-  void set indicatorColor(Color value) {
-    if (_indicatorColor != value) {
-      _indicatorColor = value;
-      markNeedsPaint();
-    }
-  }
-
-  Rect _indicatorRect;
-  Rect get indicatorRect => _indicatorRect;
-  void set indicatorRect(Rect value) {
-    if (_indicatorRect != value) {
-      _indicatorRect = value;
-      markNeedsPaint();
-    }
-  }
-
-  bool _textAndIcons;
-  bool get textAndIcons => _textAndIcons;
-  void set textAndIcons(bool value) {
-    if (_textAndIcons != value) {
-      _textAndIcons = value;
-      markNeedsLayout();
-    }
-  }
-
-  bool _isScrollable;
-  bool get isScrollable => _isScrollable;
-  void set isScrollable(bool value) {
-    if (_isScrollable != value) {
-      _isScrollable = value;
-      markNeedsLayout();
-    }
-  }
-
-  void setupParentData(RenderBox child) {
-    if (child.parentData is! _TabBarParentData)
-      child.parentData = new _TabBarParentData();
-  }
-
-  double getMinIntrinsicWidth(BoxConstraints constraints) {
-    BoxConstraints widthConstraints =
-        new BoxConstraints(maxWidth: constraints.maxWidth, maxHeight: constraints.maxHeight);
-
-    double maxWidth = 0.0;
-    RenderBox child = firstChild;
-    while (child != null) {
-      maxWidth = math.max(maxWidth, child.getMinIntrinsicWidth(widthConstraints));
-      final _TabBarParentData childParentData = child.parentData;
-      child = childParentData.nextSibling;
-    }
-    double width = isScrollable ? maxWidth : maxWidth * childCount;
-    return constraints.constrainWidth(width);
-  }
-
-  double getMaxIntrinsicWidth(BoxConstraints constraints) {
-    BoxConstraints widthConstraints =
-        new BoxConstraints(maxWidth: constraints.maxWidth, maxHeight: constraints.maxHeight);
-
-    double maxWidth = 0.0;
-    RenderBox child = firstChild;
-    while (child != null) {
-      maxWidth = math.max(maxWidth, child.getMaxIntrinsicWidth(widthConstraints));
-      final _TabBarParentData childParentData = child.parentData;
-      child = childParentData.nextSibling;
-    }
-    double width = isScrollable ? maxWidth : maxWidth * childCount;
-    return constraints.constrainWidth(width);
-  }
-
-  double get _tabHeight => textAndIcons ? _kTextAndIconTabHeight : _kTabHeight;
-  double get _tabBarHeight => _tabHeight + _kTabIndicatorHeight;
-
-  double _getIntrinsicHeight(BoxConstraints constraints) => constraints.constrainHeight(_tabBarHeight);
-
-  double getMinIntrinsicHeight(BoxConstraints constraints) => _getIntrinsicHeight(constraints);
-
-  double getMaxIntrinsicHeight(BoxConstraints constraints) => _getIntrinsicHeight(constraints);
-
-  void layoutFixedWidthTabs() {
-    double tabWidth = size.width / childCount;
-    BoxConstraints tabConstraints =
-      new BoxConstraints.tightFor(width: tabWidth, height: _tabHeight);
-    double x = 0.0;
-    RenderBox child = firstChild;
-    while (child != null) {
-      child.layout(tabConstraints);
-      final _TabBarParentData childParentData = child.parentData;
-      childParentData.position = new Point(x, 0.0);
-      x += tabWidth;
-      child = childParentData.nextSibling;
-    }
-  }
-
-  double layoutScrollableTabs() {
-    BoxConstraints tabConstraints = new BoxConstraints(
-      minWidth: _kMinTabWidth,
-      maxWidth: _kMaxTabWidth,
-      minHeight: _tabHeight,
-      maxHeight: _tabHeight
-    );
-    double x = 0.0;
-    RenderBox child = firstChild;
-    while (child != null) {
-      child.layout(tabConstraints, parentUsesSize: true);
-      final _TabBarParentData childParentData = child.parentData;
-      childParentData.position = new Point(x, 0.0);
-      x += child.size.width;
-      child = childParentData.nextSibling;
-    }
-    return x;
-  }
-
-  Size layoutSize;
-  List<double> layoutWidths;
-  TabLayoutChanged onLayoutChanged;
-
-  void reportLayoutChangedIfNeeded() {
-    assert(onLayoutChanged != null);
-    List<double> widths = new List<double>(childCount);
-    if (!isScrollable && childCount > 0) {
-      double tabWidth = size.width / childCount;
-      widths.fillRange(0, widths.length, tabWidth);
-    } else if (isScrollable) {
-      RenderBox child = firstChild;
-      int childIndex = 0;
-      while (child != null) {
-        widths[childIndex++] = child.size.width;
-        final _TabBarParentData childParentData = child.parentData;
-        child = childParentData.nextSibling;
-      }
-      assert(childIndex == widths.length);
-    }
-    if (size != layoutSize || widths != layoutWidths) {
-      layoutSize = size;
-      layoutWidths = widths;
-      onLayoutChanged(layoutSize, layoutWidths);
-    }
-  }
-
-  void performLayout() {
-    assert(constraints is BoxConstraints);
-    if (childCount == 0)
-      return;
-
-    if (isScrollable) {
-      double tabBarWidth = layoutScrollableTabs();
-      size = constraints.constrain(new Size(tabBarWidth, _tabBarHeight));
-    } else {
-      size = constraints.constrain(new Size(constraints.maxWidth, _tabBarHeight));
-      layoutFixedWidthTabs();
-    }
-
-    if (onLayoutChanged != null)
-      reportLayoutChangedIfNeeded();
-  }
-
-  bool hitTestChildren(HitTestResult result, { Point position }) {
-    return defaultHitTestChildren(result, position: position);
-  }
-
-  void _paintIndicator(PaintingCanvas canvas, RenderBox selectedTab, Offset offset) {
-    if (indicatorColor == null)
-      return;
-
-    if (indicatorRect != null) {
-      canvas.drawRect(indicatorRect.shift(offset), new Paint()..color = indicatorColor);
-      return;
-    }
-
-    final Size size = new Size(selectedTab.size.width, _kTabIndicatorHeight);
-    final _TabBarParentData selectedTabParentData = selectedTab.parentData;
-    final Point point = new Point(
-      selectedTabParentData.position.x,
-      _tabBarHeight - _kTabIndicatorHeight
-    );
-    canvas.drawRect((point + offset) & size, new Paint()..color = indicatorColor);
-  }
-
-  void paint(PaintingContext context, Offset offset) {
-    int index = 0;
-    RenderBox child = firstChild;
-    while (child != null) {
-      final _TabBarParentData childParentData = child.parentData;
-      context.paintChild(child, childParentData.position + offset);
-      if (index++ == selectedIndex)
-        _paintIndicator(context.canvas, child, offset);
-      child = childParentData.nextSibling;
-    }
-  }
-}
-
-class _TabBarWrapper extends MultiChildRenderObjectWidget {
-  _TabBarWrapper({
-    Key key,
-    List<Widget> children,
-    this.selectedIndex,
-    this.indicatorColor,
-    this.indicatorRect,
-    this.textAndIcons,
-    this.isScrollable: false,
-    this.onLayoutChanged
-  }) : super(key: key, children: children);
-
-  final int selectedIndex;
-  final Color indicatorColor;
-  final Rect indicatorRect;
-  final bool textAndIcons;
-  final bool isScrollable;
-  final TabLayoutChanged onLayoutChanged;
-
-  _RenderTabBar createRenderObject() {
-    _RenderTabBar result = new _RenderTabBar(onLayoutChanged);
-    updateRenderObject(result, null);
-    return result;
-  }
-
-  void updateRenderObject(_RenderTabBar renderObject, _TabBarWrapper oldWidget) {
-    renderObject.selectedIndex = selectedIndex;
-    renderObject.indicatorColor = indicatorColor;
-    renderObject.indicatorRect = indicatorRect;
-    renderObject.textAndIcons = textAndIcons;
-    renderObject.isScrollable = isScrollable;
-    renderObject.onLayoutChanged = onLayoutChanged;
-  }
-}
-
-class TabLabel {
-  const TabLabel({ this.text, this.icon });
-
-  final String text;
-  final String icon;
-
-  String toString() {
-    if (text != null && icon != null)
-      return '"$text" ($icon)';
-    if (text != null)
-      return '"$text"';
-    if (icon != null)
-      return '$icon';
-    return 'EMPTY TAB LABEL';
-  }
-}
-
-class Tab extends StatelessComponent {
-  Tab({
-    Key key,
-    this.onSelected,
-    this.label,
-    this.color,
-    this.selected: false,
-    this.selectedColor
-  }) : super(key: key) {
-    assert(label.text != null || label.icon != null);
-  }
-
-  final VoidCallback onSelected;
-  final TabLabel label;
-  final Color color;
-  final bool selected;
-  final Color selectedColor;
-
-  Widget _buildLabelText() {
-    assert(label.text != null);
-    TextStyle style = new TextStyle(color: selected ? selectedColor : color);
-    return new Text(label.text, style: style);
-  }
-
-  Widget _buildLabelIcon() {
-    assert(label.icon != null);
-    Color iconColor = selected ? selectedColor : color;
-    ColorFilter filter = new ColorFilter.mode(iconColor, TransferMode.srcATop);
-    return new Icon(icon: label.icon, colorFilter: filter);
-  }
-
-  Widget build(BuildContext context) {
-    Widget labelContent;
-    if (label.icon == null) {
-      labelContent = _buildLabelText();
-    } else if (label.text == null) {
-      labelContent = _buildLabelIcon();
-    } else {
-      labelContent = new Column(
-        <Widget>[
-          new Container(
-            child: _buildLabelIcon(),
-            margin: const EdgeDims.only(bottom: 10.0)
-          ),
-          _buildLabelText()
-        ],
-        justifyContent: FlexJustifyContent.center,
-        alignItems: FlexAlignItems.center
-      );
-    }
-
-    Container centeredLabel = new Container(
-      child: new Center(child: labelContent, widthFactor: 1.0, heightFactor: 1.0),
-      constraints: new BoxConstraints(minWidth: _kMinTabWidth),
-      padding: _kTabLabelPadding
-    );
-
-    return new InkWell(
-      onTap: onSelected,
-      child: centeredLabel
-    );
-  }
-
-  void debugFillDescription(List<String> description) {
-    super.debugFillDescription(description);
-    description.add('$label');
-  }
-}
-
-class _TabsScrollBehavior extends BoundedBehavior {
-  _TabsScrollBehavior();
-
-  bool isScrollable = true;
-
-  Simulation createFlingScrollSimulation(double position, double velocity) {
-    if (!isScrollable)
-      return null;
-
-    double velocityPerSecond = velocity * 1000.0;
-    return new BoundedFrictionSimulation(
-      _kTabBarScrollDrag, position, velocityPerSecond, minScrollOffset, maxScrollOffset
-    );
-  }
-
-  double applyCurve(double scrollOffset, double scrollDelta) {
-    return (isScrollable) ? super.applyCurve(scrollOffset, scrollDelta) : 0.0;
-  }
-}
-
-class TabBar extends Scrollable {
-  TabBar({
-    Key key,
-    this.labels,
-    this.selectedIndex: 0,
-    this.onChanged,
-    this.isScrollable: false
-  }) : super(key: key, scrollDirection: ScrollDirection.horizontal);
-
-  final Iterable<TabLabel> labels;
-  final int selectedIndex;
-  final TabSelectedIndexChanged onChanged;
-  final bool isScrollable;
-
-  _TabBarState createState() => new _TabBarState();
-}
-
-class _TabBarState extends ScrollableState<TabBar> {
-  void initState() {
-    super.initState();
-    _indicatorAnimation = new ValuePerformance<Rect>()
-      ..duration = _kTabBarScroll
-      ..variable = new AnimatedRectValue(null, curve: Curves.ease);
-    scrollBehavior.isScrollable = config.isScrollable;
-  }
-
-  Size _tabBarSize;
-  Size _viewportSize = Size.zero;
-  List<double> _tabWidths;
-  ValuePerformance<Rect> _indicatorAnimation;
-
-  void didUpdateConfig(TabBar oldConfig) {
-    super.didUpdateConfig(oldConfig);
-    if (!config.isScrollable)
-      scrollTo(0.0);
-  }
-
-  AnimatedRectValue get _indicatorRect => _indicatorAnimation.variable;
-
-  void _startIndicatorAnimation(int fromTabIndex, int toTabIndex) {
-    _indicatorRect
-      ..begin = (_indicatorRect.value == null ? _tabIndicatorRect(fromTabIndex) : _indicatorRect.value)
-      ..end = _tabIndicatorRect(toTabIndex);
-    _indicatorAnimation
-      ..progress = 0.0
-      ..play();
-  }
-
-  ScrollBehavior createScrollBehavior() => new _TabsScrollBehavior();
-  _TabsScrollBehavior get scrollBehavior => super.scrollBehavior;
-
-  Rect _tabRect(int tabIndex) {
-    assert(_tabBarSize != null);
-    assert(_tabWidths != null);
-    assert(tabIndex >= 0 && tabIndex < _tabWidths.length);
-    double tabLeft = 0.0;
-    if (tabIndex > 0)
-      tabLeft = _tabWidths.take(tabIndex).reduce((double sum, double width) => sum + width);
-    double tabTop = 0.0;
-    double tabBottom = _tabBarSize.height - _kTabIndicatorHeight;
-    double tabRight = tabLeft + _tabWidths[tabIndex];
-    return new Rect.fromLTRB(tabLeft, tabTop, tabRight, tabBottom);
-  }
-
-  Rect _tabIndicatorRect(int tabIndex) {
-    Rect r = _tabRect(tabIndex);
-    return new Rect.fromLTRB(r.left, r.bottom, r.right, r.bottom + _kTabIndicatorHeight);
-  }
-
-  double _centeredTabScrollOffset(int tabIndex) {
-    double viewportWidth = scrollBehavior.containerExtent;
-    return (_tabRect(tabIndex).left + _tabWidths[tabIndex] / 2.0 - viewportWidth / 2.0)
-      .clamp(scrollBehavior.minScrollOffset, scrollBehavior.maxScrollOffset);
-  }
-
-  void _handleTabSelected(int tabIndex) {
-    if (tabIndex != config.selectedIndex) {
-      if (_tabWidths != null) {
-        if (config.isScrollable)
-          scrollTo(_centeredTabScrollOffset(tabIndex), duration: _kTabBarScroll);
-        _startIndicatorAnimation(config.selectedIndex, tabIndex);
-      }
-      if (config.onChanged != null)
-        config.onChanged(tabIndex);
-    }
-  }
-
-  Widget _toTab(TabLabel label, int tabIndex, Color color, Color selectedColor) {
-    return new Tab(
-      onSelected: () => _handleTabSelected(tabIndex),
-      label: label,
-      color: color,
-      selected: tabIndex == config.selectedIndex,
-      selectedColor: selectedColor
-    );
-  }
-
-  void _updateScrollBehavior() {
-    scrollBehavior.updateExtents(
-      containerExtent: config.scrollDirection == ScrollDirection.vertical ? _viewportSize.height : _viewportSize.width,
-      contentExtent: _tabWidths.reduce((double sum, double width) => sum + width)
-    );
-  }
-
-  void _layoutChanged(Size tabBarSize, List<double> tabWidths) {
-    setState(() {
-      _tabBarSize = tabBarSize;
-      _tabWidths = tabWidths;
-      _updateScrollBehavior();
-    });
-  }
-
-  void _handleViewportSizeChanged(Size newSize) {
-    _viewportSize = newSize;
-    _updateScrollBehavior();
-  }
-
-  Widget buildContent(BuildContext context) {
-    assert(config.labels != null && config.labels.isNotEmpty);
-
-    ThemeData themeData = Theme.of(context);
-    Color backgroundColor = themeData.primaryColor;
-    Color indicatorColor = themeData.accentColor;
-    if (indicatorColor == backgroundColor) {
-      indicatorColor = Colors.white;
-    }
-
-    TextStyle textStyle = themeData.primaryTextTheme.body1;
-    IconThemeData iconTheme = themeData.primaryIconTheme;
-
-    List<Widget> tabs = <Widget>[];
-    bool textAndIcons = false;
-    int tabIndex = 0;
-    for (TabLabel label in config.labels) {
-      tabs.add(_toTab(label, tabIndex++, textStyle.color, indicatorColor));
-      if (label.text != null && label.icon != null)
-        textAndIcons = true;
-    }
-
-    Widget content = new IconTheme(
-      data: iconTheme,
-      child: new DefaultTextStyle(
-        style: textStyle,
-        child: new BuilderTransition(
-          variables: <AnimatedValue<Rect>>[_indicatorRect],
-          performance: _indicatorAnimation.view,
-          builder: (BuildContext context) {
-            return new _TabBarWrapper(
-              children: tabs,
-              selectedIndex: config.selectedIndex,
-              indicatorColor: indicatorColor,
-              indicatorRect: _indicatorRect.value,
-              textAndIcons: textAndIcons,
-              isScrollable: config.isScrollable,
-              onLayoutChanged: _layoutChanged
-            );
-          }
-        )
-      )
-    );
-
-    if (config.isScrollable) {
-      content = new SizeObserver(
-        onSizeChanged: _handleViewportSizeChanged,
-        child: new Viewport(
-          scrollDirection: ScrollDirection.horizontal,
-          scrollOffset: new Offset(scrollOffset, 0.0),
-          child: content
-        )
-      );
-    }
-
-    return new AnimatedContainer(
-      decoration: new BoxDecoration(
-        backgroundColor: backgroundColor
-      ),
-      duration: kThemeChangeDuration,
-      child: content
-    );
-  }
-}
-
-class TabNavigatorView {
-  TabNavigatorView({ this.label, this.builder }) {
-    assert(builder != null);
-  }
-
-  // this uses a builder for the contents, rather than a raw Widget child,
-  // because there might be many, many tabs and some might be relatively
-  // expensive to create up front. This way, the view is only created lazily.
-
-  final TabLabel label;
-  final WidgetBuilder builder;
-}
-
-class TabNavigator extends StatelessComponent {
-  TabNavigator({
-    Key key,
-    this.views,
-    this.selectedIndex: 0,
-    this.onChanged,
-    this.isScrollable: false
-  }) : super(key: key);
-
-  final List<TabNavigatorView> views;
-  final int selectedIndex;
-  final TabSelectedIndexChanged onChanged;
-  final bool isScrollable;
-
-  Widget build(BuildContext context) {
-    assert(views != null && views.isNotEmpty);
-    assert(selectedIndex >= 0 && selectedIndex < views.length);
-    return new Column(<Widget>[
-      new TabBar(
-        labels: views.map((TabNavigatorView view) => view.label),
-        onChanged: onChanged,
-        selectedIndex: selectedIndex,
-        isScrollable: isScrollable
-      ),
-      new Flexible(child: views[selectedIndex].builder(context))
-    ],
-      alignItems: FlexAlignItems.stretch
-    );
-  }
-}
diff --git a/sky/packages/sky/lib/src/material/theme.dart b/sky/packages/sky/lib/src/material/theme.dart
deleted file mode 100644
index 7d9233a..0000000
--- a/sky/packages/sky/lib/src/material/theme.dart
+++ /dev/null
@@ -1,36 +0,0 @@
-// Copyright 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:flutter/widgets.dart';
-
-import 'theme_data.dart';
-
-export 'theme_data.dart' show ThemeData, ThemeBrightness;
-
-class Theme extends InheritedWidget {
-  Theme({
-    Key key,
-    this.data,
-    Widget child
-  }) : super(key: key, child: child) {
-    assert(child != null);
-    assert(data != null);
-  }
-
-  final ThemeData data;
-
-  static final ThemeData _kFallbackTheme = new ThemeData.fallback();
-
-  static ThemeData of(BuildContext context) {
-    Theme theme = context.inheritedWidgetOfType(Theme);
-    return theme == null ? _kFallbackTheme : theme.data;
-  }
-
-  bool updateShouldNotify(Theme old) => data != old.data;
-
-  void debugFillDescription(List<String> description) {
-    super.debugFillDescription(description);
-    description.add('$data');
-  }
-}
diff --git a/sky/packages/sky/lib/src/material/theme_data.dart b/sky/packages/sky/lib/src/material/theme_data.dart
deleted file mode 100644
index 8e79255..0000000
--- a/sky/packages/sky/lib/src/material/theme_data.dart
+++ /dev/null
@@ -1,143 +0,0 @@
-// Copyright 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 'dart:ui' show Color;
-
-import 'colors.dart';
-import 'icon_theme_data.dart';
-import 'typography.dart';
-
-enum ThemeBrightness { dark, light }
-
-class ThemeData {
-
-  ThemeData({
-    ThemeBrightness brightness: ThemeBrightness.light,
-    Map<int, Color> primarySwatch,
-    Color accentColor,
-    this.accentColorBrightness: ThemeBrightness.dark,
-    TextTheme text
-  }): this.brightness = brightness,
-      this.primarySwatch = primarySwatch,
-      primaryColorBrightness = primarySwatch == null ? brightness : ThemeBrightness.dark,
-      canvasColor = brightness == ThemeBrightness.dark ? Colors.grey[850] : Colors.grey[50],
-      cardColor = brightness == ThemeBrightness.dark ? Colors.grey[800] : Colors.white,
-      dividerColor = brightness == ThemeBrightness.dark ? const Color(0x1FFFFFFF) : const Color(0x1F000000),
-      // Some users want the pre-multiplied color, others just want the opacity.
-      hintColor = brightness == ThemeBrightness.dark ? const Color(0x42FFFFFF) : const Color(0x4C000000),
-      hintOpacity = brightness == ThemeBrightness.dark ? 0.26 : 0.30,
-      // TODO(eseidel): Where are highlight and selected colors documented?
-      // I flipped highlight/selected to match the News app (which is clearly not quite Material)
-      // Gmail has an interesting behavior of showing selected darker until
-      // you click on a different drawer item when the first one loses its
-      // selected color and becomes lighter, the ink then fills to make the new
-      // click dark to match the previous (resting) selected state.  States
-      // revert when you cancel the tap.
-      highlightColor = const Color(0x33999999),
-      selectedColor = const Color(0x66999999),
-      text = brightness == ThemeBrightness.dark ? Typography.white : Typography.black {
-    assert(brightness != null);
-
-    if (primarySwatch == null) {
-      if (brightness == ThemeBrightness.dark) {
-        _primaryColor = Colors.grey[900];
-      } else {
-        _primaryColor = Colors.grey[100];
-      }
-    } else {
-      _primaryColor = primarySwatch[500];
-    }
-
-    if (accentColor == null) {
-      _accentColor = primarySwatch == null ? Colors.blue[500] : primarySwatch[500];
-    } else {
-      _accentColor = accentColor;
-    }
-  }
-
-  factory ThemeData.light() => new ThemeData(primarySwatch: Colors.blue, brightness: ThemeBrightness.light);
-  factory ThemeData.dark() => new ThemeData(brightness: ThemeBrightness.dark);
-  factory ThemeData.fallback() => new ThemeData.light();
-
-  /// The brightness of the overall theme of the application. Used by widgets
-  /// like buttons to determine what color to pick when not using the primary or
-  /// accent color.
-  final ThemeBrightness brightness;
-
-  final Map<int, Color> primarySwatch;
-  final Color canvasColor;
-  final Color cardColor;
-  final Color dividerColor;
-  final Color hintColor;
-  final Color highlightColor;
-  final Color selectedColor;
-  final double hintOpacity;
-  final TextTheme text;
-
-  /// The background colour for major parts of the app (toolbars, tab bars, etc)
-  Color get primaryColor => _primaryColor;
-  Color _primaryColor;
-
-  /// The brightness of the primaryColor. Used to determine the colour of text and
-  /// icons placed on top of the primary color (e.g. toolbar text).
-  final ThemeBrightness primaryColorBrightness;
-
-  /// A text theme that contrasts with the primary color.
-  TextTheme get primaryTextTheme {
-    if (primaryColorBrightness == ThemeBrightness.dark)
-      return Typography.white;
-    return Typography.black;
-  }
-
-  IconThemeData get primaryIconTheme {
-    if (primaryColorBrightness == ThemeBrightness.dark)
-      return const IconThemeData(color: IconThemeColor.white);
-    return const IconThemeData(color: IconThemeColor.black);
-  }
-
-  /// The foreground color for widgets (knobs, text, etc)
-  Color get accentColor => _accentColor;
-  Color _accentColor;
-
-  /// The brightness of the accentColor. Used to determine the colour of text
-  /// and icons placed on top of the accent color (e.g. the icons on a floating
-  /// action button).
-  final ThemeBrightness accentColorBrightness;
-
-  bool operator==(Object other) {
-    if (other.runtimeType != runtimeType)
-      return false;
-    ThemeData otherData = other;
-    return (otherData.brightness == brightness) &&
-           (otherData.primarySwatch == primarySwatch) &&
-           (otherData.canvasColor == canvasColor) &&
-           (otherData.cardColor == cardColor) &&
-           (otherData.dividerColor == dividerColor) &&
-           (otherData.hintColor == hintColor) &&
-           (otherData.highlightColor == highlightColor) &&
-           (otherData.selectedColor == selectedColor) &&
-           (otherData.hintOpacity == hintOpacity) &&
-           (otherData.text == text) &&
-           (otherData.primaryColorBrightness == primaryColorBrightness) &&
-           (otherData.accentColorBrightness == accentColorBrightness);
-  }
-  int get hashCode {
-    int value = 373;
-    value = 37 * value + brightness.hashCode;
-    value = 37 * value + primarySwatch.hashCode;
-    value = 37 * value + canvasColor.hashCode;
-    value = 37 * value + cardColor.hashCode;
-    value = 37 * value + dividerColor.hashCode;
-    value = 37 * value + hintColor.hashCode;
-    value = 37 * value + highlightColor.hashCode;
-    value = 37 * value + selectedColor.hashCode;
-    value = 37 * value + hintOpacity.hashCode;
-    value = 37 * value + text.hashCode;
-    value = 37 * value + primaryColorBrightness.hashCode;
-    value = 37 * value + accentColorBrightness.hashCode;
-    return value;
-  }
-
-  String toString() => '$primaryColor $brightness etc...';
-}
diff --git a/sky/packages/sky/lib/src/material/title.dart b/sky/packages/sky/lib/src/material/title.dart
deleted file mode 100644
index 293320c..0000000
--- a/sky/packages/sky/lib/src/material/title.dart
+++ /dev/null
@@ -1,25 +0,0 @@
-// Copyright 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:flutter/services.dart';
-import 'package:flutter/widgets.dart';
-
-import 'theme.dart';
-
-class Title extends StatelessComponent {
-  Title({ this.title, this.child });
-
-  final Widget child;
-  final String title;
-
-  Widget build(BuildContext context) {
-    updateTaskDescription(title, Theme.of(context).primaryColor);
-    return child;
-  }
-
-  void debugFillDescription(List<String> description) {
-    super.debugFillDescription(description);
-    description.add('"$title"');
-  }
-}
diff --git a/sky/packages/sky/lib/src/material/tool_bar.dart b/sky/packages/sky/lib/src/material/tool_bar.dart
deleted file mode 100644
index 1f38053..0000000
--- a/sky/packages/sky/lib/src/material/tool_bar.dart
+++ /dev/null
@@ -1,111 +0,0 @@
-// Copyright 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:flutter/widgets.dart';
-
-import 'constants.dart';
-import 'icon_theme.dart';
-import 'icon_theme_data.dart';
-import 'shadows.dart';
-import 'theme.dart';
-import 'typography.dart';
-
-class ToolBar extends StatelessComponent {
-  ToolBar({
-    Key key,
-    this.left,
-    this.center,
-    this.right,
-    this.bottom,
-    this.level: 2,
-    this.backgroundColor,
-    this.textTheme,
-    this.padding: EdgeDims.zero
-  }) : super(key: key);
-
-  final Widget left;
-  final Widget center;
-  final List<Widget> right;
-  final Widget bottom;
-  final int level;
-  final Color backgroundColor;
-  final TextTheme textTheme;
-  final EdgeDims padding;
-
-  ToolBar withPadding(EdgeDims newPadding) {
-    return new ToolBar(
-      key: key,
-      left: left,
-      center: center,
-      right: right,
-      bottom: bottom,
-      level: level,
-      backgroundColor: backgroundColor,
-      textTheme: textTheme,
-      padding: newPadding
-    );
-  }
-
-  Widget build(BuildContext context) {
-    Color color = backgroundColor;
-    IconThemeData iconThemeData;
-    TextStyle centerStyle = textTheme?.title;
-    TextStyle sideStyle = textTheme?.body1;
-
-    if (color == null || iconThemeData == null || textTheme == null) {
-      ThemeData themeData = Theme.of(context);
-      color ??= themeData.primaryColor;
-      iconThemeData ??= themeData.primaryIconTheme;
-
-      TextTheme primaryTextTheme = themeData.primaryTextTheme;
-      centerStyle ??= primaryTextTheme.title;
-      sideStyle ??= primaryTextTheme.body2;
-    }
-
-    List<Widget> children = new List<Widget>();
-
-    if (left != null)
-      children.add(left);
-
-    children.add(
-      new Flexible(
-        child: new Padding(
-          child: center != null ? new DefaultTextStyle(child: center, style: centerStyle) : null,
-          padding: new EdgeDims.only(left: 24.0)
-        )
-      )
-    );
-
-    if (right != null)
-      children.addAll(right);
-
-    final List<Widget> columnChildren = <Widget>[
-      new Container(height: kToolBarHeight, child: new Row(children))
-    ];
-
-    if (bottom != null)
-      columnChildren.add(new DefaultTextStyle(
-        style: centerStyle,
-        child: new Container(height: kExtendedToolBarHeight - kToolBarHeight, child: bottom)
-      ));
-
-    Widget content = new AnimatedContainer(
-      duration: kThemeChangeDuration,
-      padding: new EdgeDims.symmetric(horizontal: 8.0),
-      decoration: new BoxDecoration(
-        backgroundColor: color,
-        boxShadow: level == 0 ? null : shadows[2]
-      ),
-      child: new DefaultTextStyle(
-        style: sideStyle,
-        child: new Container(padding: padding, child: new Column(columnChildren, justifyContent: FlexJustifyContent.collapse))
-      )
-    );
-
-    if (iconThemeData != null)
-      content = new IconTheme(data: iconThemeData, child: content);
-    return content;
-  }
-
-}
diff --git a/sky/packages/sky/lib/src/material/typography.dart b/sky/packages/sky/lib/src/material/typography.dart
deleted file mode 100644
index 1d1f24f..0000000
--- a/sky/packages/sky/lib/src/material/typography.dart
+++ /dev/null
@@ -1,78 +0,0 @@
-// Copyright 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.
-
-// See http://www.google.com/design/spec/style/typography.html
-
-import 'dart:ui' show Color;
-
-import 'package:flutter/painting.dart';
-
-import 'colors.dart';
-
-// TODO(eseidel): Font weights are supposed to be language relative!
-// TODO(jackson): Baseline should be language relative!
-// These values are for English-like text.
-class TextTheme {
-
-  const TextTheme._black()
-    : display4 = const TextStyle(inherit: false, fontSize: 112.0, fontWeight: FontWeight.w100, color: Colors.black54, textBaseline: TextBaseline.alphabetic),
-      display3 = const TextStyle(inherit: false, fontSize:  56.0, fontWeight: FontWeight.w400, color: Colors.black54, textBaseline: TextBaseline.alphabetic),
-      display2 = const TextStyle(inherit: false, fontSize:  45.0, fontWeight: FontWeight.w400, color: Colors.black54, height: 48.0 / 45.0, textBaseline: TextBaseline.alphabetic),
-      display1 = const TextStyle(inherit: false, fontSize:  34.0, fontWeight: FontWeight.w400, color: Colors.black54, height: 40.0 / 34.0, textBaseline: TextBaseline.alphabetic),
-      headline = const TextStyle(inherit: false, fontSize:  24.0, fontWeight: FontWeight.w400, color: Colors.black87, height: 32.0 / 24.0, textBaseline: TextBaseline.alphabetic),
-      title    = const TextStyle(inherit: false, fontSize:  20.0, fontWeight: FontWeight.w500, color: Colors.black87, height: 28.0 / 20.0, textBaseline: TextBaseline.alphabetic),
-      subhead  = const TextStyle(inherit: false, fontSize:  16.0, fontWeight: FontWeight.w400, color: Colors.black87, height: 24.0 / 16.0, textBaseline: TextBaseline.alphabetic),
-      body2    = const TextStyle(inherit: false, fontSize:  14.0, fontWeight: FontWeight.w500, color: Colors.black87, height: 24.0 / 14.0, textBaseline: TextBaseline.alphabetic),
-      body1    = const TextStyle(inherit: false, fontSize:  14.0, fontWeight: FontWeight.w400, color: Colors.black87, height: 20.0 / 14.0, textBaseline: TextBaseline.alphabetic),
-      caption  = const TextStyle(inherit: false, fontSize:  12.0, fontWeight: FontWeight.w400, color: Colors.black54, textBaseline: TextBaseline.alphabetic),
-      button   = const TextStyle(inherit: false, fontSize:  14.0, fontWeight: FontWeight.w500, color: Colors.black87, textBaseline: TextBaseline.alphabetic);
-
-  const TextTheme._white()
-    : display4 = const TextStyle(inherit: false, fontSize: 112.0, fontWeight: FontWeight.w100, color: Colors.white70, textBaseline: TextBaseline.alphabetic),
-      display3 = const TextStyle(inherit: false, fontSize:  56.0, fontWeight: FontWeight.w400, color: Colors.white70, textBaseline: TextBaseline.alphabetic),
-      display2 = const TextStyle(inherit: false, fontSize:  45.0, fontWeight: FontWeight.w400, color: Colors.white70, height: 48.0 / 45.0, textBaseline: TextBaseline.alphabetic),
-      display1 = const TextStyle(inherit: false, fontSize:  34.0, fontWeight: FontWeight.w400, color: Colors.white70, height: 40.0 / 34.0, textBaseline: TextBaseline.alphabetic),
-      headline = const TextStyle(inherit: false, fontSize:  24.0, fontWeight: FontWeight.w400, color: Colors.white, height: 32.0 / 24.0, textBaseline: TextBaseline.alphabetic),
-      title    = const TextStyle(inherit: false, fontSize:  20.0, fontWeight: FontWeight.w500, color: Colors.white, height: 28.0 / 20.0, textBaseline: TextBaseline.alphabetic),
-      subhead  = const TextStyle(inherit: false, fontSize:  16.0, fontWeight: FontWeight.w400, color: Colors.white, height: 24.0 / 16.0, textBaseline: TextBaseline.alphabetic),
-      body2    = const TextStyle(inherit: false, fontSize:  14.0, fontWeight: FontWeight.w500, color: Colors.white, height: 24.0 / 14.0, textBaseline: TextBaseline.alphabetic),
-      body1    = const TextStyle(inherit: false, fontSize:  14.0, fontWeight: FontWeight.w400, color: Colors.white, height: 20.0 / 14.0, textBaseline: TextBaseline.alphabetic),
-      caption  = const TextStyle(inherit: false, fontSize:  12.0, fontWeight: FontWeight.w400, color: Colors.white70, textBaseline: TextBaseline.alphabetic),
-      button   = const TextStyle(inherit: false, fontSize:  14.0, fontWeight: FontWeight.w500, color: Colors.white, textBaseline: TextBaseline.alphabetic);
-
-  final TextStyle display4;
-  final TextStyle display3;
-  final TextStyle display2;
-  final TextStyle display1;
-  final TextStyle headline;
-  final TextStyle title;
-  final TextStyle subhead;
-  final TextStyle body2;
-  final TextStyle body1;
-  final TextStyle caption;
-  final TextStyle button;
-
-}
-
-class Typography {
-  Typography._();
-
-  static const TextTheme black = const TextTheme._black();
-  static const TextTheme white = const TextTheme._white();
-
-  // TODO(abarth): Maybe this should be hard-coded in Scaffold?
-  static const String typeface = 'font-family: sans-serif';
-
-  // TODO(ianh): Remove this when we remove fn2, now that it's hard-coded in App.
-  static const TextStyle error = const TextStyle(
-    color: const Color(0xD0FF0000),
-    fontFamily: 'monospace',
-    fontSize: 48.0,
-    fontWeight: FontWeight.w900,
-    textAlign: TextAlign.right,
-    decoration: underline,
-    decorationColor: const Color(0xFFFF00),
-    decorationStyle: TextDecorationStyle.double
-  );
-}
diff --git a/sky/packages/sky/lib/src/painting/basic_types.dart b/sky/packages/sky/lib/src/painting/basic_types.dart
deleted file mode 100644
index 88209a1..0000000
--- a/sky/packages/sky/lib/src/painting/basic_types.dart
+++ /dev/null
@@ -1,21 +0,0 @@
-// Copyright 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.
-
-export 'dart:ui' show
-  Canvas,
-  Color,
-  ColorFilter,
-  FontStyle,
-  FontWeight,
-  Offset,
-  Paint,
-  Path,
-  Point,
-  Rect,
-  Size,
-  TextAlign,
-  TextBaseline,
-  TextDecoration,
-  TextDecorationStyle,
-  VoidCallback;
diff --git a/sky/packages/sky/lib/src/painting/box_painter.dart b/sky/packages/sky/lib/src/painting/box_painter.dart
deleted file mode 100644
index ccf1f0b..0000000
--- a/sky/packages/sky/lib/src/painting/box_painter.dart
+++ /dev/null
@@ -1,1078 +0,0 @@
-// Copyright 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 'dart:math' as math;
-import 'dart:ui' as ui;
-
-import 'package:flutter/services.dart';
-
-import 'basic_types.dart';
-import 'shadows.dart';
-
-/// An immutable set of offsets in each of the four cardinal directions.
-///
-/// Typically used for an offset from each of the four sides of a box. For
-/// example, the padding inside a box can be represented using this class.
-class EdgeDims {
-  /// Constructs an EdgeDims from offsets from the top, right, bottom and left.
-  const EdgeDims.TRBL(this.top, this.right, this.bottom, this.left);
-
-  /// Constructs an EdgeDims where all the offsets are value.
-  const EdgeDims.all(double value)
-      : top = value, right = value, bottom = value, left = value;
-
-  /// Constructs an EdgeDims with only the given values non-zero.
-  const EdgeDims.only({ this.top: 0.0,
-                        this.right: 0.0,
-                        this.bottom: 0.0,
-                        this.left: 0.0 });
-
-  /// Constructs an EdgeDims with symmetrical vertical and horizontal offsets.
-  const EdgeDims.symmetric({ double vertical: 0.0,
-                             double horizontal: 0.0 })
-    : top = vertical, left = horizontal, bottom = vertical, right = horizontal;
-
-  /// The offset from the top.
-  final double top;
-
-  /// The offset from the right.
-  final double right;
-
-  /// The offset from the bottom.
-  final double bottom;
-
-  /// The offset from the left.
-  final double left;
-
-  /// Whether every dimension is non-negative.
-  bool get isNonNegative => top >= 0.0 && right >= 0.0 && bottom >= 0.0 && left >= 0.0;
-
-  /// The size that this edge dims would occupy with an empty interior.
-  Size get collapsedSize => new Size(left + right, top + bottom);
-
-  Rect inflateRect(Rect rect) {
-    return new Rect.fromLTRB(rect.left - left, rect.top - top, rect.right + right, rect.bottom + bottom);
-  }
-
-  EdgeDims operator -(EdgeDims other) {
-    return new EdgeDims.TRBL(
-      top - other.top,
-      right - other.right,
-      bottom - other.bottom,
-      left - other.left
-    );
-  }
-
-  EdgeDims operator +(EdgeDims other) {
-    return new EdgeDims.TRBL(
-      top + other.top,
-      right + other.right,
-      bottom + other.bottom,
-      left + other.left
-    );
-  }
-
-  EdgeDims operator *(double other) {
-    return new EdgeDims.TRBL(
-      top * other,
-      right * other,
-      bottom * other,
-      left * other
-    );
-  }
-
-  EdgeDims operator /(double other) {
-    return new EdgeDims.TRBL(
-      top / other,
-      right / other,
-      bottom / other,
-      left / other
-    );
-  }
-
-  EdgeDims operator ~/(double other) {
-    return new EdgeDims.TRBL(
-      (top ~/ other).toDouble(),
-      (right ~/ other).toDouble(),
-      (bottom ~/ other).toDouble(),
-      (left ~/ other).toDouble()
-    );
-  }
-
-  EdgeDims operator %(double other) {
-    return new EdgeDims.TRBL(
-      top % other,
-      right % other,
-      bottom % other,
-      left % other
-    );
-  }
-
-  /// Linearly interpolate between two EdgeDims.
-  ///
-  /// If either is null, this function interpolates from [EdgeDims.zero].
-  static EdgeDims lerp(EdgeDims a, EdgeDims b, double t) {
-    if (a == null && b == null)
-      return null;
-    if (a == null)
-      return b * t;
-    if (b == null)
-      return a * (1.0 - t);
-    return new EdgeDims.TRBL(
-      ui.lerpDouble(a.top, b.top, t),
-      ui.lerpDouble(a.right, b.right, t),
-      ui.lerpDouble(a.bottom, b.bottom, t),
-      ui.lerpDouble(a.left, b.left, t)
-    );
-  }
-
-  /// An EdgeDims with zero offsets in each direction.
-  static const EdgeDims zero = const EdgeDims.TRBL(0.0, 0.0, 0.0, 0.0);
-
-  bool operator ==(dynamic other) {
-    if (identical(this, other))
-      return true;
-    if (other is! EdgeDims)
-      return false;
-    final EdgeDims typedOther = other;
-    return top == typedOther.top &&
-           right == typedOther.right &&
-           bottom == typedOther.bottom &&
-           left == typedOther.left;
-  }
-
-  int get hashCode {
-    int value = 373;
-    value = 37 * value + top.hashCode;
-    value = 37 * value + left.hashCode;
-    value = 37 * value + bottom.hashCode;
-    value = 37 * value + right.hashCode;
-    return value;
-  }
-
-  String toString() => "EdgeDims($top, $right, $bottom, $left)";
-}
-
-/// A side of a border of a box
-class BorderSide {
-  const BorderSide({
-    this.color: const Color(0xFF000000),
-    this.width: 1.0
-  });
-
-  /// The color of this side of the border
-  final Color color;
-
-  /// The width of this side of the border
-  final double width;
-
-  /// A black border side of zero width
-  static const none = const BorderSide(width: 0.0);
-
-  bool operator ==(dynamic other) {
-    if (identical(this, other))
-      return true;
-    if (other is! BorderSide)
-      return false;
-    final BorderSide typedOther = other;
-    return color == typedOther.color &&
-           width == typedOther.width;
-  }
-
-  int get hashCode {
-    int value = 373;
-    value = 37 * value + color.hashCode;
-    value = 37 * value + width.hashCode;
-    return value;
-  }
-
-  String toString() => 'BorderSide($color, $width)';
-}
-
-/// A border of a box, comprised of four sides
-class Border {
-  const Border({
-    this.top: BorderSide.none,
-    this.right: BorderSide.none,
-    this.bottom: BorderSide.none,
-    this.left: BorderSide.none
-  });
-
-  /// A uniform border with all sides the same color and width
-  factory Border.all({
-    Color color: const Color(0xFF000000),
-    double width: 1.0
-  }) {
-    BorderSide side = new BorderSide(color: color, width: width);
-    return new Border(top: side, right: side, bottom: side, left: side);
-  }
-
-  /// The top side of this border
-  final BorderSide top;
-
-  /// The right side of this border
-  final BorderSide right;
-
-  /// The bottom side of this border
-  final BorderSide bottom;
-
-  /// The left side of this border
-  final BorderSide left;
-
-  /// The widths of the sides of this border represented as an EdgeDims
-  EdgeDims get dimensions {
-    return new EdgeDims.TRBL(top.width, right.width, bottom.width, left.width);
-  }
-
-  bool operator ==(dynamic other) {
-    if (identical(this, other))
-      return true;
-    if (other is! Border)
-      return false;
-    final Border typedOther = other;
-    return top == typedOther.top &&
-           right == typedOther.right &&
-           bottom == typedOther.bottom &&
-           left == typedOther.left;
-  }
-
-  int get hashCode {
-    int value = 373;
-    value = 37 * value + top.hashCode;
-    value = 37 * value + right.hashCode;
-    value = 37 * value + bottom.hashCode;
-    value = 37 * value + left.hashCode;
-    return value;
-  }
-
-  String toString() => 'Border($top, $right, $bottom, $left)';
-}
-
-/// A shadow cast by a box
-///
-/// Note: BoxShadow can cast non-rectangular shadows if the box is
-/// non-rectangular (e.g., has a border radius or a circular shape).
-class BoxShadow {
-  const BoxShadow({
-    this.color,
-    this.offset,
-    this.blur
-  });
-
-  /// The color of the shadow
-  final Color color;
-
-  /// The displacement of the shadow from the box
-  final Offset offset;
-
-  /// The standard deviation of the Gaussian to convolve with the box's shape
-  final double blur;
-
-  /// Returns a new box shadow with its offset and blur scaled by the given factor
-  BoxShadow scale(double factor) {
-    return new BoxShadow(
-      color: color,
-      offset: offset * factor,
-      blur: blur * factor
-    );
-  }
-
-  /// Linearly interpolate between two box shadows
-  ///
-  /// If either box shadow is null, this function linearly interpolates from a
-  /// a box shadow that matches the other box shadow in color but has a zero
-  /// offset and a zero blur.
-  static BoxShadow lerp(BoxShadow a, BoxShadow b, double t) {
-    if (a == null && b == null)
-      return null;
-    if (a == null)
-      return b.scale(t);
-    if (b == null)
-      return a.scale(1.0 - t);
-    return new BoxShadow(
-      color: Color.lerp(a.color, b.color, t),
-      offset: Offset.lerp(a.offset, b.offset, t),
-      blur: ui.lerpDouble(a.blur, b.blur, t)
-    );
-  }
-
-  /// Linearly interpolate between two lists of box shadows
-  ///
-  /// If the lists differ in length, excess items are lerped with null.
-  static List<BoxShadow> lerpList(List<BoxShadow> a, List<BoxShadow> b, double t) {
-    if (a == null && b == null)
-      return null;
-    if (a == null)
-      a = new List<BoxShadow>();
-    if (b == null)
-      b = new List<BoxShadow>();
-    List<BoxShadow> result = new List<BoxShadow>();
-    int commonLength = math.min(a.length, b.length);
-    for (int i = 0; i < commonLength; ++i)
-      result.add(BoxShadow.lerp(a[i], b[i], t));
-    for (int i = commonLength; i < a.length; ++i)
-      result.add(a[i].scale(1.0 - t));
-    for (int i = commonLength; i < b.length; ++i)
-      result.add(b[i].scale(t));
-    return result;
-  }
-
-  bool operator ==(dynamic other) {
-    if (identical(this, other))
-      return true;
-    if (other is! BoxShadow)
-      return false;
-    final BoxShadow typedOther = other;
-    return color == typedOther.color &&
-           offset == typedOther.offset &&
-           blur == typedOther.blur;
-  }
-
-  int get hashCode {
-    int value = 373;
-    value = 37 * value + color.hashCode;
-    value = 37 * value + offset.hashCode;
-    value = 37 * value + blur.hashCode;
-    return value;
-  }
-
-  String toString() => 'BoxShadow($color, $offset, $blur)';
-}
-
-/// A 2D gradient
-abstract class Gradient {
-  const Gradient();
-  ui.Shader createShader();
-}
-
-/// A 2D linear gradient
-class LinearGradient extends Gradient {
-  const LinearGradient({
-    this.begin,
-    this.end,
-    this.colors,
-    this.stops,
-    this.tileMode: ui.TileMode.clamp
-  });
-
-  /// The point at which stop 0.0 of the gradient is placed
-  final Point begin;
-
-  /// The point at which stop 1.0 of the gradient is placed
-  final Point end;
-
-  /// The colors the gradient should obtain at each of the stops
-  ///
-  /// Note: This list must have the same length as [stops].
-  final List<Color> colors;
-
-  /// A list of values from 0.0 to 1.0 that denote fractions of the vector from start to end
-  ///
-  /// Note: If specified, this list must have the same length as [colors]. Otherwise the colors
-  /// are distributed evenly between [begin] and [end].
-  final List<double> stops;
-
-  /// How this gradient should tile the plane
-  final ui.TileMode tileMode;
-
-  ui.Shader createShader() {
-    return new ui.Gradient.linear(<Point>[begin, end], this.colors, this.stops, this.tileMode);
-  }
-
-  bool operator ==(dynamic other) {
-    if (identical(this, other))
-      return true;
-    if (other is! LinearGradient)
-      return false;
-    final LinearGradient typedOther = other;
-    if (begin != typedOther.begin ||
-        end != typedOther.end ||
-        tileMode != typedOther.tileMode ||
-        colors?.length != typedOther.colors?.length ||
-        stops?.length != typedOther.stops?.length)
-      return false;
-    if (colors != null) {
-      assert(typedOther.colors != null);
-      assert(colors.length == typedOther.colors.length);
-      for (int i = 0; i < colors.length; i += 1) {
-        if (colors[i] != typedOther.colors[i])
-          return false;
-      }
-    }
-    if (stops != null) {
-      assert(typedOther.stops != null);
-      assert(stops.length == typedOther.stops.length);
-      for (int i = 0; i < stops.length; i += 1) {
-        if (stops[i] != typedOther.stops[i])
-          return false;
-      }
-    }
-    return true;
-  }
-
-  int get hashCode {
-    int value = 373;
-    value = 37 * value + begin.hashCode;
-    value = 37 * value + end.hashCode;
-    value = 37 * value + tileMode.hashCode;
-    if (colors != null) {
-      for (int i = 0; i < colors.length; i += 1)
-        value = 37 * value + colors[i].hashCode;
-    } else {
-      value = 37 * value + null.hashCode;
-    }
-    if (stops != null) {
-      for (int i = 0; i < stops.length; i += 1)
-        value = 37 * value + stops[i].hashCode;
-    } else {
-      value = 37 * value + null.hashCode;
-    }
-    return value;
-  }
-
-  String toString() {
-    return 'LinearGradient($begin, $end, $colors, $stops, $tileMode)';
-  }
-}
-
-/// A 2D radial gradient
-class RadialGradient extends Gradient {
-  const RadialGradient({
-    this.center,
-    this.radius,
-    this.colors,
-    this.stops,
-    this.tileMode: ui.TileMode.clamp
-  });
-
-  /// The center of the gradient
-  final Point center;
-
-  /// The radius at which stop 1.0 is placed
-  final double radius;
-
-  /// The colors the gradient should obtain at each of the stops
-  ///
-  /// Note: This list must have the same length as [stops].
-  final List<Color> colors;
-
-  /// A list of values from 0.0 to 1.0 that denote concentric rings
-  ///
-  /// The rings are centered at [center] and have a radius equal to the value of
-  /// the stop times [radius].
-  ///
-  /// Note: This list must have the same length as [colors].
-  final List<double> stops;
-
-  /// How this gradient should tile the plane
-  final ui.TileMode tileMode;
-
-  ui.Shader createShader() {
-    return new ui.Gradient.radial(center, radius, colors, stops, tileMode);
-  }
-
-  bool operator ==(dynamic other) {
-    if (identical(this, other))
-      return true;
-    if (other is! RadialGradient)
-      return false;
-    final RadialGradient typedOther = other;
-    if (center != typedOther.center ||
-        radius != typedOther.radius ||
-        tileMode != typedOther.tileMode ||
-        colors?.length != typedOther.colors?.length ||
-        stops?.length != typedOther.stops?.length)
-      return false;
-    if (colors != null) {
-      assert(typedOther.colors != null);
-      assert(colors.length == typedOther.colors.length);
-      for (int i = 0; i < colors.length; i += 1) {
-        if (colors[i] != typedOther.colors[i])
-          return false;
-      }
-    }
-    if (stops != null) {
-      assert(typedOther.stops != null);
-      assert(stops.length == typedOther.stops.length);
-      for (int i = 0; i < stops.length; i += 1) {
-        if (stops[i] != typedOther.stops[i])
-          return false;
-      }
-    }
-    return true;
-  }
-
-  int get hashCode {
-    int value = 373;
-    value = 37 * value + center.hashCode;
-    value = 37 * value + radius.hashCode;
-    value = 37 * value + tileMode.hashCode;
-    if (colors != null) {
-      for (int i = 0; i < colors.length; i += 1)
-        value = 37 * value + colors[i].hashCode;
-    } else {
-      value = 37 * value + null.hashCode;
-    }
-    if (stops != null) {
-      for (int i = 0; i < stops.length; i += 1)
-        value = 37 * value + stops[i].hashCode;
-    } else {
-      value = 37 * value + null.hashCode;
-    }
-    return value;
-  }
-
-  String toString() {
-    return 'RadialGradient($center, $radius, $colors, $stops, $tileMode)';
-  }
-}
-
-/// How an image should be inscribed into a box
-enum ImageFit {
-  /// Fill the box by distorting the image's aspect ratio
-  fill,
-
-  /// As large as possible while still containing the image entirely within the box
-  contain,
-
-  /// As small as possible while still covering the entire box
-  cover,
-
-  /// Center the image within the box and discard any portions of the image that
-  /// lie outside the box
-  none,
-
-  /// Center the image within the box and, if necessary, scale the image down to
-  /// ensure that the image fits within the box
-  scaleDown
-}
-
-/// How to paint any portions of a box not covered by an image
-enum ImageRepeat {
-  /// Repeat the image in both the x and y directions until the box is filled
-  repeat,
-
-  /// Repeat the image in the x direction until the box is filled horizontally
-  repeatX,
-
-  /// Repeat the image in the y direction until the box is filled vertically
-  repeatY,
-
-  /// Leave uncovered poritions of the box transparent
-  noRepeat
-}
-
-/// Paint an image into the given rectangle in the canvas
-void paintImage({
-  Canvas canvas,
-  Rect rect,
-  ui.Image image,
-  ColorFilter colorFilter,
-  ImageFit fit,
-  repeat: ImageRepeat.noRepeat,
-  Rect centerSlice,
-  double positionX: 0.5,
-  double positionY: 0.5
-}) {
-  Size outputSize = rect.size;
-  Size inputSize = new Size(image.width.toDouble(), image.height.toDouble());
-  Offset sliceBorder;
-  if (centerSlice != null) {
-    sliceBorder = new Offset(
-      centerSlice.left + inputSize.width - centerSlice.right,
-      centerSlice.top + inputSize.height - centerSlice.bottom
-    );
-    outputSize -= sliceBorder;
-    inputSize -= sliceBorder;
-  }
-  Size sourceSize;
-  Size destinationSize;
-  fit ??= centerSlice == null ? ImageFit.scaleDown : ImageFit.fill;
-  assert(centerSlice == null || (fit != ImageFit.none && fit != ImageFit.cover));
-  switch (fit) {
-    case ImageFit.fill:
-      sourceSize = inputSize;
-      destinationSize = outputSize;
-      break;
-    case ImageFit.contain:
-      sourceSize = inputSize;
-      if (outputSize.width / outputSize.height > sourceSize.width / sourceSize.height)
-        destinationSize = new Size(sourceSize.width * outputSize.height / sourceSize.height, outputSize.height);
-      else
-        destinationSize = new Size(outputSize.width, sourceSize.height * outputSize.width / sourceSize.width);
-      break;
-    case ImageFit.cover:
-      if (outputSize.width / outputSize.height > inputSize.width / inputSize.height)
-        sourceSize = new Size(inputSize.width, inputSize.width * outputSize.height / outputSize.width);
-      else
-        sourceSize = new Size(inputSize.height * outputSize.width / outputSize.height, inputSize.height);
-      destinationSize = outputSize;
-      break;
-    case ImageFit.none:
-      sourceSize = new Size(math.min(inputSize.width, outputSize.width),
-                            math.min(inputSize.height, outputSize.height));
-      destinationSize = sourceSize;
-      break;
-    case ImageFit.scaleDown:
-      sourceSize = inputSize;
-      destinationSize = outputSize;
-      if (sourceSize.height > destinationSize.height)
-        destinationSize = new Size(sourceSize.width * destinationSize.height / sourceSize.height, sourceSize.height);
-      if (sourceSize.width > destinationSize.width)
-        destinationSize = new Size(destinationSize.width, sourceSize.height * destinationSize.width / sourceSize.width);
-      break;
-  }
-  if (centerSlice != null) {
-    outputSize += sliceBorder;
-    destinationSize += sliceBorder;
-    // We don't have the ability to draw a subset of the image at the same time
-    // as we apply a nine-patch stretch.
-    assert(sourceSize == inputSize);
-  }
-  // TODO(abarth): Implement |repeat|.
-  Paint paint = new Paint()..isAntiAlias = false;
-  if (colorFilter != null)
-    paint.colorFilter = colorFilter;
-  double dx = (outputSize.width - destinationSize.width) * positionX;
-  double dy = (outputSize.height - destinationSize.height) * positionY;
-  Point destinationPosition = rect.topLeft + new Offset(dx, dy);
-  Rect destinationRect = destinationPosition & destinationSize;
-  if (centerSlice == null)
-    canvas.drawImageRect(image, Point.origin & sourceSize, destinationRect, paint);
-  else
-    canvas.drawImageNine(image, centerSlice, destinationRect, paint);
-}
-
-/// A background image for a box.
-class BackgroundImage {
-  BackgroundImage({
-    ImageResource image,
-    this.fit,
-    this.repeat: ImageRepeat.noRepeat,
-    this.centerSlice,
-    this.colorFilter
-  }) : _imageResource = image;
-
-  /// How the background image should be inscribed into the box.
-  final ImageFit fit;
-
-  /// How to paint any portions of the box not covered by the background image.
-  final ImageRepeat repeat;
-
-  /// The center slice for a nine-patch image.
-  ///
-  /// The region of the image inside the center slice will be stretched both
-  /// horizontally and vertically to fit the image into its destination. The
-  /// region of the image above and below the center slice will be stretched
-  /// only horizontally and the region of the image to the left and right of
-  /// the center slice will be stretched only vertically.
-  final Rect centerSlice;
-
-  /// A color filter to apply to the background image before painting it.
-  final ColorFilter colorFilter;
-
-  /// The image to be painted into the background.
-  ui.Image get image => _image;
-  ui.Image _image;
-
-  final ImageResource _imageResource;
-
-  final List<VoidCallback> _listeners =
-    new List<VoidCallback>();
-
-  /// Call listener when the background images changes (e.g., arrives from the network).
-  void addChangeListener(VoidCallback listener) {
-    // We add the listener to the _imageResource first so that the first change
-    // listener doesn't get callback synchronously if the image resource is
-    // already resolved.
-    if (_listeners.isEmpty)
-      _imageResource.addListener(_handleImageChanged);
-    _listeners.add(listener);
-  }
-
-  /// No longer call listener when the background image changes.
-  void removeChangeListener(VoidCallback listener) {
-    _listeners.remove(listener);
-    // We need to remove ourselves as listeners from the _imageResource so that
-    // we're not kept alive by the image_cache.
-    if (_listeners.isEmpty)
-      _imageResource.removeListener(_handleImageChanged);
-  }
-
-  void _handleImageChanged(ui.Image resolvedImage) {
-    if (resolvedImage == null)
-      return;
-    _image = resolvedImage;
-    final List<VoidCallback> localListeners =
-      new List<VoidCallback>.from(_listeners);
-    for (VoidCallback listener in localListeners)
-      listener();
-  }
-
-  bool operator ==(dynamic other) {
-    if (identical(this, other))
-      return true;
-    if (other is! BackgroundImage)
-      return false;
-    final BackgroundImage typedOther = other;
-    return fit == typedOther.fit &&
-           repeat == typedOther.repeat &&
-           centerSlice == typedOther.centerSlice &&
-           colorFilter == typedOther.colorFilter &&
-           _imageResource == typedOther._imageResource;
-  }
-
-  int get hashCode {
-    int value = 373;
-    value = 37 * value + fit.hashCode;
-    value = 37 * value + repeat.hashCode;
-    value = 37 * value + centerSlice.hashCode;
-    value = 37 * value + colorFilter.hashCode;
-    value = 37 * value + _imageResource.hashCode;
-    return value;
-  }
-
-  String toString() => 'BackgroundImage($fit, $repeat)';
-}
-
-// TODO(abarth): Rename to BoxShape?
-/// A 2D geometrical shape
-enum Shape {
-  /// An axis-aligned, 2D rectangle
-  rectangle,
-
-  /// A 2D locus of points equidistant from a single point
-  circle
-}
-
-/// An immutable description of how to paint a box
-class BoxDecoration {
-  const BoxDecoration({
-    this.backgroundColor, // null = don't draw background color
-    this.backgroundImage, // null = don't draw background image
-    this.border, // null = don't draw border
-    this.borderRadius, // null = use more efficient background drawing; note that this must be null for circles
-    this.boxShadow, // null = don't draw shadows
-    this.gradient, // null = don't allocate gradient objects
-    this.shape: Shape.rectangle
-  });
-
-  /// The color to fill in the background of the box
-  ///
-  /// The color is filled into the shape of the box (e.g., either a rectangle,
-  /// potentially with a border radius, or a circle).
-  final Color backgroundColor;
-
-  /// An image to paint above the background color
-  final BackgroundImage backgroundImage;
-
-  /// A border to draw above the background
-  final Border border;
-
-  /// If non-null, the corners of this box are rounded by this radius
-  ///
-  /// Applies only to boxes with rectangular shapes.
-  final double borderRadius;
-
-  /// A list of shadows cast by this box behind the background
-  final List<BoxShadow> boxShadow;
-
-  /// A graident to use when filling the background
-  final Gradient gradient;
-
-  /// The shape to fill the background color into and to cast as a shadow
-  final Shape shape;
-
-  /// Returns a new box decoration that is scalled by the given factor
-  BoxDecoration scale(double factor) {
-    // TODO(abarth): Scale ALL the things.
-    return new BoxDecoration(
-      backgroundColor: Color.lerp(null, backgroundColor, factor),
-      backgroundImage: backgroundImage,
-      border: border,
-      borderRadius: ui.lerpDouble(null, borderRadius, factor),
-      boxShadow: BoxShadow.lerpList(null, boxShadow, factor),
-      gradient: gradient,
-      shape: shape
-    );
-  }
-
-  /// Linearly interpolate between two box decorations
-  ///
-  /// Interpolates each parameter of the box decoration separately.
-  static BoxDecoration lerp(BoxDecoration a, BoxDecoration b, double t) {
-    if (a == null && b == null)
-      return null;
-    if (a == null)
-      return b.scale(t);
-    if (b == null)
-      return a.scale(1.0 - t);
-    // TODO(abarth): lerp ALL the fields.
-    return new BoxDecoration(
-      backgroundColor: Color.lerp(a.backgroundColor, b.backgroundColor, t),
-      backgroundImage: b.backgroundImage,
-      border: b.border,
-      borderRadius: ui.lerpDouble(a.borderRadius, b.borderRadius, t),
-      boxShadow: BoxShadow.lerpList(a.boxShadow, b.boxShadow, t),
-      gradient: b.gradient,
-      shape: b.shape
-    );
-  }
-
-  bool operator ==(dynamic other) {
-    if (identical(this, other))
-      return true;
-    if (other is! BoxDecoration)
-      return false;
-    final BoxDecoration typedOther = other;
-    return backgroundColor == typedOther.backgroundColor &&
-           backgroundImage == typedOther.backgroundImage &&
-           border == typedOther.border &&
-           borderRadius == typedOther.borderRadius &&
-           boxShadow == typedOther.boxShadow &&
-           gradient == typedOther.gradient &&
-           shape == typedOther.shape;
-  }
-
-  int get hashCode {
-    int value = 373;
-    value = 37 * value + backgroundColor.hashCode;
-    value = 37 * value + backgroundImage.hashCode;
-    value = 37 * value + border.hashCode;
-    value = 37 * value + borderRadius.hashCode;
-    value = 37 * value + boxShadow.hashCode;
-    value = 37 * value + gradient.hashCode;
-    value = 37 * value + shape.hashCode;
-    return value;
-  }
-
-  String toString([String prefix = '']) {
-    List<String> result = <String>[];
-    if (backgroundColor != null)
-      result.add('${prefix}backgroundColor: $backgroundColor');
-    if (backgroundImage != null)
-      result.add('${prefix}backgroundImage: $backgroundImage');
-    if (border != null)
-      result.add('${prefix}border: $border');
-    if (borderRadius != null)
-      result.add('${prefix}borderRadius: $borderRadius');
-    if (boxShadow != null)
-      result.add('${prefix}boxShadow: ${boxShadow.map((BoxShadow shadow) => shadow.toString())}');
-    if (gradient != null)
-      result.add('${prefix}gradient: $gradient');
-    if (shape != Shape.rectangle)
-      result.add('${prefix}shape: $shape');
-    if (result.isEmpty)
-      return '$prefix<no decorations specified>';
-    return result.join('\n');
-  }
-}
-
-/// An object that paints a [BoxDecoration] into a canvas
-class BoxPainter {
-  BoxPainter(BoxDecoration decoration) : _decoration = decoration {
-    assert(decoration != null);
-  }
-
-  BoxDecoration _decoration;
-  /// The box decoration to paint
-  BoxDecoration get decoration => _decoration;
-  void set decoration (BoxDecoration value) {
-    assert(value != null);
-    if (value == _decoration)
-      return;
-    _decoration = value;
-    _cachedBackgroundPaint = null;
-  }
-
-  Paint _cachedBackgroundPaint;
-  Paint get _backgroundPaint {
-    if (_cachedBackgroundPaint == null) {
-      Paint paint = new Paint();
-
-      if (_decoration.backgroundColor != null)
-        paint.color = _decoration.backgroundColor;
-
-      if (_decoration.boxShadow != null) {
-        var builder = new ShadowDrawLooperBuilder();
-        for (BoxShadow boxShadow in _decoration.boxShadow)
-          builder.addShadow(boxShadow.offset, boxShadow.color, boxShadow.blur);
-        paint.drawLooper = builder.build();
-      }
-
-      if (_decoration.gradient != null)
-        paint.shader = _decoration.gradient.createShader();
-
-      _cachedBackgroundPaint = paint;
-    }
-
-    return _cachedBackgroundPaint;
-  }
-
-  bool get _hasUniformBorder {
-    Color color = _decoration.border.top.color;
-    bool hasUniformColor =
-      _decoration.border.right.color == color &&
-      _decoration.border.bottom.color == color &&
-      _decoration.border.left.color == color;
-
-    if (!hasUniformColor)
-      return false;
-
-    double width = _decoration.border.top.width;
-    bool hasUniformWidth =
-      _decoration.border.right.width == width &&
-      _decoration.border.bottom.width == width &&
-      _decoration.border.left.width == width;
-
-    return hasUniformWidth;
-  }
-
-  double _getEffectiveBorderRadius(Rect rect) {
-    double shortestSide = rect.shortestSide;
-    // In principle, we should use shortestSide / 2.0, but we don't want to
-    // run into floating point rounding errors. Instead, we just use
-    // shortestSide and let ui.Canvas do any remaining clamping.
-    return _decoration.borderRadius > shortestSide ? shortestSide : _decoration.borderRadius;
-  }
-
-  void _paintBackgroundColor(ui.Canvas canvas, Rect rect) {
-    if (_decoration.backgroundColor != null ||
-        _decoration.boxShadow != null ||
-        _decoration.gradient != null) {
-      switch (_decoration.shape) {
-        case Shape.circle:
-          assert(_decoration.borderRadius == null);
-          Point center = rect.center;
-          double radius = rect.shortestSide / 2.0;
-          canvas.drawCircle(center, radius, _backgroundPaint);
-          break;
-        case Shape.rectangle:
-          if (_decoration.borderRadius == null) {
-            canvas.drawRect(rect, _backgroundPaint);
-          } else {
-            double radius = _getEffectiveBorderRadius(rect);
-            canvas.drawRRect(new ui.RRect.fromRectXY(rect, radius, radius), _backgroundPaint);
-          }
-          break;
-      }
-    }
-  }
-
-  void _paintBackgroundImage(ui.Canvas canvas, Rect rect) {
-    final BackgroundImage backgroundImage = _decoration.backgroundImage;
-    if (backgroundImage == null)
-      return;
-    ui.Image image = backgroundImage.image;
-    if (image == null)
-      return;
-    paintImage(
-      canvas: canvas,
-      rect: rect,
-      image: image,
-      colorFilter: backgroundImage.colorFilter,
-      fit:  backgroundImage.fit,
-      repeat: backgroundImage.repeat
-    );
-  }
-
-  void _paintBorder(ui.Canvas canvas, Rect rect) {
-    if (_decoration.border == null)
-      return;
-
-    if (_hasUniformBorder) {
-      if (_decoration.borderRadius != null) {
-        _paintBorderWithRadius(canvas, rect);
-        return;
-      }
-      if (_decoration.shape == Shape.circle) {
-        _paintBorderWithCircle(canvas, rect);
-        return;
-      }
-    }
-
-    assert(_decoration.borderRadius == null); // TODO(abarth): Support non-uniform rounded borders.
-    assert(_decoration.shape == Shape.rectangle); // TODO(ianh): Support non-uniform borders on circles.
-
-    assert(_decoration.border.top != null);
-    assert(_decoration.border.right != null);
-    assert(_decoration.border.bottom != null);
-    assert(_decoration.border.left != null);
-
-    Paint paint = new Paint();
-    Path path;
-
-    paint.color = _decoration.border.top.color;
-    path = new Path();
-    path.moveTo(rect.left, rect.top);
-    path.lineTo(rect.left + _decoration.border.left.width, rect.top + _decoration.border.top.width);
-    path.lineTo(rect.right - _decoration.border.right.width, rect.top + _decoration.border.top.width);
-    path.lineTo(rect.right, rect.top);
-    path.close();
-    canvas.drawPath(path, paint);
-
-    paint.color = _decoration.border.right.color;
-    path = new Path();
-    path.moveTo(rect.right, rect.top);
-    path.lineTo(rect.right - _decoration.border.right.width, rect.top + _decoration.border.top.width);
-    path.lineTo(rect.right - _decoration.border.right.width, rect.bottom - _decoration.border.bottom.width);
-    path.lineTo(rect.right, rect.bottom);
-    path.close();
-    canvas.drawPath(path, paint);
-
-    paint.color = _decoration.border.bottom.color;
-    path = new Path();
-    path.moveTo(rect.right, rect.bottom);
-    path.lineTo(rect.right - _decoration.border.right.width, rect.bottom - _decoration.border.bottom.width);
-    path.lineTo(rect.left + _decoration.border.left.width, rect.bottom - _decoration.border.bottom.width);
-    path.lineTo(rect.left, rect.bottom);
-    path.close();
-    canvas.drawPath(path, paint);
-
-    paint.color = _decoration.border.left.color;
-    path = new Path();
-    path.moveTo(rect.left, rect.bottom);
-    path.lineTo(rect.left + _decoration.border.left.width, rect.bottom - _decoration.border.bottom.width);
-    path.lineTo(rect.left + _decoration.border.left.width, rect.top + _decoration.border.top.width);
-    path.lineTo(rect.left, rect.top);
-    path.close();
-    canvas.drawPath(path, paint);
-  }
-
-  void _paintBorderWithRadius(ui.Canvas canvas, Rect rect) {
-    assert(_hasUniformBorder);
-    assert(_decoration.shape == Shape.rectangle);
-    Color color = _decoration.border.top.color;
-    double width = _decoration.border.top.width;
-    double radius = _getEffectiveBorderRadius(rect);
-
-    ui.RRect outer = new ui.RRect.fromRectXY(rect, radius, radius);
-    ui.RRect inner = new ui.RRect.fromRectXY(rect.deflate(width), radius - width, radius - width);
-    canvas.drawDRRect(outer, inner, new Paint()..color = color);
-  }
-
-  void _paintBorderWithCircle(ui.Canvas canvas, Rect rect) {
-    assert(_hasUniformBorder);
-    assert(_decoration.shape == Shape.circle);
-    assert(_decoration.borderRadius == null);
-    double width = _decoration.border.top.width;
-    if (width <= 0.0) {
-      return;
-    }
-    Paint paint = new Paint()
-      ..color = _decoration.border.top.color
-      ..strokeWidth = width
-      ..style = ui.PaintingStyle.stroke;
-    Point center = rect.center;
-    double radius = (rect.shortestSide - width) / 2.0;
-    canvas.drawCircle(center, radius, paint);
-  }
-
-  /// Paint the box decoration into the given location on the given canvas
-  void paint(ui.Canvas canvas, Rect rect) {
-    _paintBackgroundColor(canvas, rect);
-    _paintBackgroundImage(canvas, rect);
-    _paintBorder(canvas, rect);
-  }
-}
diff --git a/sky/packages/sky/lib/src/painting/shadows.dart b/sky/packages/sky/lib/src/painting/shadows.dart
deleted file mode 100644
index 28cc7be..0000000
--- a/sky/packages/sky/lib/src/painting/shadows.dart
+++ /dev/null
@@ -1,29 +0,0 @@
-// Copyright 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 'dart:ui' as ui;
-
-/// A helper class to build a [ui.DrawLooper] for drawing shadows
-class ShadowDrawLooperBuilder {
-  ui.LayerDrawLooperBuilder _builder = new ui.LayerDrawLooperBuilder();
-
-  /// Add a shadow with the given parameters
-  void addShadow(ui.Offset offset, ui.Color color, double blur) {
-    _builder.addLayerOnTop(
-      new ui.DrawLooperLayerInfo()
-        ..setPaintBits(ui.PaintBits.all)
-        ..setOffset(offset)
-        ..setColorMode(ui.TransferMode.src),
-      new ui.Paint()
-        ..color = color
-        ..maskFilter = new ui.MaskFilter.blur(ui.BlurStyle.normal, blur)
-    );
-  }
-
-  /// Returns the draw looper built for the added shadows
-  ui.DrawLooper build() {
-    _builder.addLayerOnTop(new ui.DrawLooperLayerInfo(), new ui.Paint());
-    return _builder.build();
-  }
-}
diff --git a/sky/packages/sky/lib/src/painting/text_painter.dart b/sky/packages/sky/lib/src/painting/text_painter.dart
deleted file mode 100644
index a22cc9b..0000000
--- a/sky/packages/sky/lib/src/painting/text_painter.dart
+++ /dev/null
@@ -1,211 +0,0 @@
-// Copyright 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 'dart:ui' as ui;
-
-import 'basic_types.dart';
-import 'text_style.dart';
-
-/// An immutable span of text
-abstract class TextSpan {
-  // This class must be immutable, because we won't notice when it changes
-  String toString([String prefix = '']);
-  void build(ui.ParagraphBuilder builder);
-  ui.ParagraphStyle get paragraphStyle => null;
-}
-
-/// An immutable span of unstyled text
-class PlainTextSpan extends TextSpan {
-  PlainTextSpan(this.text) {
-    assert(text != null);
-  }
-
-  /// The text contained in the span
-  final String text;
-
-  void build(ui.ParagraphBuilder builder) {
-    builder.addText(text);
-  }
-
-  bool operator ==(dynamic other) {
-    if (other is! PlainTextSpan)
-      return false;
-    final PlainTextSpan typedOther = other;
-    return text == typedOther.text;
-  }
-
-  int get hashCode => text.hashCode;
-
-  String toString([String prefix = '']) => '$prefix$runtimeType: "$text"';
-}
-
-/// An immutable text span that applies a style to a list of children
-class StyledTextSpan extends TextSpan {
-  StyledTextSpan(this.style, this.children) {
-    assert(style != null);
-    assert(children != null);
-  }
-
-  /// The style to apply to the children
-  final TextStyle style;
-
-  /// The children to which the style is applied
-  final List<TextSpan> children;
-
-  void build(ui.ParagraphBuilder builder) {
-    builder.pushStyle(style.textStyle);
-    for (TextSpan child in children)
-      child.build(builder);
-    builder.pop();
-  }
-
-  ui.ParagraphStyle get paragraphStyle => style.paragraphStyle;
-
-  bool operator ==(dynamic other) {
-    if (identical(this, other))
-      return true;
-    if (other is! StyledTextSpan)
-      return false;
-    final StyledTextSpan typedOther = other;
-    if (style != typedOther.style ||
-        children.length != typedOther.children.length)
-      return false;
-    for (int i = 0; i < children.length; ++i) {
-      if (children[i] != typedOther.children[i])
-        return false;
-    }
-    return true;
-  }
-
-  int get hashCode {
-    int value = 373;
-    value = 37 * value + style.hashCode;
-    for (TextSpan child in children)
-      value = 37 * value + child.hashCode;
-    return value;
-  }
-
-  String toString([String prefix = '']) {
-    List<String> result = <String>[];
-    result.add('$prefix$runtimeType:');
-    var indent = '$prefix  ';
-    result.add('${style.toString(indent)}');
-    for (TextSpan child in children)
-      result.add(child.toString(indent));
-    return result.join('\n');
-  }
-}
-
-/// An object that paints a [TextSpan] into a canvas
-class TextPainter {
-  TextPainter(TextSpan text) {
-    this.text = text;
-  }
-
-  ui.Paragraph _paragraph;
-  bool _needsLayout = true;
-
-  TextSpan _text;
-  /// The (potentially styled) text to paint
-  TextSpan get text => _text;
-  void set text(TextSpan value) {
-    if (_text == value)
-      return;
-    _text = value;
-    ui.ParagraphBuilder builder = new ui.ParagraphBuilder();
-    _text.build(builder);
-    _paragraph = builder.build(_text.paragraphStyle ?? new ui.ParagraphStyle());
-    _needsLayout = true;
-  }
-
-  /// The minimum width at which to layout the text
-  double get minWidth => _paragraph.minWidth;
-  void set minWidth(value) {
-    if (_paragraph.minWidth == value)
-      return;
-    _paragraph.minWidth = value;
-    _needsLayout = true;
-  }
-
-  /// The maximum width at which to layout the text
-  double get maxWidth => _paragraph.maxWidth;
-  void set maxWidth(value) {
-    if (_paragraph.maxWidth == value)
-      return;
-    _paragraph.maxWidth = value;
-    _needsLayout = true;
-  }
-
-  /// The minimum height at which to layout the text
-  double get minHeight => _paragraph.minHeight;
-  void set minHeight(value) {
-    if (_paragraph.minHeight == value)
-      return;
-    _paragraph.minHeight = value;
-    _needsLayout = true;
-  }
-
-  /// The maximum height at which to layout the text
-  double get maxHeight => _paragraph.maxHeight;
-  void set maxHeight(value) {
-    if (_paragraph.maxHeight == value)
-      return;
-    _paragraph.maxHeight = value;
-  }
-
-  // Unfortunately, using full precision floating point here causes bad layouts
-  // because floating point math isn't associative. If we add and subtract
-  // padding, for example, we'll get different values when we estimate sizes and
-  // when we actually compute layout because the operations will end up associated
-  // differently. To work around this problem for now, we round fractional pixel
-  // values up to the nearest whole pixel value. The right long-term fix is to do
-  // layout using fixed precision arithmetic.
-  double _applyFloatingPointHack(double layoutValue) {
-    return layoutValue.ceilToDouble();
-  }
-
-  /// The width at which decreasing the width of the text would prevent it from painting itself completely within its bounds
-  double get minIntrinsicWidth {
-    assert(!_needsLayout);
-    return _applyFloatingPointHack(_paragraph.minIntrinsicWidth);
-  }
-
-  /// The width at which increasing the width of the text no longer decreases the height
-  double get maxIntrinsicWidth {
-    assert(!_needsLayout);
-    return _applyFloatingPointHack(_paragraph.maxIntrinsicWidth);
-  }
-
-  Size get size {
-    assert(!_needsLayout);
-    double height = _applyFloatingPointHack(_paragraph.height);
-    double width = _applyFloatingPointHack(_paragraph.width);
-    return new Size(width, height);
-  }
-
-  /// The distance from the top of the text to the first baseline of the given type
-  double computeDistanceToActualBaseline(TextBaseline baseline) {
-    assert(!_needsLayout);
-    switch (baseline) {
-      case TextBaseline.alphabetic:
-        return _paragraph.alphabeticBaseline;
-      case TextBaseline.ideographic:
-        return _paragraph.ideographicBaseline;
-    }
-  }
-
-  /// Compute the visual position of the glyphs for painting the text
-  void layout() {
-    if (!_needsLayout)
-      return;
-    _paragraph.layout();
-    _needsLayout = false;
-  }
-
-  /// Paint the text onto the given canvas at the given offset
-  void paint(ui.Canvas canvas, ui.Offset offset) {
-    assert(!_needsLayout && "Please call layout() before paint() to position the text before painting it." is String);
-    _paragraph.paint(canvas, offset);
-  }
-}
diff --git a/sky/packages/sky/lib/src/painting/text_style.dart b/sky/packages/sky/lib/src/painting/text_style.dart
deleted file mode 100644
index a5ace3b..0000000
--- a/sky/packages/sky/lib/src/painting/text_style.dart
+++ /dev/null
@@ -1,322 +0,0 @@
-// Copyright 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 'dart:ui' as ui;
-
-import 'basic_types.dart';
-
-/// A normal font weight
-const normal = FontWeight.w400;
-
-/// A bold font weight
-const bold = FontWeight.w700;
-
-/// Draw a line underneath each line of text
-const underline = const <TextDecoration>[TextDecoration.underline];
-
-/// Draw a line above each line of text
-const overline = const <TextDecoration>[TextDecoration.overline];
-
-/// Draw a line through each line of text
-const lineThrough = const <TextDecoration>[TextDecoration.lineThrough];
-
-/// An immutable style in which paint text
-class TextStyle {
-  const TextStyle({
-    this.inherit: true,
-    this.color,
-    this.fontFamily,
-    this.fontSize,
-    this.fontWeight,
-    this.fontStyle,
-    this.textAlign,
-    this.textBaseline,
-    this.height,
-    this.decoration,
-    this.decorationColor,
-    this.decorationStyle
-  });
-
-  /// Whether null values are replaced with their value in an ancestor text style.
-  final bool inherit;
-
-  /// The color to use when painting the text
-  final Color color;
-
-  /// The name of the font to use when painting the text
-  final String fontFamily;
-
-  /// The size of gyphs (in logical pixels) to use when painting the text
-  final double fontSize;
-
-  /// The font weight to use when painting the text
-  final FontWeight fontWeight;
-
-  /// The font style to use when painting the text
-  final FontStyle fontStyle;
-
-  /// How the text should be aligned (applies only to the outermost
-  /// StyledTextSpan, which establishes the container for the text)
-  final TextAlign textAlign;
-
-  /// The baseline to use for aligning the text
-  final TextBaseline textBaseline;
-
-  /// The distance between the text baselines, as a multiple of the font size
-  final double height;
-
-  /// A list of decorations to paint near the text
-  final List<TextDecoration> decoration; // TODO(ianh): Switch this to a Set<> once Dart supports constant Sets
-
-  /// The color in which to paint the text decorations
-  final Color decorationColor;
-
-  /// The style in which to paint the text decorations
-  final TextDecorationStyle decorationStyle;
-
-  /// Returns a new text style that matches this text style but with the given
-  /// values replaced
-  TextStyle copyWith({
-    Color color,
-    String fontFamily,
-    double fontSize,
-    FontWeight fontWeight,
-    FontStyle fontStyle,
-    TextAlign textAlign,
-    TextBaseline textBaseline,
-    double height,
-    List<TextDecoration> decoration,
-    Color decorationColor,
-    TextDecorationStyle decorationStyle
-  }) {
-    return new TextStyle(
-      inherit: inherit,
-      color: color != null ? color : this.color,
-      fontFamily: fontFamily != null ? fontFamily : this.fontFamily,
-      fontSize: fontSize != null ? fontSize : this.fontSize,
-      fontWeight: fontWeight != null ? fontWeight : this.fontWeight,
-      fontStyle: fontStyle != null ? fontStyle : this.fontStyle,
-      textAlign: textAlign != null ? textAlign : this.textAlign,
-      textBaseline: textBaseline != null ? textBaseline : this.textBaseline,
-      height: height != null ? height : this.height,
-      decoration: decoration != null ? decoration : this.decoration,
-      decorationColor: decorationColor != null ? decorationColor : this.decorationColor,
-      decorationStyle: decorationStyle != null ? decorationStyle : this.decorationStyle
-    );
-  }
-
-  /// Returns a new text style that matches this text style but with some values
-  /// replaced by the non-null parameters of the given text style. If the given
-  /// text style is null, simply returns this text style.
-  TextStyle merge(TextStyle other) {
-    if (other == null)
-      return this;
-    assert(other.inherit);
-    return copyWith(
-      color: other.color,
-      fontFamily: other.fontFamily,
-      fontSize: other.fontSize,
-      fontWeight: other.fontWeight,
-      fontStyle: other.fontStyle,
-      textAlign: other.textAlign,
-      textBaseline: other.textBaseline,
-      height: other.height,
-      decoration: other.decoration,
-      decorationColor: other.decorationColor,
-      decorationStyle: other.decorationStyle
-    );
-  }
-
-  ui.TextStyle get textStyle {
-    return new ui.TextStyle(
-      color: color,
-      decoration: decoration,
-      decorationColor: decorationColor,
-      decorationStyle: decorationStyle,
-      fontWeight: fontWeight,
-      fontStyle: fontStyle,
-      fontFamily: fontFamily,
-      fontSize: fontSize
-    );
-  }
-
-  ui.ParagraphStyle get paragraphStyle {
-    return new ui.ParagraphStyle(
-      textAlign: textAlign,
-      textBaseline: textBaseline,
-      lineHeight: height
-    );
-  }
-
-  bool operator ==(dynamic other) {
-    if (identical(this, other))
-      return true;
-    if (other is! TextStyle)
-      return false;
-    final TextStyle typedOther = other;
-    return inherit == typedOther.inherit &&
-           color == typedOther.color &&
-           fontFamily == typedOther.fontFamily &&
-           fontSize == typedOther.fontSize &&
-           fontWeight == typedOther.fontWeight &&
-           fontStyle == typedOther.fontStyle &&
-           textAlign == typedOther.textAlign &&
-           textBaseline == typedOther.textBaseline &&
-           decoration == typedOther.decoration &&
-           decorationColor == typedOther.decorationColor &&
-           decorationStyle == typedOther.decorationStyle;
-  }
-
-  int get hashCode {
-    // Use Quiver: https://github.com/domokit/mojo/issues/236
-    int value = 373;
-    value = 37 * value + inherit.hashCode;
-    value = 37 * value + color.hashCode;
-    value = 37 * value + fontFamily.hashCode;
-    value = 37 * value + fontSize.hashCode;
-    value = 37 * value + fontWeight.hashCode;
-    value = 37 * value + fontStyle.hashCode;
-    value = 37 * value + textAlign.hashCode;
-    value = 37 * value + textBaseline.hashCode;
-    value = 37 * value + decoration.hashCode;
-    value = 37 * value + decorationColor.hashCode;
-    value = 37 * value + decorationStyle.hashCode;
-    return value;
-  }
-
-  String toString([String prefix = '']) {
-    List<String> result = <String>[];
-    result.add('${prefix}inhert: $inherit');
-    if (color != null)
-      result.add('${prefix}color: $color');
-    if (fontFamily != null)
-      result.add('${prefix}family: "$fontFamily"');
-    if (fontSize != null)
-      result.add('${prefix}size: $fontSize');
-    if (fontWeight != null) {
-      switch (fontWeight) {
-        case FontWeight.w100:
-          result.add('${prefix}weight: 100');
-          break;
-        case FontWeight.w200:
-          result.add('${prefix}weight: 200');
-          break;
-        case FontWeight.w300:
-          result.add('${prefix}weight: 300');
-          break;
-        case FontWeight.w400:
-          result.add('${prefix}weight: 400');
-          break;
-        case FontWeight.w500:
-          result.add('${prefix}weight: 500');
-          break;
-        case FontWeight.w600:
-          result.add('${prefix}weight: 600');
-          break;
-        case FontWeight.w700:
-          result.add('${prefix}weight: 700');
-          break;
-        case FontWeight.w800:
-          result.add('${prefix}weight: 800');
-          break;
-        case FontWeight.w900:
-          result.add('${prefix}weight: 900');
-          break;
-      }
-    }
-    if (fontStyle != null) {
-      switch (fontStyle) {
-        case FontStyle.normal:
-          result.add('${prefix}style: normal');
-          break;
-        case FontStyle.italic:
-          result.add('${prefix}style: italic');
-          break;
-      }
-    }
-    if (textAlign != null) {
-      switch (textAlign) {
-        case TextAlign.left:
-          result.add('${prefix}align: left');
-          break;
-        case TextAlign.right:
-          result.add('${prefix}align: right');
-          break;
-        case TextAlign.center:
-          result.add('${prefix}align: center');
-          break;
-      }
-    }
-    if (textBaseline != null) {
-      switch (textBaseline) {
-        case TextBaseline.alphabetic:
-          result.add('${prefix}baseline: alphabetic');
-          break;
-        case TextBaseline.ideographic:
-          result.add('${prefix}baseline: ideographic');
-          break;
-      }
-    }
-    if (decoration != null || decorationColor != null || decorationStyle != null) {
-      String decorationDescription = '${prefix}decoration: ';
-      bool haveDecorationDescription = false;
-      if (decorationStyle != null) {
-        switch (decorationStyle) {
-          case TextDecorationStyle.solid:
-            decorationDescription += 'solid';
-            break;
-          case TextDecorationStyle.double:
-            decorationDescription += 'double';
-            break;
-          case TextDecorationStyle.dotted:
-            decorationDescription += 'dotted';
-            break;
-          case TextDecorationStyle.dashed:
-            decorationDescription += 'dashed';
-            break;
-          case TextDecorationStyle.wavy:
-            decorationDescription += 'wavy';
-            break;
-        }
-        haveDecorationDescription = true;
-      }
-      if (decorationColor != null) {
-        if (haveDecorationDescription)
-          decorationDescription += ' ';
-        decorationDescription += '$decorationColor';
-        haveDecorationDescription = true;
-      }
-      if (decoration != null) {
-        if (haveDecorationDescription)
-          decorationDescription += ' ';
-        bool multipleDecorations = false;
-        for (TextDecoration value in decoration) {
-          if (multipleDecorations)
-            decorationDescription += '+';
-          switch (value) {
-            case TextDecoration.none:
-              decorationDescription += 'none';
-              break;
-            case TextDecoration.underline:
-              decorationDescription += 'underline';
-              break;
-            case TextDecoration.overline:
-              decorationDescription += 'overline';
-              break;
-            case TextDecoration.lineThrough:
-              decorationDescription += 'line-through';
-              break;
-          }
-          multipleDecorations = true;
-        }
-        haveDecorationDescription = true;
-      }
-      assert(haveDecorationDescription);
-      result.add(decorationDescription);
-    }
-    if (result.isEmpty)
-      return '$prefix<no style specified>';
-    return result.join('\n');
-  }
-}
diff --git a/sky/packages/sky/lib/src/rendering/auto_layout.dart b/sky/packages/sky/lib/src/rendering/auto_layout.dart
deleted file mode 100644
index 54f31ef..0000000
--- a/sky/packages/sky/lib/src/rendering/auto_layout.dart
+++ /dev/null
@@ -1,236 +0,0 @@
-// Copyright 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:cassowary/cassowary.dart' as al; // "auto layout"
-
-import 'box.dart';
-import 'object.dart';
-
-/// Hosts the edge parameters and vends useful methods to construct expressions
-/// for constraints. Also sets up and manages implicit constraints and edit
-/// variables. Used as a mixin by layout containers and parent data instances
-/// of render boxes taking part in auto layout
-abstract class _AutoLayoutParamMixin {
-  // Ideally, the edges would all be final, but then they would have to be
-  // initialized before the constructor. Not sure how to do that using a Mixin
-  al.Param _leftEdge;
-  al.Param _rightEdge;
-  al.Param _topEdge;
-  al.Param _bottomEdge;
-
-  List<al.Constraint> _implicitConstraints;
-
-  al.Param get leftEdge => _leftEdge;
-  al.Param get rightEdge => _rightEdge;
-  al.Param get topEdge => _topEdge;
-  al.Param get bottomEdge => _bottomEdge;
-
-  al.Expression get width => _rightEdge - _leftEdge;
-  al.Expression get height => _bottomEdge - _topEdge;
-
-  al.Expression get horizontalCenter => (_leftEdge + _rightEdge) / al.cm(2.0);
-  al.Expression get verticalCenter => (_topEdge + _bottomEdge) / al.cm(2.0);
-
-  void _setupLayoutParameters(dynamic context) {
-    _leftEdge = new al.Param.withContext(context);
-    _rightEdge = new al.Param.withContext(context);
-    _topEdge = new al.Param.withContext(context);
-    _bottomEdge = new al.Param.withContext(context);
-  }
-
-  void _setupEditVariablesInSolver(al.Solver solver, double priority) {
-    solver.addEditVariables(<al.Variable>[
-        _leftEdge.variable,
-        _rightEdge.variable,
-        _topEdge.variable,
-        _bottomEdge.variable
-      ], priority);
-  }
-
-  void _applyEditsAtSize(al.Solver solver, Size size) {
-    solver.suggestValueForVariable(_leftEdge.variable, 0.0);
-    solver.suggestValueForVariable(_topEdge.variable, 0.0);
-    solver.suggestValueForVariable(_bottomEdge.variable, size.height);
-    solver.suggestValueForVariable(_rightEdge.variable, size.width);
-  }
-
-  /// Called when the solver has updated at least one of the layout parameters
-  /// of this object. The object is now responsible for applying this update to
-  /// it other properties (if necessary)
-  void _applyAutolayoutParameterUpdates();
-
-  /// Returns the set of implicit constraints that need to be applied to all
-  /// instances of this class when they are moved into a render object with an
-  /// active solver. If no implicit constraints needs to be applied, the object
-  /// may return null.
-  List<al.Constraint> _constructImplicitConstraints();
-
-  void _setupImplicitConstraints(al.Solver solver) {
-    List<al.Constraint> implicit = _constructImplicitConstraints();
-
-    if (implicit == null || implicit.length == 0) {
-      return;
-    }
-
-    al.Result result = solver.addConstraints(implicit);
-    assert(result == al.Result.success);
-
-    _implicitConstraints = implicit;
-  }
-
-  void _removeImplicitConstraints(al.Solver solver) {
-    if (_implicitConstraints == null || _implicitConstraints.length == 0) {
-      return;
-    }
-
-    al.Result result = solver.removeConstraints(_implicitConstraints);
-    assert(result == al.Result.success);
-
-    _implicitConstraints = null;
-  }
-}
-
-class AutoLayoutParentData extends ContainerBoxParentDataMixin<RenderBox> with _AutoLayoutParamMixin {
-
-  AutoLayoutParentData(this._renderBox) {
-    _setupLayoutParameters(this);
-  }
-
-  final RenderBox _renderBox;
-
-  void _applyAutolayoutParameterUpdates() {
-    // This is called by the parent's layout function
-    // to lay our box out.
-    assert(_renderBox.parentData == this);
-    assert(() {
-      final RenderAutoLayout parent = _renderBox.parent;
-      assert(parent.debugDoingThisLayout);
-    });
-    BoxConstraints size = new BoxConstraints.tightFor(
-      width: _rightEdge.value - _leftEdge.value,
-      height: _bottomEdge.value - _topEdge.value
-    );
-    _renderBox.layout(size);
-    position = new Point(_leftEdge.value, _topEdge.value);
-  }
-
-  List<al.Constraint> _constructImplicitConstraints() {
-    return <al.Constraint>[
-      _leftEdge >= al.cm(0.0), // The left edge must be positive.
-      _rightEdge >= _leftEdge, // Width must be positive.
-    ];
-  }
-
-}
-
-class RenderAutoLayout extends RenderBox
-    with ContainerRenderObjectMixin<RenderBox, AutoLayoutParentData>,
-         RenderBoxContainerDefaultsMixin<RenderBox, AutoLayoutParentData>,
-         _AutoLayoutParamMixin {
-
-  RenderAutoLayout({ List<RenderBox> children }) {
-    _setupLayoutParameters(this);
-    _setupEditVariablesInSolver(_solver, al.Priority.required - 1);
-    addAll(children);
-  }
-
-  final al.Solver _solver = new al.Solver();
-  List<al.Constraint> _explicitConstraints = new List<al.Constraint>();
-
-  /// Adds all the given constraints to the solver. Either all constraints are
-  /// added or none
-  al.Result addConstraints(List<al.Constraint> constraints) {
-    al.Result result = _solver.addConstraints(constraints);
-    if (result == al.Result.success) {
-      markNeedsLayout();
-      _explicitConstraints.addAll(constraints);
-    }
-    return result;
-  }
-
-  /// Add the given constraint to the solver.
-  al.Result addConstraint(al.Constraint constraint) {
-    al.Result result = _solver.addConstraint(constraint);
-
-    if (result == al.Result.success) {
-      markNeedsLayout();
-      _explicitConstraints.add(constraint);
-    }
-
-    return result;
-  }
-
-  /// Removes all explicitly added constraints.
-  al.Result clearAllConstraints() {
-    al.Result result = _solver.removeConstraints(_explicitConstraints);
-
-    if (result == al.Result.success) {
-      markNeedsLayout();
-      _explicitConstraints = new List<al.Constraint>();
-    }
-
-    return result;
-  }
-
-  void adoptChild(RenderObject child) {
-    // Make sure to call super first to setup the parent data
-    super.adoptChild(child);
-    final AutoLayoutParentData childParentData = child.parentData;
-    childParentData._setupImplicitConstraints(_solver);
-    assert(child.parentData == childParentData);
-  }
-
-  void dropChild(RenderObject child) {
-    final AutoLayoutParentData childParentData = child.parentData;
-    childParentData._removeImplicitConstraints(_solver);
-    assert(child.parentData == childParentData);
-    super.dropChild(child);
-  }
-
-  void setupParentData(RenderObject child) {
-    if (child.parentData is! AutoLayoutParentData)
-      child.parentData = new AutoLayoutParentData(child);
-  }
-
-  bool get sizedByParent => true;
-
-  void performResize() {
-    size = constraints.biggest;
-  }
-
-  void performLayout() {
-    // Step 1: Update dimensions of self
-    _applyEditsAtSize(_solver, size);
-
-    // Step 2: Resolve solver updates and flush parameters
-
-    // We don't iterate over the children, instead, we ask the solver to tell
-    // us the updated parameters. Attached to the parameters (via the context)
-    // are the _AutoLayoutParamMixin instances.
-    for (_AutoLayoutParamMixin update in _solver.flushUpdates()) {
-      update._applyAutolayoutParameterUpdates();
-    }
-  }
-
-  void _applyAutolayoutParameterUpdates() {
-    // Nothing to do since the size update has already been presented to the
-    // solver as an edit variable modification. The invokation of this method
-    // only indicates that the value has been flushed to the variable.
-  }
-
-  bool hitTestChildren(HitTestResult result, {Point position}) {
-    return defaultHitTestChildren(result, position: position);
-  }
-
-  void paint(PaintingContext context, Offset offset) {
-    defaultPaint(context, offset);
-  }
-
-  List<al.Constraint> _constructImplicitConstraints() {
-    // Only edits variables are present on layout containers. If, in the future,
-    // implicit constraints (for say margins, padding, etc.) need to be added,
-    // they must be returned from here.
-    return null;
-  }
-}
diff --git a/sky/packages/sky/lib/src/rendering/basic_types.dart b/sky/packages/sky/lib/src/rendering/basic_types.dart
deleted file mode 100644
index b972578..0000000
--- a/sky/packages/sky/lib/src/rendering/basic_types.dart
+++ /dev/null
@@ -1,16 +0,0 @@
-// Copyright 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.
-
-export 'dart:ui' show
-  Canvas,
-  Color,
-  ColorFilter,
-  Offset,
-  Paint,
-  Path,
-  Point,
-  Rect,
-  Size,
-  TransferMode,
-  VoidCallback;
diff --git a/sky/packages/sky/lib/src/rendering/binding.dart b/sky/packages/sky/lib/src/rendering/binding.dart
deleted file mode 100644
index 0ba8995..0000000
--- a/sky/packages/sky/lib/src/rendering/binding.dart
+++ /dev/null
@@ -1,274 +0,0 @@
-// Copyright 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 'dart:ui' as ui;
-
-import 'package:flutter/animation.dart';
-import 'package:flutter/gestures.dart';
-import 'package:flutter/rendering.dart';
-
-import 'box.dart';
-import 'hit_test.dart';
-import 'object.dart';
-import 'view.dart';
-
-typedef void EventListener(InputEvent event);
-typedef void MetricListener(Size size);
-
-int _hammingWeight(int value) {
-  if (value == 0)
-    return 0;
-  int weight = 0;
-  for (int i = 0; i < value.bitLength; ++i) {
-    if (value & (1 << i) != 0)
-      ++weight;
-  }
-  return weight;
-}
-
-/// A hit test entry used by [FlutterBinding]
-class BindingHitTestEntry extends HitTestEntry {
-  const BindingHitTestEntry(HitTestTarget target, this.result) : super(target);
-
-  /// The result of the hit test
-  final HitTestResult result;
-}
-
-/// State used in converting ui.Event to InputEvent
-class _PointerState {
-  _PointerState({ this.pointer, this.lastPosition });
-  int pointer;
-  Point lastPosition;
-}
-
-class _UiEventConverter {
-  static InputEvent convert(ui.Event event) {
-    if (event is ui.PointerEvent)
-      return convertPointerEvent(event);
-
-    // Default event
-    return new InputEvent(
-      type: event.type,
-      timeStamp: event.timeStamp
-    );
-  }
-
-  // Map actual input pointer value to a unique value
-  // Since events are serialized we can just use a counter
-  static Map<int, _PointerState> _stateForPointer = new Map<int, _PointerState>();
-  static int _pointerCount = 0;
-
-  static PointerInputEvent convertPointerEvent(ui.PointerEvent event) {
-    Point position = new Point(event.x, event.y);
-
-    _PointerState state = _stateForPointer[event.pointer];
-    double dx = 0.0;
-    double dy = 0.0;
-    switch (event.type) {
-      case 'pointerdown':
-        if (state == null) {
-          state = new _PointerState(lastPosition: position);
-          _stateForPointer[event.pointer] = state;
-        }
-        state.pointer = _pointerCount;
-        _pointerCount++;
-        break;
-      case 'pointermove':
-        // state == null means the pointer is hovering
-        if (state != null) {
-          dx = position.x - state.lastPosition.x;
-          dy = position.y - state.lastPosition.y;
-          state.lastPosition = position;
-        }
-        break;
-      case 'pointerup':
-      case 'pointercancel':
-        // state == null indicates spurious events
-        if (state != null) {
-          // Only remove the pointer state when the last button has been released.
-          if (_hammingWeight(event.buttons) <= 1)
-            _stateForPointer.remove(event.pointer);
-        }
-        break;
-    }
-
-    int pointer = (state == null) ? event.pointer : state.pointer;
-
-    return new PointerInputEvent(
-       type: event.type,
-       timeStamp: event.timeStamp,
-       pointer: pointer,
-       kind: event.kind,
-       x: event.x,
-       y: event.y,
-       dx: dx,
-       dy: dy,
-       buttons: event.buttons,
-       down: event.down,
-       primary: event.primary,
-       obscured: event.obscured,
-       pressure: event.pressure,
-       pressureMin: event.pressureMin,
-       pressureMax: event.pressureMax,
-       distance: event.distance,
-       distanceMin: event.distanceMin,
-       distanceMax: event.distanceMax,
-       radiusMajor: event.radiusMajor,
-       radiusMinor: event.radiusMinor,
-       radiusMin: event.radiusMin,
-       radiusMax: event.radiusMax,
-       orientation: event.orientation,
-       tilt: event.tilt
-     );
-  }
-
-}
-
-/// The glue between the render tree and the Flutter engine
-class FlutterBinding extends HitTestTarget {
-
-  FlutterBinding({ RenderBox root: null, RenderView renderViewOverride }) {
-    assert(_instance == null);
-    _instance = this;
-
-    ui.window.onEvent = _handleEvent;
-    ui.window.onMetricsChanged = _handleMetricsChanged;
-
-    if (renderViewOverride == null) {
-      _renderView = new RenderView(child: root);
-      _renderView.attach();
-      _handleMetricsChanged();
-      _renderView.scheduleInitialFrame();
-    } else {
-      _renderView = renderViewOverride;
-    }
-    assert(_renderView != null);
-    scheduler.addPersistentFrameCallback(_handlePersistentFrameCallback);
-
-    assert(_instance == this);
-  }
-
-  /// The singleton instance of the binding
-  static FlutterBinding get instance => _instance;
-  static FlutterBinding _instance;
-
-  /// The render tree that's attached to the output surface
-  RenderView get renderView => _renderView;
-  RenderView _renderView;
-
-  final List<MetricListener> _metricListeners = new List<MetricListener>();
-
-  /// Calls listener for every event that isn't localized to a given view coordinate
-  void addMetricListener(MetricListener listener) => _metricListeners.add(listener);
-
-  /// Stops calling listener for every event that isn't localized to a given view coordinate
-  bool removeMetricListener(MetricListener listener) => _metricListeners.remove(listener);
-
-  void _handleMetricsChanged() {
-    Size size = ui.window.size;
-    _renderView.rootConstraints = new ViewConstraints(size: size);
-    for (MetricListener listener in _metricListeners)
-      listener(size);
-  }
-
-  void _handlePersistentFrameCallback(Duration timeStamp) {
-    beginFrame();
-  }
-
-  /// Pump the rendering pipeline to generate a frame for the given time stamp
-  void beginFrame() {
-    RenderObject.flushLayout();
-    _renderView.updateCompositingBits();
-    RenderObject.flushPaint();
-    _renderView.compositeFrame();
-  }
-
-  final List<EventListener> _eventListeners = new List<EventListener>();
-
-  /// Calls listener for every event that isn't localized to a given view coordinate
-  void addEventListener(EventListener listener) => _eventListeners.add(listener);
-
-  /// Stops calling listener for every event that isn't localized to a given view coordinate
-  bool removeEventListener(EventListener listener) => _eventListeners.remove(listener);
-
-  void _handleEvent(ui.Event event) {
-    InputEvent ourEvent = _UiEventConverter.convert(event);
-    if (ourEvent is PointerInputEvent) {
-      _handlePointerInputEvent(ourEvent);
-    } else {
-      assert(event.type == 'back');
-      for (EventListener listener in _eventListeners)
-        listener(ourEvent);
-    }
-  }
-
-  /// A router that routes all pointer events received from the engine
-  final PointerRouter pointerRouter = new PointerRouter();
-
-  /// State for all pointers which are currently down.
-  /// We do not track the state of hovering pointers because we need
-  /// to hit-test them on each movement.
-  Map<int, HitTestResult> _resultForPointer = new Map<int, HitTestResult>();
-
-  void _handlePointerInputEvent(PointerInputEvent event) {
-    HitTestResult result = _resultForPointer[event.pointer];
-    switch (event.type) {
-      case 'pointerdown':
-        if (result == null) {
-          result = hitTest(new Point(event.x, event.y));
-          _resultForPointer[event.pointer] = result;
-        }
-        break;
-      case 'pointermove':
-        if (result == null) {
-          // The pointer is hovering, ignore it for now since we don't
-          // know what to do with it yet.
-          return;
-        }
-        break;
-      case 'pointerup':
-      case 'pointercancel':
-        if (result == null) {
-          // This seems to be a spurious event.  Ignore it.
-          return;
-        }
-        // Only remove the hit test result when the last button has been released.
-        if (_hammingWeight(event.buttons) <= 1)
-          _resultForPointer.remove(event.pointer);
-        break;
-    }
-    dispatchEvent(event, result);
-  }
-
-  /// Determine which [HitTestTarget] objects are located at a given position
-  HitTestResult hitTest(Point position) {
-    HitTestResult result = new HitTestResult();
-    _renderView.hitTest(result, position: position);
-    result.add(new BindingHitTestEntry(this, result));
-    return result;
-  }
-
-  /// Dispatch the given event to the path of the given hit test result
-  void dispatchEvent(InputEvent event, HitTestResult result) {
-    assert(result != null);
-    for (HitTestEntry entry in result.path)
-      entry.target.handleEvent(event, entry);
-  }
-
-  void handleEvent(InputEvent e, BindingHitTestEntry entry) {
-    if (e is PointerInputEvent) {
-      PointerInputEvent event = e;
-      pointerRouter.route(event);
-      if (event.type == 'pointerdown')
-        GestureArena.instance.close(event.pointer);
-      else if (event.type == 'pointerup')
-        GestureArena.instance.sweep(event.pointer);
-    }
-  }
-}
-
-/// Prints a textual representation of the entire render tree
-void debugDumpRenderTree() {
-  debugPrint(FlutterBinding.instance.renderView.toStringDeep());
-}
diff --git a/sky/packages/sky/lib/src/rendering/block.dart b/sky/packages/sky/lib/src/rendering/block.dart
deleted file mode 100644
index 275a883..0000000
--- a/sky/packages/sky/lib/src/rendering/block.dart
+++ /dev/null
@@ -1,437 +0,0 @@
-// Copyright 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 'dart:math' as math;
-
-import 'package:vector_math/vector_math_64.dart';
-
-import 'box.dart';
-import 'object.dart';
-
-/// Parent data for use with [RenderBlockBase]
-class BlockParentData extends ContainerBoxParentDataMixin<RenderBox> { }
-
-/// The direction in which the block should lay out
-enum BlockDirection {
-  /// Children are arranged horizontally, from left to right
-  horizontal,
-  /// Children are arranged vertically, from top to bottom
-  vertical
-}
-
-typedef double _ChildSizingFunction(RenderBox child, BoxConstraints constraints);
-typedef double _Constrainer(double value);
-
-/// Implements the block layout algorithm
-///
-/// In block layout, children are arranged linearly along the main axis (either
-/// horizontally or vertically). In the cross axis, children are stretched to
-/// match the block's cross-axis extent. In the main axis, children are given
-/// unlimited space and the block expands its main axis to contain all its
-/// children. Because blocks expand in the main axis, blocks must be given
-/// unlimited space in the main axis, typically by being contained in a
-/// viewport with a scrolling direction that matches the block's main axis.
-abstract class RenderBlockBase extends RenderBox with ContainerRenderObjectMixin<RenderBox, BlockParentData>,
-                                                      RenderBoxContainerDefaultsMixin<RenderBox, BlockParentData> {
-
-  RenderBlockBase({
-    List<RenderBox> children,
-    BlockDirection direction: BlockDirection.vertical,
-    double itemExtent,
-    double minExtent: 0.0
-  }) : _direction = direction, _itemExtent = itemExtent, _minExtent = minExtent {
-    addAll(children);
-  }
-
-  void setupParentData(RenderBox child) {
-    if (child.parentData is! BlockParentData)
-      child.parentData = new BlockParentData();
-  }
-
-  /// The direction to use as the main axis
-  BlockDirection get direction => _direction;
-  BlockDirection _direction;
-  void set direction (BlockDirection value) {
-    if (_direction != value) {
-      _direction = value;
-      markNeedsLayout();
-    }
-  }
-
-  /// If non-null, forces children to be exactly this large in the main axis
-  double get itemExtent => _itemExtent;
-  double _itemExtent;
-  void set itemExtent(double value) {
-    if (value != _itemExtent) {
-      _itemExtent = value;
-      markNeedsLayout();
-    }
-  }
-
-  /// Forces the block to be at least this large in the main-axis
-  double get minExtent => _minExtent;
-  double _minExtent;
-  void set minExtent(double value) {
-    if (value != _minExtent) {
-      _minExtent = value;
-      markNeedsLayout();
-    }
-  }
-
-  /// Whether the main axis is vertical
-  bool get isVertical => _direction == BlockDirection.vertical;
-
-  BoxConstraints _getInnerConstraints(BoxConstraints constraints) {
-    if (isVertical)
-      return new BoxConstraints.tightFor(width: constraints.constrainWidth(constraints.maxWidth),
-                                         height: itemExtent);
-    return new BoxConstraints.tightFor(height: constraints.constrainHeight(constraints.maxHeight),
-                                       width: itemExtent);
-  }
-
-  double get _mainAxisExtent {
-    RenderBox child = lastChild;
-    if (child == null)
-      return minExtent;
-    BoxParentData parentData = child.parentData;
-    return isVertical ?
-        math.max(minExtent, parentData.position.y + child.size.height) :
-        math.max(minExtent, parentData.position.x + child.size.width);
-  }
-
-  void performLayout() {
-    BoxConstraints innerConstraints = _getInnerConstraints(constraints);
-    double position = 0.0;
-    RenderBox child = firstChild;
-    while (child != null) {
-      child.layout(innerConstraints, parentUsesSize: true);
-      final BlockParentData childParentData = child.parentData;
-      childParentData.position = isVertical ? new Point(0.0, position) : new Point(position, 0.0);
-      position += isVertical ? child.size.height : child.size.width;
-      assert(child.parentData == childParentData);
-      child = childParentData.nextSibling;
-    }
-    size = isVertical ?
-        constraints.constrain(new Size(constraints.maxWidth, _mainAxisExtent)) :
-        constraints.constrain(new Size(_mainAxisExtent, constraints.maxHeight));
-    assert(!size.isInfinite);
-  }
-
-  void debugDescribeSettings(List<String> settings) {
-    super.debugDescribeSettings(settings);
-    settings.add('direction: $direction');
-  }
-}
-
-/// A block layout with a concrete set of children
-class RenderBlock extends RenderBlockBase {
-
-  RenderBlock({
-    List<RenderBox> children,
-    BlockDirection direction: BlockDirection.vertical,
-    double itemExtent,
-    double minExtent: 0.0
-  }) : super(children: children, direction: direction, itemExtent: itemExtent, minExtent: minExtent);
-
-  double _getIntrinsicCrossAxis(BoxConstraints constraints, _ChildSizingFunction childSize) {
-    double extent = 0.0;
-    BoxConstraints innerConstraints = isVertical ? constraints.widthConstraints() : constraints.heightConstraints();
-    RenderBox child = firstChild;
-    while (child != null) {
-      extent = math.max(extent, childSize(child, innerConstraints));
-      final BlockParentData childParentData = child.parentData;
-      child = childParentData.nextSibling;
-    }
-    return extent;
-  }
-
-  double _getIntrinsicMainAxis(BoxConstraints constraints) {
-    double extent = 0.0;
-    BoxConstraints innerConstraints = _getInnerConstraints(constraints);
-    RenderBox child = firstChild;
-    while (child != null) {
-      double childExtent = isVertical ?
-        child.getMinIntrinsicHeight(innerConstraints) :
-        child.getMinIntrinsicWidth(innerConstraints);
-      assert(() {
-        if (isVertical)
-          return childExtent == child.getMaxIntrinsicHeight(innerConstraints);
-        return childExtent == child.getMaxIntrinsicWidth(innerConstraints);
-      });
-      extent += childExtent;
-      final BlockParentData childParentData = child.parentData;
-      child = childParentData.nextSibling;
-    }
-    return math.max(extent, minExtent);
-  }
-
-  double getMinIntrinsicWidth(BoxConstraints constraints) {
-    if (isVertical) {
-      return _getIntrinsicCrossAxis(
-        constraints,
-        (RenderBox child, BoxConstraints innerConstraints) => child.getMinIntrinsicWidth(innerConstraints)
-      );
-    }
-    return _getIntrinsicMainAxis(constraints);
-  }
-
-  double getMaxIntrinsicWidth(BoxConstraints constraints) {
-    if (isVertical) {
-      return _getIntrinsicCrossAxis(
-        constraints,
-        (RenderBox child, BoxConstraints innerConstraints) => child.getMaxIntrinsicWidth(innerConstraints)
-      );
-    }
-    return _getIntrinsicMainAxis(constraints);
-  }
-
-  double getMinIntrinsicHeight(BoxConstraints constraints) {
-    if (isVertical)
-      return _getIntrinsicMainAxis(constraints);
-    return _getIntrinsicCrossAxis(
-      constraints,
-      (RenderBox child, BoxConstraints innerConstraints) => child.getMinIntrinsicWidth(innerConstraints)
-    );
-  }
-
-  double getMaxIntrinsicHeight(BoxConstraints constraints) {
-    if (isVertical)
-      return _getIntrinsicMainAxis(constraints);
-    return _getIntrinsicCrossAxis(
-      constraints,
-      (RenderBox child, BoxConstraints innerConstraints) => child.getMaxIntrinsicWidth(innerConstraints)
-    );
-  }
-
-  double computeDistanceToActualBaseline(TextBaseline baseline) {
-    return defaultComputeDistanceToFirstActualBaseline(baseline);
-  }
-
-  void performLayout() {
-    assert((isVertical ? constraints.maxHeight >= double.INFINITY : constraints.maxWidth >= double.INFINITY) &&
-           'RenderBlock does not clip or resize its children, so it must be placed in a parent that does not constrain ' +
-           'the block\'s main direction. You probably want to put the RenderBlock inside a RenderViewport.' is String);
-    super.performLayout();
-  }
-
-  void paint(PaintingContext context, Offset offset) {
-    defaultPaint(context, offset);
-  }
-
-  bool hitTestChildren(HitTestResult result, { Point position }) {
-    return defaultHitTestChildren(result, position: position);
-  }
-
-}
-
-/// A block layout whose children depend on its layout
-///
-/// This class invokes a callbacks for layout and intrinsic dimensions. The main
-/// [callback] (constructor argument and property) is expected to modify the
-/// element's child list. The regular block layout algorithm is then applied to
-/// the children. The intrinsic dimension callbacks are called to determine
-/// intrinsic dimensions; if no value can be returned, they should not be set
-/// or, if set, should return null.
-class RenderBlockViewport extends RenderBlockBase {
-
-  RenderBlockViewport({
-    LayoutCallback callback,
-    ExtentCallback totalExtentCallback,
-    ExtentCallback maxCrossAxisDimensionCallback,
-    ExtentCallback minCrossAxisDimensionCallback,
-    Painter overlayPainter,
-    BlockDirection direction: BlockDirection.vertical,
-    double itemExtent,
-    double minExtent: 0.0,
-    double startOffset: 0.0,
-    List<RenderBox> children
-  }) : _callback = callback,
-       _totalExtentCallback = totalExtentCallback,
-       _maxCrossAxisExtentCallback = maxCrossAxisDimensionCallback,
-       _minCrossAxisExtentCallback = minCrossAxisDimensionCallback,
-       _overlayPainter = overlayPainter,
-       _startOffset = startOffset,
-       super(children: children, direction: direction, itemExtent: itemExtent, minExtent: minExtent);
-
-  bool _inCallback = false;
-
-  /// Called during [layout] to determine the blocks children
-  ///
-  /// Typically the callback will mutate the child list appropriately, for
-  /// example so the child list contains only visible children.
-  LayoutCallback get callback => _callback;
-  LayoutCallback _callback;
-  void set callback(LayoutCallback value) {
-    assert(!_inCallback);
-    if (value == _callback)
-      return;
-    _callback = value;
-    markNeedsLayout();
-  }
-
-  /// Returns the total main-axis extent of all the children that could be included by [callback] in one go
-  ExtentCallback get totalExtentCallback => _totalExtentCallback;
-  ExtentCallback _totalExtentCallback;
-  void set totalExtentCallback(ExtentCallback value) {
-    assert(!_inCallback);
-    if (value == _totalExtentCallback)
-      return;
-    _totalExtentCallback = value;
-    markNeedsLayout();
-  }
-
-  /// Returns the minimum cross-axis extent across all the children that could be included by [callback] in one go
-  ExtentCallback get minCrossAxisExtentCallback => _minCrossAxisExtentCallback;
-  ExtentCallback _minCrossAxisExtentCallback;
-  void set minCrossAxisExtentCallback(ExtentCallback value) {
-    assert(!_inCallback);
-    if (value == _minCrossAxisExtentCallback)
-      return;
-    _minCrossAxisExtentCallback = value;
-    markNeedsLayout();
-  }
-
-  /// Returns the maximum cross-axis extent across all the children that could be included by [callback] in one go
-  ExtentCallback get maxCrossAxisExtentCallback => _maxCrossAxisExtentCallback;
-  ExtentCallback _maxCrossAxisExtentCallback;
-  void set maxCrossAxisExtentCallback(ExtentCallback value) {
-    assert(!_inCallback);
-    if (value == _maxCrossAxisExtentCallback)
-      return;
-    _maxCrossAxisExtentCallback = value;
-    markNeedsLayout();
-  }
-
-  Painter get overlayPainter => _overlayPainter;
-  Painter _overlayPainter;
-  void set overlayPainter(Painter value) {
-    if (_overlayPainter == value)
-      return;
-    _overlayPainter?.detach();
-    _overlayPainter = value;
-    _overlayPainter?.attach(this);
-    markNeedsPaint();
-  }
-
-  void attach() {
-    super.attach();
-    _overlayPainter?.attach(this);
-  }
-
-  void detach() {
-    super.detach();
-    _overlayPainter?.detach();
-  }
-
-  /// The offset at which to paint the first child
-  ///
-  /// Note: you can modify this property from within [callback], if necessary.
-  double get startOffset => _startOffset;
-  double _startOffset;
-  void set startOffset(double value) {
-    if (value != _startOffset) {
-      _startOffset = value;
-      markNeedsPaint();
-    }
-  }
-
-  double _getIntrinsicDimension(BoxConstraints constraints, ExtentCallback intrinsicCallback, _Constrainer constrainer) {
-    assert(!_inCallback);
-    double result;
-    if (intrinsicCallback == null) {
-      assert(() {
-        'RenderBlockViewport does not support returning intrinsic dimensions if the relevant callbacks have not been specified.';
-        return false;
-      });
-      return constrainer(0.0);
-    }
-    try {
-      _inCallback = true;
-      result = intrinsicCallback(constraints);
-      if (result == null)
-        result = constrainer(0.0);
-      else
-        result = constrainer(result);
-    } finally {
-      _inCallback = false;
-    }
-    return result;
-  }
-
-  double getMinIntrinsicWidth(BoxConstraints constraints) {
-    if (isVertical)
-      return _getIntrinsicDimension(constraints, minCrossAxisExtentCallback, constraints.constrainWidth);
-    return constraints.constrainWidth(minExtent);
-  }
-
-  double getMaxIntrinsicWidth(BoxConstraints constraints) {
-    if (isVertical)
-      return _getIntrinsicDimension(constraints, maxCrossAxisExtentCallback, constraints.constrainWidth);
-    return _getIntrinsicDimension(constraints, totalExtentCallback, new BoxConstraints(minWidth: minExtent).enforce(constraints).constrainWidth);
-  }
-
-  double getMinIntrinsicHeight(BoxConstraints constraints) {
-    if (!isVertical)
-      return _getIntrinsicDimension(constraints, minCrossAxisExtentCallback, constraints.constrainHeight);
-    return constraints.constrainHeight(0.0);
-  }
-
-  double getMaxIntrinsicHeight(BoxConstraints constraints) {
-    if (!isVertical)
-      return _getIntrinsicDimension(constraints, maxCrossAxisExtentCallback, constraints.constrainHeight);
-    return _getIntrinsicDimension(constraints, totalExtentCallback, new BoxConstraints(minHeight: minExtent).enforce(constraints).constrainHeight);
-  }
-
-  // We don't override computeDistanceToActualBaseline(), because we
-  // want the default behaviour (returning null). Otherwise, as you
-  // scroll the RenderBlockViewport, it would shift in its parent if
-  // the parent was baseline-aligned, which makes no sense.
-
-  bool get debugDoesLayoutWithCallback => true;
-  void performLayout() {
-    if (_callback != null) {
-      try {
-        _inCallback = true;
-        invokeLayoutCallback(_callback);
-      } finally {
-        _inCallback = false;
-      }
-    }
-    super.performLayout();
-  }
-
-  void paint(PaintingContext context, Offset offset) {
-    context.canvas.save();
-
-    context.canvas.clipRect(offset & size);
-    if (isVertical)
-      defaultPaint(context, offset.translate(0.0, startOffset));
-    else
-      defaultPaint(context, offset.translate(startOffset, 0.0));
-
-    overlayPainter?.paint(context, offset);
-
-    context.canvas.restore();
-  }
-
-  void applyPaintTransform(Matrix4 transform) {
-    super.applyPaintTransform(transform);
-    if (isVertical)
-      transform.translate(0.0, startOffset);
-    else
-      transform.translate(startOffset, 0.0);
-  }
-
-  bool hitTestChildren(HitTestResult result, { Point position }) {
-    if (isVertical)
-      return defaultHitTestChildren(result, position: position + new Offset(0.0, -startOffset));
-    else
-      return defaultHitTestChildren(result, position: position + new Offset(-startOffset, 0.0));
-  }
-
-  void debugDescribeSettings(List<String> settings) {
-    super.debugDescribeSettings(settings);
-    settings.add('startOffset: $startOffset');
-  }
-}
diff --git a/sky/packages/sky/lib/src/rendering/box.dart b/sky/packages/sky/lib/src/rendering/box.dart
deleted file mode 100644
index f2e1df4..0000000
--- a/sky/packages/sky/lib/src/rendering/box.dart
+++ /dev/null
@@ -1,814 +0,0 @@
-// Copyright 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 'dart:math' as math;
-import 'dart:ui' as ui;
-
-import 'package:flutter/animation.dart';
-import 'package:flutter/gestures.dart';
-import 'package:flutter/painting.dart';
-import 'package:vector_math/vector_math_64.dart';
-
-import 'debug.dart';
-import 'object.dart';
-
-export 'package:flutter/painting.dart' show TextBaseline;
-
-// This class should only be used in debug builds
-class _DebugSize extends Size {
-  _DebugSize(Size source, this._owner, this._canBeUsedByParent): super.copy(source);
-  final RenderBox _owner;
-  final bool _canBeUsedByParent;
-}
-
-/// Immutable layout constraints for box layout
-///
-/// A size respects a BoxConstraints if, and only if, all of the following
-/// relations hold:
-///
-/// * `minWidth <= size.width <= maxWidth`
-/// * `minHeight <= size.height <= maxHeight`
-///
-/// The constraints themselves must satisfy these relations:
-///
-/// * `0.0 <= minWidth <= maxWidth <= double.INFINITY`
-/// * `0.0 <= minHeight <= maxHeight <= double.INFINITY`
-///
-/// Note: `double.INFINITY` is a legal value for each constraint.
-class BoxConstraints extends Constraints {
-  /// Constructs box constraints with the given constraints
-  const BoxConstraints({
-    this.minWidth: 0.0,
-    this.maxWidth: double.INFINITY,
-    this.minHeight: 0.0,
-    this.maxHeight: double.INFINITY
-  });
-
-  final double minWidth;
-  final double maxWidth;
-  final double minHeight;
-  final double maxHeight;
-
-  /// Constructs box constraints that is respected only by the given size
-  BoxConstraints.tight(Size size)
-    : minWidth = size.width,
-      maxWidth = size.width,
-      minHeight = size.height,
-      maxHeight = size.height;
-
-  /// Constructs box constraints that require the given width or height
-  const BoxConstraints.tightFor({
-    double width,
-    double height
-  }): minWidth = width != null ? width : 0.0,
-      maxWidth = width != null ? width : double.INFINITY,
-      minHeight = height != null ? height : 0.0,
-      maxHeight = height != null ? height : double.INFINITY;
-
-  /// Constructs box constraints that forbid sizes larger than the given size
-  BoxConstraints.loose(Size size)
-    : minWidth = 0.0,
-      maxWidth = size.width,
-      minHeight = 0.0,
-      maxHeight = size.height;
-
-  /// Constructs box constraints that expand to fill another box contraints
-  ///
-  /// If width or height is given, the constraints will require exactly the
-  /// given value in the given dimension.
-  const BoxConstraints.expand({
-    double width,
-    double height
-  }): minWidth = width != null ? width : double.INFINITY,
-      maxWidth = width != null ? width : double.INFINITY,
-      minHeight = height != null ? height : double.INFINITY,
-      maxHeight = height != null ? height : double.INFINITY;
-
-  /// Returns new box constraints that are smaller by the given edge dimensions
-  BoxConstraints deflate(EdgeDims edges) {
-    assert(edges != null);
-    double horizontal = edges.left + edges.right;
-    double vertical = edges.top + edges.bottom;
-    double deflatedMinWidth = math.max(0.0, minWidth - horizontal);
-    double deflatedMinHeight = math.max(0.0, minHeight - vertical);
-    return new BoxConstraints(
-      minWidth: deflatedMinWidth,
-      maxWidth: math.max(deflatedMinWidth, maxWidth - horizontal),
-      minHeight: deflatedMinHeight,
-      maxHeight: math.max(deflatedMinHeight, maxHeight - vertical)
-    );
-  }
-
-  /// Returns new box constraints that remove the minimum width and height requirements
-  BoxConstraints loosen() {
-    return new BoxConstraints(
-      minWidth: 0.0,
-      maxWidth: maxWidth,
-      minHeight: 0.0,
-      maxHeight: maxHeight
-    );
-  }
-
-  /// Returns new box constraints that respect the given constraints while being as close as possible to the original constraints
-  BoxConstraints enforce(BoxConstraints constraints) {
-    return new BoxConstraints(
-      minWidth: clamp(min: constraints.minWidth, max: constraints.maxWidth, value: minWidth),
-      maxWidth: clamp(min: constraints.minWidth, max: constraints.maxWidth, value: maxWidth),
-      minHeight: clamp(min: constraints.minHeight, max: constraints.maxHeight, value: minHeight),
-      maxHeight: clamp(min: constraints.minHeight, max: constraints.maxHeight, value: maxHeight)
-    );
-  }
-
-  /// Returns new box constraints with a tight width as close to the given width as possible while still respecting the original box constraints
-  BoxConstraints tightenWidth(double width) {
-    return new BoxConstraints(minWidth: math.max(math.min(maxWidth, width), minWidth),
-                              maxWidth: math.max(math.min(maxWidth, width), minWidth),
-                              minHeight: minHeight,
-                              maxHeight: maxHeight);
-  }
-
-  /// Returns new box constraints with a tight height as close to the given height as possible while still respecting the original box constraints
-  BoxConstraints tightenHeight(double height) {
-    return new BoxConstraints(minWidth: minWidth,
-                              maxWidth: maxWidth,
-                              minHeight: math.max(math.min(maxHeight, height), minHeight),
-                              maxHeight: math.max(math.min(maxHeight, height), minHeight));
-  }
-
-  /// Returns box constraints with the same width constraints but with unconstrainted height
-  BoxConstraints widthConstraints() => new BoxConstraints(minWidth: minWidth, maxWidth: maxWidth);
-
-  /// Returns box constraints with the same height constraints but with unconstrainted width
-  BoxConstraints heightConstraints() => new BoxConstraints(minHeight: minHeight, maxHeight: maxHeight);
-
-  /// Returns the width that both satisfies the constraints and is as close as possible to the given width
-  double constrainWidth([double width = double.INFINITY]) {
-    return clamp(min: minWidth, max: maxWidth, value: width);
-  }
-
-  /// Returns the height that both satisfies the constraints and is as close as possible to the given height
-  double constrainHeight([double height = double.INFINITY]) {
-    return clamp(min: minHeight, max: maxHeight, value: height);
-  }
-
-  /// Returns the size that both satisfies the constraints and is as close as possible to the given size
-  Size constrain(Size size) {
-    Size result = new Size(constrainWidth(size.width), constrainHeight(size.height));
-    if (size is _DebugSize)
-      result = new _DebugSize(result, size._owner, size._canBeUsedByParent);
-    return result;
-  }
-
-  /// The biggest size that satisifes the constraints
-  Size get biggest => new Size(constrainWidth(), constrainHeight());
-
-  /// The smallest size that satisfies the constraints
-  Size get smallest => new Size(constrainWidth(0.0), constrainHeight(0.0));
-
-  /// Whether there is exactly one width value that satisfies the constraints
-  bool get hasTightWidth => minWidth >= maxWidth;
-
-  /// Whether there is exactly one height value that satisfies the constraints
-  bool get hasTightHeight => minHeight >= maxHeight;
-
-  /// Whether there is exactly one size that satifies the constraints
-  bool get isTight => hasTightWidth && hasTightHeight;
-
-  /// Whether the given size satisfies the constraints
-  bool isSatisfiedBy(Size size) {
-    return (minWidth <= size.width) && (size.width <= math.max(minWidth, maxWidth)) &&
-           (minHeight <= size.height) && (size.height <= math.max(minHeight, maxHeight));
-  }
-
-  BoxConstraints operator*(double other) {
-    return new BoxConstraints(
-      minWidth: minWidth * other,
-      maxWidth: maxWidth * other,
-      minHeight: minHeight * other,
-      maxHeight: maxHeight * other
-    );
-  }
-
-  BoxConstraints operator/(double other) {
-    return new BoxConstraints(
-      minWidth: minWidth / other,
-      maxWidth: maxWidth / other,
-      minHeight: minHeight / other,
-      maxHeight: maxHeight / other
-    );
-  }
-
-  BoxConstraints operator~/(double other) {
-    return new BoxConstraints(
-      minWidth: (minWidth ~/ other).toDouble(),
-      maxWidth: (maxWidth ~/ other).toDouble(),
-      minHeight: (minHeight ~/ other).toDouble(),
-      maxHeight: (maxHeight ~/ other).toDouble()
-    );
-  }
-
-  BoxConstraints operator%(double other) {
-    return new BoxConstraints(
-      minWidth: minWidth % other,
-      maxWidth: maxWidth % other,
-      minHeight: minHeight % other,
-      maxHeight: maxHeight % other
-    );
-  }
-
-  /// Linearly interpolate between two BoxConstraints
-  ///
-  /// If either is null, this function interpolates from [BoxConstraints.zero].
-  static BoxConstraints lerp(BoxConstraints a, BoxConstraints b, double t) {
-    if (a == null && b == null)
-      return null;
-    if (a == null)
-      return b * t;
-    if (b == null)
-      return a * (1.0 - t);
-    return new BoxConstraints(
-      minWidth: ui.lerpDouble(a.minWidth, b.minWidth, t),
-      maxWidth: ui.lerpDouble(a.maxWidth, b.maxWidth, t),
-      minHeight: ui.lerpDouble(a.minHeight, b.minHeight, t),
-      maxHeight: ui.lerpDouble(a.maxHeight, b.maxHeight, t)
-    );
-  }
-
-  bool operator ==(dynamic other) {
-    if (identical(this, other))
-      return true;
-    if (other is! BoxConstraints)
-      return false;
-    final BoxConstraints typedOther = other;
-    return minWidth == typedOther.minWidth &&
-           maxWidth == typedOther.maxWidth &&
-           minHeight == typedOther.minHeight &&
-           maxHeight == typedOther.maxHeight;
-  }
-
-  int get hashCode {
-    int value = 373;
-    value = 37 * value + minWidth.hashCode;
-    value = 37 * value + maxWidth.hashCode;
-    value = 37 * value + minHeight.hashCode;
-    value = 37 * value + maxHeight.hashCode;
-    return value;
-  }
-
-  String toString() {
-    if (minWidth == double.INFINITY && minHeight == double.INFINITY)
-      return 'BoxConstraints(biggest)';
-    if (minWidth == 0 && maxWidth == double.INFINITY &&
-        minHeight == 0 && maxHeight == double.INFINITY)
-      return 'BoxConstraints(unconstrained)';
-    String describe(double min, double max, String dim) {
-      if (min == max)
-        return '$dim=${min.toStringAsFixed(1)}';
-      return '${min.toStringAsFixed(1)}<=$dim<=${max.toStringAsFixed(1)}';
-    }
-    final String width = describe(minWidth, maxWidth, 'w');
-    final String height = describe(minHeight, maxHeight, 'h');
-    return 'BoxConstraints($width, $height)';
-  }
-}
-
-/// A hit test entry used by [RenderBox]
-class BoxHitTestEntry extends HitTestEntry {
-  const BoxHitTestEntry(HitTestTarget target, this.localPosition) : super(target);
-
-  /// The position of the hit test in the local coordinates of [target]
-  final Point localPosition;
-}
-
-/// Parent data used by [RenderBox] and its subclasses
-class BoxParentData extends ParentData {
-  Point _position = Point.origin;
-  /// The point at which to paint the child in the parent's coordinate system
-  Point get position => _position;
-  void set position(Point value) {
-    assert(RenderObject.debugDoingLayout);
-    _position = value;
-  }
-  String toString() => 'position=$position';
-}
-
-/// Abstract ParentData subclass for RenderBox subclasses that want the
-/// ContainerRenderObjectMixin.
-abstract class ContainerBoxParentDataMixin<ChildType extends RenderObject> extends BoxParentData with ContainerParentDataMixin<ChildType> { }
-
-/// A render object in a 2D cartesian coordinate system
-///
-/// The size of each box is expressed as a width and a height. Each box has its
-/// own coordinate system in which its upper left corner is placed at (0, 0).
-/// The lower right corner of the box is therefore at (width, height). The box
-/// contains all the points including the upper left corner and extending to,
-/// but not including, the lower right corner.
-///
-/// Box layout is performed by passing a [BoxConstraints] object down the tree.
-/// The box constraints establish a min and max value for the child's width
-/// and height. In determining its size, the child must respect the constraints
-/// given to it by its parent.
-///
-/// This protocol is sufficient for expressing a number of common box layout
-/// data flows.  For example, to implement a width-in-height-out data flow, call
-/// your child's [layout] function with a set of box constraints with a tight
-/// width value (and pass true for parentUsesSize). After the child determines
-/// its height, use the child's height to determine your size.
-abstract class RenderBox extends RenderObject {
-
-  void setupParentData(RenderObject child) {
-    if (child.parentData is! BoxParentData)
-      child.parentData = new BoxParentData();
-  }
-
-  /// Returns the minimum width that this box could be without failing to paint
-  /// its contents within itself
-  ///
-  /// Override in subclasses that implement [performLayout].
-  double getMinIntrinsicWidth(BoxConstraints constraints) {
-    return constraints.constrainWidth(0.0);
-  }
-
-  /// Returns the smallest width beyond which increasing the width never
-  /// decreases the height
-  ///
-  /// Override in subclasses that implement [performLayout].
-  double getMaxIntrinsicWidth(BoxConstraints constraints) {
-    return constraints.constrainWidth(0.0);
-  }
-
-  /// Return the minimum height that this box could be without failing to render
-  /// its contents within itself.
-  ///
-  /// Override in subclasses that implement [performLayout].
-  double getMinIntrinsicHeight(BoxConstraints constraints) {
-    return constraints.constrainHeight(0.0);
-  }
-
-  /// Returns the smallest height beyond which increasing the height never
-  /// decreases the width.
-  ///
-  /// If the layout algorithm used is width-in-height-out, i.e. the height
-  /// depends on the width and not vice versa, then this will return the same
-  /// as getMinIntrinsicHeight().
-  ///
-  /// Override in subclasses that implement [performLayout].
-  double getMaxIntrinsicHeight(BoxConstraints constraints) {
-    return constraints.constrainHeight(0.0);
-  }
-
-  /// The size of this render box computed during layout
-  ///
-  /// This value is stale whenever this object is marked as needing layout.
-  /// During [performLayout], do not read the size of a child unless you pass
-  /// true for parentUsesSize when calling the child's [layout] function.
-  ///
-  /// The size of a box should be set only during the box's [performLayout] or
-  /// [performResize] functions. If you wish to change the size of a box outside
-  /// of those functins, call [markNeedsLayout] instead to schedule a layout of
-  /// the box.
-  Size get size {
-    assert(hasSize);
-    assert(() {
-      if (_size is _DebugSize) {
-        final _DebugSize _size = this._size;
-        assert(_size._owner == this);
-        if (RenderObject.debugActiveLayout != null) {
-          // We are always allowed to access our own size (for print debugging
-          // and asserts if nothing else). Other than us, the only object that's
-          // allowed to read our size is our parent, if they've said they will.
-          // If you hit this assert trying to access a child's size, pass
-          // "parentUsesSize: true" to that child's layout().
-          assert(debugDoingThisResize || debugDoingThisLayout ||
-                 (RenderObject.debugActiveLayout == parent && _size._canBeUsedByParent));
-        }
-        assert(_size == this._size);
-      }
-      return true;
-    });
-    return _size;
-  }
-  bool get hasSize => _size != null;
-  Size _size;
-  void set size(Size value) {
-    assert((sizedByParent && debugDoingThisResize) ||
-           (!sizedByParent && debugDoingThisLayout));
-    assert(() {
-      if (value is _DebugSize) {
-        if (value._owner != this) {
-          assert(value._owner.parent == this);
-          assert(value._canBeUsedByParent);
-        }
-      }
-      return true;
-    });
-    _size = value;
-    assert(() {
-      _size = new _DebugSize(_size, this, debugCanParentUseSize);
-      return true;
-    });
-    assert(debugDoesMeetConstraints());
-  }
-
-  void debugResetSize() {
-    // updates the value of size._canBeUsedByParent if necessary
-    size = size;
-  }
-
-  Map<TextBaseline, double> _cachedBaselines;
-  bool _ancestorUsesBaseline = false;
-  static bool _debugDoingBaseline = false;
-  static bool _debugSetDoingBaseline(bool value) {
-    _debugDoingBaseline = value;
-    return true;
-  }
-
-  /// Returns the distance from the y-coordinate of the position of the box to
-  /// the y-coordinate of the first given baseline in the box's contents.
-  ///
-  /// Used by certain layout models to align adjacent boxes on a common
-  /// baseline, regardless of padding, font size differences, etc. If there is
-  /// no baseline, this function returns the distance from the y-coordinate of
-  /// the position of the box to the y-coordinate of the bottom of the box
-  /// (i.e., the height of the box) unless the the caller passes true
-  /// for `onlyReal`, in which case the function returns null.
-  ///
-  /// Only call this function calling [layout] on this box. You are only
-  /// allowed to call this from the parent of this box during that parent's
-  /// [performLayout] or [paint] functions.
-  double getDistanceToBaseline(TextBaseline baseline, { bool onlyReal: false }) {
-    assert(!needsLayout);
-    assert(!_debugDoingBaseline);
-    final RenderObject parent = this.parent;
-    assert(() {
-      if (RenderObject.debugDoingLayout)
-        return (RenderObject.debugActiveLayout == parent) && parent.debugDoingThisLayout;
-      if (RenderObject.debugDoingPaint)
-        return ((RenderObject.debugActivePaint == parent) && parent.debugDoingThisPaint) ||
-               ((RenderObject.debugActivePaint == this) && debugDoingThisPaint);
-      return false;
-    });
-    assert(_debugSetDoingBaseline(true));
-    double result = getDistanceToActualBaseline(baseline);
-    assert(_debugSetDoingBaseline(false));
-    assert(parent == this.parent);
-    if (result == null && !onlyReal)
-      return size.height;
-    return result;
-  }
-
-  /// Calls [computeDistanceToActualBaseline] and caches the result.
-  ///
-  /// This function must only be called from [getDistanceToBaseline] and
-  /// [computeDistanceToActualBaseline]. Do not call this function directly from
-  /// outside those two methods.
-  double getDistanceToActualBaseline(TextBaseline baseline) {
-    assert(_debugDoingBaseline);
-    _ancestorUsesBaseline = true;
-    if (_cachedBaselines == null)
-      _cachedBaselines = new Map<TextBaseline, double>();
-    _cachedBaselines.putIfAbsent(baseline, () => computeDistanceToActualBaseline(baseline));
-    return _cachedBaselines[baseline];
-  }
-
-  /// Returns the distance from the y-coordinate of the position of the box to
-  /// the y-coordinate of the first given baseline in the box's contents, if
-  /// any, or null otherwise.
-  ///
-  /// Do not call this function directly. Instead, call [getDistanceToBaseline]
-  /// if you need to know the baseline of a child from an invocation of
-  /// [performLayout] or [paint] and call [getDistanceToActualBaseline] if you
-  /// are implementing [computeDistanceToActualBaseline] and need to defer to a
-  /// child.
-  ///
-  /// Subclasses should override this function to supply the distances to their
-  /// baselines.
-  double computeDistanceToActualBaseline(TextBaseline baseline) {
-    assert(_debugDoingBaseline);
-    return null;
-  }
-
-  /// The box constraints most recently received from the parent
-  BoxConstraints get constraints => super.constraints;
-  bool debugDoesMeetConstraints() {
-    assert(constraints != null);
-    assert(_size != null);
-    assert(() {
-      'See https://flutter.github.io/layout/#unbounded-constraints';
-      return !_size.isInfinite;
-    });
-    bool result = constraints.isSatisfiedBy(_size);
-    if (!result)
-      debugPrint("${this.runtimeType} does not meet its constraints. Constraints: $constraints, size: $_size");
-    return result;
-  }
-
-  void markNeedsLayout() {
-    if (_cachedBaselines != null && _cachedBaselines.isNotEmpty) {
-      // if we have cached data, then someone must have used our data
-      assert(_ancestorUsesBaseline);
-      final RenderObject parent = this.parent;
-      parent.markNeedsLayout();
-      assert(parent == this.parent);
-      // Now that they're dirty, we can forget that they used the
-      // baseline. If they use it again, then we'll set the bit
-      // again, and if we get dirty again, we'll notify them again.
-      _ancestorUsesBaseline = false;
-      _cachedBaselines.clear();
-    } else {
-      // if we've never cached any data, then nobody can have used it
-      assert(!_ancestorUsesBaseline);
-    }
-    super.markNeedsLayout();
-  }
-  void performResize() {
-    // default behaviour for subclasses that have sizedByParent = true
-    size = constraints.constrain(Size.zero);
-    assert(!size.isInfinite);
-  }
-  void performLayout() {
-    // descendants have to either override performLayout() to set both
-    // width and height and lay out children, or, set sizedByParent to
-    // true so that performResize()'s logic above does its thing.
-    assert(sizedByParent);
-  }
-
-  /// Determines the set of render objects located at the given position
-  ///
-  /// Returns true if the given point is contained in this render object or one
-  /// of its descendants. Adds any render objects that contain the point to the
-  /// given hit test result.
-  ///
-  /// The caller is responsible for transforming [position] into the local
-  /// coordinate space of the callee.  The callee is responsible for checking
-  /// whether the given position is within its bounds.
-  bool hitTest(HitTestResult result, { Point position }) {
-    assert(!needsLayout);
-    if (position.x >= 0.0 && position.x < _size.width &&
-        position.y >= 0.0 && position.y < _size.height) {
-      if (hitTestChildren(result, position: position) || hitTestSelf(position)) {
-        result.add(new BoxHitTestEntry(this, position));
-        return true;
-      }
-    }
-    return false;
-  }
-
-  /// Override this function if this render object can be hit even if its
-  /// children were not hit
-  bool hitTestSelf(Point position) => false;
-
-  /// Override this function to check whether any children are located at the
-  /// given position
-  ///
-  /// Typically children should be hit tested in reverse paint order so that
-  /// hit tests at locations where children overlap hit the child that is
-  /// visually "on top" (i.e., paints later).
-  bool hitTestChildren(HitTestResult result, { Point position }) => false;
-
-  /// Multiply the transform from the parent's coordinate system to this box's
-  /// coordinate system into the given transform
-  ///
-  /// This function is used to convert coordinate systems between boxes.
-  /// Subclasses that apply transforms during painting should override this
-  /// function to factor those transforms into the calculation.
-  void applyPaintTransform(Matrix4 transform) {
-    if (parentData is BoxParentData) {
-      Point position = (parentData as BoxParentData).position;
-      transform.translate(position.x, position.y);
-    }
-  }
-
-  static Point _transformPoint(Matrix4 transform, Point point) {
-    Vector3 position3 = new Vector3(point.x, point.y, 0.0);
-    Vector3 transformed3 = transform.transform3(position3);
-    return new Point(transformed3.x, transformed3.y);
-  }
-
-  /// Convert the given point from the global coodinate system to the local
-  /// coordinate system for this box
-  Point globalToLocal(Point point) {
-    assert(attached);
-    Matrix4 transform = new Matrix4.identity();
-    RenderObject renderer = this;
-    while(renderer != null) {
-      renderer.applyPaintTransform(transform);
-      renderer = renderer.parent;
-    }
-    /* double det = */ transform.invert();
-    // TODO(abarth): Check the determinant for degeneracy.
-    return _transformPoint(transform, point);
-  }
-
-  /// Convert the given point from the local coordiante system for this box to
-  /// the global coordinate sytem
-  Point localToGlobal(Point point) {
-    List <RenderObject> renderers = <RenderObject>[];
-    for (RenderObject renderer = this; renderer != null; renderer = renderer.parent)
-      renderers.add(renderer);
-    Matrix4 transform = new Matrix4.identity();
-    for (RenderObject renderer in renderers.reversed)
-      renderer.applyPaintTransform(transform);
-    return _transformPoint(transform, point);
-  }
-
-  /// Returns a rectangle that contains all the pixels painted by this box
-  ///
-  /// The paint bounds can be larger or smaller than [size], which is the amount
-  /// of space this box takes up during layout. For example, if this box casts a
-  /// shadow, that shadow might extend beyond the space allocated to this box
-  /// during layout.
-  ///
-  /// The paint bounds are used to size the buffers into which this box paints.
-  /// If the box attempts to paints outside its paint bounds, there might not be
-  /// enough memory allocated to represent the box's visual appearance, which
-  /// can lead to undefined behavior.
-  ///
-  /// The returned paint bounds are in the local coordinate system of this box.
-  Rect get paintBounds => Point.origin & size;
-
-  int _debugActivePointers = 0;
-  void handleEvent(InputEvent event, HitTestEntry entry) {
-    super.handleEvent(event, entry);
-    assert(() {
-      if (debugPaintPointersEnabled) {
-        if (event.type == 'pointerdown')
-          _debugActivePointers += 1;
-        if (event.type == 'pointerup' || event.type == 'pointercancel')
-          _debugActivePointers -= 1;
-        markNeedsPaint();
-      }
-      return true;
-    });
-  }
-
-  void debugPaint(PaintingContext context, Offset offset) {
-    if (debugPaintSizeEnabled)
-      debugPaintSize(context, offset);
-    if (debugPaintBaselinesEnabled)
-      debugPaintBaselines(context, offset);
-    if (debugPaintPointersEnabled)
-      debugPaintPointers(context, offset);
-  }
-  void debugPaintSize(PaintingContext context, Offset offset) {
-    Paint paint = new Paint()
-     ..style = ui.PaintingStyle.stroke
-     ..strokeWidth = 1.0
-     ..color = debugPaintSizeColor;
-    context.canvas.drawRect(offset & size, paint);
-  }
-  void debugPaintBaselines(PaintingContext context, Offset offset) {
-    Paint paint = new Paint()
-     ..style = ui.PaintingStyle.stroke
-     ..strokeWidth = 0.25;
-    Path path;
-    // ideographic baseline
-    double baselineI = getDistanceToBaseline(TextBaseline.ideographic, onlyReal: true);
-    if (baselineI != null) {
-      paint.color = debugPaintIdeographicBaselineColor;
-      path = new Path();
-      path.moveTo(offset.dx, offset.dy + baselineI);
-      path.lineTo(offset.dx + size.width, offset.dy + baselineI);
-      context.canvas.drawPath(path, paint);
-    }
-    // alphabetic baseline
-    double baselineA = getDistanceToBaseline(TextBaseline.alphabetic, onlyReal: true);
-    if (baselineA != null) {
-      paint.color = debugPaintAlphabeticBaselineColor;
-      path = new Path();
-      path.moveTo(offset.dx, offset.dy + baselineA);
-      path.lineTo(offset.dx + size.width, offset.dy + baselineA);
-      context.canvas.drawPath(path, paint);
-    }
-  }
-  void debugPaintPointers(PaintingContext context, Offset offset) {
-    if (_debugActivePointers > 0) {
-      Paint paint = new Paint()
-       ..color = new Color(debugPaintPointersColorValue | ((0x04000000 * depth) & 0xFF000000));
-      context.canvas.drawRect(offset & size, paint);
-    }
-  }
-
-  void debugDescribeSettings(List<String> settings) {
-    super.debugDescribeSettings(settings);
-    settings.add('size: ${ hasSize ? size : "MISSING" }');
-  }
-}
-
-/// A mixin that provides useful default behaviors for boxes with children
-/// managed by the [ContainerRenderObjectMixin] mixin.
-///
-/// By convention, this class doesn't override any members of the superclass.
-/// Instead, it provides helpful functions that subclasses can call as
-/// appropriate.
-abstract class RenderBoxContainerDefaultsMixin<ChildType extends RenderBox, ParentDataType extends ContainerBoxParentDataMixin<ChildType>> implements ContainerRenderObjectMixin<ChildType, ParentDataType> {
-
-  /// Returns the baseline of the first child with a baseline
-  ///
-  /// Useful when the children are displayed vertically in the same order they
-  /// appear in the child list.
-  double defaultComputeDistanceToFirstActualBaseline(TextBaseline baseline) {
-    assert(!needsLayout);
-    RenderBox child = firstChild;
-    while (child != null) {
-      final ParentDataType childParentData = child.parentData;
-      double result = child.getDistanceToActualBaseline(baseline);
-      if (result != null)
-        return result + childParentData.position.y;
-      child = childParentData.nextSibling;
-    }
-    return null;
-  }
-
-  /// Returns the minimum baseline value among every child
-  ///
-  /// Useful when the vertical position of the children isn't determined by the
-  /// order in the child list.
-  double defaultComputeDistanceToHighestActualBaseline(TextBaseline baseline) {
-    assert(!needsLayout);
-    double result;
-    RenderBox child = firstChild;
-    while (child != null) {
-      final ParentDataType childParentData = child.parentData;
-      double candidate = child.getDistanceToActualBaseline(baseline);
-      if (candidate != null) {
-        candidate += childParentData.position.y;
-        if (result != null)
-          result = math.min(result, candidate);
-        else
-          result = candidate;
-      }
-      child = childParentData.nextSibling;
-    }
-    return result;
-  }
-
-  /// Performs a hit test on each child by walking the child list backwards
-  ///
-  /// Stops walking once after the first child reports that it contains the
-  /// given point. Returns whether any children contain the given point.
-  bool defaultHitTestChildren(HitTestResult result, { Point position }) {
-    // the x, y parameters have the top left of the node's box as the origin
-    ChildType child = lastChild;
-    while (child != null) {
-      final ParentDataType childParentData = child.parentData;
-      Point transformed = new Point(position.x - childParentData.position.x,
-                                    position.y - childParentData.position.y);
-      if (child.hitTest(result, position: transformed))
-        return true;
-      child = childParentData.previousSibling;
-    }
-    return false;
-  }
-
-  /// Paints each child by walking the child list forwards
-  void defaultPaint(PaintingContext context, Offset offset) {
-    RenderBox child = firstChild;
-    while (child != null) {
-      final ParentDataType childParentData = child.parentData;
-      context.paintChild(child, childParentData.position + offset);
-      child = childParentData.nextSibling;
-    }
-  }
-}
-
-/// An offset that's expressed as a fraction of a Size.
-///
-/// FractionalOffset(1.0, 0.0) represents the top right of the Size,
-/// FractionalOffset(0.0, 1.0) represents the bottom left of the Size,
-class FractionalOffset {
-  const FractionalOffset(this.x, this.y);
-  final double x;
-  final double y;
-  bool operator ==(dynamic other) {
-    if (other is! FractionalOffset)
-      return false;
-    final FractionalOffset typedOther = other;
-    return x == typedOther.x &&
-           y == typedOther.y;
-  }
-  int get hashCode {
-    int value = 373;
-    value = 37 * value + x.hashCode;
-    value = 37 * value + y.hashCode;
-    return value;
-  }
-  static FractionalOffset lerp(FractionalOffset a, FractionalOffset b, double t) {
-    if (a == null && b == null)
-      return null;
-    if (a == null)
-      return new FractionalOffset(b.x * t, b.y * t);
-    if (b == null)
-      return new FractionalOffset(b.x * (1.0 - t), b.y * (1.0 - t));
-    return new FractionalOffset(ui.lerpDouble(a.x, b.x, t), ui.lerpDouble(a.y, b.y, t));
-  }
-  String toString() => '$runtimeType($x, $y)';
-}
-
-class AnimatedFractionalOffsetValue extends AnimatedValue<FractionalOffset> {
-  AnimatedFractionalOffsetValue(FractionalOffset begin, { FractionalOffset end, Curve curve, Curve reverseCurve })
-    : super(begin, end: end, curve: curve, reverseCurve: reverseCurve);
-
-  FractionalOffset lerp(double t) => FractionalOffset.lerp(begin, end, t);
-}
diff --git a/sky/packages/sky/lib/src/rendering/custom_layout.dart b/sky/packages/sky/lib/src/rendering/custom_layout.dart
deleted file mode 100644
index 871c797..0000000
--- a/sky/packages/sky/lib/src/rendering/custom_layout.dart
+++ /dev/null
@@ -1,122 +0,0 @@
-// Copyright 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 'box.dart';
-import 'object.dart';
-
-class MultiChildLayoutParentData extends ContainerBoxParentDataMixin<RenderBox> {
-  Object id;
-}
-
-abstract class MultiChildLayoutDelegate {
-  final Map<Object, RenderBox> _idToChild = new Map<Object, RenderBox>();
-
-  /// Returns the size of this object given the incomming constraints.
-  /// The size cannot reflect the instrinsic sizes of the children.
-  /// If this layout has a fixed width or height the returned size
-  /// can reflect that.
-  Size getSize(BoxConstraints constraints) => constraints.biggest;
-
-  /// True if a non-null LayoutChild was provided for the specified id.
-  bool isChild(Object childId) => _idToChild[childId] != null;
-
-  /// Ask the child to update its layout within the limits specified by
-  /// the constraints parameter. The child's size is returned.
-  Size layoutChild(Object childId, BoxConstraints constraints) {
-    final RenderBox child = _idToChild[childId];
-    assert(child != null);
-    child.layout(constraints, parentUsesSize: true);
-    return child.size;
-  }
-
-  /// Specify the child's origin relative to this origin.
-  void positionChild(Object childId, Point position) {
-    final RenderBox child = _idToChild[childId];
-    assert(child != null);
-    final MultiChildLayoutParentData childParentData = child.parentData;
-    childParentData.position = position;
-  }
-
-  void _callPerformLayout(Size size, BoxConstraints constraints, RenderBox firstChild) {
-    RenderBox child = firstChild;
-    while (child != null) {
-      final MultiChildLayoutParentData childParentData = child.parentData;
-      assert(childParentData.id != null);
-      _idToChild[childParentData.id] = child;
-      child = childParentData.nextSibling;
-    }
-    performLayout(size, constraints);
-    _idToChild.clear();
-  }
-
-  /// Layout and position all children given this widget's size and the specified
-  /// constraints. This method must apply layoutChild() to each child. It should
-  /// specify the final position of each child with positionChild().
-  void performLayout(Size size, BoxConstraints constraints);
-}
-
-class RenderCustomMultiChildLayoutBox extends RenderBox
-  with ContainerRenderObjectMixin<RenderBox, MultiChildLayoutParentData>,
-       RenderBoxContainerDefaultsMixin<RenderBox, MultiChildLayoutParentData> {
-  RenderCustomMultiChildLayoutBox({
-    List<RenderBox> children,
-    MultiChildLayoutDelegate delegate
-  }) : _delegate = delegate {
-    assert(delegate != null);
-    addAll(children);
-  }
-
-  void setupParentData(RenderBox child) {
-    if (child.parentData is! MultiChildLayoutParentData)
-      child.parentData = new MultiChildLayoutParentData();
-  }
-
-  MultiChildLayoutDelegate get delegate => _delegate;
-  MultiChildLayoutDelegate _delegate;
-  void set delegate (MultiChildLayoutDelegate newDelegate) {
-    assert(newDelegate != null);
-    if (_delegate == newDelegate)
-      return;
-    _delegate = newDelegate;
-    markNeedsLayout();
-  }
-
-  Size _getSize(BoxConstraints constraints) {
-    return constraints.constrain(_delegate.getSize(constraints));
-  }
-
-  double getMinIntrinsicWidth(BoxConstraints constraints) {
-    return _getSize(constraints).width;
-  }
-
-  double getMaxIntrinsicWidth(BoxConstraints constraints) {
-    return _getSize(constraints).width;
-  }
-
-  double getMinIntrinsicHeight(BoxConstraints constraints) {
-    return _getSize(constraints).height;
-  }
-
-  double getMaxIntrinsicHeight(BoxConstraints constraints) {
-    return _getSize(constraints).height;
-  }
-
-  bool get sizedByParent => true;
-
-  void performResize() {
-    size = _getSize(constraints);
-  }
-
-  void performLayout() {
-    delegate._callPerformLayout(size, constraints, firstChild);
-  }
-
-  void paint(PaintingContext context, Offset offset) {
-    defaultPaint(context, offset);
-  }
-
-  bool hitTestChildren(HitTestResult result, { Point position }) {
-    return defaultHitTestChildren(result, position: position);
-  }
-}
diff --git a/sky/packages/sky/lib/src/rendering/debug.dart b/sky/packages/sky/lib/src/rendering/debug.dart
deleted file mode 100644
index 93c3047..0000000
--- a/sky/packages/sky/lib/src/rendering/debug.dart
+++ /dev/null
@@ -1,80 +0,0 @@
-// Copyright 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 'dart:ui' as ui;
-import 'dart:async';
-import 'dart:collection';
-
-/// Causes each RenderBox to paint a box around its bounds.
-bool debugPaintSizeEnabled = false;
-
-/// The color to use when painting RenderObject bounds.
-ui.Color debugPaintSizeColor = const ui.Color(0xFF00FFFF);
-
-/// Causes each RenderBox to paint a line at each of its baselines.
-bool debugPaintBaselinesEnabled = false;
-
-/// The color to use when painting alphabetic baselines.
-ui.Color debugPaintAlphabeticBaselineColor = const ui.Color(0xFF00FF00);
-
-/// The color ot use when painting ideographic baselines.
-ui.Color debugPaintIdeographicBaselineColor = const ui.Color(0xFFFFD000);
-
-/// Causes each Layer to paint a box around its bounds.
-bool debugPaintLayerBordersEnabled = false;
-
-/// The color to use when painting Layer borders.
-ui.Color debugPaintLayerBordersColor = const ui.Color(0xFFFF9800);
-
-/// Causes RenderObjects to paint warnings when painting outside their bounds.
-bool debugPaintBoundsEnabled = false;
-
-/// Causes RenderBox objects to flash while they are being tapped
-bool debugPaintPointersEnabled = false;
-
-/// The color to use when reporting pointers.
-int debugPaintPointersColorValue = 0x00BBBB;
-
-/// The color to use when painting RenderError boxes in checked mode.
-ui.Color debugErrorBoxColor = const ui.Color(0xFFFF0000);
-
-/// Prints a message to the console, which you can access using the "flutter"
-/// tool's "logs" command ("flutter logs").
-///
-/// This function very crudely attempts to throttle the rate at which messages
-/// are sent to avoid data loss on Android. This means that interleaving calls
-/// to this function (directly or indirectly via [debugDumpRenderTree] or
-/// [debugDumpApp]) and to the Dart [print] method can result in out-of-order
-/// messages in the logs.
-void debugPrint(String message) {
-  _debugPrintBuffer.addAll(message.split('\n'));
-  if (!_debugPrintScheduled)
-    _debugPrintTask();
-}
-int _debugPrintedCharacters = 0;
-int _kDebugPrintCapacity = 16 * 1024;
-Duration _kDebugPrintPauseTime = const Duration(seconds: 1);
-Queue<String> _debugPrintBuffer = new Queue<String>();
-Stopwatch _debugPrintStopwatch = new Stopwatch();
-bool _debugPrintScheduled = false;
-void _debugPrintTask() {
-  _debugPrintScheduled = false;
-  if (_debugPrintStopwatch.elapsed > _kDebugPrintPauseTime) {
-    _debugPrintStopwatch.stop();
-    _debugPrintStopwatch.reset();
-    _debugPrintedCharacters = 0;
-  }
-  while (_debugPrintedCharacters < _kDebugPrintCapacity && _debugPrintBuffer.length > 0) {
-    String line = _debugPrintBuffer.removeFirst();
-    _debugPrintedCharacters += line.length; // TODO(ianh): Use the UTF-8 byte length instead
-    print(line);
-  }
-  if (_debugPrintBuffer.length > 0) {
-    _debugPrintScheduled = true;
-    _debugPrintedCharacters = 0;
-    new Timer(_kDebugPrintPauseTime, _debugPrintTask);
-  } else {
-    _debugPrintStopwatch.start();
-  }
-}
diff --git a/sky/packages/sky/lib/src/rendering/editable_paragraph.dart b/sky/packages/sky/lib/src/rendering/editable_paragraph.dart
deleted file mode 100644
index 2d3a9e8..0000000
--- a/sky/packages/sky/lib/src/rendering/editable_paragraph.dart
+++ /dev/null
@@ -1,125 +0,0 @@
-// Copyright 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:flutter/painting.dart';
-
-import 'box.dart';
-import 'object.dart';
-import 'paragraph.dart';
-import 'proxy_box.dart' show SizeChangedCallback;
-
-const _kCursorGap = 1.0; // pixels
-const _kCursorHeightOffset = 2.0; // pixels
-const _kCursorWidth = 1.0; // pixels
-
-/// A render object used by EditableText widgets.  This is similar to
-/// RenderParagraph but also renders a cursor and provides support for
-/// scrolling.
-class RenderEditableParagraph extends RenderParagraph {
-
-  RenderEditableParagraph({
-    TextSpan text,
-    Color cursorColor,
-    bool showCursor,
-    this.onContentSizeChanged,
-    Offset scrollOffset
-  }) : _cursorColor = cursorColor,
-       _showCursor = showCursor,
-       _scrollOffset = scrollOffset,
-       super(text);
-
-  Color _cursorColor;
-  bool _showCursor;
-  SizeChangedCallback onContentSizeChanged;
-  Offset _scrollOffset;
-
-  Size _contentSize;
-
-  Color get cursorColor => _cursorColor;
-  void set cursorColor(Color value) {
-    if (_cursorColor == value)
-      return;
-    _cursorColor = value;
-    markNeedsPaint();
-  }
-
-  bool get showCursor => _showCursor;
-  void set showCursor(bool value) {
-    if (_showCursor == value)
-      return;
-    _showCursor = value;
-    markNeedsPaint();
-  }
-
-  Offset get scrollOffset => _scrollOffset;
-  void set scrollOffset(Offset value) {
-    if (_scrollOffset == value)
-      return;
-    _scrollOffset = value;
-    markNeedsPaint();
-  }
-
-  // Editable text does not support line wrap.
-  bool get allowLineWrap => false;
-
-  double _getIntrinsicWidth(BoxConstraints constraints) {
-    // There should be no difference between the minimum and maximum width
-    // because we only support single-line text.
-    layoutText(constraints);
-    return constraints.constrainWidth(
-      textPainter.size.width + _kCursorGap + _kCursorWidth
-    );
-  }
-
-  double getMinIntrinsicWidth(BoxConstraints constraints) {
-    return _getIntrinsicWidth(constraints);
-  }
-
-  double getMaxIntrinsicWidth(BoxConstraints constraints) {
-    return _getIntrinsicWidth(constraints);
-  }
-
-  void performLayout() {
-    layoutText(constraints);
-
-    Offset cursorPadding = const Offset(_kCursorGap + _kCursorWidth, 0.0);
-    Size newContentSize = textPainter.size + cursorPadding;
-    size = constraints.constrain(newContentSize);
-
-    if (_contentSize == null || _contentSize != newContentSize) {
-      _contentSize = newContentSize;
-      if (onContentSizeChanged != null)
-        onContentSizeChanged(newContentSize);
-    }
-  }
-
-  void paint(PaintingContext context, Offset offset) {
-    layoutText(constraints);
-
-    bool needsClipping = (_contentSize.width > size.width);
-    if (needsClipping) {
-      context.canvas.save();
-      context.canvas.clipRect(offset & size);
-    }
-
-    textPainter.paint(context.canvas, offset - _scrollOffset);
-
-    if (_showCursor) {
-      Rect cursorRect =  new Rect.fromLTWH(
-        textPainter.size.width + _kCursorGap,
-        _kCursorHeightOffset,
-        _kCursorWidth,
-        size.height - 2.0 * _kCursorHeightOffset
-      );
-      context.canvas.drawRect(
-        cursorRect.shift(offset - _scrollOffset),
-        new Paint()..color = _cursorColor
-      );
-    }
-
-    if (needsClipping)
-      context.canvas.restore();
-  }
-
-}
diff --git a/sky/packages/sky/lib/src/rendering/error.dart b/sky/packages/sky/lib/src/rendering/error.dart
deleted file mode 100644
index 4e4b8c2..0000000
--- a/sky/packages/sky/lib/src/rendering/error.dart
+++ /dev/null
@@ -1,43 +0,0 @@
-// Copyright 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 'box.dart';
-import 'debug.dart';
-import 'object.dart';
-
-const double _kMaxWidth = 100000.0;
-const double _kMaxHeight = 100000.0;
-
-/// A render object used as a placeholder when an error occurs
-class RenderErrorBox extends RenderBox {
-
-  double getMinIntrinsicWidth(BoxConstraints constraints) {
-    return constraints.constrainWidth(0.0);
-  }
-
-  double getMaxIntrinsicWidth(BoxConstraints constraints) {
-    return constraints.constrainWidth(_kMaxWidth);
-  }
-
-  double getMinIntrinsicHeight(BoxConstraints constraints) {
-    return constraints.constrainHeight(0.0);
-  }
-
-  double getMaxIntrinsicHeight(BoxConstraints constraints) {
-    return constraints.constrainHeight(_kMaxHeight);
-  }
-
-  bool get sizedByParent => true;
-
-  bool hitTestSelf(Point position) => true;
-
-  void performResize() {
-    size = constraints.constrain(const Size(_kMaxWidth, _kMaxHeight));
-  }
-
-  void paint(PaintingContext context, Offset offset) {
-    context.canvas.drawRect(offset & size, new Paint() .. color = debugErrorBoxColor);
-  }
-
-}
diff --git a/sky/packages/sky/lib/src/rendering/flex.dart b/sky/packages/sky/lib/src/rendering/flex.dart
deleted file mode 100644
index 9de7591..0000000
--- a/sky/packages/sky/lib/src/rendering/flex.dart
+++ /dev/null
@@ -1,608 +0,0 @@
-// Copyright 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 'dart:math' as math;
-
-import 'box.dart';
-import 'object.dart';
-
-/// Parent data for use with [RenderFlex]
-class FlexParentData extends ContainerBoxParentDataMixin<RenderBox> {
-  /// The flex factor to use for this child
-  ///
-  /// If null, the child is inflexible and determines its own size. If non-null,
-  /// the child is flexible and its extent in the main axis is determined by
-  /// dividing the free space (after placing the inflexible children)
-  /// according to the flex factors of the flexible children.
-  int flex;
-
-  void merge(FlexParentData other) {
-    if (other.flex != null)
-      flex = other.flex;
-    super.merge(other);
-  }
-
-  String toString() => '${super.toString()}; flex=$flex';
-}
-
-/// The direction in which the box should flex
-enum FlexDirection {
-  /// Children are arranged horizontally, from left to right
-  horizontal,
-  /// Children are arranged vertically, from top to bottom
-  vertical
-}
-
-/// How the children should be placed along the main axis in a flex layout
-enum FlexJustifyContent {
-  /// Place the children as close to the start of the main axis as possible
-  start,
-  /// Place the children as close to the end of the main axis as possible
-  end,
-  /// Place the children as close to the middle of the main axis as possible
-  center,
-  /// Place the free space evenly between the children
-  spaceBetween,
-  /// Place the free space evenly between the children as well as before and after the first and last child
-  spaceAround,
-  /// Do not expand to fill the free space. None of the children may specify a flex factor.
-  collapse,
-}
-
-/// How the children should be placed along the cross axis in a flex layout
-enum FlexAlignItems {
-  /// Place the children as close to the start of the cross axis as possible
-  start,
-  /// Place the children as close to the end of the cross axis as possible
-  end,
-  /// Place the children as close to the middle of the cross axis as possible
-  center,
-  /// Require the children to fill the cross axis
-  stretch,
-  /// Place the children along the cross axis such that their baselines match
-  baseline,
-}
-
-typedef double _ChildSizingFunction(RenderBox child, BoxConstraints constraints);
-
-/// Implements the flex layout algorithm
-///
-/// In flex layout, children are arranged linearly along the main axis (either
-/// horizontally or vertically). First, inflexible children (those with a null
-/// flex factor) are allocated space along the main axis. If the flex is given
-/// unlimited space in the main axis, the flex sizes its main axis to the total
-/// size of the inflexible children along the main axis and forbids flexible
-/// children. Otherwise, the flex expands to the maximum max-axis size and the
-/// remaining space along is divided among the flexible children according to
-/// their flex factors. Any remaining free space (i.e., if there aren't any
-/// flexible children) is allocated according to the [justifyContent] property.
-///
-/// In the cross axis, children determine their own size. The flex then sizes
-/// its cross axis to fix the largest of its children. The children are then
-/// positioned along the cross axis according to the [alignItems] property.
-class RenderFlex extends RenderBox with ContainerRenderObjectMixin<RenderBox, FlexParentData>,
-                                        RenderBoxContainerDefaultsMixin<RenderBox, FlexParentData> {
-
-  RenderFlex({
-    List<RenderBox> children,
-    FlexDirection direction: FlexDirection.horizontal,
-    FlexJustifyContent justifyContent: FlexJustifyContent.start,
-    FlexAlignItems alignItems: FlexAlignItems.center,
-    TextBaseline textBaseline
-  }) : _direction = direction,
-       _justifyContent = justifyContent,
-       _alignItems = alignItems,
-       _textBaseline = textBaseline {
-    addAll(children);
-  }
-
-  /// The direction to use as the main axis
-  FlexDirection get direction => _direction;
-  FlexDirection _direction;
-  void set direction (FlexDirection value) {
-    if (_direction != value) {
-      _direction = value;
-      markNeedsLayout();
-    }
-  }
-
-  /// How the children should be placed along the main axis
-  FlexJustifyContent get justifyContent => _justifyContent;
-  FlexJustifyContent _justifyContent;
-  void set justifyContent (FlexJustifyContent value) {
-    if (_justifyContent != value) {
-      _justifyContent = value;
-      markNeedsLayout();
-    }
-  }
-
-  /// How the children should be placed along the cross axis
-  FlexAlignItems get alignItems => _alignItems;
-  FlexAlignItems _alignItems;
-  void set alignItems (FlexAlignItems value) {
-    if (_alignItems != value) {
-      _alignItems = value;
-      markNeedsLayout();
-    }
-  }
-
-  /// If using aligning items according to their baseline, which baseline to use
-  TextBaseline get textBaseline => _textBaseline;
-  TextBaseline _textBaseline;
-  void set textBaseline (TextBaseline value) {
-    if (_textBaseline != value) {
-      _textBaseline = value;
-      markNeedsLayout();
-    }
-  }
-
-  /// Set during layout if overflow occurred on the main axis
-  double _overflow;
-
-  void setupParentData(RenderBox child) {
-    if (child.parentData is! FlexParentData)
-      child.parentData = new FlexParentData();
-  }
-
-  double _getIntrinsicSize({ BoxConstraints constraints,
-                             FlexDirection sizingDirection,
-                             _ChildSizingFunction childSize }) {
-    // http://www.w3.org/TR/2015/WD-css-flexbox-1-20150514/#intrinsic-sizes
-    if (_direction == sizingDirection) {
-      // INTRINSIC MAIN SIZE
-      // Intrinsic main size is the smallest size the flex container can take
-      // while maintaining the min/max-content contributions of its flex items.
-      BoxConstraints childConstraints;
-      switch(_direction) {
-        case FlexDirection.horizontal:
-          childConstraints = new BoxConstraints(maxHeight: constraints.maxHeight);
-          break;
-        case FlexDirection.vertical:
-          childConstraints = new BoxConstraints(maxWidth: constraints.maxWidth);
-          break;
-      }
-
-      double totalFlex = 0.0;
-      double inflexibleSpace = 0.0;
-      double maxFlexFractionSoFar = 0.0;
-      RenderBox child = firstChild;
-      while (child != null) {
-        int flex = _getFlex(child);
-        totalFlex += flex;
-        if (flex > 0) {
-          double flexFraction = childSize(child, childConstraints) / _getFlex(child);
-          maxFlexFractionSoFar = math.max(maxFlexFractionSoFar, flexFraction);
-        } else {
-          inflexibleSpace += childSize(child, childConstraints);
-        }
-        final FlexParentData childParentData = child.parentData;
-        child = childParentData.nextSibling;
-      }
-      double mainSize = maxFlexFractionSoFar * totalFlex + inflexibleSpace;
-
-      // Ensure that we don't violate the given constraints with our result
-      switch(_direction) {
-        case FlexDirection.horizontal:
-          return constraints.constrainWidth(mainSize);
-        case FlexDirection.vertical:
-          return constraints.constrainHeight(mainSize);
-      }
-    } else {
-      // INTRINSIC CROSS SIZE
-      // The spec wants us to perform layout into the given available main-axis
-      // space and return the cross size. That's too expensive, so instead we
-      // size inflexible children according to their max intrinsic size in the
-      // main direction and use those constraints to determine their max
-      // intrinsic size in the cross direction. We don't care if the caller
-      // asked for max or min -- the answer is always computed using the
-      // max size in the main direction.
-
-      double availableMainSpace;
-      BoxConstraints childConstraints;
-      switch(_direction) {
-        case FlexDirection.horizontal:
-          childConstraints = new BoxConstraints(maxWidth: constraints.maxWidth);
-          availableMainSpace = constraints.maxWidth;
-          break;
-        case FlexDirection.vertical:
-          childConstraints = new BoxConstraints(maxHeight: constraints.maxHeight);
-          availableMainSpace = constraints.maxHeight;
-          break;
-      }
-
-      // Get inflexible space using the max in the main direction
-      int totalFlex = 0;
-      double inflexibleSpace = 0.0;
-      double maxCrossSize = 0.0;
-      RenderBox child = firstChild;
-      while (child != null) {
-        int flex = _getFlex(child);
-        totalFlex += flex;
-        double mainSize;
-        double crossSize;
-        if (flex == 0) {
-          switch (_direction) {
-              case FlexDirection.horizontal:
-                mainSize = child.getMaxIntrinsicWidth(childConstraints);
-                BoxConstraints widthConstraints =
-                  new BoxConstraints(minWidth: mainSize, maxWidth: mainSize);
-                crossSize = child.getMaxIntrinsicHeight(widthConstraints);
-                break;
-              case FlexDirection.vertical:
-                mainSize = child.getMaxIntrinsicHeight(childConstraints);
-                BoxConstraints heightConstraints =
-                  new BoxConstraints(minWidth: mainSize, maxWidth: mainSize);
-                crossSize = child.getMaxIntrinsicWidth(heightConstraints);
-                break;
-          }
-          inflexibleSpace += mainSize;
-          maxCrossSize = math.max(maxCrossSize, crossSize);
-        }
-        final FlexParentData childParentData = child.parentData;
-        child = childParentData.nextSibling;
-      }
-
-      // Determine the spacePerFlex by allocating the remaining available space
-      double spacePerFlex = (availableMainSpace - inflexibleSpace) / totalFlex;
-
-      // Size remaining items, find the maximum cross size
-      child = firstChild;
-      while (child != null) {
-        int flex = _getFlex(child);
-        if (flex > 0) {
-          double childMainSize = spacePerFlex * flex;
-          double crossSize;
-          switch (_direction) {
-            case FlexDirection.horizontal:
-              BoxConstraints childConstraints =
-                new BoxConstraints(minWidth: childMainSize, maxWidth: childMainSize);
-              crossSize = child.getMaxIntrinsicHeight(childConstraints);
-              break;
-            case FlexDirection.vertical:
-              BoxConstraints childConstraints =
-                new BoxConstraints(minHeight: childMainSize, maxHeight: childMainSize);
-              crossSize = child.getMaxIntrinsicWidth(childConstraints);
-              break;
-          }
-          maxCrossSize = math.max(maxCrossSize, crossSize);
-        }
-        final FlexParentData childParentData = child.parentData;
-        child = childParentData.nextSibling;
-      }
-
-      // Ensure that we don't violate the given constraints with our result
-      switch(_direction) {
-        case FlexDirection.horizontal:
-          return constraints.constrainHeight(maxCrossSize);
-        case FlexDirection.vertical:
-          return constraints.constrainWidth(maxCrossSize);
-      }
-    }
-  }
-
-  double getMinIntrinsicWidth(BoxConstraints constraints) {
-    return _getIntrinsicSize(
-      constraints: constraints,
-      sizingDirection: FlexDirection.horizontal,
-      childSize: (RenderBox child, BoxConstraints innerConstraints) => child.getMinIntrinsicWidth(innerConstraints)
-    );
-  }
-
-  double getMaxIntrinsicWidth(BoxConstraints constraints) {
-    return _getIntrinsicSize(
-      constraints: constraints,
-      sizingDirection: FlexDirection.horizontal,
-      childSize: (RenderBox child, BoxConstraints innerConstraints) => child.getMaxIntrinsicWidth(innerConstraints)
-    );
-  }
-
-  double getMinIntrinsicHeight(BoxConstraints constraints) {
-    return _getIntrinsicSize(
-      constraints: constraints,
-      sizingDirection: FlexDirection.vertical,
-      childSize: (RenderBox child, BoxConstraints innerConstraints) => child.getMinIntrinsicHeight(innerConstraints)
-    );
-  }
-
-  double getMaxIntrinsicHeight(BoxConstraints constraints) {
-    return _getIntrinsicSize(
-      constraints: constraints,
-      sizingDirection: FlexDirection.vertical,
-      childSize: (RenderBox child, BoxConstraints innerConstraints) => child.getMaxIntrinsicHeight(innerConstraints));
-  }
-
-  double computeDistanceToActualBaseline(TextBaseline baseline) {
-    if (_direction == FlexDirection.horizontal)
-      return defaultComputeDistanceToHighestActualBaseline(baseline);
-    return defaultComputeDistanceToFirstActualBaseline(baseline);
-  }
-
-  int _getFlex(RenderBox child) {
-    final FlexParentData childParentData = child.parentData;
-    return childParentData.flex != null ? childParentData.flex : 0;
-  }
-
-  double _getCrossSize(RenderBox child) {
-    return (_direction == FlexDirection.horizontal) ? child.size.height : child.size.width;
-  }
-
-  double _getMainSize(RenderBox child) {
-    return (_direction == FlexDirection.horizontal) ? child.size.width : child.size.height;
-  }
-
-  void performLayout() {
-    // Originally based on http://www.w3.org/TR/css-flexbox-1/ Section 9.7 Resolving Flexible Lengths
-
-    // Determine used flex factor, size inflexible items, calculate free space.
-    int totalFlex = 0;
-    int totalChildren = 0;
-    assert(constraints != null);
-    final double mainSize = (_direction == FlexDirection.horizontal) ? constraints.constrainWidth() : constraints.constrainHeight();
-    final bool canFlex = mainSize < double.INFINITY && justifyContent != FlexJustifyContent.collapse;
-    double crossSize = 0.0;  // This is determined as we lay out the children
-    double freeSpace = canFlex ? mainSize : 0.0;
-    RenderBox child = firstChild;
-    while (child != null) {
-      final FlexParentData childParentData = child.parentData;
-      totalChildren++;
-      int flex = _getFlex(child);
-      if (flex > 0) {
-        // Flexible children can only be used when the RenderFlex box's container has a finite size.
-        // When the container is infinite, for example if you are in a scrollable viewport, then
-        // it wouldn't make any sense to have a flexible child.
-        assert(canFlex && 'See https://flutter.github.io/layout/#flex' is String);
-        totalFlex += childParentData.flex;
-      } else {
-        BoxConstraints innerConstraints;
-        if (alignItems == FlexAlignItems.stretch) {
-          switch (_direction) {
-            case FlexDirection.horizontal:
-              innerConstraints = new BoxConstraints(minHeight: constraints.maxHeight,
-                                                    maxHeight: constraints.maxHeight);
-              break;
-            case FlexDirection.vertical:
-              innerConstraints = new BoxConstraints(minWidth: constraints.maxWidth,
-                                                    maxWidth: constraints.maxWidth);
-              break;
-          }
-        } else {
-          switch (_direction) {
-            case FlexDirection.horizontal:
-              innerConstraints = new BoxConstraints(maxHeight: constraints.maxHeight);
-              break;
-            case FlexDirection.vertical:
-              innerConstraints = new BoxConstraints(maxWidth: constraints.maxWidth);
-              break;
-          }
-        }
-        child.layout(innerConstraints, parentUsesSize: true);
-        freeSpace -= _getMainSize(child);
-        crossSize = math.max(crossSize, _getCrossSize(child));
-      }
-      assert(child.parentData == childParentData);
-      child = childParentData.nextSibling;
-    }
-    _overflow = math.max(0.0, -freeSpace);
-    freeSpace = math.max(0.0, freeSpace);
-
-    // Distribute remaining space to flexible children, and determine baseline.
-    double maxBaselineDistance = 0.0;
-    double usedSpace = 0.0;
-    if (totalFlex > 0 || alignItems == FlexAlignItems.baseline) {
-      double spacePerFlex = totalFlex > 0 ? (freeSpace / totalFlex) : 0.0;
-      child = firstChild;
-      while (child != null) {
-        int flex = _getFlex(child);
-        if (flex > 0) {
-          double spaceForChild = spacePerFlex * flex;
-          BoxConstraints innerConstraints;
-          if (alignItems == FlexAlignItems.stretch) {
-            switch (_direction) {
-              case FlexDirection.horizontal:
-                innerConstraints = new BoxConstraints(minWidth: spaceForChild,
-                                                      maxWidth: spaceForChild,
-                                                      minHeight: constraints.maxHeight,
-                                                      maxHeight: constraints.maxHeight);
-                break;
-              case FlexDirection.vertical:
-                innerConstraints = new BoxConstraints(minWidth: constraints.maxWidth,
-                                                      maxWidth: constraints.maxWidth,
-                                                      minHeight: spaceForChild,
-                                                      maxHeight: spaceForChild);
-                break;
-            }
-          } else {
-            switch (_direction) {
-              case FlexDirection.horizontal:
-                innerConstraints = new BoxConstraints(minWidth: spaceForChild,
-                                                      maxWidth: spaceForChild,
-                                                      maxHeight: constraints.maxHeight);
-                break;
-              case FlexDirection.vertical:
-                innerConstraints = new BoxConstraints(maxWidth: constraints.maxWidth,
-                                                      minHeight: spaceForChild,
-                                                      maxHeight: spaceForChild);
-                break;
-            }
-          }
-          child.layout(innerConstraints, parentUsesSize: true);
-          usedSpace += _getMainSize(child);
-          crossSize = math.max(crossSize, _getCrossSize(child));
-        }
-        if (alignItems == FlexAlignItems.baseline) {
-          assert(textBaseline != null && 'To use FlexAlignItems.baseline, you must also specify which baseline to use using the "baseline" argument.' is String);
-          double distance = child.getDistanceToBaseline(textBaseline, onlyReal: true);
-          if (distance != null)
-            maxBaselineDistance = math.max(maxBaselineDistance, distance);
-        }
-        final FlexParentData childParentData = child.parentData;
-        child = childParentData.nextSibling;
-      }
-    }
-
-    // Align items along the main axis.
-    double leadingSpace;
-    double betweenSpace;
-    double remainingSpace;
-    if (canFlex) {
-      remainingSpace = math.max(0.0, freeSpace - usedSpace);
-      switch (_direction) {
-        case FlexDirection.horizontal:
-          size = constraints.constrain(new Size(mainSize, crossSize));
-          crossSize = size.height;
-          assert(size.width == mainSize);
-          break;
-        case FlexDirection.vertical:
-          size = constraints.constrain(new Size(crossSize, mainSize));
-          crossSize = size.width;
-          assert(size.height == mainSize);
-          break;
-      }
-    } else {
-      leadingSpace = 0.0;
-      betweenSpace = 0.0;
-      switch (_direction) {
-        case FlexDirection.horizontal:
-          size = constraints.constrain(new Size(_overflow, crossSize));
-          crossSize = size.height;
-          assert(size.width >= _overflow);
-          remainingSpace = size.width - _overflow;
-          break;
-        case FlexDirection.vertical:
-          size = constraints.constrain(new Size(crossSize, _overflow));
-          crossSize = size.width;
-          assert(size.height >= _overflow);
-          remainingSpace = size.height - _overflow;
-          break;
-      }
-      _overflow = 0.0;
-    }
-    switch (_justifyContent) {
-      case FlexJustifyContent.start:
-      case FlexJustifyContent.collapse:
-        leadingSpace = 0.0;
-        betweenSpace = 0.0;
-        break;
-      case FlexJustifyContent.end:
-        leadingSpace = remainingSpace;
-        betweenSpace = 0.0;
-        break;
-      case FlexJustifyContent.center:
-        leadingSpace = remainingSpace / 2.0;
-        betweenSpace = 0.0;
-        break;
-      case FlexJustifyContent.spaceBetween:
-        leadingSpace = 0.0;
-        betweenSpace = totalChildren > 1 ? remainingSpace / (totalChildren - 1) : 0.0;
-        break;
-      case FlexJustifyContent.spaceAround:
-        betweenSpace = totalChildren > 0 ? remainingSpace / totalChildren : 0.0;
-        leadingSpace = betweenSpace / 2.0;
-        break;
-    }
-
-    // Position elements
-    double childMainPosition = leadingSpace;
-    child = firstChild;
-    while (child != null) {
-      final FlexParentData childParentData = child.parentData;
-      double childCrossPosition;
-      switch (_alignItems) {
-        case FlexAlignItems.stretch:
-        case FlexAlignItems.start:
-          childCrossPosition = 0.0;
-          break;
-        case FlexAlignItems.end:
-          childCrossPosition = crossSize - _getCrossSize(child);
-          break;
-        case FlexAlignItems.center:
-          childCrossPosition = crossSize / 2.0 - _getCrossSize(child) / 2.0;
-          break;
-        case FlexAlignItems.baseline:
-          childCrossPosition = 0.0;
-          if (_direction == FlexDirection.horizontal) {
-            assert(textBaseline != null);
-            double distance = child.getDistanceToBaseline(textBaseline, onlyReal: true);
-            if (distance != null)
-              childCrossPosition = maxBaselineDistance - distance;
-          }
-          break;
-      }
-      switch (_direction) {
-        case FlexDirection.horizontal:
-          childParentData.position = new Point(childMainPosition, childCrossPosition);
-          break;
-        case FlexDirection.vertical:
-          childParentData.position = new Point(childCrossPosition, childMainPosition);
-          break;
-      }
-      childMainPosition += _getMainSize(child) + betweenSpace;
-      child = childParentData.nextSibling;
-    }
-  }
-
-  bool hitTestChildren(HitTestResult result, { Point position }) {
-    return defaultHitTestChildren(result, position: position);
-  }
-
-  void paint(PaintingContext context, Offset offset) {
-    if (_overflow <= 0.0) {
-      defaultPaint(context, offset);
-      return;
-    }
-
-    // We have overflow. Clip it.
-    context.canvas.save();
-    context.canvas.clipRect(offset & size);
-    defaultPaint(context, offset);
-    context.canvas.restore();
-    assert(() {
-      // In debug mode, if you have overflow, we highlight where the
-      // overflow would be by painting that area red. Since that is
-      // likely to be clipped by an ancestor, we also draw a thick red
-      // line at the edge that's overflowing.
-
-      // If you do want clipping, use a RenderClip (Clip in the
-      // Widgets library).
-
-      Paint markerPaint = new Paint()..color = const Color(0xE0FF0000);
-      Paint highlightPaint = new Paint()..color = const Color(0x7FFF0000);
-      const kMarkerSize = 0.1;
-      Rect markerRect, overflowRect;
-      switch(direction) {
-        case FlexDirection.horizontal:
-          markerRect = offset + new Offset(size.width * (1.0 - kMarkerSize), 0.0) &
-                       new Size(size.width * kMarkerSize, size.height);
-          overflowRect = offset + new Offset(size.width, 0.0) &
-                         new Size(_overflow, size.height);
-          break;
-        case FlexDirection.vertical:
-          markerRect = offset + new Offset(0.0, size.height * (1.0 - kMarkerSize)) &
-                       new Size(size.width, size.height * kMarkerSize);
-          overflowRect = offset + new Offset(0.0, size.height) &
-                         new Size(size.width, _overflow);
-          break;
-      }
-      context.canvas.drawRect(markerRect, markerPaint);
-      context.canvas.drawRect(overflowRect, highlightPaint);
-      return true;
-    });
-  }
-
-  String toString() {
-    String header = super.toString();
-    if (_overflow is double && _overflow > 0.0)
-      header += ' OVERFLOWING';
-    return header;
-  }
-
-  void debugDescribeSettings(List<String> settings) {
-    super.debugDescribeSettings(settings);
-    settings.add('direction: $_direction');
-    settings.add('justifyContent: $_justifyContent');
-    settings.add('alignItems: $_alignItems');
-    settings.add('textBaseline: $_textBaseline');
-  }
-
-}
diff --git a/sky/packages/sky/lib/src/rendering/grid.dart b/sky/packages/sky/lib/src/rendering/grid.dart
deleted file mode 100644
index b22ff83..0000000
--- a/sky/packages/sky/lib/src/rendering/grid.dart
+++ /dev/null
@@ -1,151 +0,0 @@
-// Copyright 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 'box.dart';
-import 'object.dart';
-
-class _GridMetrics {
-  // Grid is width-in, height-out.  We fill the max width and adjust height
-  // accordingly.
-  factory _GridMetrics({ double width, int childCount, double maxChildExtent }) {
-    assert(width != null);
-    assert(childCount != null);
-    assert(maxChildExtent != null);
-    double childExtent = maxChildExtent;
-    int childrenPerRow = (width / childExtent).floor();
-    // If the child extent divides evenly into the width use that, otherwise + 1
-    if (width / childExtent != childrenPerRow.toDouble()) childrenPerRow += 1;
-    double totalPadding = 0.0;
-    if (childrenPerRow * childExtent > width) {
-      // TODO(eseidel): We should snap to pixel bounderies.
-      childExtent = width / childrenPerRow;
-    } else {
-      totalPadding = width - (childrenPerRow * childExtent);
-    }
-    double childPadding = totalPadding / (childrenPerRow + 1.0);
-    int rowCount = (childCount / childrenPerRow).ceil();
-
-    double height = childPadding * (rowCount + 1) + (childExtent * rowCount);
-    Size childSize = new Size(childExtent, childExtent);
-    Size size = new Size(width, height);
-    return new _GridMetrics._(size, childSize, childrenPerRow, childPadding, rowCount);
-  }
-
-  const _GridMetrics._(this.size, this.childSize, this.childrenPerRow, this.childPadding, this.rowCount);
-
-  final Size size;
-  final Size childSize;
-  final int childrenPerRow; // aka columnCount
-  final double childPadding;
-  final int rowCount;
-}
-
-/// Parent data for use with [RenderGrid]
-class GridParentData extends ContainerBoxParentDataMixin<RenderBox> {}
-
-/// Implements the grid layout algorithm
-///
-/// In grid layout, children are arranged into rows and collumns in on a two
-/// dimensional grid. The grid determines how many children will be placed in
-/// each row by making the children as wide as possible while still respecting
-/// the given [maxChildExtent].
-class RenderGrid extends RenderBox with ContainerRenderObjectMixin<RenderBox, GridParentData>,
-                                        RenderBoxContainerDefaultsMixin<RenderBox, GridParentData> {
-  RenderGrid({ List<RenderBox> children, double maxChildExtent }) {
-    addAll(children);
-    _maxChildExtent = maxChildExtent;
-  }
-
-  double _maxChildExtent;
-  bool _hasVisualOverflow = false;
-
-  double get maxChildExtent => _maxChildExtent;
-  void set maxChildExtent (double value) {
-    if (_maxChildExtent != value) {
-      _maxChildExtent = value;
-      markNeedsLayout();
-    }
-  }
-
-  void setupParentData(RenderBox child) {
-    if (child.parentData is! GridParentData)
-      child.parentData = new GridParentData();
-  }
-
-  double getMinIntrinsicWidth(BoxConstraints constraints) {
-    // We can render at any width.
-    return constraints.constrainWidth(0.0);
-  }
-
-  double getMaxIntrinsicWidth(BoxConstraints constraints) {
-    double maxWidth = childCount * _maxChildExtent;
-    return constraints.constrainWidth(maxWidth);
-  }
-
-  double getMinIntrinsicHeight(BoxConstraints constraints) {
-    double desiredHeight = _computeMetrics().size.height;
-    return constraints.constrainHeight(desiredHeight);
-  }
-
-  double getMaxIntrinsicHeight(BoxConstraints constraints) {
-    return getMinIntrinsicHeight(constraints);
-  }
-
-  double computeDistanceToActualBaseline(TextBaseline baseline) {
-    return defaultComputeDistanceToHighestActualBaseline(baseline);
-  }
-
-  _GridMetrics _computeMetrics() {
-    return new _GridMetrics(
-      width: constraints.maxWidth,
-      childCount: childCount,
-      maxChildExtent: _maxChildExtent
-    );
-  }
-
-  void performLayout() {
-    // We could shrink-wrap our contents when infinite, but for now we don't.
-    assert(constraints.maxWidth < double.INFINITY);
-    _GridMetrics metrics = _computeMetrics();
-    size = constraints.constrain(metrics.size);
-    if (constraints.maxHeight < size.height)
-      _hasVisualOverflow = true;
-
-    int row = 0;
-    int column = 0;
-    RenderBox child = firstChild;
-    while (child != null) {
-      child.layout(new BoxConstraints.tight(metrics.childSize));
-
-      double x = (column + 1) * metrics.childPadding + (column * metrics.childSize.width);
-      double y = (row + 1) * metrics.childPadding + (row * metrics.childSize.height);
-      final GridParentData childParentData = child.parentData;
-      childParentData.position = new Point(x, y);
-
-      column += 1;
-      if (column >= metrics.childrenPerRow) {
-        row += 1;
-        column = 0;
-      }
-
-      assert(child.parentData == childParentData);
-      child = childParentData.nextSibling;
-    }
-  }
-
-  bool hitTestChildren(HitTestResult result, { Point position }) {
-    return defaultHitTestChildren(result, position: position);
-  }
-
-  void paint(PaintingContext context, Offset offset) {
-    if (_hasVisualOverflow) {
-      context.canvas.save();
-      context.canvas.clipRect(offset & size);
-      defaultPaint(context, offset);
-      context.canvas.restore();
-    } else {
-      defaultPaint(context, offset);
-    }
-  }
-}
diff --git a/sky/packages/sky/lib/src/rendering/hit_test.dart b/sky/packages/sky/lib/src/rendering/hit_test.dart
deleted file mode 100644
index 12396b1..0000000
--- a/sky/packages/sky/lib/src/rendering/hit_test.dart
+++ /dev/null
@@ -1,44 +0,0 @@
-// Copyright 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:flutter/gestures.dart';
-
-/// An object that can handle events.
-abstract class HitTestTarget {
-  /// Override this function to receive events.
-  void handleEvent(InputEvent event, HitTestEntry entry);
-}
-
-/// Data collected during a hit test about a specific [HitTestTarget].
-///
-/// Subclass this object to pass additional information from the hit test phase
-/// to the event propagation phase.
-class HitTestEntry {
-  const HitTestEntry(this.target);
-
-  /// The [HitTestTarget] encountered during the hit test.
-  final HitTestTarget target;
-}
-
-/// The result of performing a hit test.
-class HitTestResult {
-  HitTestResult({ List<HitTestEntry> path })
-    : path = path != null ? path : new List<HitTestEntry>();
-
-  /// The list of [HitTestEntry] objects recorded during the hit test.
-  ///
-  /// The first entry in the path is the most specific, typically the one at
-  /// the leaf of tree being hit tested. Event propagation starts with the most
-  /// specific (i.e., first) entry and proceeds in order through the path.
-  final List<HitTestEntry> path;
-
-  /// Add a [HitTestEntry] to the path.
-  ///
-  /// The new entry is added at the end of the path, which means entries should
-  /// be added in order from most specific to least specific, typically during a
-  /// upward walk in the tree being hit tested.
-  void add(HitTestEntry entry) {
-    path.add(entry);
-  }
-}
diff --git a/sky/packages/sky/lib/src/rendering/image.dart b/sky/packages/sky/lib/src/rendering/image.dart
deleted file mode 100644
index 0de513c..0000000
--- a/sky/packages/sky/lib/src/rendering/image.dart
+++ /dev/null
@@ -1,207 +0,0 @@
-// Copyright 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 'dart:ui' as ui;
-
-import 'package:flutter/painting.dart';
-
-import 'box.dart';
-import 'object.dart';
-
-export 'package:flutter/painting.dart' show
-  ImageFit,
-  ImageRepeat;
-
-/// An image in the render tree.
-///
-/// The render image attempts to find a size for itself that fits in the given
-/// constraints and preserves the image's intrinisc aspect ratio.
-class RenderImage extends RenderBox {
-  RenderImage({
-    ui.Image image,
-    double width,
-    double height,
-    ColorFilter colorFilter,
-    ImageFit fit,
-    repeat: ImageRepeat.noRepeat,
-    Rect centerSlice
-  }) : _image = image,
-      _width = width,
-      _height = height,
-      _colorFilter = colorFilter,
-      _fit = fit,
-      _repeat = repeat,
-      _centerSlice = centerSlice;
-
-  /// The image to display.
-  ui.Image get image => _image;
-  ui.Image _image;
-  void set image (ui.Image value) {
-    if (value == _image)
-      return;
-    _image = value;
-    markNeedsPaint();
-    if (_width == null || _height == null)
-      markNeedsLayout();
-  }
-
-  /// If non-null, requires the image to have this width.
-  double get width => _width;
-  double _width;
-  void set width (double value) {
-    if (value == _width)
-      return;
-    _width = value;
-    markNeedsLayout();
-  }
-
-  /// If non-null, requires the image to have this height.
-  double get height => _height;
-  double _height;
-  void set height (double value) {
-    if (value == _height)
-      return;
-    _height = value;
-    markNeedsLayout();
-  }
-
-  /// If non-null, apply this color filter to the image before painint.
-  ColorFilter get colorFilter => _colorFilter;
-  ColorFilter _colorFilter;
-  void set colorFilter (ColorFilter value) {
-    if (value == _colorFilter)
-      return;
-    _colorFilter = value;
-    markNeedsPaint();
-  }
-
-  /// How to inscribe the image into the place allocated during layout.
-  ImageFit get fit => _fit;
-  ImageFit _fit;
-  void set fit (ImageFit value) {
-    if (value == _fit)
-      return;
-    _fit = value;
-    markNeedsPaint();
-  }
-
-  /// Not yet implemented.
-  ImageRepeat get repeat => _repeat;
-  ImageRepeat _repeat;
-  void set repeat (ImageRepeat value) {
-    if (value == _repeat)
-      return;
-    _repeat = value;
-    markNeedsPaint();
-  }
-
-  /// The center slice for a nine-patch image.
-  ///
-  /// The region of the image inside the center slice will be stretched both
-  /// horizontally and vertically to fit the image into its destination. The
-  /// region of the image above and below the center slice will be stretched
-  /// only horizontally and the region of the image to the left and right of
-  /// the center slice will be stretched only vertically.
-  Rect get centerSlice => _centerSlice;
-  Rect _centerSlice;
-  void set centerSlice (Rect value) {
-    if (value == _centerSlice)
-      return;
-    _centerSlice = value;
-    markNeedsPaint();
-  }
-
-  /// Find a size for the render image within the given constraints.
-  ///
-  ///  - The dimensions of the RenderImage must fit within the constraints.
-  ///  - The aspect ratio of the RenderImage matches the instrinsic aspect
-  ///    ratio of the image.
-  ///  - The RenderImage's dimension are maximal subject to being smaller than
-  ///    the intrinsic size of the image.
-  Size _sizeForConstraints(BoxConstraints constraints) {
-    // Folds the given |width| and |height| into |cosntraints| so they can all
-    // be treated uniformly.
-    constraints = new BoxConstraints.tightFor(
-      width: _width,
-      height: _height
-    ).enforce(constraints);
-
-    if (constraints.isTight || _image == null)
-      return constraints.smallest;
-
-    double width = _image.width.toDouble();
-    double height = _image.height.toDouble();
-    assert(width > 0.0);
-    assert(height > 0.0);
-    double aspectRatio = width / height;
-
-    if (width > constraints.maxWidth) {
-      width = constraints.maxWidth;
-      height = width / aspectRatio;
-    }
-
-    if (height > constraints.maxHeight) {
-      height = constraints.maxHeight;
-      width = height * aspectRatio;
-    }
-
-    if (width < constraints.minWidth) {
-      width = constraints.minWidth;
-      height = width / aspectRatio;
-    }
-
-    if (height < constraints.minHeight) {
-      height = constraints.minHeight;
-      width = height * aspectRatio;
-    }
-
-    return constraints.constrain(new Size(width, height));
-  }
-
-  double getMinIntrinsicWidth(BoxConstraints constraints) {
-    if (_width == null && _height == null)
-      return constraints.constrainWidth(0.0);
-    return _sizeForConstraints(constraints).width;
-  }
-
-  double getMaxIntrinsicWidth(BoxConstraints constraints) {
-    return _sizeForConstraints(constraints).width;
-  }
-
-  double getMinIntrinsicHeight(BoxConstraints constraints) {
-    if (_width == null && _height == null)
-      return constraints.constrainHeight(0.0);
-    return _sizeForConstraints(constraints).height;
-  }
-
-  double getMaxIntrinsicHeight(BoxConstraints constraints) {
-    return _sizeForConstraints(constraints).height;
-  }
-
-  bool hitTestSelf(Point position) => true;
-
-  void performLayout() {
-    size = _sizeForConstraints(constraints);
-  }
-
-  void paint(PaintingContext context, Offset offset) {
-    if (_image == null)
-      return;
-    paintImage(
-      canvas: context.canvas,
-      rect: offset & size,
-      image: _image,
-      colorFilter: _colorFilter,
-      fit: _fit,
-      centerSlice: _centerSlice,
-      repeat: _repeat
-    );
-  }
-
-  void debugDescribeSettings(List<String> settings) {
-    super.debugDescribeSettings(settings);
-    settings.add('width: $width');
-    settings.add('height: $height');
-  }
-}
diff --git a/sky/packages/sky/lib/src/rendering/layer.dart b/sky/packages/sky/lib/src/rendering/layer.dart
deleted file mode 100644
index 3da0d16..0000000
--- a/sky/packages/sky/lib/src/rendering/layer.dart
+++ /dev/null
@@ -1,309 +0,0 @@
-// Copyright 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 'dart:ui' as ui;
-
-import 'package:vector_math/vector_math_64.dart';
-
-import 'basic_types.dart';
-
-export 'basic_types.dart';
-
-/// A composited layer
-///
-/// During painting, the render tree generates a tree of composited layers that
-/// are uploaded into the engine and displayed by the compositor. This class is
-/// the base class for all composited layers.
-abstract class Layer {
-  Layer({ this.offset: Offset.zero });
-
-  /// Offset from parent in the parent's coordinate system.
-  Offset offset;
-
-  /// This layer's parent in the layer tree
-  ContainerLayer get parent => _parent;
-  ContainerLayer _parent;
-
-  /// This layer's next sibling in the parent layer's child list
-  Layer get nextSibling => _nextSibling;
-  Layer _nextSibling;
-
-  /// This layer's previous sibling in the parent layer's child list
-  Layer get previousSibling => _previousSibling;
-  Layer _previousSibling;
-
-  /// Removes this layer from its parent layer's child list
-  void detach() {
-    if (_parent != null)
-      _parent._remove(this);
-  }
-
-  /// Replaces this layer with the given layer in the parent layer's child list
-  void replaceWith(Layer newLayer) {
-    assert(_parent != null);
-    assert(newLayer._parent == null);
-    assert(newLayer._nextSibling == null);
-    assert(newLayer._previousSibling == null);
-    newLayer._nextSibling = _nextSibling;
-    if (_nextSibling != null)
-      newLayer._nextSibling._previousSibling = newLayer;
-    newLayer._previousSibling = _previousSibling;
-    if (_previousSibling != null)
-      newLayer._previousSibling._nextSibling = newLayer;
-    newLayer._parent = _parent;
-    if (_parent._firstChild == this)
-      _parent._firstChild = newLayer;
-    if (_parent._lastChild == this)
-      _parent._lastChild = newLayer;
-    _nextSibling = null;
-    _previousSibling = null;
-    _parent = null;
-  }
-
-  /// Override this function to upload this layer to the engine
-  ///
-  /// The layerOffset is the accumulated offset of this layer's parent from the
-  /// origin of the builder's coordinate system.
-  void addToScene(ui.SceneBuilder builder, Offset layerOffset);
-}
-
-/// A composited layer containing a [Picture]
-class PictureLayer extends Layer {
-  PictureLayer({ Offset offset: Offset.zero, this.paintBounds })
-    : super(offset: offset);
-
-  /// The rectangle in this layer's coodinate system that bounds the recording
-  ///
-  /// The paint bounds are used to decide how much graphics memory to allocate
-  /// when rasterizing this layer.
-  Rect paintBounds;
-
-  /// The picture recorded for this layer
-  ///
-  /// The picture's coodinate system matches this layer's coodinate system
-  ui.Picture picture;
-
-  void addToScene(ui.SceneBuilder builder, Offset layerOffset) {
-    builder.addPicture(offset + layerOffset, picture, paintBounds);
-  }
-
-}
-
-/// A layer that indicates to the compositor that it should display
-/// certain statistics within it
-class StatisticsLayer extends Layer {
-  StatisticsLayer({
-    Offset offset: Offset.zero,
-    this.paintBounds,
-    this.optionsMask,
-    this.rasterizerThreshold
-  }) : super(offset: offset);
-
-  /// The rectangle in this layer's coodinate system that bounds the recording
-  Rect paintBounds;
-
-  /// A mask specifying the statistics to display
-  final int optionsMask;
-
-  final int rasterizerThreshold;
-
-  void addToScene(ui.SceneBuilder builder, Offset layerOffset) {
-    assert(optionsMask != null);
-    builder.addStatistics(optionsMask, paintBounds.shift(layerOffset));
-    builder.setRasterizerTracingThreshold(rasterizerThreshold);
-  }
-
-}
-
-
-/// A composited layer that has a list of children
-class ContainerLayer extends Layer {
-  ContainerLayer({ Offset offset: Offset.zero }) : super(offset: offset);
-
-  /// The first composited layer in this layer's child list
-  Layer get firstChild => _firstChild;
-  Layer _firstChild;
-
-  /// The last composited layer in this layer's child list
-  Layer get lastChild => _lastChild;
-  Layer _lastChild;
-
-  bool _debugUltimatePreviousSiblingOf(Layer child, { Layer equals }) {
-    while (child._previousSibling != null) {
-      assert(child._previousSibling != child);
-      child = child._previousSibling;
-    }
-    return child == equals;
-  }
-
-  bool _debugUltimateNextSiblingOf(Layer child, { Layer equals }) {
-    while (child._nextSibling != null) {
-      assert(child._nextSibling != child);
-      child = child._nextSibling;
-    }
-    return child == equals;
-  }
-
-  /// Adds the given layer to the end of this layer's child list
-  void append(Layer child) {
-    assert(child != this);
-    assert(child != _firstChild);
-    assert(child != _lastChild);
-    assert(child._parent == null);
-    assert(child._nextSibling == null);
-    assert(child._previousSibling == null);
-    child._parent = this;
-    child._previousSibling = _lastChild;
-    if (_lastChild != null)
-      _lastChild._nextSibling = child;
-    _lastChild = child;
-    if (_firstChild == null)
-      _firstChild = child;
-  }
-
-  void _remove(Layer child) {
-    assert(child._parent == this);
-    assert(_debugUltimatePreviousSiblingOf(child, equals: _firstChild));
-    assert(_debugUltimateNextSiblingOf(child, equals: _lastChild));
-    if (child._previousSibling == null) {
-      assert(_firstChild == child);
-      _firstChild = child._nextSibling;
-    } else {
-      child._previousSibling._nextSibling = child._nextSibling;
-    }
-    if (child._nextSibling == null) {
-      assert(_lastChild == child);
-      _lastChild = child._previousSibling;
-    } else {
-      child._nextSibling._previousSibling = child._previousSibling;
-    }
-    child._previousSibling = null;
-    child._nextSibling = null;
-    child._parent = null;
-  }
-
-  /// Removes all of this layer's children from its child list
-  void removeAllChildren() {
-    Layer child = _firstChild;
-    while (child != null) {
-      Layer next = child.nextSibling;
-      child._previousSibling = null;
-      child._nextSibling = null;
-      child._parent = null;
-      child = next;
-    }
-    _firstChild = null;
-    _lastChild = null;
-  }
-
-  void addToScene(ui.SceneBuilder builder, Offset layerOffset) {
-    addChildrenToScene(builder, offset + layerOffset);
-  }
-
-  /// Uploads all of this layer's children to the engine
-  void addChildrenToScene(ui.SceneBuilder builder, Offset layerOffset) {
-    Layer child = _firstChild;
-    while (child != null) {
-      child.addToScene(builder, layerOffset);
-      child = child.nextSibling;
-    }
-  }
-
-}
-
-/// A composite layer that clips its children using a rectangle
-class ClipRectLayer extends ContainerLayer {
-  ClipRectLayer({ Offset offset: Offset.zero, this.clipRect }) : super(offset: offset);
-
-  /// The rectangle to clip in the parent's coordinate system
-  Rect clipRect;
-  // TODO(abarth): Why is the rectangle in the parent's coordinate system
-  // instead of in the coordinate system of this layer?
-
-  void addToScene(ui.SceneBuilder builder, Offset layerOffset) {
-    builder.pushClipRect(clipRect.shift(layerOffset));
-    addChildrenToScene(builder, offset + layerOffset);
-    builder.pop();
-  }
-
-}
-
-/// A composite layer that clips its children using a rounded rectangle
-class ClipRRectLayer extends ContainerLayer {
-  ClipRRectLayer({ Offset offset: Offset.zero, this.bounds, this.clipRRect }) : super(offset: offset);
-
-  /// Unused
-  Rect bounds;
-  // TODO(abarth): Remove.
-
-  /// The rounded-rect to clip in the parent's coordinate system
-  ui.RRect clipRRect;
-  // TODO(abarth): Why is the rounded-rect in the parent's coordinate system
-  // instead of in the coordinate system of this layer?
-
-  void addToScene(ui.SceneBuilder builder, Offset layerOffset) {
-    builder.pushClipRRect(clipRRect.shift(layerOffset), bounds.shift(layerOffset));
-    addChildrenToScene(builder, offset + layerOffset);
-    builder.pop();
-  }
-
-}
-
-/// A composite layer that clips its children using a path
-class ClipPathLayer extends ContainerLayer {
-  ClipPathLayer({ Offset offset: Offset.zero, this.bounds, this.clipPath }) : super(offset: offset);
-
-  /// Unused
-  Rect bounds;
-  // TODO(abarth): Remove.
-
-  /// The path to clip in the parent's coordinate system
-  Path clipPath;
-  // TODO(abarth): Why is the path in the parent's coordinate system instead of
-  // in the coordinate system of this layer?
-
-  void addToScene(ui.SceneBuilder builder, Offset layerOffset) {
-    builder.pushClipPath(clipPath.shift(layerOffset), bounds.shift(layerOffset));
-    addChildrenToScene(builder, offset + layerOffset);
-    builder.pop();
-  }
-
-}
-
-/// A composited layer that applies a transformation matrix to its children
-class TransformLayer extends ContainerLayer {
-  TransformLayer({ Offset offset: Offset.zero, this.transform }) : super(offset: offset);
-
-  /// The matrix to apply
-  Matrix4 transform;
-
-  void addToScene(ui.SceneBuilder builder, Offset layerOffset) {
-    Matrix4 offsetTransform = new Matrix4.identity();
-    offsetTransform.translate(offset.dx + layerOffset.dx, offset.dy + layerOffset.dy);
-    builder.pushTransform((offsetTransform * transform).storage);
-    addChildrenToScene(builder, Offset.zero);
-    builder.pop();
-  }
-}
-
-/// A composited layer that makes its children partially transparent
-class OpacityLayer extends ContainerLayer {
-  OpacityLayer({ Offset offset: Offset.zero, this.bounds, this.alpha }) : super(offset: offset);
-
-  /// Unused
-  Rect bounds;
-  // TODO(abarth): Remove.
-
-  /// The amount to multiply into the alpha channel
-  ///
-  /// The opacity is expressed as an integer from 0 to 255, where 0 is fully
-  /// transparent and 255 is fully opaque.
-  int alpha;
-
-  void addToScene(ui.SceneBuilder builder, Offset layerOffset) {
-    builder.pushOpacity(alpha, bounds?.shift(layerOffset));
-    addChildrenToScene(builder, offset + layerOffset);
-    builder.pop();
-  }
-}
diff --git a/sky/packages/sky/lib/src/rendering/node.dart b/sky/packages/sky/lib/src/rendering/node.dart
deleted file mode 100644
index fb989de..0000000
--- a/sky/packages/sky/lib/src/rendering/node.dart
+++ /dev/null
@@ -1,109 +0,0 @@
-// Copyright 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.
-
-/// An abstract node in a tree
-///
-/// AbstractNode has as notion of depth, attachment, and parent, but does not
-/// have a model for children.
-///
-/// * When a subclass is changing the parent of a child, it should
-///   call either parent.adoptChild(child) or parent.dropChild(child)
-///   as appropriate. Subclasses should expose an API for
-///   manipulating the tree if you want to (e.g. a setter for a
-///   'child' property, or an 'add()' method to manipulate a list).
-///
-/// * You can see the current parent by querying 'parent'.
-///
-/// * You can see the current attachment state by querying
-///   'attached'. The root of any tree that is to be considered
-///   attached should be manually attached by calling 'attach()'.
-///   Other than that, don't call 'attach()' or 'detach()'. This is
-///   all managed automatically assuming you call the 'adoptChild()'
-///   and 'dropChild()' methods appropriately.
-///
-/// * Subclasses that have children must override 'attach()' and
-///   'detach()' as described below.
-///
-/// * Nodes always have a 'depth' greater than their ancestors'.
-///   There's no guarantee regarding depth between siblings. The
-///   depth of a node is used to ensure that nodes are processed in
-///   depth order. The 'depth' of a child can be more than one
-///   greater than the 'depth' of the parent, because the 'depth'
-///   values are never decreased: all that matters is that it's
-///   greater than the parent. Consider a tree with a root node A, a
-///   child B, and a grandchild C. Initially, A will have 'depth' 0,
-///   B 'depth' 1, and C 'depth' 2. If C is moved to be a child of A,
-///   sibling of B, then the numbers won't change. C's 'depth' will
-///   still be 2. This is all managed automatically assuming you call
-///   'adoptChild()' and 'dropChild()' appropriately.
-class AbstractNode {
-
-  // AbstractNode represents a node in a tree.
-  // The AbstractNode protocol is described in README.md.
-
-  int _depth = 0;
-  /// The depth of this node in the tree.
-  ///
-  /// The depth of nodes in a tree monotonically increases as you traverse down
-  /// the trees.
-  int get depth => _depth;
-
-  /// Call only from overrides of [redepthChildren]
-  void redepthChild(AbstractNode child) {
-    assert(child._attached == _attached);
-    if (child._depth <= _depth) {
-      child._depth = _depth + 1;
-      child.redepthChildren();
-    }
-  }
-
-  /// Override this function in subclasses with child nodes to call
-  /// redepthChild(child) for each child. Do not call directly.
-  void redepthChildren() { }
-
-  bool _attached = false;
-  /// Whether this node is in a tree whose root is attached to something.
-  bool get attached => _attached;
-
-  /// Mark this node as attached.
-  ///
-  /// Typically called only from the parent's attach(), and to mark the root of
-  /// a tree attached.
-  void attach() {
-    _attached = true;
-  }
-
-  /// Mark this node as detached.
-  ///
-  /// Typically called only from the parent's detach(), and to mark the root of
-  /// a tree detached.
-  void detach() {
-    _attached = false;
-  }
-
-  AbstractNode _parent;
-  /// The parent of this node in the tree.
-  AbstractNode get parent => _parent;
-
-  /// Subclasses should call this function when they acquire a new child.
-  void adoptChild(AbstractNode child) {
-    assert(child != null);
-    assert(child._parent == null);
-    child._parent = this;
-    if (attached)
-      child.attach();
-    redepthChild(child);
-  }
-
-  /// Subclasses should call this function when they lose a child.
-  void dropChild(AbstractNode child) {
-    assert(child != null);
-    assert(child._parent == this);
-    assert(child.attached == attached);
-    child._parent = null;
-    if (attached)
-      child.detach();
-  }
-
-}
diff --git a/sky/packages/sky/lib/src/rendering/object.dart b/sky/packages/sky/lib/src/rendering/object.dart
deleted file mode 100644
index e1c7a65..0000000
--- a/sky/packages/sky/lib/src/rendering/object.dart
+++ /dev/null
@@ -1,1462 +0,0 @@
-// Copyright 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 'dart:math' as math;
-import 'dart:ui' as ui;
-
-import 'package:flutter/animation.dart';
-import 'package:flutter/gestures.dart';
-import 'package:vector_math/vector_math_64.dart';
-
-import 'debug.dart';
-import 'hit_test.dart';
-import 'layer.dart';
-import 'node.dart';
-
-export 'layer.dart';
-export 'hit_test.dart';
-
-typedef ui.Shader ShaderCallback(Rect bounds);
-
-/// Base class for data associated with a [RenderObject] by its parent
-///
-/// Some render objects wish to store data on their children, such as their
-/// input parameters to the parent's layout algorithm or their position relative
-/// to other children.
-class ParentData {
-  /// Called when the RenderObject is removed from the tree.
-  void detach() { }
-
-  /// Override this function in subclasses to merge in data from other instance
-  /// into this instance.
-  void merge(ParentData other) {
-    assert(other.runtimeType == this.runtimeType);
-  }
-
-  String toString() => '<none>';
-}
-
-/// Obsolete class that will be removed eventually
-class PaintingCanvas extends Canvas {
-  PaintingCanvas(ui.PictureRecorder recorder, Rect bounds) : super(recorder, bounds);
-  // TODO(ianh): Just use ui.Canvas everywhere instead
-}
-
-/// A place to paint
-///
-/// Rather than holding a canvas directly, render objects paint using a painting
-/// context. The painting context has a canvas, which receives the
-/// individual draw operations, and also has functions for painting child
-/// render objects.
-///
-/// When painting a child render object, the canvas held by the painting context
-/// can change because the draw operations issued before and after painting the
-/// child might be recorded in separate compositing layers. For this reason, do
-/// not hold a reference to the canvas across operations that might paint
-/// child render objects.
-class PaintingContext {
-  /// Construct a painting context at a given offset with the given bounds
-  PaintingContext.withOffset(Offset offset, Rect paintBounds) {
-    _containerLayer = new ContainerLayer(offset: offset);
-    _startRecording(paintBounds);
-  }
-
-  /// Construct a painting context for painting into the given layer with the given bounds
-  PaintingContext.withLayer(ContainerLayer containerLayer, Rect paintBounds) {
-    _containerLayer = containerLayer;
-    _startRecording(paintBounds);
-  }
-
-  /// A backdoor for testing that lets the test set a specific canvas
-  PaintingContext.forTesting(this._canvas);
-
-  ContainerLayer _containerLayer;
-  /// The layer contain all the composting layers that will be used for this context
-  ContainerLayer get containerLayer => _containerLayer;
-
-  PictureLayer _currentLayer;
-  ui.PictureRecorder _recorder;
-  PaintingCanvas _canvas;
-  /// The canvas on which to paint
-  ///
-  /// This getter can return a different canvas object after painting child
-  /// render objects using this canvas because draw operations before and after
-  /// a child might need to be recorded in separate compositing layers.
-  PaintingCanvas get canvas => _canvas;
-
-  void _startRecording(Rect paintBounds) {
-    assert(_currentLayer == null);
-    assert(_recorder == null);
-    assert(_canvas == null);
-    _currentLayer = new PictureLayer(paintBounds: paintBounds);
-    _recorder = new ui.PictureRecorder();
-    _canvas = new PaintingCanvas(_recorder, paintBounds);
-    _containerLayer.append(_currentLayer);
-  }
-
-  /// Stop recording draw operations into the current compositing layer
-  void endRecording() {
-    assert(_currentLayer != null);
-    assert(_recorder != null);
-    assert(_canvas != null);
-    _currentLayer.picture = _recorder.endRecording();
-    _currentLayer = null;
-    _recorder = null;
-    _canvas = null;
-  }
-
-  /// Whether the canvas is in a state that permits drawing the given child
-  bool debugCanPaintChild(RenderObject child) {
-    // You need to use layers if you are applying transforms, clips,
-    // or similar, to a child. To do so, use the paintChildWith*()
-    // methods below.
-    // (commented out for now because we haven't ported everything yet)
-    assert(canvas.getSaveCount() == 1 || !child.needsCompositing);
-    return true;
-  }
-
-  /// Paint a child render object at the given position
-  ///
-  /// If the child needs compositing, a new composited layer will be created
-  /// and inserted into the containerLayer. If the child does not require
-  /// compositing, the child will be painted into the current canvas.
-  ///
-  /// Note: After calling this function, the current canvas might change.
-  void paintChild(RenderObject child, Point childPosition) {
-    assert(debugCanPaintChild(child));
-    final Offset childOffset = childPosition.toOffset();
-    if (!child.hasLayer) {
-      insertChild(child, childOffset);
-    } else {
-      compositeChild(child, childOffset: childOffset, parentLayer: _containerLayer);
-    }
-  }
-
-  void paintStatistics(int optionsMask, int rasterizerThreshold, Offset offset, Size size) {
-    StatisticsLayer statsLayer = new StatisticsLayer(
-      offset: offset,
-      paintBounds: new Rect.fromLTWH(0.0, 0.0, size.width, size.height),
-      optionsMask : optionsMask,
-      rasterizerThreshold : rasterizerThreshold
-    );
-    _containerLayer.append(statsLayer);
-  }
-
-  // Below we have various variants of the paintChild() method, which
-  // do additional work, such as clipping or transforming, at the same
-  // time as painting the children.
-
-  // If none of the descendants require compositing, then these don't
-  // need to use a new layer, because at no point will any of the
-  // children introduce a new layer of their own. In that case, we
-  // just use regular canvas commands to do the work.
-
-  // If at least one of the descendants requires compositing, though,
-  // we introduce a new layer to do the work, so that when the
-  // children are split into a new layer, the work (e.g. clip) is not
-  // lost, as it would if we didn't introduce a new layer.
-
-  static final Paint _disableAntialias = new Paint()..isAntiAlias = false;
-
-  /// Paint a child with a rectangular clip
-  ///
-  /// If the child needs compositing, the clip will be applied by a
-  /// compositing layer. Otherwise, the clip will be applied by the canvas.
-  ///
-  /// Note: clipRect is in the parent's coordinate space
-  void paintChildWithClipRect(RenderObject child, Point childPosition, Rect clipRect) {
-    assert(debugCanPaintChild(child));
-    final Offset childOffset = childPosition.toOffset();
-    if (!child.needsCompositing) {
-      canvas.save();
-      canvas.clipRect(clipRect);
-      insertChild(child, childOffset);
-      canvas.restore();
-    } else {
-      ClipRectLayer clipLayer = new ClipRectLayer(offset: childOffset, clipRect: clipRect);
-      _containerLayer.append(clipLayer);
-      compositeChild(child, parentLayer: clipLayer);
-    }
-  }
-
-  /// Paint a child with a rounded-rectangular clip
-  ///
-  /// If the child needs compositing, the clip will be applied by a
-  /// compositing layer. Otherwise, the clip will be applied by the canvas.
-  ///
-  /// Note: clipRRect is in the parent's coordinate space
-  void paintChildWithClipRRect(RenderObject child, Point childPosition, Rect bounds, ui.RRect clipRRect) {
-    assert(debugCanPaintChild(child));
-    final Offset childOffset = childPosition.toOffset();
-    if (!child.needsCompositing) {
-      canvas.saveLayer(bounds, _disableAntialias);
-      canvas.clipRRect(clipRRect);
-      insertChild(child, childOffset);
-      canvas.restore();
-    } else {
-      ClipRRectLayer clipLayer = new ClipRRectLayer(offset: childOffset, bounds: bounds, clipRRect: clipRRect);
-      _containerLayer.append(clipLayer);
-      compositeChild(child, parentLayer: clipLayer);
-    }
-  }
-
-  /// Paint a child with a clip path
-  ///
-  /// If the child needs compositing, the clip will be applied by a
-  /// compositing layer. Otherwise, the clip will be applied by the canvas.
-  ///
-  /// Note: bounds and clipPath are in the parent's coordinate space
-  void paintChildWithClipPath(RenderObject child, Point childPosition, Rect bounds, Path clipPath) {
-    assert(debugCanPaintChild(child));
-    final Offset childOffset = childPosition.toOffset();
-    if (!child.needsCompositing) {
-      canvas.saveLayer(bounds, _disableAntialias);
-      canvas.clipPath(clipPath);
-      canvas.translate(childOffset.dx, childOffset.dy);
-      insertChild(child, Offset.zero);
-      canvas.restore();
-    } else {
-      ClipPathLayer clipLayer = new ClipPathLayer(offset: childOffset, bounds: bounds, clipPath: clipPath);
-      _containerLayer.append(clipLayer);
-      compositeChild(child, parentLayer: clipLayer);
-    }
-  }
-
-  /// Paint a child with a transform
-  ///
-  /// If the child needs compositing, the transform will be applied by a
-  /// compositing layer. Otherwise, the transform will be applied by the canvas.
-  void paintChildWithTransform(RenderObject child, Point childPosition, Matrix4 transform) {
-    assert(debugCanPaintChild(child));
-    final Offset childOffset = childPosition.toOffset();
-    if (!child.needsCompositing) {
-      canvas.save();
-      canvas.translate(childOffset.dx, childOffset.dy);
-      canvas.concat(transform.storage);
-      insertChild(child, Offset.zero);
-      canvas.restore();
-    } else {
-      TransformLayer transformLayer = new TransformLayer(offset: childOffset, transform: transform);
-      _containerLayer.append(transformLayer);
-      compositeChild(child, parentLayer: transformLayer);
-    }
-  }
-
-  static Paint _getPaintForAlpha(int alpha) {
-    return new Paint()
-      ..color = new Color.fromARGB(alpha, 0, 0, 0)
-      ..transferMode = TransferMode.srcOver
-      ..isAntiAlias = false;
-  }
-
-  /// Paint a child with an opacity
-  ///
-  /// If the child needs compositing, the blending operation will be applied by
-  /// a compositing layer. Otherwise, the blending operation will be applied by
-  /// the canvas.
-  void paintChildWithOpacity(RenderObject child,
-                             Point childPosition,
-                             Rect bounds,
-                             int alpha) {
-    assert(debugCanPaintChild(child));
-    final Offset childOffset = childPosition.toOffset();
-    if (!child.needsCompositing) {
-      canvas.saveLayer(bounds, _getPaintForAlpha(alpha));
-      canvas.translate(childOffset.dx, childOffset.dy);
-      insertChild(child, Offset.zero);
-      canvas.restore();
-    } else {
-      OpacityLayer paintLayer = new OpacityLayer(
-          offset: childOffset,
-          bounds: bounds,
-          alpha: alpha);
-      _containerLayer.append(paintLayer);
-      compositeChild(child, parentLayer: paintLayer);
-    }
-  }
-
-  static Paint _getPaintForShaderMask(Rect bounds,
-                                      ShaderCallback shaderCallback,
-                                      TransferMode transferMode) {
-    return new Paint()
-     ..transferMode = transferMode
-     ..shader = shaderCallback(bounds);
-  }
-
-  void paintChildWithShaderMask(RenderObject child,
-                                Point childPosition,
-                                Rect bounds,
-                                ShaderCallback shaderCallback,
-                                TransferMode transferMode) {
-    assert(debugCanPaintChild(child));
-    final Offset childOffset = childPosition.toOffset();
-    if (!child.needsCompositing) {
-      canvas.saveLayer(bounds, new Paint());
-      canvas.translate(childOffset.dx, childOffset.dy);
-      insertChild(child, Offset.zero);
-      Paint shaderPaint = _getPaintForShaderMask(bounds, shaderCallback, transferMode);
-      canvas.drawRect(Offset.zero & new Size(bounds.width, bounds.height), shaderPaint);
-      canvas.restore();
-    } else {
-      // TODO(hansmuller) support compositing ShaderMasks
-      assert('Support for compositing ShaderMasks is TBD' is String);
-    }
-  }
-
-  /// Instructs the child to draw itself onto this context at the given offset
-  ///
-  /// Do not call directly. This function is visible so that it can be
-  /// overridden in tests.
-  void insertChild(RenderObject child, Offset offset) {
-    child._paintWithContext(this, offset);
-  }
-
-  /// Instructs the child to paint itself into a new composited layer using this context
-  ///
-  /// Do not call directly. This function is visible so that it can be
-  /// overridden in tests.
-  void compositeChild(RenderObject child, { Offset childOffset: Offset.zero, ContainerLayer parentLayer }) {
-    // This ends the current layer and starts a new layer for the
-    // remainder of our rendering. It also creates a new layer for the
-    // child, and inserts that layer into the given parentLayer, which
-    // must either be our current layer's parent layer, or at least
-    // must have our current layer's parent layer as an ancestor.
-    final PictureLayer originalLayer = _currentLayer;
-    assert(() {
-      assert(parentLayer != null);
-      assert(originalLayer != null);
-      assert(originalLayer.parent != null);
-      ContainerLayer ancestor = parentLayer;
-      while (ancestor != null && ancestor != originalLayer.parent)
-        ancestor = ancestor.parent;
-      assert(ancestor == originalLayer.parent);
-      assert(originalLayer.parent == _containerLayer);
-      return true;
-    });
-
-    // End our current layer.
-    endRecording();
-
-    // Create a layer for our child, and paint the child into it.
-    if (child.needsPaint || !child.hasLayer) {
-      PaintingContext newContext = new PaintingContext.withOffset(childOffset, child.paintBounds);
-      child._layer = newContext.containerLayer;
-      child._paintWithContext(newContext, Offset.zero);
-      newContext.endRecording();
-    } else {
-      assert(child._layer != null);
-      child._layer.detach();
-      child._layer.offset = childOffset;
-    }
-    parentLayer.append(child._layer);
-
-    // Start a new layer for anything that remains of our own paint.
-    _startRecording(originalLayer.paintBounds);
-  }
-
-}
-
-/// An encapsulation of a renderer and a paint() method.
-///
-/// A renderer may allow its paint() method to be augmented or redefined by
-/// providing a Painter. See for example overlayPainter in BlockViewport.
-abstract class Painter {
-  RenderObject get renderObject => _renderObject;
-  RenderObject _renderObject;
-
-  void attach(RenderObject renderObject) {
-    assert(_renderObject == null);
-    _renderObject = renderObject;
-  }
-
-  void detach() {
-    assert(_renderObject != null);
-    _renderObject = null;
-  }
-
-  void paint(PaintingContext context, Offset offset);
-}
-
-/// An abstract set of layout constraints
-///
-/// Concrete layout models (such as box) will create concrete subclasses to
-/// communicate layout constraints between parents and children.
-abstract class Constraints {
-  const Constraints();
-
-  /// Whether there is exactly one size possible given these constraints
-  bool get isTight;
-}
-
-typedef void RenderObjectVisitor(RenderObject child);
-typedef void LayoutCallback(Constraints constraints);
-typedef double ExtentCallback(Constraints constraints);
-
-typedef void RenderingExceptionHandler(RenderObject source, String method, dynamic exception, StackTrace stack);
-/// This callback is invoked whenever an exception is caught by the rendering
-/// system. The 'source' argument is the [RenderObject] object that caught the
-/// exception. The 'method' argument is the method in which the exception
-/// occurred; it will be one of 'performResize', 'performLayout, or 'paint'. The
-/// 'exception' argument contains the object that was thrown, and the 'stack'
-/// argument contains the stack trace. The callback is invoked after the
-/// information is printed to the console, and could be used to print additional
-/// information, such as from [debugDumpRenderTree()].
-RenderingExceptionHandler debugRenderingExceptionHandler;
-
-/// An object in the render tree
-///
-/// Render objects have a reference to their parent but do not commit to a model
-/// for their children.
-abstract class RenderObject extends AbstractNode implements HitTestTarget {
-
-  // LAYOUT
-
-  /// Data for use by the parent render object
-  ///
-  /// The parent data is used by the render object that lays out this object
-  /// (typically this object's parent in the render tree) to store information
-  /// relevant to itself and to any other nodes who happen to know exactly what
-  /// the data means. The parent data is opaque to the child.
-  ///
-  /// - The parent data object must inherit from [ParentData] (despite being
-  ///   typed as `dynamic`).
-  /// - The parent data field must not be directly set, except by calling
-  ///   [setupParentData] on the parent node.
-  /// - The parent data can be set before the child is added to the parent, by
-  ///   calling [setupParentData] on the future parent node.
-  /// - The conventions for using the parent data depend on the layout protocol
-  ///   used between the parent and child. For example, in box layout, the
-  ///   parent data is completely opaque but in sector layout the child is
-  ///   permitted to read some fields of the parent data.
-  ParentData parentData;
-
-  /// Override to setup parent data correctly for your children
-  ///
-  /// You can call this function to set up the parent data for child before the
-  /// child is added to the parent's child list.
-  void setupParentData(RenderObject child) {
-    assert(debugCanPerformMutations);
-    if (child.parentData is! ParentData)
-      child.parentData = new ParentData();
-  }
-
-  /// Called by subclases when they decide a render object is a child
-  ///
-  /// Only for use by subclasses when changing their child lists. Calling this
-  /// in other cases will lead to an inconsistent tree and probably cause crashes.
-  void adoptChild(RenderObject child) {
-    assert(debugCanPerformMutations);
-    assert(child != null);
-    setupParentData(child);
-    super.adoptChild(child);
-    markNeedsLayout();
-    _markNeedsCompositingBitsUpdate();
-  }
-
-  /// Called by subclases when they decide a render object is no longer a child
-  ///
-  /// Only for use by subclasses when changing their child lists. Calling this
-  /// in other cases will lead to an inconsistent tree and probably cause crashes.
-  void dropChild(RenderObject child) {
-    assert(debugCanPerformMutations);
-    assert(child != null);
-    assert(child.parentData != null);
-    child._cleanRelayoutSubtreeRoot();
-    child.parentData.detach();
-    child.parentData = null;
-    super.dropChild(child);
-    markNeedsLayout();
-    _markNeedsCompositingBitsUpdate();
-  }
-
-  /// Calls visitor for each immediate child of this render object
-  ///
-  /// Override in subclasses with children and call the visitor for each child
-  void visitChildren(RenderObjectVisitor visitor) { }
-
-  dynamic debugOwner = '';
-  void _debugReportException(String method, dynamic exception, StackTrace stack) {
-    debugPrint('-- EXCEPTION --');
-    debugPrint('The following exception was raised during $method():');
-    debugPrint('$exception');
-    debugPrint('Stack trace:');
-    debugPrint('$stack');
-    debugPrint('The following RenderObject was being processed when the exception was fired:\n${this}');
-    if (debugOwner != '')
-      debugPrint('That RenderObject had the following owner:\n$debugOwner');
-    if (debugRenderingExceptionHandler != null)
-      debugRenderingExceptionHandler(this, method, exception, stack);
-  }
-
-  static bool _debugDoingLayout = false;
-  static bool get debugDoingLayout => _debugDoingLayout;
-  bool _debugDoingThisResize = false;
-  bool get debugDoingThisResize => _debugDoingThisResize;
-  bool _debugDoingThisLayout = false;
-  bool get debugDoingThisLayout => _debugDoingThisLayout;
-  static RenderObject _debugActiveLayout = null;
-  static RenderObject get debugActiveLayout => _debugActiveLayout;
-  bool _debugMutationsLocked = false;
-  bool _debugCanParentUseSize;
-  bool get debugCanParentUseSize => _debugCanParentUseSize;
-  bool get debugCanPerformMutations {
-    RenderObject node = this;
-    while (true) {
-      if (node._doingThisLayoutWithCallback)
-        return true;
-      if (node._debugMutationsLocked)
-        return false;
-      if (node.parent is! RenderObject)
-        return true;
-      node = node.parent;
-    }
-  }
-
-  static List<RenderObject> _nodesNeedingLayout = new List<RenderObject>();
-  bool _needsLayout = true;
-  /// Whether this render object's layout information is dirty
-  bool get needsLayout => _needsLayout;
-  RenderObject _relayoutSubtreeRoot;
-  bool _doingThisLayoutWithCallback = false;
-  Constraints _constraints;
-  /// The layout constraints most recently supplied by the parent
-  Constraints get constraints => _constraints;
-  /// Override this function in a subclass to verify that your state matches the constraints object
-  bool debugDoesMeetConstraints();
-  bool debugAncestorsAlreadyMarkedNeedsLayout() {
-    if (_relayoutSubtreeRoot == null)
-      return true; // we haven't yet done layout even once, so there's nothing for us to do
-    RenderObject node = this;
-    while (node != _relayoutSubtreeRoot) {
-      assert(node._relayoutSubtreeRoot == _relayoutSubtreeRoot);
-      assert(node.parent != null);
-      node = node.parent as RenderObject;
-      if ((!node._needsLayout) && (!node._debugDoingThisLayout))
-        return false;
-    }
-    assert(node._relayoutSubtreeRoot == node);
-    return true;
-  }
-
-  /// Mark this render object's layout information as dirty
-  ///
-  /// Rather than eagerly updating layout information in response to writes into
-  /// this render object, we instead mark the layout information as dirty, which
-  /// schedules a visual update. As part of the visual update, the rendering
-  /// pipeline will update this render object's layout information.
-  ///
-  /// This mechanism batches the layout work so that multiple sequential writes
-  /// are coalesced, removing redundant computation.
-  ///
-  /// Causes [needsLayout] to return true for this render object. If the parent
-  /// render object indicated that it uses the size of this render object in
-  /// computing its layout information, this function will also mark the parent
-  /// as needing layout.
-  void markNeedsLayout() {
-    assert(debugCanPerformMutations);
-    if (_needsLayout) {
-      assert(debugAncestorsAlreadyMarkedNeedsLayout());
-      return;
-    }
-    _needsLayout = true;
-    assert(_relayoutSubtreeRoot != null);
-    if (_relayoutSubtreeRoot != this) {
-      final RenderObject parent = this.parent;
-      if (!_doingThisLayoutWithCallback) {
-        parent.markNeedsLayout();
-      } else {
-        assert(parent._debugDoingThisLayout);
-      }
-      assert(parent == this.parent);
-    } else {
-      _nodesNeedingLayout.add(this);
-      scheduler.ensureVisualUpdate();
-    }
-  }
-
-  void _cleanRelayoutSubtreeRoot() {
-    if (_relayoutSubtreeRoot != this) {
-      _relayoutSubtreeRoot = null;
-      _needsLayout = true;
-      visitChildren((RenderObject child) {
-        child._cleanRelayoutSubtreeRoot();
-      });
-    }
-  }
-
-  /// Bootstrap the rendering pipeline by scheduling the very first layout
-  ///
-  /// Requires this render object to be attached and that this render object
-  /// is the root of the render tree.
-  ///
-  /// See [RenderView] for an example of how this function is used.
-  void scheduleInitialLayout() {
-    assert(attached);
-    assert(parent is! RenderObject);
-    assert(!_debugDoingLayout);
-    assert(_relayoutSubtreeRoot == null);
-    _relayoutSubtreeRoot = this;
-    assert(() {
-      _debugCanParentUseSize = false;
-      return true;
-    });
-    _nodesNeedingLayout.add(this);
-  }
-
-  /// Update the layout information for all dirty render objects
-  ///
-  /// This function is one of the core stages of the rendering pipeline. Layout
-  /// information is cleaned prior to painting so that render objects will
-  /// appear on screen in their up-to-date locations.
-  ///
-  /// See [FlutterBinding] for an example of how this function is used.
-  static void flushLayout() {
-    ui.tracing.begin('RenderObject.flushLayout');
-    _debugDoingLayout = true;
-    try {
-      // TODO(ianh): assert that we're not allowing previously dirty nodes to redirty themeselves
-      while(_nodesNeedingLayout.isNotEmpty) {
-        List<RenderObject> dirtyNodes = _nodesNeedingLayout;
-        _nodesNeedingLayout = new List<RenderObject>();
-        dirtyNodes..sort((RenderObject a, RenderObject b) => a.depth - b.depth)..forEach((RenderObject node) {
-          if (node._needsLayout && node.attached)
-            node._layoutWithoutResize();
-        });
-      }
-    } finally {
-      _debugDoingLayout = false;
-      ui.tracing.end('RenderObject.flushLayout');
-    }
-  }
-  void _layoutWithoutResize() {
-    assert(_relayoutSubtreeRoot == this);
-    RenderObject debugPreviousActiveLayout;
-    assert(!_debugMutationsLocked);
-    assert(!_doingThisLayoutWithCallback);
-    assert(_debugCanParentUseSize != null);
-    assert(() {
-      _debugMutationsLocked = true;
-      _debugDoingThisLayout = true;
-      debugPreviousActiveLayout = _debugActiveLayout;
-      _debugActiveLayout = this;
-      return true;
-    });
-    try {
-      performLayout();
-    } catch (e, stack) {
-      _debugReportException('performLayout', e, stack);
-    }
-    assert(() {
-      _debugActiveLayout = debugPreviousActiveLayout;
-      _debugDoingThisLayout = false;
-      _debugMutationsLocked = false;
-      return true;
-    });
-    _needsLayout = false;
-    markNeedsPaint();
-  }
-
-  /// Compute the layout for this render object
-  ///
-  /// This function is the main entry point for parents to ask their children to
-  /// update their layout information. The parent passes a constraints object,
-  /// which informs the child as which layouts are permissible. The child is
-  /// required to obey the given constraints.
-  ///
-  /// If the parent reads information computed during the child's layout, the
-  /// parent must pass true for parentUsesSize. In that case, the parent will be
-  /// marked as needing layout whenever the child is marked as needing layout
-  /// because the parent's layout information depends on the child's layout
-  /// information. If the parent uses the default value (false) for
-  /// parentUsesSize, the child can change its layout information (subject to
-  /// the given constraints) without informing the parent.
-  ///
-  /// Subclasses should not override layout directly. Instead, they should
-  /// override performResize and/or performLayout.
-  ///
-  /// The parent's performLayout method should call the layout of all its
-  /// children unconditionally. It is the layout functions's responsibility (as
-  /// implemented here) to return early if the child does not need to do any
-  /// work to update its layout information.
-  void layout(Constraints constraints, { bool parentUsesSize: false }) {
-    assert(!_debugDoingThisResize);
-    assert(!_debugDoingThisLayout);
-    final RenderObject parent = this.parent;
-    RenderObject relayoutSubtreeRoot;
-    if (!parentUsesSize || sizedByParent || constraints.isTight || parent is! RenderObject)
-      relayoutSubtreeRoot = this;
-    else
-      relayoutSubtreeRoot = parent._relayoutSubtreeRoot;
-    assert(parent == this.parent);
-    assert(() {
-      _debugCanParentUseSize = parentUsesSize;
-      return true;
-    });
-    if (!needsLayout && constraints == _constraints && relayoutSubtreeRoot == _relayoutSubtreeRoot) {
-      assert(() {
-        // in case parentUsesSize changed since the last invocation, set size
-        // to itself, so it has the right internal debug values.
-        _debugDoingThisResize = sizedByParent;
-        _debugDoingThisLayout = !sizedByParent;
-        RenderObject debugPreviousActiveLayout = _debugActiveLayout;
-        _debugActiveLayout = this;
-        debugResetSize();
-        _debugActiveLayout = debugPreviousActiveLayout;
-        _debugDoingThisLayout = false;
-        _debugDoingThisResize = false;
-        return true;
-      });
-      return;
-    }
-    _constraints = constraints;
-    _relayoutSubtreeRoot = relayoutSubtreeRoot;
-    assert(!_debugMutationsLocked);
-    assert(!_doingThisLayoutWithCallback);
-    assert(() {
-      _debugMutationsLocked = true;
-      return true;
-    });
-    if (sizedByParent) {
-      assert(() { _debugDoingThisResize = true; return true; });
-      try {
-        performResize();
-        assert(debugDoesMeetConstraints());
-      } catch (e, stack) {
-        _debugReportException('performResize', e, stack);
-      }
-      assert(() { _debugDoingThisResize = false; return true; });
-    }
-    RenderObject debugPreviousActiveLayout;
-    assert(() {
-      _debugDoingThisLayout = true;
-      debugPreviousActiveLayout = _debugActiveLayout;
-      _debugActiveLayout = this;
-      return true;
-    });
-    try {
-      performLayout();
-      assert(debugDoesMeetConstraints());
-    } catch (e, stack) {
-      _debugReportException('performLayout', e, stack);
-    }
-    assert(() {
-      _debugActiveLayout = debugPreviousActiveLayout;
-      _debugDoingThisLayout = false;
-      _debugMutationsLocked = false;
-      return true;
-    });
-    _needsLayout = false;
-    markNeedsPaint();
-    assert(parent == this.parent);
-  }
-
-  /// If a subclass has a "size" (the state controlled by "parentUsesSize",
-  /// whatever it is in the subclass, e.g. the actual "size" property of
-  /// RenderBox), and the subclass verifies that in checked mode this "size"
-  /// property isn't used when debugCanParentUseSize isn't set, then that
-  /// subclass should override debugResetSize() to reapply the current values of
-  /// debugCanParentUseSize to that state.
-  void debugResetSize() { }
-
-  /// Whether the constraints are the only input to the sizing algorithm (in
-  /// particular, child nodes have no impact)
-  ///
-  /// Returning false is always correct, but returning true can be more
-  /// efficient when computing the size of this render object because we don't
-  /// need to recompute the size if the constraints don't change.
-  bool get sizedByParent => false;
-
-  /// Updates the render objects size using only the constraints
-  ///
-  /// Do not call this function directly: call [layout] instead. This function
-  /// is called by [layout] when there is actually work to be done by this
-  /// render object during layout. The layout constraints provided by your
-  /// parent are available via the [constraints] getter.
-  ///
-  /// Subclasses that set [sizedByParent] to true should override this function
-  /// to compute their size.
-  ///
-  /// Note: This function is called only if [sizedByParent] is true.
-  void performResize();
-
-  /// Do the work of computing the layout for this render object
-  ///
-  /// Do not call this function directly: call [layout] instead. This function
-  /// is called by [layout] when there is actually work to be done by this
-  /// render object during layout. The layout constraints provided by your
-  /// parent are available via the [constraints] getter.
-  ///
-  /// If [sizedByParent] is true, then this function should not actually change
-  /// the dimensions of this render object. Instead, that work should be done by
-  /// [performResize]. If [sizedByParent] is false, then this function should
-  /// both change the dimensions of this render object and instruct its children
-  /// to layout.
-  ///
-  /// In implementing this function, you must call [layout] on each of your
-  /// children, passing true for parentUsesSize if your layout information is
-  /// dependent on your child's layout information. Passing true for
-  /// parentUsesSize ensures that this render object will undergo layout if the
-  /// child undergoes layout. Otherwise, the child can changes its layout
-  /// information without informing this render object.
-  void performLayout();
-
-  /// Allows this render object to mutation its child list during layout and
-  /// invokes callback
-  void invokeLayoutCallback(LayoutCallback callback) {
-    assert(_debugMutationsLocked);
-    assert(_debugDoingThisLayout);
-    assert(!_doingThisLayoutWithCallback);
-    _doingThisLayoutWithCallback = true;
-    try {
-      callback(constraints);
-    } finally {
-      _doingThisLayoutWithCallback = false;
-    }
-  }
-
-  /// Rotate this render object (not yet implemented)
-  void rotate({
-    int oldAngle, // 0..3
-    int newAngle, // 0..3
-    Duration time
-  }) { }
-
-  // when the parent has rotated (e.g. when the screen has been turned
-  // 90 degrees), immediately prior to layout() being called for the
-  // new dimensions, rotate() is called with the old and new angles.
-  // The next time paint() is called, the coordinate space will have
-  // been rotated N quarter-turns clockwise, where:
-  //    N = newAngle-oldAngle
-  // ...but the rendering is expected to remain the same, pixel for
-  // pixel, on the output device. Then, the layout() method or
-  // equivalent will be invoked.
-
-
-  // PAINTING
-
-  static bool _debugDoingPaint = false;
-  static bool get debugDoingPaint => _debugDoingPaint;
-  static void set debugDoingPaint(bool value) {
-    _debugDoingPaint = value;
-  }
-  bool _debugDoingThisPaint = false;
-  bool get debugDoingThisPaint => _debugDoingThisPaint;
-  static RenderObject _debugActivePaint = null;
-  static RenderObject get debugActivePaint => _debugActivePaint;
-
-  static List<RenderObject> _nodesNeedingPaint = new List<RenderObject>();
-
-  /// Whether this render object paints using a composited layer
-  ///
-  /// Override this in subclasses to indicate that instances of your class need
-  /// to have their own compositing layer. For example, videos should return
-  /// true if they use hardware decoders.
-  ///
-  /// Note: This getter must not change value over the lifetime of this object.
-  bool get hasLayer => false;
-
-  ContainerLayer _layer;
-  /// The compositing layer that this render object uses to paint
-  ///
-  /// Call only when [hasLayer] is true.
-  ContainerLayer get layer {
-    assert(hasLayer);
-    assert(!_needsPaint);
-    return _layer;
-  }
-
-  bool _needsCompositingBitsUpdate = true;
-  /// Mark the compositing state for this render object as dirty
-  ///
-  /// When the subtree is mutated, we need to recompute our [needsCompositing]
-  /// bit, and our ancestors need to do the same (in case ours changed).
-  /// Therefore, [adoptChild] and [dropChild] call
-  /// [markNeedsCompositingBitsUpdate].
-  void _markNeedsCompositingBitsUpdate() {
-    if (_needsCompositingBitsUpdate)
-      return;
-    _needsCompositingBitsUpdate = true;
-    final AbstractNode parent = this.parent;
-    if (parent is RenderObject)
-      parent._markNeedsCompositingBitsUpdate();
-    assert(parent == this.parent);
-  }
-  bool _needsCompositing = false;
-  /// Whether we or one of our descendants has a compositing layer
-  ///
-  /// Only legal to call after [flushLayout] and [updateCompositingBits] have
-  /// been called.
-  bool get needsCompositing {
-    assert(!_needsCompositingBitsUpdate); // make sure we don't use this bit when it is dirty
-    return _needsCompositing;
-  }
-
-  /// Updates the [needsCompositing] bits
-  ///
-  /// Called as part of the rendering pipeline after [flushLayout] and before
-  /// [flushPaint].
-  void updateCompositingBits() {
-    if (!_needsCompositingBitsUpdate)
-      return;
-    bool didHaveCompositedDescendant = _needsCompositing;
-    visitChildren((RenderObject child) {
-      child.updateCompositingBits();
-      if (child.needsCompositing)
-        _needsCompositing = true;
-    });
-    if (hasLayer)
-      _needsCompositing = true;
-    if (didHaveCompositedDescendant != _needsCompositing)
-      markNeedsPaint();
-    _needsCompositingBitsUpdate = false;
-  }
-
-  bool _needsPaint = true;
-  /// The visual appearance of this render object has changed since it last painted
-  bool get needsPaint => _needsPaint;
-
-  /// Mark this render object as having changed its visual appearance
-  ///
-  /// Rather than eagerly updating this render object's display list
-  /// in response to writes, we instead mark the the render object as needing to
-  /// paint, which schedules a visual update. As part of the visual update, the
-  /// rendering pipeline will give this render object an opportunity to update
-  /// its display list.
-  ///
-  /// This mechanism batches the painting work so that multiple sequential
-  /// writes are coalesced, removing redundant computation.
-  void markNeedsPaint() {
-    assert(!debugDoingPaint);
-    if (!attached) return; // Don't try painting things that aren't in the hierarchy
-    if (_needsPaint) return;
-    if (hasLayer) {
-      // If we always have our own layer, then we can just repaint
-      // ourselves without involving any other nodes.
-      assert(_layer != null);
-      _needsPaint = true;
-      _nodesNeedingPaint.add(this);
-      scheduler.ensureVisualUpdate();
-    } else if (parent is RenderObject) {
-      // We don't have our own layer; one of our ancestors will take
-      // care of updating the layer we're in and when they do that
-      // we'll get our paint() method called.
-      assert(_layer == null);
-      final RenderObject parent = this.parent;
-      parent.markNeedsPaint();
-      assert(parent == this.parent);
-    } else {
-      // If we're the root of the render tree (probably a RenderView),
-      // then we have to paint ourselves, since nobody else can paint
-      // us. We don't add ourselves to _nodesNeedingPaint in this
-      // case, because the root is always told to paint regardless.
-      _needsPaint = true;
-      scheduler.ensureVisualUpdate();
-    }
-  }
-
-  /// Update the display lists for all render objects
-  ///
-  /// This function is one of the core stages of the rendering pipeline.
-  /// Painting occurs after layout and before the scene is recomposited so that
-  /// scene is composited with up-to-date display lists for every render object.
-  ///
-  /// See [FlutterBinding] for an example of how this function is used.
-  static void flushPaint() {
-    ui.tracing.begin('RenderObject.flushPaint');
-    _debugDoingPaint = true;
-    try {
-      List<RenderObject> dirtyNodes = _nodesNeedingPaint;
-      _nodesNeedingPaint = new List<RenderObject>();
-      // Sort the dirty nodes in reverse order (deepest first).
-      for (RenderObject node in dirtyNodes..sort((RenderObject a, RenderObject b) => b.depth - a.depth)) {
-        assert(node._needsPaint);
-        if (node.attached)
-          node._repaint();
-      };
-      assert(_nodesNeedingPaint.length == 0);
-    } finally {
-      _debugDoingPaint = false;
-      ui.tracing.end('RenderObject.flushPaint');
-    }
-  }
-
-  /// Bootstrap the rendering pipeline by scheduling the very first paint
-  ///
-  /// Requires that this render object is attached, is the root of the render
-  /// tree, and has a composited layer.
-  ///
-  /// See [RenderView] for an example of how this function is used.
-  void scheduleInitialPaint(ContainerLayer rootLayer) {
-    assert(attached);
-    assert(parent is! RenderObject);
-    assert(!_debugDoingPaint);
-    assert(hasLayer);
-    assert(_layer == null);
-    _layer = rootLayer;
-    assert(_needsPaint);
-    _nodesNeedingPaint.add(this);
-  }
-  void _repaint() {
-    assert(hasLayer);
-    assert(_layer != null);
-    _layer.removeAllChildren();
-    PaintingContext context = new PaintingContext.withLayer(_layer, paintBounds);
-    _layer = context._containerLayer;
-    _paintWithContext(context, Offset.zero);
-    context.endRecording();
-  }
-  void _paintWithContext(PaintingContext context, Offset offset) {
-    assert(!_debugDoingThisPaint);
-    assert(!_needsLayout);
-    assert(!_needsCompositingBitsUpdate);
-    RenderObject debugLastActivePaint;
-    assert(() {
-      _debugDoingThisPaint = true;
-      debugLastActivePaint = _debugActivePaint;
-      _debugActivePaint = this;
-      if (debugPaintBoundsEnabled) {
-        context.canvas.save();
-        context.canvas.clipRect(paintBounds.shift(offset));
-      }
-      assert(!hasLayer || _layer != null);
-      return true;
-    });
-    _needsPaint = false;
-    try {
-      paint(context, offset);
-      assert(!_needsLayout); // check that the paint() method didn't mark us dirty again
-      assert(!_needsPaint); // check that the paint() method didn't mark us dirty again
-    } catch (e, stack) {
-      _debugReportException('paint', e, stack);
-    }
-    assert(() {
-      debugPaint(context, offset);
-      if (debugPaintBoundsEnabled)
-        context.canvas.restore();
-      _debugActivePaint = debugLastActivePaint;
-      _debugDoingThisPaint = false;
-      return true;
-    });
-  }
-
-  /// The bounds within which this render object will paint
-  ///
-  /// A render object is permitted to paint outside the region it occupies
-  /// during layout but is not permitted to paint outside these paints bounds.
-  /// These paint bounds are used to construct memory-efficient composited
-  /// layers, which means attempting to paint outside these bounds can attempt
-  /// to write to pixels that do not exist in this render object's composited
-  /// layer.
-  Rect get paintBounds;
-
-  /// Override this function to paint debugging information
-  void debugPaint(PaintingContext context, Offset offset) { }
-
-  /// Paint this render object into the given context at the given offset
-  ///
-  /// Subclasses should override this function to provide a visual appearance
-  /// for themselves. The render object's local coordinate system is
-  /// axis-aligned with the coordinate system of the context's canvas and the
-  /// render object's local origin (i.e, x=0 and y=0) is placed at the given
-  /// offset in the context's canvas.
-  ///
-  /// Do not call this function directly. If you wish to paint yourself, call
-  /// [markNeedsPaint] instead to schedule a call to this function. If you wish
-  /// to paint one of your children, call one of the paint child functions on
-  /// the given context, such as [paintChild] or [paintChildWithClipRect].
-  ///
-  /// When painting one of your children (via a paint child function on the
-  /// given context), the current canvas held by the context might change
-  /// because draw operations before and after painting children might need to
-  /// be recorded on separate compositing layers.
-  void paint(PaintingContext context, Offset offset) { }
-
-  /// If this render object applies a transform before painting, apply that
-  /// transform to the given matrix
-  ///
-  /// Used by coordinate conversion functions to translate coordiantes local to
-  /// one render object into coordinates local to another render object.
-  void applyPaintTransform(Matrix4 transform) { }
-
-
-  // EVENTS
-
-  /// Override this function to handle events that hit this render object
-  void handleEvent(InputEvent event, HitTestEntry entry) { }
-
-
-  // HIT TESTING
-
-  // RenderObject subclasses are expected to have a method like the
-  // following (with the signature being whatever passes for coordinates
-  // for this particular class):
-  // bool hitTest(HitTestResult result, { Point position }) {
-  //   // If (x,y) is not inside this node, then return false. (You
-  //   // can assume that the given coordinate is inside your
-  //   // dimensions. You only need to check this if you're an
-  //   // irregular shape, e.g. if you have a hole.)
-  //   // Otherwise:
-  //   // For each child that intersects x,y, in z-order starting from the top,
-  //   // call hitTest() for that child, passing it /result/, and the coordinates
-  //   // converted to the child's coordinate origin, and stop at the first child
-  //   // that returns true.
-  //   // Then, add yourself to /result/, and return true.
-  // }
-  // You must not add yourself to /result/ if you return false.
-
-
-  /// Returns a human understandable name
-  String toString() {
-    String header = '$runtimeType';
-    if (_relayoutSubtreeRoot != null && _relayoutSubtreeRoot != this) {
-      int count = 1;
-      RenderObject target = parent;
-      while (target != null && target != _relayoutSubtreeRoot) {
-        target = target.parent as RenderObject;
-        count += 1;
-      }
-      header += ' relayoutSubtreeRoot=up$count';
-    }
-    if (_needsLayout)
-      header += ' NEEDS-LAYOUT';
-    if (!attached)
-      header += ' DETACHED';
-    return header;
-  }
-
-  /// Returns a description of the tree rooted at this node.
-  /// If the prefix argument is provided, then every line in the output
-  /// will be prefixed by that string.
-  String toStringDeep([String prefixLineOne = '', String prefixOtherLines = '']) {
-    RenderObject debugPreviousActiveLayout = _debugActiveLayout;
-    _debugActiveLayout = null;
-    String result = '$prefixLineOne$this\n';
-    final String childrenDescription = debugDescribeChildren(prefixOtherLines);
-    final String settingsPrefix = childrenDescription != '' ? '$prefixOtherLines \u2502 ' : '$prefixOtherLines   ';
-    List<String> settings = <String>[];
-    debugDescribeSettings(settings);
-    result += settings.map((String setting) => "$settingsPrefix$setting\n").join();
-    if (childrenDescription == '')
-      result += '$prefixOtherLines\n';
-    result += childrenDescription;
-    _debugActiveLayout = debugPreviousActiveLayout;
-    return result;
-  }
-
-  /// Returns a list of strings describing the current node's fields, one field
-  /// per string. Subclasses should override this to have their information
-  /// included in toStringDeep().
-  void debugDescribeSettings(List<String> settings) {
-    settings.add('parentData: $parentData');
-    settings.add('constraints: $constraints');
-    if (debugOwner != '')
-      settings.add('owner: $debugOwner');
-  }
-
-  /// Returns a string describing the current node's descendants. Each line of
-  /// the subtree in the output should be indented by the prefix argument.
-  String debugDescribeChildren(String prefix) => '';
-
-}
-
-/// Obsolete function that will be removed eventually
-double clamp({ double min: 0.0, double value: 0.0, double max: double.INFINITY }) {
-  assert(min != null);
-  assert(value != null);
-  assert(max != null);
-  return math.max(min, math.min(max, value));
-}
-
-
-/// Generic mixin for render objects with one child
-///
-/// Provides a child model for a render object subclass that has a unique child
-abstract class RenderObjectWithChildMixin<ChildType extends RenderObject> implements RenderObject {
-  ChildType _child;
-  /// The render object's unique child
-  ChildType get child => _child;
-  void set child (ChildType value) {
-    if (_child != null)
-      dropChild(_child);
-    _child = value;
-    if (_child != null)
-      adoptChild(_child);
-  }
-  void attach() {
-    super.attach();
-    if (_child != null)
-      _child.attach();
-  }
-  void detach() {
-    super.detach();
-    if (_child != null)
-      _child.detach();
-  }
-  void visitChildren(RenderObjectVisitor visitor) {
-    if (_child != null)
-      visitor(_child);
-  }
-  String debugDescribeChildren(String prefix) {
-    if (child != null)
-      return '$prefix \u2502\n${child.toStringDeep('$prefix \u2514\u2500child: ', '$prefix  ')}';
-    return '';
-  }
-}
-
-/// Parent data to support a doubly-linked list of children
-abstract class ContainerParentDataMixin<ChildType extends RenderObject> implements ParentData {
-  /// The previous sibling in the parent's child list
-  ChildType previousSibling;
-  /// The next sibling in the parent's child list
-  ChildType nextSibling;
-
-  /// Clear the sibling pointers.
-  void detach() {
-    super.detach();
-    if (previousSibling != null) {
-      final ContainerParentDataMixin<ChildType> previousSiblingParentData = previousSibling.parentData;
-      assert(previousSibling != this);
-      assert(previousSiblingParentData.nextSibling == this);
-      previousSiblingParentData.nextSibling = nextSibling;
-    }
-    if (nextSibling != null) {
-      final ContainerParentDataMixin<ChildType> nextSiblingParentData = nextSibling.parentData;
-      assert(nextSibling != this);
-      assert(nextSiblingParentData.previousSibling == this);
-      nextSiblingParentData.previousSibling = previousSibling;
-    }
-    previousSibling = null;
-    nextSibling = null;
-  }
-}
-
-/// Generic mixin for render objects with a list of children
-///
-/// Provides a child model for a render object subclass that has a doubly-linked
-/// list of children.
-abstract class ContainerRenderObjectMixin<ChildType extends RenderObject, ParentDataType extends ContainerParentDataMixin<ChildType>> implements RenderObject {
-
-  bool _debugUltimatePreviousSiblingOf(ChildType child, { ChildType equals }) {
-    ParentDataType childParentData = child.parentData;
-    while (childParentData.previousSibling != null) {
-      assert(childParentData.previousSibling != child);
-      child = childParentData.previousSibling;
-      childParentData = child.parentData;
-    }
-    return child == equals;
-  }
-  bool _debugUltimateNextSiblingOf(ChildType child, { ChildType equals }) {
-    ParentDataType childParentData = child.parentData;
-    while (childParentData.nextSibling != null) {
-      assert(childParentData.nextSibling != child);
-      child = childParentData.nextSibling;
-      childParentData = child.parentData;
-    }
-    return child == equals;
-  }
-
-  int _childCount = 0;
-  /// The number of children
-  int get childCount => _childCount;
-
-  ChildType _firstChild;
-  ChildType _lastChild;
-  void _addToChildList(ChildType child, { ChildType before }) {
-    final ParentDataType childParentData = child.parentData;
-    assert(childParentData.nextSibling == null);
-    assert(childParentData.previousSibling == null);
-    _childCount += 1;
-    assert(_childCount > 0);
-    if (before == null) {
-      // append at the end (_lastChild)
-      childParentData.previousSibling = _lastChild;
-      if (_lastChild != null) {
-        final ParentDataType _lastChildParentData = _lastChild.parentData;
-        _lastChildParentData.nextSibling = child;
-      }
-      _lastChild = child;
-      if (_firstChild == null)
-        _firstChild = child;
-    } else {
-      assert(_firstChild != null);
-      assert(_lastChild != null);
-      assert(_debugUltimatePreviousSiblingOf(before, equals: _firstChild));
-      assert(_debugUltimateNextSiblingOf(before, equals: _lastChild));
-      final ParentDataType beforeParentData = before.parentData;
-      if (beforeParentData.previousSibling == null) {
-        // insert at the start (_firstChild); we'll end up with two or more children
-        assert(before == _firstChild);
-        childParentData.nextSibling = before;
-        beforeParentData.previousSibling = child;
-        _firstChild = child;
-      } else {
-        // insert in the middle; we'll end up with three or more children
-        // set up links from child to siblings
-        childParentData.previousSibling = beforeParentData.previousSibling;
-        childParentData.nextSibling = before;
-        // set up links from siblings to child
-        final ParentDataType childPreviousSiblingParentData = childParentData.previousSibling.parentData;
-        final ParentDataType childNextSiblingParentData = childParentData.nextSibling.parentData;
-        childPreviousSiblingParentData.nextSibling = child;
-        childNextSiblingParentData.previousSibling = child;
-        assert(beforeParentData.previousSibling == child);
-      }
-    }
-  }
-  /// Insert child into this render object's child list before the given child
-  ///
-  /// To insert a child at the end of the child list, omit the before parameter.
-  void add(ChildType child, { ChildType before }) {
-    assert(child != this);
-    assert(before != this);
-    assert(child != before);
-    assert(child != _firstChild);
-    assert(child != _lastChild);
-    adoptChild(child);
-    _addToChildList(child, before: before);
-  }
-
-  /// Add all the children to the end of this render object's child list
-  void addAll(List<ChildType> children) {
-    if (children != null)
-      for (ChildType child in children)
-        add(child);
-  }
-
-  void _removeFromChildList(ChildType child) {
-    final ParentDataType childParentData = child.parentData;
-    assert(_debugUltimatePreviousSiblingOf(child, equals: _firstChild));
-    assert(_debugUltimateNextSiblingOf(child, equals: _lastChild));
-    assert(_childCount >= 0);
-    if (childParentData.previousSibling == null) {
-      assert(_firstChild == child);
-      _firstChild = childParentData.nextSibling;
-    } else {
-      final ParentDataType childPreviousSiblingParentData = childParentData.previousSibling.parentData;
-      childPreviousSiblingParentData.nextSibling = childParentData.nextSibling;
-    }
-    if (childParentData.nextSibling == null) {
-      assert(_lastChild == child);
-      _lastChild = childParentData.previousSibling;
-    } else {
-      final ParentDataType childNextSiblingParentData = childParentData.nextSibling.parentData;
-      childNextSiblingParentData.previousSibling = childParentData.previousSibling;
-    }
-    childParentData.previousSibling = null;
-    childParentData.nextSibling = null;
-    _childCount -= 1;
-  }
-
-  /// Remove this child from the child list
-  ///
-  /// Requires the child to be present in the child list.
-  void remove(ChildType child) {
-    _removeFromChildList(child);
-    dropChild(child);
-  }
-
-  /// Remove all their children from this render object's child list
-  ///
-  /// More efficient than removing them individually.
-  void removeAll() {
-    ChildType child = _firstChild;
-    while (child != null) {
-      final ParentDataType childParentData = child.parentData;
-      ChildType next = childParentData.nextSibling;
-      childParentData.previousSibling = null;
-      childParentData.nextSibling = null;
-      dropChild(child);
-      child = next;
-    }
-    _firstChild = null;
-    _lastChild = null;
-    _childCount = 0;
-  }
-
-  /// Move this child in the child list to be before the given child
-  ///
-  /// More efficient than removing and re-adding the child. Requires the child
-  /// to already be in the child list at some position. Pass null for before to
-  /// move the child to the end of the child list.
-  void move(ChildType child, { ChildType before }) {
-    assert(child != this);
-    assert(before != this);
-    assert(child != before);
-    assert(child.parent == this);
-    final ParentDataType childParentData = child.parentData;
-    if (childParentData.nextSibling == before)
-      return;
-    _removeFromChildList(child);
-    _addToChildList(child, before: before);
-  }
-
-  void attach() {
-    super.attach();
-    ChildType child = _firstChild;
-    while (child != null) {
-      child.attach();
-      final ParentDataType childParentData = child.parentData;
-      child = childParentData.nextSibling;
-    }
-  }
-
-  void detach() {
-    super.detach();
-    ChildType child = _firstChild;
-    while (child != null) {
-      child.detach();
-      final ParentDataType childParentData = child.parentData;
-      child = childParentData.nextSibling;
-    }
-  }
-
-  void redepthChildren() {
-    ChildType child = _firstChild;
-    while (child != null) {
-      redepthChild(child);
-      final ParentDataType childParentData = child.parentData;
-      child = childParentData.nextSibling;
-    }
-  }
-
-  void visitChildren(RenderObjectVisitor visitor) {
-    ChildType child = _firstChild;
-    while (child != null) {
-      visitor(child);
-      final ParentDataType childParentData = child.parentData;
-      child = childParentData.nextSibling;
-    }
-  }
-
-  /// The first child in the child list
-  ChildType get firstChild => _firstChild;
-
-  /// The last child in the child list
-  ChildType get lastChild => _lastChild;
-
-  /// The next child after the given child in the child list
-  ChildType childAfter(ChildType child) {
-    final ParentDataType childParentData = child.parentData;
-    return childParentData.nextSibling;
-  }
-
-  String debugDescribeChildren(String prefix) {
-    String result = '$prefix \u2502\n';
-    if (_firstChild != null) {
-      ChildType child = _firstChild;
-      int count = 1;
-      while (child != _lastChild) {
-        result += '${child.toStringDeep("$prefix \u251C\u2500child $count: ", "$prefix \u2502")}';
-        count += 1;
-        final ParentDataType childParentData = child.parentData;
-        child = childParentData.nextSibling;
-      }
-      if (child != null) {
-        assert(child == _lastChild);
-        result += '${child.toStringDeep("$prefix \u2514\u2500child $count: ", "$prefix  ")}';
-      }
-    }
-    return result;
-  }
-}
diff --git a/sky/packages/sky/lib/src/rendering/overflow.dart b/sky/packages/sky/lib/src/rendering/overflow.dart
deleted file mode 100644
index d1cd29d..0000000
--- a/sky/packages/sky/lib/src/rendering/overflow.dart
+++ /dev/null
@@ -1,231 +0,0 @@
-// Copyright 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 'box.dart';
-import 'object.dart';
-
-export 'package:flutter/src/painting/box_painter.dart';
-
-/// A render object that imposes different constraints on its child than it gets
-/// from its parent, possibly allowing the child to overflow the parent.
-///
-/// A render overflow box proxies most functions in the render box protocol to
-/// its child, except that when laying out its child, it passes constraints
-/// based on the minWidth, maxWidth, minHeight, and maxHeight fields instead of
-/// just passing the parent's constraints in. Specifically, it overrides any of
-/// the equivalent fields on the constraints given by the parent with the
-/// constraints given by these fields for each such field that is not null. It
-/// then sizes itself based on the parent's constraints' maxWidth and maxHeight,
-/// ignoring the child's dimensions.
-///
-/// For example, if you wanted a box to always render 50 pixels high, regardless
-/// of where it was rendered, you would wrap it in a RenderOverflow with
-/// minHeight and maxHeight set to 50.0. Generally speaking, to avoid confusing
-/// behaviour around hit testing, a RenderOverflowBox should usually be wrapped
-/// in a RenderClipRect.
-///
-/// The child is positioned at the top left of the box. To position a smaller
-/// child inside a larger parent, use [RenderPositionedBox] and
-/// [RenderConstrainedBox] rather than RenderOverflowBox.
-class RenderOverflowBox extends RenderBox with RenderObjectWithChildMixin<RenderBox> {
-  RenderOverflowBox({
-    RenderBox child,
-    double minWidth,
-    double maxWidth,
-    double minHeight,
-    double maxHeight
-  }) : _minWidth = minWidth, _maxWidth = maxWidth, _minHeight = minHeight, _maxHeight = maxHeight {
-    this.child = child;
-  }
-
-  /// The minimum width constraint to give the child. Set this to null (the
-  /// default) to use the constraint from the parent instead.
-  double get minWidth => _minWidth;
-  double _minWidth;
-  void set minWidth (double value) {
-    if (_minWidth == value)
-      return;
-    _minWidth = value;
-    markNeedsLayout();
-  }
-
-  /// The maximum width constraint to give the child. Set this to null (the
-  /// default) to use the constraint from the parent instead.
-  double get maxWidth => _maxWidth;
-  double _maxWidth;
-  void set maxWidth (double value) {
-    if (_maxWidth == value)
-      return;
-    _maxWidth = value;
-    markNeedsLayout();
-  }
-
-  /// The minimum height constraint to give the child. Set this to null (the
-  /// default) to use the constraint from the parent instead.
-  double get minHeight => _minHeight;
-  double _minHeight;
-  void set minHeight (double value) {
-    if (_minHeight == value)
-      return;
-    _minHeight = value;
-    markNeedsLayout();
-  }
-
-  /// The maximum height constraint to give the child. Set this to null (the
-  /// default) to use the constraint from the parent instead.
-  double get maxHeight => _maxHeight;
-  double _maxHeight;
-  void set maxHeight (double value) {
-    if (_maxHeight == value)
-      return;
-    _maxHeight = value;
-    markNeedsLayout();
-  }
-
-  BoxConstraints _getInnerConstraints(BoxConstraints constraints) {
-    return new BoxConstraints(
-      minWidth: _minWidth ?? constraints.minWidth,
-      maxWidth: _maxWidth ?? constraints.maxWidth,
-      minHeight: _minHeight ?? constraints.minHeight,
-      maxHeight: _maxHeight ?? constraints.maxHeight
-    );
-  }
-
-  double getMinIntrinsicWidth(BoxConstraints constraints) {
-    return constraints.constrainWidth();
-  }
-
-  double getMaxIntrinsicWidth(BoxConstraints constraints) {
-    return constraints.constrainWidth();
-  }
-
-  double getMinIntrinsicHeight(BoxConstraints constraints) {
-    return constraints.constrainHeight();
-  }
-
-  double getMaxIntrinsicHeight(BoxConstraints constraints) {
-    return constraints.constrainHeight();
-  }
-
-  double computeDistanceToActualBaseline(TextBaseline baseline) {
-    if (child != null)
-      return child.getDistanceToActualBaseline(baseline);
-    return super.computeDistanceToActualBaseline(baseline);
-  }
-
-  bool get sizedByParent => true;
-
-  void performResize() {
-    size = constraints.biggest;
-  }
-
-  void performLayout() {
-    if (child != null)
-      child.layout(_getInnerConstraints(constraints));
-  }
-
-  bool hitTestChildren(HitTestResult result, { Point position }) {
-    return child?.hitTest(result, position: position) ?? false;
-  }
-
-  void paint(PaintingContext context, Offset offset) {
-    if (child != null)
-      context.paintChild(child, offset.toPoint());
-  }
-
-  void debugDescribeSettings(List<String> settings) {
-    super.debugDescribeSettings(settings);
-    settings.add('minWidth: ${minWidth ?? "use parent minWidth constraint"}');
-    settings.add('maxWidth: ${maxWidth ?? "use parent maxWidth constraint"}');
-    settings.add('minHeight: ${minHeight ?? "use parent minHeight constraint"}');
-    settings.add('maxHeight: ${maxHeight ?? "use parent maxHeight constraint"}');
-  }
-}
-
-/// A render box that's a specific size but passes its original constraints through to its child, which will probably overflow
-class RenderSizedOverflowBox extends RenderBox with RenderObjectWithChildMixin<RenderBox> {
-  RenderSizedOverflowBox({
-    RenderBox child,
-    Size requestedSize
-  }) : _requestedSize = requestedSize {
-    assert(requestedSize != null);
-    this.child = child;
-  }
-
-  /// The size this render box should attempt to be.
-  Size get requestedSize => _requestedSize;
-  Size _requestedSize;
-  void set requestedSize (Size value) {
-    assert(value != null);
-    if (_requestedSize == value)
-      return;
-    _requestedSize = value;
-    markNeedsLayout();
-  }
-
-  double getMinIntrinsicWidth(BoxConstraints constraints) {
-    return constraints.constrainWidth(_requestedSize.width);
-  }
-
-  double getMaxIntrinsicWidth(BoxConstraints constraints) {
-    return constraints.constrainWidth(_requestedSize.width);
-  }
-
-  double getMinIntrinsicHeight(BoxConstraints constraints) {
-    return constraints.constrainWidth(_requestedSize.height);
-  }
-
-  double getMaxIntrinsicHeight(BoxConstraints constraints) {
-    return constraints.constrainWidth(_requestedSize.height);
-  }
-
-  double computeDistanceToActualBaseline(TextBaseline baseline) {
-    if (child != null)
-      return child.getDistanceToActualBaseline(baseline);
-    return super.computeDistanceToActualBaseline(baseline);
-  }
-
-  void performLayout() {
-    size = constraints.constrain(_requestedSize);
-    if (child != null)
-      child.layout(constraints);
-  }
-
-  bool hitTestChildren(HitTestResult result, { Point position }) {
-    return child?.hitTest(result, position: position) ?? false;
-  }
-
-  void paint(PaintingContext context, Offset offset) {
-    if (child != null)
-      context.paintChild(child, offset.toPoint());
-  }
-}
-
-/// Lays the child out as if it was in the tree, but without painting anything,
-/// without making the child available for hit testing, and without taking any
-/// room in the parent.
-class RenderOffStage extends RenderBox with RenderObjectWithChildMixin<RenderBox> {
-  RenderOffStage({ RenderBox child }) {
-    this.child = child;
-  }
-
-  double getMinIntrinsicWidth(BoxConstraints constraints) => constraints.minWidth;
-  double getMaxIntrinsicWidth(BoxConstraints constraints) => constraints.minWidth;
-  double getMinIntrinsicHeight(BoxConstraints constraints) => constraints.minHeight;
-  double getMaxIntrinsicHeight(BoxConstraints constraints) => constraints.minHeight;
-
-  bool get sizedByParent => true;
-
-  void performResize() {
-    size = constraints.smallest;
-  }
-
-  void performLayout() {
-    if (child != null)
-      child.layout(constraints);
-  }
-
-  bool hitTest(HitTestResult result, { Point position }) => false;
-  void paint(PaintingContext context, Offset offset) { }
-}
diff --git a/sky/packages/sky/lib/src/rendering/paragraph.dart b/sky/packages/sky/lib/src/rendering/paragraph.dart
deleted file mode 100644
index 7277206..0000000
--- a/sky/packages/sky/lib/src/rendering/paragraph.dart
+++ /dev/null
@@ -1,126 +0,0 @@
-// Copyright 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:flutter/painting.dart';
-
-import 'box.dart';
-import 'object.dart';
-
-export 'package:flutter/painting.dart' show
-  FontStyle,
-  FontWeight,
-  PlainTextSpan,
-  StyledTextSpan,
-  TextAlign,
-  TextBaseline,
-  TextDecoration,
-  TextDecorationStyle,
-  TextSpan,
-  TextStyle,
-  normal,
-  bold,
-  underline,
-  overline,
-  lineThrough;
-
-/// A render object that displays a paragraph of text
-class RenderParagraph extends RenderBox {
-
-  RenderParagraph(
-    TextSpan text
-  ) : textPainter = new TextPainter(text) {
-    assert(text != null);
-  }
-
-  final TextPainter textPainter;
-
-  BoxConstraints _constraintsForCurrentLayout; // when null, we don't have a current layout
-
-  /// The text to display
-  TextSpan get text => textPainter.text;
-  void set text(TextSpan value) {
-    if (textPainter.text == value)
-      return;
-    textPainter.text = value;
-    _constraintsForCurrentLayout = null;
-    markNeedsLayout();
-  }
-
-  // Whether the text should be allowed to wrap to multiple lines.
-  bool get allowLineWrap => true;
-
-  void layoutText(BoxConstraints constraints) {
-    assert(constraints != null);
-    if (_constraintsForCurrentLayout == constraints)
-      return; // already cached this layout
-    textPainter.maxWidth = allowLineWrap ? constraints.maxWidth : double.INFINITY;
-    textPainter.minWidth = constraints.minWidth;
-    textPainter.minHeight = constraints.minHeight;
-    textPainter.maxHeight = constraints.maxHeight;
-    textPainter.layout();
-    // By default, we shrinkwrap to the intrinsic width.
-    double width = constraints.constrainWidth(textPainter.maxIntrinsicWidth);
-    textPainter.minWidth = width;
-    textPainter.maxWidth = width;
-    textPainter.layout();
-    _constraintsForCurrentLayout = constraints;
-  }
-
-  double getMinIntrinsicWidth(BoxConstraints constraints) {
-    layoutText(constraints);
-    return constraints.constrainWidth(textPainter.minIntrinsicWidth);
-  }
-
-  double getMaxIntrinsicWidth(BoxConstraints constraints) {
-    layoutText(constraints);
-    return constraints.constrainWidth(textPainter.maxIntrinsicWidth);
-  }
-
-  double _getIntrinsicHeight(BoxConstraints constraints) {
-    layoutText(constraints);
-    return constraints.constrainHeight(textPainter.size.height);
-  }
-
-  double getMinIntrinsicHeight(BoxConstraints constraints) {
-    return _getIntrinsicHeight(constraints);
-  }
-
-  double getMaxIntrinsicHeight(BoxConstraints constraints) {
-    return _getIntrinsicHeight(constraints);
-  }
-
-  double computeDistanceToActualBaseline(TextBaseline baseline) {
-    assert(!needsLayout);
-    layoutText(constraints);
-    return textPainter.computeDistanceToActualBaseline(baseline);
-  }
-
-  bool hitTestSelf(Point position) => true;
-
-  void performLayout() {
-    layoutText(constraints);
-    size = constraints.constrain(textPainter.size);
-  }
-
-  void paint(PaintingContext context, Offset offset) {
-    // Ideally we could compute the min/max intrinsic width/height with a
-    // non-destructive operation. However, currently, computing these values
-    // will destroy state inside the painter. If that happens, we need to
-    // get back the correct state by calling _layout again.
-    //
-    // TODO(abarth): Make computing the min/max intrinsic width/height
-    // a non-destructive operation.
-    layoutText(constraints);
-    textPainter.paint(context.canvas, offset);
-  }
-
-  // we should probably expose a way to do precise (inter-glpyh) hit testing
-
-  String debugDescribeChildren(String prefix) {
-    return '$prefix \u2558\u2550\u2566\u2550\u2550 text \u2550\u2550\u2550\n'
-           '${text.toString("$prefix   \u2551 ")}\n'
-           '$prefix   \u255A\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n'
-           '$prefix\n';
-  }
-}
diff --git a/sky/packages/sky/lib/src/rendering/proxy_box.dart b/sky/packages/sky/lib/src/rendering/proxy_box.dart
deleted file mode 100644
index 27e3fbc..0000000
--- a/sky/packages/sky/lib/src/rendering/proxy_box.dart
+++ /dev/null
@@ -1,1073 +0,0 @@
-// Copyright 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 'dart:math' as math;
-import 'dart:ui' as ui;
-
-import 'package:flutter/painting.dart';
-import 'package:flutter/gestures.dart';
-import 'package:vector_math/vector_math_64.dart';
-
-import 'box.dart';
-import 'object.dart';
-
-export 'package:flutter/src/painting/box_painter.dart';
-export 'package:flutter/gestures.dart' show InputEvent, PointerInputEvent;
-
-/// A base class for render objects that resemble their children
-///
-/// A proxy box has a single child and simply mimics all the properties of that
-/// child by calling through to the child for each function in the render box
-/// protocol. For example, a proxy box determines its size by askings its child
-/// to layout with the same constraints and then matching the size.
-///
-/// A proxy box isn't useful on its own because you might as well just replace
-/// the proxy box with its child. However, RenderProxyBox is a useful base class
-/// for render objects that wish to mimic most, but not all, of the properties
-/// of their child.
-class RenderProxyBox extends RenderBox with RenderObjectWithChildMixin<RenderBox> {
-
-  RenderProxyBox([RenderBox child = null]) {
-    this.child = child;
-  }
-
-  double getMinIntrinsicWidth(BoxConstraints constraints) {
-    if (child != null)
-      return child.getMinIntrinsicWidth(constraints);
-    return super.getMinIntrinsicWidth(constraints);
-  }
-
-  double getMaxIntrinsicWidth(BoxConstraints constraints) {
-    if (child != null)
-      return child.getMaxIntrinsicWidth(constraints);
-    return super.getMaxIntrinsicWidth(constraints);
-  }
-
-  double getMinIntrinsicHeight(BoxConstraints constraints) {
-    if (child != null)
-      return child.getMinIntrinsicHeight(constraints);
-    return super.getMinIntrinsicHeight(constraints);
-  }
-
-  double getMaxIntrinsicHeight(BoxConstraints constraints) {
-    if (child != null)
-      return child.getMaxIntrinsicHeight(constraints);
-    return super.getMaxIntrinsicHeight(constraints);
-  }
-
-  double computeDistanceToActualBaseline(TextBaseline baseline) {
-    if (child != null)
-      return child.getDistanceToActualBaseline(baseline);
-    return super.computeDistanceToActualBaseline(baseline);
-  }
-
-  void performLayout() {
-    if (child != null) {
-      child.layout(constraints, parentUsesSize: true);
-      size = child.size;
-    } else {
-      performResize();
-    }
-  }
-
-  bool hitTestChildren(HitTestResult result, { Point position }) {
-    return child?.hitTest(result, position: position) ?? false;
-  }
-
-  void paint(PaintingContext context, Offset offset) {
-    if (child != null)
-      context.paintChild(child, offset.toPoint());
-  }
-}
-
-/// A render object that imposes additional constraints on its child
-///
-/// A render constrained box proxies most functions in the render box protocol
-/// to its child, except that when laying out its child, it tightens the
-/// constraints provided by its parent by enforcing the [additionalConstraints]
-/// as well.
-///
-/// For example, if you wanted [child] to have a minimum height, you could use
-/// `const BoxConstraints(minHeight: 50.0)`` as the [additionalConstraints].
-class RenderConstrainedBox extends RenderProxyBox {
-  RenderConstrainedBox({
-    RenderBox child,
-    BoxConstraints additionalConstraints
-  }) : _additionalConstraints = additionalConstraints, super(child) {
-    assert(additionalConstraints != null);
-  }
-
-  /// Additional constraints to apply to [child] during layout
-  BoxConstraints get additionalConstraints => _additionalConstraints;
-  BoxConstraints _additionalConstraints;
-  void set additionalConstraints (BoxConstraints newConstraints) {
-    assert(newConstraints != null);
-    if (_additionalConstraints == newConstraints)
-      return;
-    _additionalConstraints = newConstraints;
-    markNeedsLayout();
-  }
-
-  double getMinIntrinsicWidth(BoxConstraints constraints) {
-    if (child != null)
-      return child.getMinIntrinsicWidth(_additionalConstraints.enforce(constraints));
-    return _additionalConstraints.enforce(constraints).constrainWidth(0.0);
-  }
-
-  double getMaxIntrinsicWidth(BoxConstraints constraints) {
-    if (child != null)
-      return child.getMaxIntrinsicWidth(_additionalConstraints.enforce(constraints));
-    return _additionalConstraints.enforce(constraints).constrainWidth(0.0);
-  }
-
-  double getMinIntrinsicHeight(BoxConstraints constraints) {
-    if (child != null)
-      return child.getMinIntrinsicHeight(_additionalConstraints.enforce(constraints));
-    return _additionalConstraints.enforce(constraints).constrainHeight(0.0);
-  }
-
-  double getMaxIntrinsicHeight(BoxConstraints constraints) {
-    if (child != null)
-      return child.getMaxIntrinsicHeight(_additionalConstraints.enforce(constraints));
-    return _additionalConstraints.enforce(constraints).constrainHeight(0.0);
-  }
-
-  void performLayout() {
-    if (child != null) {
-      child.layout(_additionalConstraints.enforce(constraints), parentUsesSize: true);
-      size = child.size;
-    } else {
-      size = _additionalConstraints.enforce(constraints).constrain(Size.zero);
-    }
-  }
-
-  void debugDescribeSettings(List<String> settings) {
-    super.debugDescribeSettings(settings);
-    settings.add('additionalConstraints: $additionalConstraints');
-  }
-}
-
-/// A render object that, for both width and height, imposes a tight constraint
-/// on its child that is a multiple (typically less than 1.0) of the maximum
-/// constraint it received from its parent on that axis. If the factor for a
-/// given axis is null, then the constraints from the parent are just passed
-/// through instead.
-///
-/// It then tries to size itself the size of its child.
-class RenderFractionallySizedBox extends RenderProxyBox {
-  RenderFractionallySizedBox({
-    RenderBox child,
-    double widthFactor,
-    double heightFactor
-  }) : _widthFactor = widthFactor, _heightFactor = heightFactor, super(child) {
-    assert(_widthFactor == null || _widthFactor > 0.0);
-    assert(_heightFactor == null || _heightFactor > 0.0);
-  }
-
-  /// The multiple to apply to the incoming maximum width constraint to use as
-  /// the tight width constraint for the child, or null to pass through the
-  /// constraints given by the parent.
-  double get widthFactor => _widthFactor;
-  double _widthFactor;
-  void set widthFactor (double value) {
-    assert(value == null || value > 0.0);
-    if (_widthFactor == value)
-      return;
-    _widthFactor = value;
-    markNeedsLayout();
-  }
-
-  /// The multiple to apply to the incoming maximum height constraint to use as
-  /// the tight height constraint for the child, or null to pass through the
-  /// constraints given by the parent.
-  double get heightFactor => _heightFactor;
-  double _heightFactor;
-  void set heightFactor (double value) {
-    assert(value == null || value > 0.0);
-    if (_heightFactor == value)
-      return;
-    _heightFactor = value;
-    markNeedsLayout();
-  }
-
-  BoxConstraints _getInnerConstraints(BoxConstraints constraints) {
-    return new BoxConstraints(
-      minWidth: _widthFactor == null ? constraints.minWidth : constraints.maxWidth * _widthFactor,
-      maxWidth: _widthFactor == null ? constraints.maxWidth : constraints.maxWidth * _widthFactor,
-      minHeight: _heightFactor == null ? constraints.minHeight : constraints.maxHeight * _heightFactor,
-      maxHeight: _heightFactor == null ? constraints.maxHeight : constraints.maxHeight * _heightFactor
-    );
-  }
-
-  double getMinIntrinsicWidth(BoxConstraints constraints) {
-    if (child != null)
-      return child.getMinIntrinsicWidth(_getInnerConstraints(constraints));
-    return _getInnerConstraints(constraints).constrainWidth(0.0);
-  }
-
-  double getMaxIntrinsicWidth(BoxConstraints constraints) {
-    if (child != null)
-      return child.getMaxIntrinsicWidth(_getInnerConstraints(constraints));
-    return _getInnerConstraints(constraints).constrainWidth(0.0);
-  }
-
-  double getMinIntrinsicHeight(BoxConstraints constraints) {
-    if (child != null)
-      return child.getMinIntrinsicHeight(_getInnerConstraints(constraints));
-    return _getInnerConstraints(constraints).constrainHeight(0.0);
-  }
-
-  double getMaxIntrinsicHeight(BoxConstraints constraints) {
-    if (child != null)
-      return child.getMaxIntrinsicHeight(_getInnerConstraints(constraints));
-    return _getInnerConstraints(constraints).constrainHeight(0.0);
-  }
-
-  void performLayout() {
-    if (child != null) {
-      child.layout(_getInnerConstraints(constraints), parentUsesSize: true);
-      size = child.size;
-    } else {
-      size = _getInnerConstraints(constraints).constrain(Size.zero);
-    }
-  }
-
-  void debugDescribeSettings(List<String> settings) {
-    super.debugDescribeSettings(settings);
-    settings.add('widthFactor: ${_widthFactor ?? "pass-through"}');
-    settings.add('heightFactor: ${_heightFactor ?? "pass-through"}');
-  }
-}
-
-/// Forces child to layout at a specific aspect ratio
-///
-/// The width of this render object is the largest width permited by the layout
-/// constraints. The height of the render object is determined by applying the
-/// given aspect ratio to the width, expressed as a ratio of width to height.
-/// For example, a 16:9 width:height aspect ratio would have a value of 16.0/9.0.
-///
-/// For example, given an aspect ratio of 2.0 and layout constraints that
-/// require the width to be between 0.0 and 100.0 and the height to be between
-/// 0.0 and 100.0, we'll select a width of 100.0 (the biggest allowed) and a
-/// height of 50.0 (to match the aspect ratio).
-///
-/// In that same situation, if the aspect ratio is 0.5, we'll also select a
-/// width of 100.0 (still the biggest allowed) and we'll attempt to use a height
-/// of 200.0. Unfortunately, that violates the constraints and we'll end up with
-/// a height of 100.0 instead.
-class RenderAspectRatio extends RenderProxyBox {
-  RenderAspectRatio({
-    RenderBox child,
-    double aspectRatio
-  }) : _aspectRatio = aspectRatio, super(child) {
-    assert(_aspectRatio != null);
-  }
-
-  /// The aspect ratio to use when computing the height from the width
-  ///
-  /// The aspect ratio is expressed as a ratio of width to height. For example,
-  /// a 16:9 width:height aspect ratio would have a value of 16.0/9.0.
-  double get aspectRatio => _aspectRatio;
-  double _aspectRatio;
-  void set aspectRatio (double newAspectRatio) {
-    assert(newAspectRatio != null);
-    if (_aspectRatio == newAspectRatio)
-      return;
-    _aspectRatio = newAspectRatio;
-    markNeedsLayout();
-  }
-
-  double getMinIntrinsicHeight(BoxConstraints constraints) {
-    return _applyAspectRatio(constraints).height;
-  }
-
-  double getMaxIntrinsicHeight(BoxConstraints constraints) {
-    return _applyAspectRatio(constraints).height;
-  }
-
-  Size _applyAspectRatio(BoxConstraints constraints) {
-    double width = constraints.constrainWidth();
-    double height = constraints.constrainHeight(width / _aspectRatio);
-    return new Size(width, height);
-  }
-
-  bool get sizedByParent => true;
-
-  void performResize() {
-    size = _applyAspectRatio(constraints);
-  }
-
-  void performLayout() {
-    if (child != null)
-      child.layout(new BoxConstraints.tight(size));
-  }
-
-  void debugDescribeSettings(List<String> settings) {
-    super.debugDescribeSettings(settings);
-    settings.add('aspectRatio: $aspectRatio');
-  }
-}
-
-/// Sizes its child to the child's intrinsic width
-///
-/// This class will size its child's width to the child's maximum intrinsic
-/// width. If [stepWidth] is non-null, the child's width will be snapped to a
-/// multiple of the [stepWidth]. Similarly, if [stepHeight] is non-null, the
-/// child's height will be snapped to a multiple of the [stepHeight].
-///
-/// This class is useful, for example, when unlimited width is available and
-/// you would like a child that would otherwise attempt to expand infinitely to
-/// instead size itself to a more reasonable width.
-///
-/// Note: This class is relatively expensive. Avoid using it where possible.
-class RenderIntrinsicWidth extends RenderProxyBox {
-
-  RenderIntrinsicWidth({
-    double stepWidth,
-    double stepHeight,
-    RenderBox child
-  }) : _stepWidth = stepWidth, _stepHeight = stepHeight, super(child);
-
-  /// If non-null, force the child's width to be a multiple of this value
-  double get stepWidth => _stepWidth;
-  double _stepWidth;
-  void set stepWidth(double newStepWidth) {
-    if (newStepWidth == _stepWidth)
-      return;
-    _stepWidth = newStepWidth;
-    markNeedsLayout();
-  }
-
-  /// If non-null, force the child's height to be a multiple of this value
-  double get stepHeight => _stepHeight;
-  double _stepHeight;
-  void set stepHeight(double newStepHeight) {
-    if (newStepHeight == _stepHeight)
-      return;
-    _stepHeight = newStepHeight;
-    markNeedsLayout();
-  }
-
-  static double _applyStep(double input, double step) {
-    if (step == null)
-      return input;
-    return (input / step).ceil() * step;
-  }
-
-  BoxConstraints _getInnerConstraints(BoxConstraints constraints) {
-    assert(child != null);
-    if (constraints.hasTightWidth)
-      return constraints;
-    double width = child.getMaxIntrinsicWidth(constraints);
-    assert(width == constraints.constrainWidth(width));
-    return constraints.tightenWidth(_applyStep(width, _stepWidth));
-  }
-
-  double getMinIntrinsicWidth(BoxConstraints constraints) {
-    return getMaxIntrinsicWidth(constraints);
-  }
-
-  double getMaxIntrinsicWidth(BoxConstraints constraints) {
-    if (child == null)
-      return constraints.constrainWidth(0.0);
-    double childResult = child.getMaxIntrinsicWidth(constraints);
-    return constraints.constrainWidth(_applyStep(childResult, _stepWidth));
-  }
-
-  double getMinIntrinsicHeight(BoxConstraints constraints) {
-    if (child == null)
-      return constraints.constrainHeight(0.0);
-    double childResult = child.getMinIntrinsicHeight(_getInnerConstraints(constraints));
-    return constraints.constrainHeight(_applyStep(childResult, _stepHeight));
-  }
-
-  double getMaxIntrinsicHeight(BoxConstraints constraints) {
-    if (child == null)
-      return constraints.constrainHeight(0.0);
-    double childResult = child.getMaxIntrinsicHeight(_getInnerConstraints(constraints));
-    return constraints.constrainHeight(_applyStep(childResult, _stepHeight));
-  }
-
-  void performLayout() {
-    if (child != null) {
-      BoxConstraints childConstraints = _getInnerConstraints(constraints);
-      if (_stepHeight != null)
-        childConstraints.tightenHeight(getMaxIntrinsicHeight(childConstraints));
-      child.layout(childConstraints, parentUsesSize: true);
-      size = child.size;
-    } else {
-      performResize();
-    }
-  }
-
-  void debugDescribeSettings(List<String> settings) {
-    super.debugDescribeSettings(settings);
-    settings.add('stepWidth: $stepWidth');
-    settings.add('stepHeight: $stepHeight');
-  }
-}
-
-/// Sizes its child to the child's intrinsic height
-///
-/// This class will size its child's height to the child's maximum intrinsic
-/// height.
-///
-/// This class is useful, for example, when unlimited height is available and
-/// you would like a child that would otherwise attempt to expand infinitely to
-/// instead size itself to a more reasonable height.
-///
-/// Note: This class is relatively expensive. Avoid using it where possible.
-class RenderIntrinsicHeight extends RenderProxyBox {
-
-  RenderIntrinsicHeight({
-    RenderBox child
-  }) : super(child);
-
-  BoxConstraints _getInnerConstraints(BoxConstraints constraints) {
-    assert(child != null);
-    if (constraints.hasTightHeight)
-      return constraints;
-    double height = child.getMaxIntrinsicHeight(constraints);
-    assert(height == constraints.constrainHeight(height));
-    return constraints.tightenHeight(height);
-  }
-
-  double getMinIntrinsicWidth(BoxConstraints constraints) {
-    if (child == null)
-      return constraints.constrainWidth(0.0);
-    return child.getMinIntrinsicWidth(_getInnerConstraints(constraints));
-  }
-
-  double getMaxIntrinsicWidth(BoxConstraints constraints) {
-    if (child == null)
-      return constraints.constrainWidth(0.0);
-    return child.getMaxIntrinsicWidth(_getInnerConstraints(constraints));
-  }
-
-  double getMinIntrinsicHeight(BoxConstraints constraints) {
-    return getMaxIntrinsicHeight(constraints);
-  }
-
-  double getMaxIntrinsicHeight(BoxConstraints constraints) {
-    if (child == null)
-      return constraints.constrainHeight(0.0);
-    return child.getMaxIntrinsicHeight(constraints);
-  }
-
-  void performLayout() {
-    if (child != null) {
-      child.layout(_getInnerConstraints(constraints), parentUsesSize: true);
-      size = child.size;
-    } else {
-      performResize();
-    }
-  }
-
-}
-
-/// Makes its child partially transparent
-///
-/// This class paints its child into an intermediate buffer and then blends the
-/// child back into the scene partially transparent.
-///
-/// Note: This class is relatively expensive because it requires painting the
-/// child into an intermediate buffer.
-class RenderOpacity extends RenderProxyBox {
-  RenderOpacity({ RenderBox child, double opacity })
-    : this._opacity = opacity, super(child) {
-    assert(opacity >= 0.0 && opacity <= 1.0);
-  }
-
-  /// The fraction to scale the child's alpha value
-  ///
-  /// An opacity of 1.0 is fully opaque. An opacity of 0.0 is fully transparent
-  /// (i.e., invisible).
-  double get opacity => _opacity;
-  double _opacity;
-  void set opacity (double newOpacity) {
-    assert(newOpacity != null);
-    assert(newOpacity >= 0.0 && newOpacity <= 1.0);
-    if (_opacity == newOpacity)
-      return;
-    _opacity = newOpacity;
-    markNeedsPaint();
-  }
-
-  int get _alpha => (_opacity * 255).round();
-
-  void paint(PaintingContext context, Offset offset) {
-    if (child != null) {
-      int a = _alpha;
-      if (a == 0)
-        return;
-      if (a == 255)
-        context.paintChild(child, offset.toPoint());
-      else
-        context.paintChildWithOpacity(child, offset.toPoint(), null, a);
-    }
-  }
-
-  void debugDescribeSettings(List<String> settings) {
-    super.debugDescribeSettings(settings);
-    settings.add('opacity: ${opacity.toStringAsFixed(1)}');
-  }
-}
-
-class RenderShaderMask extends RenderProxyBox {
-  RenderShaderMask({ RenderBox child, ShaderCallback shaderCallback, TransferMode transferMode })
-    : _shaderCallback = shaderCallback, _transferMode = transferMode, super(child);
-
-  ShaderCallback get shaderCallback => _shaderCallback;
-  ShaderCallback _shaderCallback;
-  void set shaderCallback (ShaderCallback newShaderCallback) {
-    assert(newShaderCallback != null);
-    if (_shaderCallback == newShaderCallback)
-      return;
-    _shaderCallback = newShaderCallback;
-    markNeedsPaint();
-  }
-
-  TransferMode get transferMode => _transferMode;
-  TransferMode _transferMode;
-  void set transferMode (TransferMode newTransferMode) {
-    assert(newTransferMode != null);
-    if (_transferMode == newTransferMode)
-      return;
-    _transferMode = newTransferMode;
-    markNeedsPaint();
-  }
-
-  void paint(PaintingContext context, Offset offset) {
-    if (child != null)
-      context.paintChildWithShaderMask(child, offset.toPoint(), offset & size, _shaderCallback, _transferMode);
-  }
-}
-
-/// Clips its child using a rectangle
-///
-/// Prevents its child from painting outside its bounds.
-class RenderClipRect extends RenderProxyBox {
-  RenderClipRect({ RenderBox child }) : super(child);
-
-  void paint(PaintingContext context, Offset offset) {
-    if (child != null)
-      context.paintChildWithClipRect(child, offset.toPoint(), offset & size);
-  }
-}
-
-/// Clips its child using a rounded rectangle
-///
-/// Creates a rounded rectangle from its layout dimensions and the given x and
-/// y radius values and prevents its child from painting outside that rounded
-/// rectangle.
-class RenderClipRRect extends RenderProxyBox {
-  RenderClipRRect({ RenderBox child, double xRadius, double yRadius })
-    : _xRadius = xRadius, _yRadius = yRadius, super(child) {
-    assert(_xRadius != null);
-    assert(_yRadius != null);
-  }
-
-  /// The radius of the rounded corners in the horizontal direction in logical pixels
-  ///
-  /// Values are clamped to be between zero and half the width of the render
-  /// object.
-  double get xRadius => _xRadius;
-  double _xRadius;
-  void set xRadius (double newXRadius) {
-    assert(newXRadius != null);
-    if (_xRadius == newXRadius)
-      return;
-    _xRadius = newXRadius;
-    markNeedsPaint();
-  }
-
-  /// The radius of the rounded corners in the vertical direction in logical pixels
-  ///
-  /// Values are clamped to be between zero and half the height of the render
-  /// object.
-  double get yRadius => _yRadius;
-  double _yRadius;
-  void set yRadius (double newYRadius) {
-    assert(newYRadius != null);
-    if (_yRadius == newYRadius)
-      return;
-    _yRadius = newYRadius;
-    markNeedsPaint();
-  }
-
-  void paint(PaintingContext context, Offset offset) {
-    if (child != null) {
-      Rect rect = offset & size;
-      ui.RRect rrect = new ui.RRect.fromRectXY(rect, xRadius, yRadius);
-      context.paintChildWithClipRRect(child, offset.toPoint(), rect, rrect);
-    }
-  }
-}
-
-/// Clips its child using an oval
-///
-/// Inscribes an oval into its layout dimensions and prevents its child from
-/// painting outside that oval.
-class RenderClipOval extends RenderProxyBox {
-  RenderClipOval({ RenderBox child }) : super(child);
-
-  Rect _cachedRect;
-  Path _cachedPath;
-
-  Path _getPath(Rect rect) {
-    if (rect != _cachedRect) {
-      _cachedRect = rect;
-      _cachedPath = new Path()..addOval(_cachedRect);
-    }
-    return _cachedPath;
-  }
-
-  bool hitTest(HitTestResult result, { Point position }) {
-    Point center = size.center(Point.origin);
-    Offset offset = new Offset((position.x - center.x) / size.width,
-                               (position.y - center.y) / size.height);
-    if (offset.distance > 0.5)
-      return false;
-    return super.hitTest(result, position: position);
-  }
-
-  void paint(PaintingContext context, Offset offset) {
-    if (child != null) {
-      Rect rect = offset & size;
-      context.paintChildWithClipPath(child, offset.toPoint(), rect, _getPath(rect));
-    }
-  }
-}
-
-/// Where to paint a box decoration
-enum BoxDecorationPosition {
-  /// Paint the box decoration behind the children
-  background,
-
-  /// Paint the box decoration in front of the children
-  foreground,
-}
-
-/// Paints a [BoxDecoration] either before or after its child paints
-class RenderDecoratedBox extends RenderProxyBox {
-
-  RenderDecoratedBox({
-    BoxDecoration decoration,
-    RenderBox child,
-    BoxDecorationPosition position: BoxDecorationPosition.background
-  }) : _painter = new BoxPainter(decoration),
-       _position = position,
-       super(child) {
-    assert(decoration != null);
-    assert(position != null);
-  }
-
-  /// Where to paint the box decoration
-  BoxDecorationPosition get position => _position;
-  BoxDecorationPosition _position;
-  void set position (BoxDecorationPosition newPosition) {
-    assert(newPosition != null);
-    if (newPosition == _position)
-      return;
-    markNeedsPaint();
-  }
-
-  /// What decoration to paint
-  BoxDecoration get decoration => _painter.decoration;
-  void set decoration (BoxDecoration newDecoration) {
-    assert(newDecoration != null);
-    if (newDecoration == _painter.decoration)
-      return;
-    _removeBackgroundImageListenerIfNeeded();
-    _painter.decoration = newDecoration;
-    _addBackgroundImageListenerIfNeeded();
-    markNeedsPaint();
-  }
-
-  final BoxPainter _painter;
-
-  bool get _needsBackgroundImageListener {
-    return attached &&
-        _painter.decoration != null &&
-        _painter.decoration.backgroundImage != null;
-  }
-
-  void _addBackgroundImageListenerIfNeeded() {
-    if (_needsBackgroundImageListener)
-      _painter.decoration.backgroundImage.addChangeListener(markNeedsPaint);
-  }
-
-  void _removeBackgroundImageListenerIfNeeded() {
-    if (_needsBackgroundImageListener)
-      _painter.decoration.backgroundImage.removeChangeListener(markNeedsPaint);
-  }
-
-  void attach() {
-    super.attach();
-    _addBackgroundImageListenerIfNeeded();
-  }
-
-  void detach() {
-    _removeBackgroundImageListenerIfNeeded();
-    super.detach();
-  }
-
-  bool hitTestSelf(Point position) {
-    switch (_painter.decoration.shape) {
-      case Shape.rectangle:
-        // TODO(abarth): We should check the border radius.
-        return true;
-      case Shape.circle:
-        // Circles are inscribed into our smallest dimension.
-        Point center = size.center(Point.origin);
-        double distance = (position - center).distance;
-        return distance <= math.min(size.width, size.height) / 2.0;
-    }
-  }
-
-  void paint(PaintingContext context, Offset offset) {
-    assert(size.width != null);
-    assert(size.height != null);
-    if (position == BoxDecorationPosition.background)
-      _painter.paint(context.canvas, offset & size);
-    super.paint(context, offset);
-    if (position == BoxDecorationPosition.foreground)
-      _painter.paint(context.canvas, offset & size);
-  }
-
-  void debugDescribeSettings(List<String> settings) {
-    super.debugDescribeSettings(settings);
-    settings.add('decoration:');
-    settings.addAll(_painter.decoration.toString("  ").split('\n'));
-  }
-}
-
-/// Applies a transformation before painting its child
-class RenderTransform extends RenderProxyBox {
-  RenderTransform({
-    Matrix4 transform,
-    Offset origin,
-    FractionalOffset alignment,
-    RenderBox child
-  }) : super(child) {
-    assert(transform != null);
-    assert(alignment == null || (alignment.x != null && alignment.y != null));
-    this.transform = transform;
-    this.alignment = alignment;
-    this.origin = origin;
-  }
-
-  /// The origin of the coordinate system (relative to the upper left corder of
-  /// this render object) in which to apply the matrix
-  ///
-  /// Setting an origin is equivalent to conjugating the transform matrix by a
-  /// translation. This property is provided just for convenience.
-  Offset get origin => _origin;
-  Offset _origin;
-  void set origin (Offset newOrigin) {
-    if (_origin == newOrigin)
-      return;
-    _origin = newOrigin;
-    markNeedsPaint();
-  }
-
-  /// The alignment of the origin, relative to the size of the box.
-  ///
-  /// This is equivalent to setting an origin based on the size of the box.
-  /// If it is specificed at the same time as an offset, both are applied.
-  FractionalOffset get alignment => _alignment;
-  FractionalOffset _alignment;
-  void set alignment (FractionalOffset newAlignment) {
-    assert(newAlignment == null || (newAlignment.x != null && newAlignment.y != null));
-    if (_alignment == newAlignment)
-      return;
-    _alignment = newAlignment;
-    markNeedsPaint();
-  }
-
-  // Note the lack of a getter for transform because Matrix4 is not immutable
-  Matrix4 _transform;
-
-  /// The matrix to transform the child by during painting
-  void set transform(Matrix4 newTransform) {
-    assert(newTransform != null);
-    if (_transform == newTransform)
-      return;
-    _transform = new Matrix4.copy(newTransform);
-    markNeedsPaint();
-  }
-
-  /// Sets the transform to the identity matrix
-  void setIdentity() {
-    _transform.setIdentity();
-    markNeedsPaint();
-  }
-
-  /// Concatenates a rotation about the x axis into the transform
-  void rotateX(double radians) {
-    _transform.rotateX(radians);
-    markNeedsPaint();
-  }
-
-  /// Concatenates a rotation about the y axis into the transform
-  void rotateY(double radians) {
-    _transform.rotateY(radians);
-    markNeedsPaint();
-  }
-
-  /// Concatenates a rotation about the z axis into the transform
-  void rotateZ(double radians) {
-    _transform.rotateZ(radians);
-    markNeedsPaint();
-  }
-
-  /// Concatenates a translation by (x, y, z) into the transform
-  void translate(x, [double y = 0.0, double z = 0.0]) {
-    _transform.translate(x, y, z);
-    markNeedsPaint();
-  }
-
-  /// Concatenates a scale into the transform
-  void scale(x, [double y, double z]) {
-    _transform.scale(x, y, z);
-    markNeedsPaint();
-  }
-
-  Matrix4 get _effectiveTransform {
-    if (_origin == null && _alignment == null)
-      return _transform;
-    Matrix4 result = new Matrix4.identity();
-    if (_origin != null)
-      result.translate(_origin.dx, _origin.dy);
-    if (_alignment != null)
-      result.translate(_alignment.x * size.width, _alignment.y * size.height);
-    result.multiply(_transform);
-    if (_alignment != null)
-      result.translate(-_alignment.x * size.width, -_alignment.y * size.height);
-    if (_origin != null)
-      result.translate(-_origin.dx, -_origin.dy);
-    return result;
-  }
-
-  bool hitTest(HitTestResult result, { Point position }) {
-    Matrix4 inverse = new Matrix4.zero();
-    // TODO(abarth): Check the determinant for degeneracy.
-    inverse.copyInverse(_effectiveTransform);
-
-    Vector3 position3 = new Vector3(position.x, position.y, 0.0);
-    Vector3 transformed3 = inverse.transform3(position3);
-    Point transformed = new Point(transformed3.x, transformed3.y);
-    return super.hitTest(result, position: transformed);
-  }
-
-  void paint(PaintingContext context, Offset offset) {
-    if (child != null)
-      context.paintChildWithTransform(child, offset.toPoint(), _effectiveTransform);
-  }
-
-  void applyPaintTransform(Matrix4 transform) {
-    super.applyPaintTransform(transform);
-    transform.multiply(_effectiveTransform);
-  }
-
-  void debugDescribeSettings(List<String> settings) {
-    super.debugDescribeSettings(settings);
-    List<String> matrix = _transform.toString().split('\n').map((String s) => '  $s').toList();
-    matrix.removeLast();
-    settings.add('transform matrix:');
-    settings.addAll(matrix);
-    settings.add('origin: $origin');
-    settings.add('alignment: $alignment');
-  }
-}
-
-/// Called when a size changes
-typedef void SizeChangedCallback(Size newSize);
-
-/// Calls [onSizeChanged] whenever the child's layout size changes
-///
-/// Note: Size observer calls its callback during layout, which means you cannot
-/// dirty layout information during the callback.
-class RenderSizeObserver extends RenderProxyBox {
-  RenderSizeObserver({
-    this.onSizeChanged,
-    RenderBox child
-  }) : super(child) {
-    assert(onSizeChanged != null);
-  }
-
-  /// The callback to call whenever the child's layout size changes
-  SizeChangedCallback onSizeChanged;
-
-  void performLayout() {
-    Size oldSize = hasSize ? size : null;
-    super.performLayout();
-    if (oldSize != size) {
-      // We make a copy of the Size object here because if we leak a _DebugSize
-      // object out of the render tree, we can get confused later if it comes
-      // back and gets set as the size property of a RenderBox.
-      onSizeChanged(new Size(size.width, size.height));
-    }
-  }
-}
-
-/// Called when its time to paint into the given canvas
-typedef void CustomPaintCallback(PaintingCanvas canvas, Size size);
-typedef bool CustomHitTestCallback(Point position);
-
-/// Delegates its painting to [onPaint]
-///
-/// When asked to paint, custom paint first calls its callback with the current
-/// canvas and then paints its children. The coodinate system of the canvas
-/// matches the coordinate system of the custom paint object. The callback is
-/// expected to paint with in a rectangle starting at the origin and
-/// encompassing a region of the given size. If the callback paints outside
-/// those bounds, there might be insufficient memory allocated to rasterize the
-/// painting commands and the resulting behavior is undefined.
-///
-/// Note: Custom paint calls its callback during paint, which means you cannot
-/// dirty layout or paint information during the callback.
-class RenderCustomPaint extends RenderProxyBox {
-
-  RenderCustomPaint({
-    CustomPaintCallback onPaint,
-    this.onHitTest,
-    RenderBox child
-  }) : super(child) {
-    assert(onPaint != null);
-    _onPaint = onPaint;
-  }
-
-  /// The callback to which this render object delegates its painting
-  ///
-  /// The callback must be non-null whenever the render object is attached to
-  /// the render tree.
-  CustomPaintCallback get onPaint => _onPaint;
-  CustomPaintCallback _onPaint;
-  void set onPaint (CustomPaintCallback newCallback) {
-    assert(newCallback != null || !attached);
-    if (_onPaint == newCallback)
-      return;
-    _onPaint = newCallback;
-    markNeedsPaint();
-  }
-
-  CustomHitTestCallback onHitTest;
-
-  void attach() {
-    assert(_onPaint != null);
-    super.attach();
-  }
-
-  bool hitTestSelf(Point position) {
-    return onHitTest == null || onHitTest(position);
-  }
-
-  void paint(PaintingContext context, Offset offset) {
-    assert(_onPaint != null);
-    context.canvas.translate(offset.dx, offset.dy);
-    _onPaint(context.canvas, size);
-    // TODO(abarth): We should translate back before calling super because in
-    // the future, super.paint might switch our compositing layer.
-    super.paint(context, Offset.zero);
-    context.canvas.translate(-offset.dx, -offset.dy);
-  }
-}
-
-typedef void PointerEventListener(PointerInputEvent e);
-
-enum HitTestBehavior {
-  deferToChild,
-  opaque,
-  translucent,
-}
-
-/// Invokes the callbacks in response to pointer events.
-class RenderPointerListener extends RenderProxyBox {
-  RenderPointerListener({
-    this.onPointerDown,
-    this.onPointerMove,
-    this.onPointerUp,
-    this.onPointerCancel,
-    this.behavior: HitTestBehavior.deferToChild,
-    RenderBox child
-  }) : super(child);
-
-  PointerEventListener onPointerDown;
-  PointerEventListener onPointerMove;
-  PointerEventListener onPointerUp;
-  PointerEventListener onPointerCancel;
-  HitTestBehavior behavior;
-
-  bool hitTest(HitTestResult result, { Point position }) {
-    bool hitTarget = false;
-    if (position.x >= 0.0 && position.x < size.width &&
-        position.y >= 0.0 && position.y < size.height) {
-      hitTarget = hitTestChildren(result, position: position) || hitTestSelf(position);
-      if (hitTarget || behavior == HitTestBehavior.translucent)
-        result.add(new BoxHitTestEntry(this, position));
-    }
-    return hitTarget;
-  }
-
-  bool hitTestSelf(Point position) => behavior == HitTestBehavior.opaque;
-
-  void handleEvent(InputEvent event, HitTestEntry entry) {
-    if (onPointerDown != null && event.type == 'pointerdown')
-      return onPointerDown(event);
-    if (onPointerMove != null && event.type == 'pointermove')
-      return onPointerMove(event);
-    if (onPointerUp != null && event.type == 'pointerup')
-      return onPointerUp(event);
-    if (onPointerCancel != null && event.type == 'pointercancel')
-      return onPointerCancel(event);
-  }
-
-  void debugDescribeSettings(List<String> settings) {
-    super.debugDescribeSettings(settings);
-    List<String> listeners = <String>[];
-    if (onPointerDown != null)
-      listeners.add('down');
-    if (onPointerMove != null)
-      listeners.add('move');
-    if (onPointerUp != null)
-      listeners.add('up');
-    if (onPointerCancel != null)
-      listeners.add('cancel');
-    if (listeners.isEmpty)
-      listeners.add('<none>');
-    settings.add('listeners: ${listeners.join(", ")}');
-    if (behavior != HitTestBehavior.deferToChild)
-      settings.add('behavior: $behavior');
-  }
-}
-
-/// Is invisible during hit testing.
-///
-/// When [ignoring] is true, this render object (and its subtree) is invisible
-/// to hit testing. It still consumes space during layout and paints its child
-/// as usual. It just cannot be the target of located events because it returns
-/// false from [hitTest].
-class RenderIgnorePointer extends RenderProxyBox {
-  RenderIgnorePointer({ RenderBox child, this.ignoring: true }) : super(child);
-
-  bool ignoring;
-
-  bool hitTest(HitTestResult result, { Point position }) {
-    return ignoring ? false : super.hitTest(result, position: position);
-  }
-
-  void debugDescribeSettings(List<String> settings) {
-    super.debugDescribeSettings(settings);
-    settings.add('ignoring: $ignoring');
-  }
-}
-
-/// Holds opaque meta data in the render tree
-class RenderMetaData extends RenderProxyBox {
-  RenderMetaData({ RenderBox child, this.metaData }) : super(child);
-
-  /// Opaque meta data ignored by the render tree
-  dynamic metaData;
-}
diff --git a/sky/packages/sky/lib/src/rendering/shifted_box.dart b/sky/packages/sky/lib/src/rendering/shifted_box.dart
deleted file mode 100644
index a2b2886..0000000
--- a/sky/packages/sky/lib/src/rendering/shifted_box.dart
+++ /dev/null
@@ -1,332 +0,0 @@
-// Copyright 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:flutter/painting.dart';
-
-import 'box.dart';
-import 'object.dart';
-
-abstract class RenderShiftedBox extends RenderBox with RenderObjectWithChildMixin<RenderBox> {
-
-  // Abstract class for one-child-layout render boxes
-
-  RenderShiftedBox(RenderBox child) {
-    this.child = child;
-  }
-
-  double getMinIntrinsicWidth(BoxConstraints constraints) {
-    if (child != null)
-      return child.getMinIntrinsicWidth(constraints);
-    return super.getMinIntrinsicWidth(constraints);
-  }
-
-  double getMaxIntrinsicWidth(BoxConstraints constraints) {
-    if (child != null)
-      return child.getMaxIntrinsicWidth(constraints);
-    return super.getMaxIntrinsicWidth(constraints);
-  }
-
-  double getMinIntrinsicHeight(BoxConstraints constraints) {
-    if (child != null)
-      return child.getMinIntrinsicHeight(constraints);
-    return super.getMinIntrinsicHeight(constraints);
-  }
-
-  double getMaxIntrinsicHeight(BoxConstraints constraints) {
-    if (child != null)
-      return child.getMaxIntrinsicHeight(constraints);
-    return super.getMaxIntrinsicHeight(constraints);
-  }
-
-  double computeDistanceToActualBaseline(TextBaseline baseline) {
-    double result;
-    if (child != null) {
-      assert(!needsLayout);
-      result = child.getDistanceToActualBaseline(baseline);
-      final BoxParentData childParentData = child.parentData;
-      if (result != null)
-        result += childParentData.position.y;
-    } else {
-      result = super.computeDistanceToActualBaseline(baseline);
-    }
-    return result;
-  }
-
-  void paint(PaintingContext context, Offset offset) {
-    if (child != null) {
-      final BoxParentData childParentData = child.parentData;
-      context.paintChild(child, childParentData.position + offset);
-    }
-  }
-
-  bool hitTestChildren(HitTestResult result, { Point position }) {
-    if (child != null) {
-      final BoxParentData childParentData = child.parentData;
-      final Point childPosition = new Point(position.x - childParentData.position.x,
-                                            position.y - childParentData.position.y);
-      return child.hitTest(result, position: childPosition);
-    }
-    return false;
-  }
-
-}
-
-class RenderPadding extends RenderShiftedBox {
-
-  RenderPadding({ EdgeDims padding, RenderBox child }) : super(child) {
-    assert(padding != null);
-    this.padding = padding;
-  }
-
-  EdgeDims _padding;
-  EdgeDims get padding => _padding;
-  void set padding (EdgeDims value) {
-    assert(value != null);
-    assert(value.isNonNegative);
-    if (_padding == value)
-      return;
-    _padding = value;
-    markNeedsLayout();
-  }
-
-  double getMinIntrinsicWidth(BoxConstraints constraints) {
-    double totalPadding = padding.left + padding.right;
-    if (child != null)
-      return child.getMinIntrinsicWidth(constraints.deflate(padding)) + totalPadding;
-    return constraints.constrainWidth(totalPadding);
-  }
-
-  double getMaxIntrinsicWidth(BoxConstraints constraints) {
-    double totalPadding = padding.left + padding.right;
-    if (child != null)
-      return child.getMaxIntrinsicWidth(constraints.deflate(padding)) + totalPadding;
-    return constraints.constrainWidth(totalPadding);
-  }
-
-  double getMinIntrinsicHeight(BoxConstraints constraints) {
-    double totalPadding = padding.top + padding.bottom;
-    if (child != null)
-      return child.getMinIntrinsicHeight(constraints.deflate(padding)) + totalPadding;
-    return constraints.constrainHeight(totalPadding);
-  }
-
-  double getMaxIntrinsicHeight(BoxConstraints constraints) {
-    double totalPadding = padding.top + padding.bottom;
-    if (child != null)
-      return child.getMaxIntrinsicHeight(constraints.deflate(padding)) + totalPadding;
-    return constraints.constrainHeight(totalPadding);
-  }
-
-  void performLayout() {
-    assert(padding != null);
-    if (child == null) {
-      size = constraints.constrain(new Size(
-        padding.left + padding.right,
-        padding.top + padding.bottom
-      ));
-      return;
-    }
-    BoxConstraints innerConstraints = constraints.deflate(padding);
-    child.layout(innerConstraints, parentUsesSize: true);
-    final BoxParentData childParentData = child.parentData;
-    childParentData.position = new Point(padding.left, padding.top);
-    size = constraints.constrain(new Size(
-      padding.left + child.size.width + padding.right,
-      padding.top + child.size.height + padding.bottom
-    ));
-  }
-
-  void debugDescribeSettings(List<String> settings) {
-    super.debugDescribeSettings(settings);
-    settings.add('padding: $padding');
-  }
-}
-
-class RenderPositionedBox extends RenderShiftedBox {
-
-  // This box aligns a child box within itself. It's only useful for
-  // children that don't always size to fit their parent. For example,
-  // to align a box at the bottom right, you would pass this box a
-  // tight constraint that is bigger than the child's natural size,
-  // with horizontal and vertical set to 1.0.
-
-  RenderPositionedBox({
-    RenderBox child,
-    FractionalOffset alignment: const FractionalOffset(0.5, 0.5),
-    double widthFactor,
-    double heightFactor
-  }) : _alignment = alignment,
-       _widthFactor = widthFactor,
-       _heightFactor = heightFactor,
-       super(child) {
-    assert(alignment != null);
-  }
-
-  FractionalOffset get alignment => _alignment;
-  FractionalOffset _alignment;
-  void set alignment (FractionalOffset newAlignment) {
-    assert(newAlignment != null && newAlignment.x != null && newAlignment.y != null);
-    if (_alignment == newAlignment)
-      return;
-    _alignment = newAlignment;
-    markNeedsLayout();
-  }
-
-  double _widthFactor;
-  double get widthFactor => _widthFactor;
-  void set widthFactor (double value) {
-    if (_widthFactor == value)
-      return;
-    _widthFactor = value;
-    markNeedsLayout();
-  }
-
-  double _heightFactor;
-  double get heightFactor => _heightFactor;
-  void set heightFactor (double value) {
-    if (_heightFactor == value)
-      return;
-    _heightFactor = value;
-    markNeedsLayout();
-  }
-
-  void performLayout() {
-    final bool shrinkWrapWidth = _widthFactor != null || constraints.maxWidth == double.INFINITY;
-    final bool shrinkWrapHeight = _heightFactor != null || constraints.maxHeight == double.INFINITY;
-
-    if (child != null) {
-      child.layout(constraints.loosen(), parentUsesSize: true);
-      size = constraints.constrain(new Size(shrinkWrapWidth ? child.size.width * (_widthFactor ?? 1.0) : double.INFINITY,
-                                            shrinkWrapHeight ? child.size.height * (_heightFactor ?? 1.0) : double.INFINITY));
-      final Offset delta = size - child.size;
-      final BoxParentData childParentData = child.parentData;
-      childParentData.position = delta.scale(_alignment.x, _alignment.y).toPoint();
-    } else {
-      size = constraints.constrain(new Size(shrinkWrapWidth ? 0.0 : double.INFINITY,
-                                            shrinkWrapHeight ? 0.0 : double.INFINITY));
-    }
-  }
-
-  void debugDescribeSettings(List<String> settings) {
-    super.debugDescribeSettings(settings);
-    settings.add('alignment: $alignment');
-  }
-}
-
-/// A delegate for computing the layout of a render object with a single child.
-class OneChildLayoutDelegate {
-  /// Returns the size of this object given the incomming constraints.
-  Size getSize(BoxConstraints constraints) => constraints.biggest;
-
-  /// Returns the box constraints for the child given the incomming constraints.
-  BoxConstraints getConstraintsForChild(BoxConstraints constraints) => constraints;
-
-  /// Returns the position where the child should be placed given the size of this object and the size of the child.
-  Point getPositionForChild(Size size, Size childSize) => Point.origin;
-}
-
-class RenderCustomOneChildLayoutBox extends RenderShiftedBox {
-  RenderCustomOneChildLayoutBox({
-    RenderBox child,
-    OneChildLayoutDelegate delegate
-  }) : _delegate = delegate, super(child) {
-    assert(delegate != null);
-  }
-
-  OneChildLayoutDelegate get delegate => _delegate;
-  OneChildLayoutDelegate _delegate;
-  void set delegate (OneChildLayoutDelegate newDelegate) {
-    assert(newDelegate != null);
-    if (_delegate == newDelegate)
-      return;
-    _delegate = newDelegate;
-    markNeedsLayout();
-  }
-
-  Size _getSize(BoxConstraints constraints) {
-    return constraints.constrain(_delegate.getSize(constraints));
-  }
-
-  double getMinIntrinsicWidth(BoxConstraints constraints) {
-    return _getSize(constraints).width;
-  }
-
-  double getMaxIntrinsicWidth(BoxConstraints constraints) {
-    return _getSize(constraints).width;
-  }
-
-  double getMinIntrinsicHeight(BoxConstraints constraints) {
-    return _getSize(constraints).height;
-  }
-
-  double getMaxIntrinsicHeight(BoxConstraints constraints) {
-    return _getSize(constraints).height;
-  }
-
-  bool get sizedByParent => true;
-
-  void performResize() {
-    size = _getSize(constraints);
-  }
-
-  void performLayout() {
-    if (child != null) {
-      child.layout(delegate.getConstraintsForChild(constraints), parentUsesSize: true);
-      final BoxParentData childParentData = child.parentData;
-      childParentData.position = delegate.getPositionForChild(size, child.size);
-    }
-  }
-}
-
-class RenderBaseline extends RenderShiftedBox {
-
-  RenderBaseline({
-    RenderBox child,
-    double baseline,
-    TextBaseline baselineType
-  }) : _baseline = baseline,
-       _baselineType = baselineType,
-       super(child) {
-    assert(baseline != null);
-    assert(baselineType != null);
-  }
-
-  double _baseline;
-  double get baseline => _baseline;
-  void set baseline (double value) {
-    assert(value != null);
-    if (_baseline == value)
-      return;
-    _baseline = value;
-    markNeedsLayout();
-  }
-
-  TextBaseline _baselineType;
-  TextBaseline get baselineType => _baselineType;
-  void set baselineType (TextBaseline value) {
-    assert(value != null);
-    if (_baselineType == value)
-      return;
-    _baselineType = value;
-    markNeedsLayout();
-  }
-
-  void performLayout() {
-    if (child != null) {
-      child.layout(constraints.loosen(), parentUsesSize: true);
-      size = constraints.constrain(child.size);
-      double delta = baseline - child.getDistanceToBaseline(baselineType);
-      final BoxParentData childParentData = child.parentData;
-      childParentData.position = new Point(0.0, delta);
-    } else {
-      performResize();
-    }
-  }
-
-  void debugDescribeSettings(List<String> settings) {
-    super.debugDescribeSettings(settings);
-    settings.add('baseline: $baseline');
-    settings.add('baselineType: $baselineType');
-  }
-}
diff --git a/sky/packages/sky/lib/src/rendering/stack.dart b/sky/packages/sky/lib/src/rendering/stack.dart
deleted file mode 100644
index 40db7cc..0000000
--- a/sky/packages/sky/lib/src/rendering/stack.dart
+++ /dev/null
@@ -1,476 +0,0 @@
-// Copyright 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 'dart:math' as math;
-import 'dart:ui' show lerpDouble;
-
-import 'box.dart';
-import 'object.dart';
-
-/// An immutable 2D, axis-aligned, floating-point rectangle whose coordinates
-/// are given relative to another rectangle's edges, known as the container.
-/// Since the dimensions of the rectangle are relative to those of the
-/// container, this class has no width and height members. To determine the
-/// width or height of the rectangle, convert it to a [Rect] using [toRect()]
-/// (passing the container's own Rect), and then examine that object.
-class RelativeRect {
-
-  /// Creates a RelativeRect with the given values.
-  const RelativeRect.fromLTRB(this.left, this.top, this.right, this.bottom);
-
-  /// Creates a RelativeRect from a Rect and a Size. The Rect (first argument)
-  /// and the RelativeRect (the output) are in the coordinate space of the
-  /// rectangle described by the Size, with 0,0 being at the top left.
-  factory RelativeRect.fromSize(Rect rect, Size container) {
-    return new RelativeRect.fromLTRB(rect.left, rect.top, container.width - rect.right, container.height - rect.bottom);
-  }
-
-  /// Creates a RelativeRect from two Rects. The second Rect provides the
-  /// container, the first provides the rectangle, in the same coordinate space,
-  /// that is to be converted to a RelativeRect. The output will be in the
-  /// container's coordinate space.
-  ///
-  /// For example, if the top left of the rect is at 0,0, and the top left of
-  /// the container is at 100,100, then the top left of the output will be at
-  /// -100,-100.
-  ///
-  /// If the first rect is actually in the container's coordinate space, then
-  /// use [RelativeRect.fromSize] and pass the container's size as the second
-  /// argument instead.
-  factory RelativeRect.fromRect(Rect rect, Rect container) {
-    return new RelativeRect.fromLTRB(
-      rect.left - container.left,
-      rect.top - container.top,
-      container.right - rect.right,
-      container.bottom - rect.bottom
-    );
-  }
-
-  static final RelativeRect fill = new RelativeRect.fromLTRB(0.0, 0.0, 0.0, 0.0);
-
-  /// Distance from the left side of the container to the left side of this rectangle.
-  final double left;
-
-  /// Distance from the top side of the container to the top side of this rectangle.
-  final double top;
-
-  /// Distance from the right side of the container to the right side of this rectangle.
-  final double right;
-
-  /// Distance from the bottom side of the container to the bottom side of this rectangle.
-  final double bottom;
-
-  /// Returns a new rectangle object translated by the given offset.
-  RelativeRect shift(Offset offset) {
-    return new RelativeRect.fromLTRB(left + offset.dx, top + offset.dy, right + offset.dx, bottom + offset.dy);
-  }
-
-  /// Returns a new rectangle with edges moved outwards by the given delta.
-  RelativeRect inflate(double delta) {
-    return new RelativeRect.fromLTRB(left - delta, top - delta, right + delta, bottom + delta);
-  }
-
-  /// Returns a new rectangle with edges moved inwards by the given delta.
-  RelativeRect deflate(double delta) {
-    return inflate(-delta);
-  }
-
-  /// Returns a new rectangle that is the intersection of the given rectangle and this rectangle.
-  RelativeRect intersect(RelativeRect other) {
-    return new RelativeRect.fromLTRB(
-      math.max(left, other.left),
-      math.max(top, other.top),
-      math.max(right, other.right),
-      math.max(bottom, other.bottom)
-    );
-  }
-
-  /// Convert this RelativeRect to a Rect, in the coordinate space of the container.
-  Rect toRect(Rect container) {
-    return new Rect.fromLTRB(left, top, container.width - right, container.height - bottom);
-  }
-
-  /// Linearly interpolate between two RelativeRects.
-  ///
-  /// If either rect is null, this function interpolates from [RelativeRect.fill].
-  static RelativeRect lerp(RelativeRect a, RelativeRect b, double t) {
-    if (a == null && b == null)
-      return null;
-    if (a == null)
-      return new RelativeRect.fromLTRB(b.left * t, b.top * t, b.right * t, b.bottom * t);
-    if (b == null) {
-      double k = 1.0 - t;
-      return new RelativeRect.fromLTRB(b.left * k, b.top * k, b.right * k, b.bottom * k);
-    }
-    return new RelativeRect.fromLTRB(
-      lerpDouble(a.left, b.left, t),
-      lerpDouble(a.top, b.top, t),
-      lerpDouble(a.right, b.right, t),
-      lerpDouble(a.bottom, b.bottom, t)
-    );
-  }
-
-  bool operator ==(dynamic other) {
-    if (identical(this, other))
-      return true;
-    if (other is! RelativeRect)
-      return false;
-    final RelativeRect typedOther = other;
-    return left == typedOther.left &&
-           top == typedOther.top &&
-           right == typedOther.right &&
-           bottom == typedOther.bottom;
-  }
-
-  int get hashCode {
-    int value = 373;
-    value = 37 * value + left.hashCode;
-    value = 37 * value + top.hashCode;
-    value = 37 * value + right.hashCode;
-    value = 37 * value + bottom.hashCode;
-    return value;
-  }
-
-  String toString() => "RelativeRect.fromLTRB(${left.toStringAsFixed(1)}, ${top.toStringAsFixed(1)}, ${right.toStringAsFixed(1)}, ${bottom.toStringAsFixed(1)})";
-}
-
-/// Parent data for use with [RenderStack]
-class StackParentData extends ContainerBoxParentDataMixin<RenderBox> {
-  /// The offset of the child's top edge from the top of the stack
-  double top;
-
-  /// The offset of the child's right edge from the right of the stack
-  double right;
-
-  /// The offset of the child's bottom edge from the bottom of the stack
-  double bottom;
-
-  /// The offset of the child's left edge from the left of the stack
-  double left;
-
-  /// Get or set the current values in terms of a RelativeRect object.
-  RelativeRect get rect => new RelativeRect.fromLTRB(left, top, right, bottom);
-  void set rect(RelativeRect value) {
-    left = value.left;
-    top = value.top;
-    right = value.right;
-    bottom = value.bottom;
-  }
-
-  void merge(StackParentData other) {
-    if (other.top != null)
-      top = other.top;
-    if (other.right != null)
-      right = other.right;
-    if (other.bottom != null)
-      bottom = other.bottom;
-    if (other.left != null)
-      left = other.left;
-    super.merge(other);
-  }
-
-  /// Whether this child is considered positioned
-  ///
-  /// A child is positioned if any of the top, right, bottom, or left offsets
-  /// are non-null. Positioned children do not factor into determining the size
-  /// of the stack but are instead placed relative to the non-positioned
-  /// children in the stack.
-  bool get isPositioned => top != null || right != null || bottom != null || left != null;
-
-  String toString() => '${super.toString()}; top=$top; right=$right; bottom=$bottom, left=$left';
-}
-
-abstract class RenderStackBase extends RenderBox
-    with ContainerRenderObjectMixin<RenderBox, StackParentData>,
-         RenderBoxContainerDefaultsMixin<RenderBox, StackParentData> {
-  RenderStackBase({
-    List<RenderBox> children,
-    alignment: const FractionalOffset(0.0, 0.0)
-  }) : _alignment = alignment {
-    addAll(children);
-  }
-
-  bool _hasVisualOverflow = false;
-
-  void setupParentData(RenderBox child) {
-    if (child.parentData is! StackParentData)
-      child.parentData = new StackParentData();
-  }
-
-  FractionalOffset get alignment => _alignment;
-  FractionalOffset _alignment;
-  void set alignment (FractionalOffset value) {
-    if (_alignment != value) {
-      _alignment = value;
-      markNeedsLayout();
-    }
-  }
-
-  double getMinIntrinsicWidth(BoxConstraints constraints) {
-    double width = constraints.minWidth;
-    RenderBox child = firstChild;
-    while (child != null) {
-      final StackParentData childParentData = child.parentData;
-      if (!childParentData.isPositioned)
-        width = math.max(width, child.getMinIntrinsicWidth(constraints));
-      assert(child.parentData == childParentData);
-      child = childParentData.nextSibling;
-    }
-    assert(width == constraints.constrainWidth(width));
-    return width;
-  }
-
-  double getMaxIntrinsicWidth(BoxConstraints constraints) {
-    bool hasNonPositionedChildren = false;
-    double width = constraints.minWidth;
-    RenderBox child = firstChild;
-    while (child != null) {
-      final StackParentData childParentData = child.parentData;
-      if (!childParentData.isPositioned) {
-        hasNonPositionedChildren = true;
-        width = math.max(width, child.getMaxIntrinsicWidth(constraints));
-      }
-      assert(child.parentData == childParentData);
-      child = childParentData.nextSibling;
-    }
-    if (!hasNonPositionedChildren)
-      return constraints.constrainWidth();
-    assert(width == constraints.constrainWidth(width));
-    return width;
-  }
-
-  double getMinIntrinsicHeight(BoxConstraints constraints) {
-    double height = constraints.minHeight;
-    RenderBox child = firstChild;
-    while (child != null) {
-      final StackParentData childParentData = child.parentData;
-      if (!childParentData.isPositioned)
-        height = math.max(height, child.getMinIntrinsicHeight(constraints));
-      assert(child.parentData == childParentData);
-      child = childParentData.nextSibling;
-    }
-    assert(height == constraints.constrainHeight(height));
-    return height;
-  }
-
-  double getMaxIntrinsicHeight(BoxConstraints constraints) {
-    bool hasNonPositionedChildren = false;
-    double height = constraints.minHeight;
-    RenderBox child = firstChild;
-    while (child != null) {
-      final StackParentData childParentData = child.parentData;
-      if (!childParentData.isPositioned) {
-        hasNonPositionedChildren = true;
-        height = math.max(height, child.getMaxIntrinsicHeight(constraints));
-      }
-      assert(child.parentData == childParentData);
-      child = childParentData.nextSibling;
-    }
-    if (!hasNonPositionedChildren)
-      return constraints.constrainHeight();
-    assert(height == constraints.constrainHeight(height));
-    return height;
-  }
-
-  double computeDistanceToActualBaseline(TextBaseline baseline) {
-    return defaultComputeDistanceToHighestActualBaseline(baseline);
-  }
-
-  void performLayout() {
-    _hasVisualOverflow = false;
-    bool hasNonPositionedChildren = false;
-
-    double width = 0.0;
-    double height = 0.0;
-
-    RenderBox child = firstChild;
-    while (child != null) {
-      final StackParentData childParentData = child.parentData;
-
-      if (!childParentData.isPositioned) {
-        hasNonPositionedChildren = true;
-
-        child.layout(constraints, parentUsesSize: true);
-        childParentData.position = Point.origin;
-
-        final Size childSize = child.size;
-        width = math.max(width, childSize.width);
-        height = math.max(height, childSize.height);
-      }
-
-      child = childParentData.nextSibling;
-    }
-
-    if (hasNonPositionedChildren) {
-      size = new Size(width, height);
-      assert(size.width == constraints.constrainWidth(width));
-      assert(size.height == constraints.constrainHeight(height));
-    } else {
-      size = constraints.biggest;
-    }
-
-    assert(!size.isInfinite);
-
-    child = firstChild;
-    while (child != null) {
-      final StackParentData childParentData = child.parentData;
-
-      if (!childParentData.isPositioned) {
-        double x = (size.width - child.size.width) * alignment.x;
-        double y = (size.height - child.size.height) * alignment.y;
-        childParentData.position = new Point(x, y);
-      } else {
-        BoxConstraints childConstraints = const BoxConstraints();
-
-        if (childParentData.left != null && childParentData.right != null)
-          childConstraints = childConstraints.tightenWidth(size.width - childParentData.right - childParentData.left);
-
-        if (childParentData.top != null && childParentData.bottom != null)
-          childConstraints = childConstraints.tightenHeight(size.height - childParentData.bottom - childParentData.top);
-
-        child.layout(childConstraints, parentUsesSize: true);
-
-        double x = 0.0;
-        if (childParentData.left != null)
-          x = childParentData.left;
-        else if (childParentData.right != null)
-          x = size.width - childParentData.right - child.size.width;
-
-        if (x < 0.0 || x + child.size.width > size.width)
-          _hasVisualOverflow = true;
-
-        double y = 0.0;
-        if (childParentData.top != null)
-          y = childParentData.top;
-        else if (childParentData.bottom != null)
-          y = size.height - childParentData.bottom - child.size.height;
-
-        if (y < 0.0 || y + child.size.height > size.height)
-          _hasVisualOverflow = true;
-
-        childParentData.position = new Point(x, y);
-      }
-
-      assert(child.parentData == childParentData);
-      child = childParentData.nextSibling;
-    }
-  }
-
-  bool hitTestChildren(HitTestResult result, { Point position }) {
-    return defaultHitTestChildren(result, position: position);
-  }
-
-  void paintStack(PaintingContext context, Offset offset);
-
-  void paint(PaintingContext context, Offset offset) {
-    if (_hasVisualOverflow) {
-      context.canvas.save();
-      context.canvas.clipRect(offset & size);
-      paintStack(context, offset);
-      context.canvas.restore();
-    } else {
-      paintStack(context, offset);
-    }
-  }
-}
-
-/// Implements the stack layout algorithm
-///
-/// In a stack layout, the children are positioned on top of each other in the
-/// order in which they appear in the child list. First, the non-positioned
-/// children (those with null values for top, right, bottom, and left) are
-/// initially layed out and placed in the upper-left corner of the stack. The
-/// stack is then sized to enclose all of the non-positioned children. If there
-/// are no non-positioned children, the stack becomes as large as possible.
-///
-/// The final location of non-positioned children is determined by the alignment
-/// parameter. The left of each non-positioned child becomes the
-/// difference between the child's width and the stack's width scaled by
-/// alignment.x. The top of each non-positioned child is computed
-/// similarly and scaled by alignement.y. So if the alignment x and y properties
-/// are 0.0 (the default) then the non-positioned children remain in the
-/// upper-left corner. If the alignment x and y properties are 0.5 then the
-/// non-positioned children are centered within the stack.
-///
-/// Next, the positioned children are laid out. If a child has top and bottom
-/// values that are both non-null, the child is given a fixed height determined
-/// by deflating the width of the stack by the sum of the top and bottom values.
-/// Similarly, if the child has rigth and left values that are both non-null,
-/// the child is given a fixed width. Otherwise, the child is given unbounded
-/// space in the non-fixed dimensions.
-///
-/// Once the child is laid out, the stack positions the child according to the
-/// top, right, bottom, and left offsets. For example, if the top value is 10.0,
-/// the top edge of the child will be placed 10.0 pixels from the top edge of
-/// the stack. If the child extends beyond the bounds of the stack, the stack
-/// will clip the child's painting to the bounds of the stack.
-class RenderStack extends RenderStackBase {
-  RenderStack({
-    List<RenderBox> children,
-    alignment: const FractionalOffset(0.0, 0.0)
-  }) : super(
-   children: children,
-   alignment: alignment
- );
-
-  void paintStack(PaintingContext context, Offset offset) {
-    defaultPaint(context, offset);
-  }
-}
-
-/// Implements the same layout algorithm as RenderStack but only paints the child
-/// specified by index.
-/// Note: although only one child is displayed, the cost of the layout algorithm is
-/// still O(N), like an ordinary stack.
-class RenderIndexedStack extends RenderStackBase {
-  RenderIndexedStack({
-    List<RenderBox> children,
-    alignment: const FractionalOffset(0.0, 0.0),
-    int index: 0
-  }) : _index = index, super(
-   children: children,
-   alignment: alignment
-  );
-
-  int get index => _index;
-  int _index;
-  void set index (int value) {
-    if (_index != value) {
-      _index = value;
-      markNeedsLayout();
-    }
-  }
-
-  RenderBox _childAtIndex() {
-    RenderBox child = firstChild;
-    int i = 0;
-    while (child != null && i < index) {
-      final StackParentData childParentData = child.parentData;
-      child = childParentData.nextSibling;
-      i += 1;
-    }
-    assert(i == index);
-    assert(child != null);
-    return child;
-  }
-
-  bool hitTestChildren(HitTestResult result, { Point position }) {
-    if (firstChild == null)
-      return false;
-    assert(position != null);
-    RenderBox child = _childAtIndex();
-    final StackParentData childParentData = child.parentData;
-    Point transformed = new Point(position.x - childParentData.position.x,
-                                  position.y - childParentData.position.y);
-    return child.hitTest(result, position: transformed);
-  }
-
-  void paintStack(PaintingContext context, Offset offset) {
-    if (firstChild == null)
-      return;
-    RenderBox child = _childAtIndex();
-    final StackParentData childParentData = child.parentData;
-    context.paintChild(child, childParentData.position + offset);
-  }
-}
diff --git a/sky/packages/sky/lib/src/rendering/statistics_box.dart b/sky/packages/sky/lib/src/rendering/statistics_box.dart
deleted file mode 100644
index 54f78e8..0000000
--- a/sky/packages/sky/lib/src/rendering/statistics_box.dart
+++ /dev/null
@@ -1,59 +0,0 @@
-// Copyright 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 'box.dart';
-import 'object.dart';
-
-class StatisticsBox extends RenderBox {
-
-  StatisticsBox({int optionsMask: 0, int rasterizerThreshold: 0})
-    : _optionsMask = optionsMask,
-      _rasterizerThreshold = rasterizerThreshold;
-
-  int _optionsMask;
-  int get optionsMask => _optionsMask;
-  void set optionsMask (int mask) {
-    if (mask == _optionsMask) {
-      return;
-    }
-    _optionsMask = mask;
-    markNeedsPaint();
-  }
-
-  int _rasterizerThreshold;
-  int get rasterizerThreshold => _rasterizerThreshold;
-  void set rasterizerThreshold (int threshold) {
-    if  (threshold == _rasterizerThreshold) {
-      return;
-    }
-    _rasterizerThreshold = threshold;
-    markNeedsPaint();
-  }
-
-  bool get sizedByParent => true;
-
-  double getMinIntrinsicWidth(BoxConstraints constraints) {
-    return constraints.minWidth;
-  }
-
-  double getMaxIntrinsicWidth(BoxConstraints constraints) {
-    return constraints.maxWidth;
-  }
-
-  double getMinIntrinsicHeight(BoxConstraints constraints) {
-    return constraints.minHeight;
-  }
-
-  double getMaxIntrinsicHeight(BoxConstraints constraints) {
-    return constraints.maxHeight;
-  }
-
-  void performResize() {
-    size = constraints.biggest;
-  }
-
-  void paint(PaintingContext context, Offset offset) {
-    context.paintStatistics(optionsMask, rasterizerThreshold, offset, size);
-  }
-}
diff --git a/sky/packages/sky/lib/src/rendering/toggleable.dart b/sky/packages/sky/lib/src/rendering/toggleable.dart
deleted file mode 100644
index 5c9d22d..0000000
--- a/sky/packages/sky/lib/src/rendering/toggleable.dart
+++ /dev/null
@@ -1,78 +0,0 @@
-// Copyright 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:flutter/animation.dart';
-import 'package:flutter/gestures.dart';
-
-import 'binding.dart';
-import 'box.dart';
-import 'object.dart';
-import 'proxy_box.dart';
-
-typedef void ValueChanged<T>(T value);
-
-const Duration _kToggleDuration = const Duration(milliseconds: 200);
-
-// RenderToggleable is a base class for material style toggleable controls with
-// toggle animations. It handles storing the current value, dispatching
-// ValueChanged on a tap gesture and driving a changed animation. Subclasses are
-// responsible for painting.
-abstract class RenderToggleable extends RenderConstrainedBox {
-  RenderToggleable({
-    bool value,
-    Size size,
-    this.onChanged
-  }) : _value = value,
-       super(additionalConstraints: new BoxConstraints.tight(size)) {
-    _performance = new ValuePerformance<double>(
-      variable: new AnimatedValue<double>(0.0, end: 1.0, curve: Curves.easeIn, reverseCurve: Curves.easeOut),
-      duration: _kToggleDuration,
-      progress: _value ? 1.0 : 0.0
-    )..addListener(markNeedsPaint);
-  }
-
-  bool get value => _value;
-  bool _value;
-  void set value(bool value) {
-    if (value == _value)
-      return;
-    _value = value;
-    performance.play(value ? AnimationDirection.forward : AnimationDirection.reverse);
-  }
-
-  ValueChanged<bool> onChanged;
-
-  ValuePerformance<double> get performance => _performance;
-  ValuePerformance<double> _performance;
-
-  double get position => _performance.value;
-
-  TapGestureRecognizer _tap;
-
-  void attach() {
-    super.attach();
-    _tap = new TapGestureRecognizer(
-      router: FlutterBinding.instance.pointerRouter,
-      onTap: _handleTap
-    );
-  }
-
-  void detach() {
-    _tap.dispose();
-    _tap = null;
-    super.detach();
-  }
-
-  void handleEvent(InputEvent event, BoxHitTestEntry entry) {
-    if (event.type == 'pointerdown' && onChanged != null)
-      _tap.addPointer(event);
-  }
-
-  void _handleTap() {
-    if (onChanged != null)
-      onChanged(!_value);
-  }
-
-  bool hitTestSelf(Point position) => true;
-}
diff --git a/sky/packages/sky/lib/src/rendering/view.dart b/sky/packages/sky/lib/src/rendering/view.dart
deleted file mode 100644
index 5a4b444..0000000
--- a/sky/packages/sky/lib/src/rendering/view.dart
+++ /dev/null
@@ -1,139 +0,0 @@
-// Copyright 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 'dart:ui' as ui;
-
-import 'package:flutter/animation.dart';
-import 'package:vector_math/vector_math_64.dart';
-
-import 'box.dart';
-import 'layer.dart';
-import 'object.dart';
-
-/// The layout constraints for the root render object
-class ViewConstraints {
-  const ViewConstraints({
-    this.size: Size.zero,
-    this.orientation
-  });
-
-  /// The size of the output surface
-  final Size size;
-
-  /// The orientation of the output surface (aspirational)
-  final int orientation;
-
-  String toString() => '$size';
-}
-
-/// The root of the render tree
-///
-/// The view represents the total output surface of the render tree and handles
-/// bootstraping the rendering pipeline. The view has a unique child
-/// [RenderBox], which is required to fill the entire output surface.
-class RenderView extends RenderObject with RenderObjectWithChildMixin<RenderBox> {
-  RenderView({
-    RenderBox child,
-    this.timeForRotation: const Duration(microseconds: 83333)
-  }) {
-    this.child = child;
-  }
-
-  /// The amount of time the screen rotation animation should last (aspirational)
-  Duration timeForRotation;
-
-  /// The current layout size of the view
-  Size get size => _size;
-  Size _size = Size.zero;
-
-  /// The current orientation of the view (aspirational)
-  int get orientation => _orientation;
-  int _orientation; // 0..3
-
-  /// The constraints used for the root layout
-  ViewConstraints get rootConstraints => _rootConstraints;
-  ViewConstraints _rootConstraints;
-  void set rootConstraints(ViewConstraints value) {
-    if (rootConstraints == value)
-      return;
-    _rootConstraints = value;
-    markNeedsLayout();
-  }
-
-  Matrix4 get _logicalToDeviceTransform {
-    double devicePixelRatio = ui.window.devicePixelRatio;
-    return new Matrix4.diagonal3Values(devicePixelRatio, devicePixelRatio, 1.0);
-  }
-
-  /// Bootstrap the rendering pipeline by scheduling the first frame
-  void scheduleInitialFrame() {
-    scheduleInitialLayout();
-    scheduleInitialPaint(new TransformLayer(transform: _logicalToDeviceTransform));
-    scheduler.ensureVisualUpdate();
-  }
-
-  // We never call layout() on this class, so this should never get
-  // checked. (This class is laid out using scheduleInitialLayout().)
-  bool debugDoesMeetConstraints() { assert(false); return false; }
-
-  void performResize() {
-    assert(false);
-  }
-
-  void performLayout() {
-    if (rootConstraints.orientation != _orientation) {
-      if (_orientation != null && child != null)
-        child.rotate(oldAngle: _orientation, newAngle: rootConstraints.orientation, time: timeForRotation);
-      _orientation = rootConstraints.orientation;
-    }
-    _size = rootConstraints.size;
-    assert(!_size.isInfinite);
-
-    if (child != null)
-      child.layout(new BoxConstraints.tight(_size));
-  }
-
-  void rotate({ int oldAngle, int newAngle, Duration time }) {
-    assert(false); // nobody tells the screen to rotate, the whole rotate() dance is started from our performResize()
-  }
-
-  bool hitTest(HitTestResult result, { Point position }) {
-    if (child != null)
-      child.hitTest(result, position: position);
-    result.add(new HitTestEntry(this));
-    return true;
-  }
-
-  bool get hasLayer => true;
-
-  void paint(PaintingContext context, Offset offset) {
-    if (child != null)
-      context.paintChild(child, offset.toPoint());
-  }
-
-  /// Uploads the composited layer tree to the engine
-  ///
-  /// Actually causes the output of the rendering pipeline to appear on screen.
-  void compositeFrame() {
-    ui.tracing.begin('RenderView.compositeFrame');
-    try {
-      (layer as TransformLayer).transform = _logicalToDeviceTransform;
-      Rect bounds = Point.origin & (size * ui.window.devicePixelRatio);
-      ui.SceneBuilder builder = new ui.SceneBuilder(bounds);
-      layer.addToScene(builder, Offset.zero);
-      ui.window.render(builder.build());
-    } finally {
-      ui.tracing.end('RenderView.compositeFrame');
-    }
-  }
-
-  Rect get paintBounds => Point.origin & size;
-
-  void debugDescribeSettings(List<String> settings) {
-    // call to ${super.debugDescribeSettings(prefix)} is omitted because the root superclasses don't include any interesting information for this class
-    settings.add('window size: ${ui.window.size} (in device pixels)');
-    settings.add('device pixel ratio: ${ui.window.devicePixelRatio} (device pixels per logical pixel)');
-    settings.add('root constraints: $rootConstraints (in logical pixels)');
-  }
-}
diff --git a/sky/packages/sky/lib/src/rendering/viewport.dart b/sky/packages/sky/lib/src/rendering/viewport.dart
deleted file mode 100644
index 03f317e..0000000
--- a/sky/packages/sky/lib/src/rendering/viewport.dart
+++ /dev/null
@@ -1,171 +0,0 @@
-// Copyright 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 'dart:ui' as ui;
-
-import 'package:vector_math/vector_math_64.dart';
-
-import 'box.dart';
-import 'object.dart';
-
-/// The direction in which to scroll
-enum ScrollDirection {
-  /// Scroll left and right
-  horizontal,
-
-  /// Scroll up and down
-  vertical,
-
-  /// Scroll in all four cardinal directions
-  both
-}
-
-/// A render object that's bigger on the inside
-///
-/// A viewport is the core scrolling primitive in the render tree. The child of
-/// a viewport can layout to a larger size than the viewport itself. If that
-/// happens, only a portion of the child will be visible through the viewport.
-/// The portiion of the child that is visible is controlled by the scroll
-/// offset.
-class RenderViewport extends RenderBox with RenderObjectWithChildMixin<RenderBox> {
-
-  RenderViewport({
-    RenderBox child,
-    Offset scrollOffset: Offset.zero,
-    ScrollDirection scrollDirection: ScrollDirection.vertical
-  }) : _scrollOffset = scrollOffset,
-       _scrollDirection = scrollDirection {
-    assert(_offsetIsSane(scrollOffset, scrollDirection));
-    this.child = child;
-  }
-
-  bool _offsetIsSane(Offset offset, ScrollDirection direction) {
-    switch (direction) {
-      case ScrollDirection.both:
-        return true;
-      case ScrollDirection.horizontal:
-        return offset.dy == 0.0;
-      case ScrollDirection.vertical:
-        return offset.dx == 0.0;
-    }
-  }
-
-  /// The offset at which to paint the child
-  ///
-  /// The offset can be non-zero only in the [scrollDirection].
-  Offset get scrollOffset => _scrollOffset;
-  Offset _scrollOffset;
-  void set scrollOffset(Offset value) {
-    if (value == _scrollOffset)
-      return;
-    assert(_offsetIsSane(value, scrollDirection));
-    _scrollOffset = value;
-    markNeedsPaint();
-  }
-
-  /// In which direction the child is permitted to be larger than the viewport
-  ///
-  /// If the viewport is scrollable in a particular direction (e.g., vertically),
-  /// the child is given layout constraints that are fully unconstrainted in
-  /// that direction (e.g., the child can be as tall as it wants).
-  ScrollDirection get scrollDirection => _scrollDirection;
-  ScrollDirection _scrollDirection;
-  void set scrollDirection(ScrollDirection value) {
-    if (value == _scrollDirection)
-      return;
-    assert(_offsetIsSane(scrollOffset, value));
-    _scrollDirection = value;
-    markNeedsLayout();
-  }
-
-  BoxConstraints _getInnerConstraints(BoxConstraints constraints) {
-    BoxConstraints innerConstraints;
-    switch (scrollDirection) {
-      case ScrollDirection.both:
-        innerConstraints = new BoxConstraints();
-        break;
-      case ScrollDirection.horizontal:
-        innerConstraints = constraints.heightConstraints();
-        break;
-      case ScrollDirection.vertical:
-        innerConstraints = constraints.widthConstraints();
-        break;
-    }
-    return innerConstraints;
-  }
-
-  double getMinIntrinsicWidth(BoxConstraints constraints) {
-    if (child != null)
-      return child.getMinIntrinsicWidth(_getInnerConstraints(constraints));
-    return super.getMinIntrinsicWidth(constraints);
-  }
-
-  double getMaxIntrinsicWidth(BoxConstraints constraints) {
-    if (child != null)
-      return child.getMaxIntrinsicWidth(_getInnerConstraints(constraints));
-    return super.getMaxIntrinsicWidth(constraints);
-  }
-
-  double getMinIntrinsicHeight(BoxConstraints constraints) {
-    if (child != null)
-      return child.getMinIntrinsicHeight(_getInnerConstraints(constraints));
-    return super.getMinIntrinsicHeight(constraints);
-  }
-
-  double getMaxIntrinsicHeight(BoxConstraints constraints) {
-    if (child != null)
-      return child.getMaxIntrinsicHeight(_getInnerConstraints(constraints));
-    return super.getMaxIntrinsicHeight(constraints);
-  }
-
-  // We don't override computeDistanceToActualBaseline(), because we
-  // want the default behaviour (returning null). Otherwise, as you
-  // scroll the RenderViewport, it would shift in its parent if the
-  // parent was baseline-aligned, which makes no sense.
-
-  void performLayout() {
-    if (child != null) {
-      child.layout(_getInnerConstraints(constraints), parentUsesSize: true);
-      size = constraints.constrain(child.size);
-      final BoxParentData childParentData = child.parentData;
-      childParentData.position = Point.origin;
-    } else {
-      performResize();
-    }
-  }
-
-  Offset get _scrollOffsetRoundedToIntegerDevicePixels {
-    double devicePixelRatio = ui.window.devicePixelRatio;
-    int dxInDevicePixels = (scrollOffset.dx * devicePixelRatio).round();
-    int dyInDevicePixels = (scrollOffset.dy * devicePixelRatio).round();
-    return new Offset(dxInDevicePixels / devicePixelRatio,
-                      dyInDevicePixels / devicePixelRatio);
-  }
-
-  void paint(PaintingContext context, Offset offset) {
-    if (child != null) {
-      Offset roundedScrollOffset = _scrollOffsetRoundedToIntegerDevicePixels;
-      bool _needsClip = offset < Offset.zero ||
-                        !(offset & size).contains(((offset - roundedScrollOffset) & child.size).bottomRight);
-      if (_needsClip)
-        context.paintChildWithClipRect(child, (offset - roundedScrollOffset).toPoint(), offset & size);
-      else
-        context.paintChild(child, (offset - roundedScrollOffset).toPoint());
-    }
-  }
-
-  void applyPaintTransform(Matrix4 transform) {
-    super.applyPaintTransform(transform);
-    transform.translate(-scrollOffset.dx, -scrollOffset.dy);
-  }
-
-  bool hitTestChildren(HitTestResult result, { Point position }) {
-    if (child != null) {
-      assert(child.parentData is BoxParentData);
-      Point transformed = position + _scrollOffsetRoundedToIntegerDevicePixels;
-      return child.hitTest(result, position: transformed);
-    }
-    return false;
-  }
-}
diff --git a/sky/packages/sky/lib/src/services/activity.dart b/sky/packages/sky/lib/src/services/activity.dart
deleted file mode 100644
index 6891a99..0000000
--- a/sky/packages/sky/lib/src/services/activity.dart
+++ /dev/null
@@ -1,70 +0,0 @@
-// Copyright 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 'dart:ui';
-import 'dart:async';
-
-import 'package:sky_services/activity/activity.mojom.dart';
-
-import 'shell.dart';
-
-export 'package:sky_services/activity/activity.mojom.dart';
-
-/// Dart wrapper around Activity mojo service available in Sky on Android.
-///
-/// Most clients will want to use these methods instead of the activity service
-/// directly.
-
-const int NEW_DOCUMENT = 0x00080000;
-const int NEW_TASK = 0x10000000;
-const int MULTIPLE_TASK = 0x08000000;
-
-ActivityProxy _initActivityProxy() {
-  ActivityProxy activity = new ActivityProxy.unbound();
-  shell.connectToService(null, activity);
-  return activity;
-}
-
-final ActivityProxy _activityProxy = _initActivityProxy();
-final Activity activity = _activityProxy.ptr;
-
-UserFeedbackProxy _initUserFeedbackProxy() {
-  UserFeedbackProxy proxy = new UserFeedbackProxy.unbound();
-  _activityProxy.ptr.getUserFeedback(proxy);
-  return proxy;
-}
-
-final UserFeedbackProxy _userFeedbackProxy = _initUserFeedbackProxy();
-final UserFeedback userFeedback = _userFeedbackProxy.ptr;
-
-PathServiceProxy _initPathServiceProxy() {
-  PathServiceProxy proxy = new PathServiceProxy.unbound();
-  shell.connectToService(null, proxy);
-  return proxy;
-}
-
-final PathServiceProxy _pathServiceProxy = _initPathServiceProxy();
-final PathService pathService = _pathServiceProxy.ptr;
-
-Color _cachedPrimaryColor;
-String _cachedLabel;
-
-/// Sets the TaskDescription for the current Activity
-void updateTaskDescription(String label, Color color) {
-  if (_cachedPrimaryColor == color && _cachedLabel == label)
-    return;
-
-  _cachedPrimaryColor = color;
-  _cachedLabel = label;
-
-  TaskDescription description = new TaskDescription()
-    ..label = label
-    ..primaryColor = color?.value;
-
-  _activityProxy.ptr.setTaskDescription(description);
-}
-
-Future<String> getAppDataDir() async => (await _pathServiceProxy.ptr.getAppDataDir()).path;
-Future<String> getFilesDir() async => (await _pathServiceProxy.ptr.getFilesDir()).path;
-Future<String> getCacheDir() async => (await _pathServiceProxy.ptr.getCacheDir()).path;
diff --git a/sky/packages/sky/lib/src/services/asset_bundle.dart b/sky/packages/sky/lib/src/services/asset_bundle.dart
deleted file mode 100644
index 2700005..0000000
--- a/sky/packages/sky/lib/src/services/asset_bundle.dart
+++ /dev/null
@@ -1,106 +0,0 @@
-// Copyright 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 'dart:async';
-import 'dart:ui' as ui;
-import 'dart:ui_internals' as internals;
-import 'dart:typed_data';
-
-import 'package:mojo/core.dart' as core;
-import 'package:mojo_services/mojo/asset_bundle/asset_bundle.mojom.dart';
-
-import 'fetch.dart';
-import 'image_cache.dart';
-import 'image_decoder.dart';
-import 'image_resource.dart';
-import 'shell.dart';
-
-abstract class AssetBundle {
-  void close();
-  ImageResource loadImage(String key);
-  Future<String> loadString(String key);
-  Future<core.MojoDataPipeConsumer> load(String key);
-}
-
-class NetworkAssetBundle extends AssetBundle {
-  NetworkAssetBundle(Uri baseUrl) : _baseUrl = baseUrl;
-
-  final Uri _baseUrl;
-
-  void close() { }
-
-  String _urlFromKey(String key) => _baseUrl.resolve(key).toString();
-
-  Future<core.MojoDataPipeConsumer> load(String key) async {
-    return (await fetchUrl(_urlFromKey(key))).body;
-  }
-
-  ImageResource loadImage(String key) => imageCache.load(_urlFromKey(key));
-
-  Future<String> loadString(String key) => fetchString(_urlFromKey(key));
-}
-
-Future _fetchAndUnpackBundle(String relativeUrl, AssetBundleProxy bundle) async {
-  core.MojoDataPipeConsumer bundleData = (await fetchUrl(relativeUrl)).body;
-  AssetUnpackerProxy unpacker = new AssetUnpackerProxy.unbound();
-  shell.connectToService("mojo:asset_bundle", unpacker);
-  unpacker.ptr.unpackZipStream(bundleData, bundle);
-  unpacker.close();
-}
-
-class MojoAssetBundle extends AssetBundle {
-  MojoAssetBundle(this._bundle);
-
-  factory MojoAssetBundle.fromNetwork(String relativeUrl) {
-    AssetBundleProxy bundle = new AssetBundleProxy.unbound();
-    _fetchAndUnpackBundle(relativeUrl, bundle);
-    return new MojoAssetBundle(bundle);
-  }
-
-  AssetBundleProxy _bundle;
-  Map<String, ImageResource> _imageCache = new Map<String, ImageResource>();
-  Map<String, Future<String>> _stringCache = new Map<String, Future<String>>();
-
-  void close() {
-    _bundle.close();
-    _bundle = null;
-    _imageCache = null;
-  }
-
-  Future<ui.Image> _fetchImage(String key) async {
-    return await decodeImageFromDataPipe(await load(key));
-  }
-
-  ImageResource loadImage(String key) {
-    return _imageCache.putIfAbsent(key, () {
-      return new ImageResource(_fetchImage(key));
-    });
-  }
-
-  Future<String> _fetchString(String key) async {
-    core.MojoDataPipeConsumer pipe = await load(key);
-    ByteData data = await core.DataPipeDrainer.drainHandle(pipe);
-    return new String.fromCharCodes(new Uint8List.view(data.buffer));
-  }
-
-  Future<core.MojoDataPipeConsumer> load(String key) async {
-    return (await _bundle.ptr.getAsStream(key)).assetData;
-  }
-
-  Future<String> loadString(String key) {
-    return _stringCache.putIfAbsent(key, () => _fetchString(key));
-  }
-}
-
-AssetBundle _initRootBundle() {
-  try {
-    AssetBundleProxy bundle = new AssetBundleProxy.fromHandle(
-        new core.MojoHandle(internals.takeRootBundleHandle()));
-    return new MojoAssetBundle(bundle);
-  } catch (e) {
-    return null;
-  }
-}
-
-final AssetBundle rootBundle = _initRootBundle();
diff --git a/sky/packages/sky/lib/src/services/fetch.dart b/sky/packages/sky/lib/src/services/fetch.dart
deleted file mode 100644
index 4b1fee2..0000000
--- a/sky/packages/sky/lib/src/services/fetch.dart
+++ /dev/null
@@ -1,71 +0,0 @@
-// Copyright 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 'dart:async';
-import 'dart:typed_data';
-
-import 'package:mojo/core.dart' as core;
-import 'package:mojo/mojo/url_request.mojom.dart';
-import 'package:mojo/mojo/url_response.mojom.dart';
-import 'package:mojo_services/mojo/network_service.mojom.dart';
-import 'package:mojo_services/mojo/url_loader.mojom.dart';
-
-import 'shell.dart';
-
-export 'package:mojo/mojo/url_response.mojom.dart' show UrlResponse;
-
-NetworkServiceProxy _initNetworkService() {
-  NetworkServiceProxy networkService = new NetworkServiceProxy.unbound();
-  shell.connectToService("mojo:authenticated_network_service", networkService);
-  return networkService;
-}
-
-final NetworkServiceProxy _networkService = _initNetworkService();
-
-class Response {
-  ByteData body;
-
-  Response(this.body);
-
-  String bodyAsString() {
-    if (body == null)
-      return null;
-    return new String.fromCharCodes(new Uint8List.view(body.buffer));
-  }
-}
-
-Future<UrlResponse> fetch(UrlRequest request) async {
-  UrlLoaderProxy loader = new UrlLoaderProxy.unbound();
-  try {
-    _networkService.ptr.createUrlLoader(loader);
-    UrlResponse response = (await loader.ptr.start(request)).response;
-    return response;
-  } catch (e) {
-    print("NetworkService unavailable $e");
-    return new UrlResponse()..statusCode = 500;
-  } finally {
-    loader.close();
-  }
-}
-
-Future<UrlResponse> fetchUrl(String relativeUrl) {
-  String url = Uri.base.resolve(relativeUrl).toString();
-  UrlRequest request = new UrlRequest()
-    ..url = url
-    ..autoFollowRedirects = true;
-  return fetch(request);
-}
-
-Future<Response> fetchBody(String relativeUrl) async {
-  UrlResponse response = await fetchUrl(relativeUrl);
-  if (response.body == null) return new Response(null);
-
-  ByteData data = await core.DataPipeDrainer.drainHandle(response.body);
-  return new Response(data);
-}
-
-Future<String> fetchString(String relativeUrl) async {
-  Response response = await fetchBody(relativeUrl);
-  return response.bodyAsString();
-}
diff --git a/sky/packages/sky/lib/src/services/image_cache.dart b/sky/packages/sky/lib/src/services/image_cache.dart
deleted file mode 100644
index 8826477..0000000
--- a/sky/packages/sky/lib/src/services/image_cache.dart
+++ /dev/null
@@ -1,35 +0,0 @@
-// Copyright 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 'dart:async';
-import 'dart:ui' as ui;
-
-import 'package:mojo/mojo/url_response.mojom.dart';
-
-import 'fetch.dart';
-import 'image_decoder.dart';
-import 'image_resource.dart';
-
-Future<ui.Image> _fetchImage(String url) async {
-  UrlResponse response = await fetchUrl(url);
-  if (response.statusCode >= 400) {
-    print("Failed (${response.statusCode}) to load image $url");
-    return null;
-  }
-  return await decodeImageFromDataPipe(response.body);
-}
-
-class _ImageCache {
-  _ImageCache._();
-
-  final Map<String, ImageResource> _cache = new Map<String, ImageResource>();
-
-  ImageResource load(String url) {
-    return _cache.putIfAbsent(url, () {
-      return new ImageResource(_fetchImage(url));
-    });
-  }
-}
-
-final _ImageCache imageCache = new _ImageCache._();
diff --git a/sky/packages/sky/lib/src/services/image_decoder.dart b/sky/packages/sky/lib/src/services/image_decoder.dart
deleted file mode 100644
index fcba7ec..0000000
--- a/sky/packages/sky/lib/src/services/image_decoder.dart
+++ /dev/null
@@ -1,25 +0,0 @@
-// Copyright 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 'dart:async';
-import 'dart:typed_data';
-import 'dart:ui' as ui;
-
-import 'package:mojo/core.dart' show MojoDataPipeConsumer;
-
-Future<ui.Image> decodeImageFromDataPipe(MojoDataPipeConsumer consumerHandle) {
-  Completer<ui.Image> completer = new Completer<ui.Image>();
-  ui.decodeImageFromDataPipe(consumerHandle.handle.h, (ui.Image image) {
-    completer.complete(image);
-  });
-  return completer.future;
-}
-
-Future<ui.Image> decodeImageFromList(Uint8List list) {
-  Completer<ui.Image> completer = new Completer<ui.Image>();
-  ui.decodeImageFromList(list, (ui.Image image) {
-    completer.complete(image);
-  });
-  return completer.future;
-}
diff --git a/sky/packages/sky/lib/src/services/image_resource.dart b/sky/packages/sky/lib/src/services/image_resource.dart
deleted file mode 100644
index 0ac5e2f..0000000
--- a/sky/packages/sky/lib/src/services/image_resource.dart
+++ /dev/null
@@ -1,67 +0,0 @@
-// Copyright 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 'dart:async';
-import 'dart:ui' as ui;
-
-/// A callback for when the image is available.
-typedef void ImageListener(ui.Image image);
-
-/// A handle to an image resource
-///
-/// ImageResource represents a handle to a [ui.Image] object. The underlying
-/// image object might change over time, either because the image is animating
-/// or because the underlying image resource was mutated.
-class ImageResource {
-  ImageResource(this._futureImage) {
-    _futureImage.then(_handleImageLoaded, onError: _handleImageError);
-  }
-
-  bool _resolved = false;
-  Future<ui.Image> _futureImage;
-  ui.Image _image;
-  final List<ImageListener> _listeners = new List<ImageListener>();
-
-  /// The first concrete [ui.Image] object represented by this handle.
-  ///
-  /// Instead of receivingly only the first image, most clients will want to
-  /// [addListener] to be notified whenever a a concrete image is available.
-  Future<ui.Image> get first => _futureImage;
-
-  /// Adds a listener callback that is called whenever a concrete [ui.Image]
-  /// object is available. Note: If a concrete image is available currently,
-  /// this object will call the listener synchronously.
-  void addListener(ImageListener listener) {
-    _listeners.add(listener);
-    if (_resolved)
-      listener(_image);
-  }
-
-  /// Stop listening for new concrete [ui.Image] objects.
-  void removeListener(ImageListener listener) {
-    _listeners.remove(listener);
-  }
-
-  void _handleImageLoaded(ui.Image image) {
-    _image = image;
-    _resolved = true;
-    _notifyListeners();
-  }
-
-  void _handleImageError(e, stackTrace) {
-    print('Failed to load image: $e\nStack trace: $stackTrace');
-  }
-
-  void _notifyListeners() {
-    assert(_resolved);
-    List<ImageListener> localListeners = new List<ImageListener>.from(_listeners);
-    for (ImageListener listener in localListeners) {
-      try {
-        listener(_image);
-      } catch(e) {
-        print('Image listener had exception: $e');
-      }
-    }
-  }
-}
diff --git a/sky/packages/sky/lib/src/services/keyboard.dart b/sky/packages/sky/lib/src/services/keyboard.dart
deleted file mode 100644
index a1dfa79..0000000
--- a/sky/packages/sky/lib/src/services/keyboard.dart
+++ /dev/null
@@ -1,112 +0,0 @@
-// Copyright 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 'dart:async';
-
-import 'package:mojo_services/keyboard/keyboard.mojom.dart';
-
-import 'shell.dart';
-
-export 'package:mojo_services/keyboard/keyboard.mojom.dart';
-
-class _KeyboardConnection {
-
-  _KeyboardConnection() {
-    proxy = new KeyboardServiceProxy.unbound();
-    shell.connectToService("mojo:keyboard", proxy);
-  }
-
-  KeyboardServiceProxy proxy;
-  KeyboardService get keyboardService => proxy.ptr;
-
-  static final _KeyboardConnection instance = new _KeyboardConnection();
-}
-
-class Keyboard {
-
-  Keyboard(this.service);
-
-  // The service is exposed in case you need direct access.
-  // However, as a general rule, you should be able to do
-  // most of what you need using only this class.
-  final KeyboardService service;
-
-  KeyboardHandle _currentHandle;
-
-  bool _hidePending = false;
-
-  KeyboardHandle show(KeyboardClientStub stub, KeyboardType keyboardType) {
-    assert(stub != null);
-    if (_currentHandle != null) {
-      if (_currentHandle.stub == stub)
-        return _currentHandle;
-      _currentHandle.release();
-    }
-    _currentHandle = new KeyboardHandle._show(this, stub, keyboardType);
-    return _currentHandle;
-  }
-
-  void _scheduleHide() {
-    if (_hidePending) return;
-    _hidePending = true;
-
-    // Schedule a deferred task that hides the keyboard.  If someone else shows
-    // the keyboard during this update cycle, then the task will do nothing.
-    scheduleMicrotask(() {
-      _hidePending = false;
-      if (_currentHandle == null) {
-        service.hide();
-      }
-    });
-  }
-
-}
-
-class KeyboardHandle {
-
-  KeyboardHandle._show(Keyboard keyboard, this.stub, KeyboardType keyboardType) : _keyboard = keyboard {
-    _keyboard.service.show(stub, keyboardType);
-    _attached = true;
-  }
-
-  KeyboardHandle._unattached(Keyboard keyboard) : _keyboard = keyboard, stub = null, _attached = false;
-  static final unattached = new KeyboardHandle._unattached(keyboard);
-
-  final Keyboard _keyboard;
-  final KeyboardClientStub stub;
-
-  bool _attached;
-  bool get attached => _attached;
-
-  void showByRequest() {
-    assert(_attached);
-    assert(_keyboard._currentHandle == this);
-    _keyboard.service.showByRequest();
-  }
-
-  void release() {
-    if (_attached) {
-      assert(_keyboard._currentHandle == this);
-      _attached = false;
-      _keyboard._currentHandle = null;
-      _keyboard._scheduleHide();
-    }
-    assert(_keyboard._currentHandle != this);
-  }
-
-  void setText(String text) {
-    assert(_attached);
-    assert(_keyboard._currentHandle == this);
-    _keyboard.service.setText(text);
-  }
-
-  void setSelection(int start, int end) {
-    assert(_attached);
-    assert(_keyboard._currentHandle == this);
-    _keyboard.service.setSelection(start, end);
-  }
-
-}
-
-final Keyboard keyboard = new Keyboard(_KeyboardConnection.instance.keyboardService);
diff --git a/sky/packages/sky/lib/src/services/service_registry.dart b/sky/packages/sky/lib/src/services/service_registry.dart
deleted file mode 100644
index 66424f3..0000000
--- a/sky/packages/sky/lib/src/services/service_registry.dart
+++ /dev/null
@@ -1,18 +0,0 @@
-// Copyright 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 'dart:ui_internals' as internals;
-
-import 'package:mojo_services/mojo/service_registry.mojom.dart';
-import 'package:mojo/core.dart' as core;
-
-ServiceRegistryProxy _initServiceRegistryProxy() {
-  core.MojoHandle serviceRegistryHandle = new core.MojoHandle(internals.takeShellProxyHandle());
-  if (!serviceRegistryHandle.isValid)
-    return null;
-  return new ServiceRegistryProxy.fromHandle(serviceRegistryHandle);
-}
-
-final ServiceRegistryProxy _serviceRegistryProxy = _initServiceRegistryProxy();
-final ServiceRegistry serviceRegistry = _serviceRegistryProxy?.ptr;
diff --git a/sky/packages/sky/lib/src/services/shell.dart b/sky/packages/sky/lib/src/services/shell.dart
deleted file mode 100644
index 86856c8..0000000
--- a/sky/packages/sky/lib/src/services/shell.dart
+++ /dev/null
@@ -1,78 +0,0 @@
-// Copyright 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 'dart:ui_internals' as internals;
-
-import 'package:mojo/application.dart';
-import 'package:mojo/bindings.dart' as bindings;
-import 'package:mojo/core.dart' as core;
-import 'package:mojo/mojo/service_provider.mojom.dart';
-import 'package:mojo/mojo/shell.mojom.dart';
-
-// A replacement for shell.connectToService.  Implementations should return true
-// if they handled the request, or false if the request should fall through
-// to the default requestService.
-typedef bool OverrideConnectToService(String url, Object proxy);
-
-// Set this to intercept calls to shell.connectToService and supply an
-// alternative implementation of a service (for example, a mock for testing).
-OverrideConnectToService overrideConnectToService;
-
-ShellProxy _initShellProxy() {
-  core.MojoHandle shellHandle = new core.MojoHandle(internals.takeShellProxyHandle());
-  if (!shellHandle.isValid)
-    return null;
-  return new ShellProxy.fromHandle(shellHandle);
-}
-
-ApplicationConnection _initEmbedderConnection() {
-  core.MojoHandle servicesHandle = new core.MojoHandle(internals.takeServicesProvidedByEmbedder());
-  core.MojoHandle exposedServicesHandle = new core.MojoHandle(internals.takeServicesProvidedToEmbedder());
-  ServiceProviderProxy services = servicesHandle.isValid ?
-      new ServiceProviderProxy.fromHandle(servicesHandle) : null;
-  ServiceProviderStub exposedServices = exposedServicesHandle.isValid ?
-      new ServiceProviderStub.fromHandle(exposedServicesHandle) : null;
-  return new ApplicationConnection(exposedServices, services);
-}
-
-final ShellProxy _shellProxy = _initShellProxy();
-final Shell _shell = _shellProxy?.ptr;
-final ApplicationConnection _embedderConnection = _initEmbedderConnection();
-
-class _Shell {
-  _Shell._();
-
-  ApplicationConnection connectToApplication(String url) {
-    if (_shell == null)
-      return null;
-    ServiceProviderProxy services = new ServiceProviderProxy.unbound();
-    ServiceProviderStub exposedServices = new ServiceProviderStub.unbound();
-    _shell.connectToApplication(url, services, exposedServices);
-    return new ApplicationConnection(exposedServices, services);
-  }
-
-  void _connectToService(String url, bindings.ProxyBase proxy) {
-    if (_shell == null || url == null) {
-      // If we don't have a shell or a url, we try to get the services from the
-      // embedder directly instead of using the shell to connect.
-      _embedderConnection.requestService(proxy);
-      return;
-    }
-
-    ServiceProviderProxy services = new ServiceProviderProxy.unbound();
-    _shell.connectToApplication(url, services, null);
-    var pipe = new core.MojoMessagePipe();
-    proxy.impl.bind(pipe.endpoints[0]);
-    services.ptr.connectToService(proxy.name, pipe.endpoints[1]);
-    services.close();
-  }
-
-  void connectToService(String url, Object proxy) {
-    if (overrideConnectToService != null && overrideConnectToService(url, proxy))
-      return;
-    _connectToService(url, proxy);
-  }
-}
-
-final _Shell shell = new _Shell._();
diff --git a/sky/packages/sky/lib/src/widgets/animated_container.dart b/sky/packages/sky/lib/src/widgets/animated_container.dart
deleted file mode 100644
index 8a1831b..0000000
--- a/sky/packages/sky/lib/src/widgets/animated_container.dart
+++ /dev/null
@@ -1,247 +0,0 @@
-// Copyright 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:flutter/animation.dart';
-
-import 'basic.dart';
-import 'framework.dart';
-
-import 'package:vector_math/vector_math_64.dart';
-
-class AnimatedBoxConstraintsValue extends AnimatedValue<BoxConstraints> {
-  AnimatedBoxConstraintsValue(BoxConstraints begin, { BoxConstraints end, Curve curve, Curve reverseCurve })
-    : super(begin, end: end, curve: curve, reverseCurve: reverseCurve);
-
-  BoxConstraints lerp(double t) => BoxConstraints.lerp(begin, end, t);
-}
-
-class AnimatedBoxDecorationValue extends AnimatedValue<BoxDecoration> {
-  AnimatedBoxDecorationValue(BoxDecoration begin, { BoxDecoration end, Curve curve, Curve reverseCurve })
-    : super(begin, end: end, curve: curve, reverseCurve: reverseCurve);
-
-  BoxDecoration lerp(double t) => BoxDecoration.lerp(begin, end, t);
-}
-
-class AnimatedEdgeDimsValue extends AnimatedValue<EdgeDims> {
-  AnimatedEdgeDimsValue(EdgeDims begin, { EdgeDims end, Curve curve, Curve reverseCurve })
-    : super(begin, end: end, curve: curve, reverseCurve: reverseCurve);
-
-  EdgeDims lerp(double t) => EdgeDims.lerp(begin, end, t);
-}
-
-class AnimatedMatrix4Value extends AnimatedValue<Matrix4> {
-  AnimatedMatrix4Value(Matrix4 begin, { Matrix4 end, Curve curve, Curve reverseCurve })
-    : super(begin, end: end, curve: curve, reverseCurve: reverseCurve);
-
-  Matrix4 lerp(double t) {
-    // TODO(mpcomplete): Animate the full matrix. Will animating the cells
-    // separately work?
-    Vector3 beginT = begin.getTranslation();
-    Vector3 endT = end.getTranslation();
-    Vector3 lerpT = beginT*(1.0-t) + endT*t;
-    return new Matrix4.identity()..translate(lerpT);
-  }
-}
-
-class AnimatedContainer extends StatefulComponent {
-  AnimatedContainer({
-    Key key,
-    this.child,
-    this.constraints,
-    this.decoration,
-    this.foregroundDecoration,
-    this.margin,
-    this.padding,
-    this.transform,
-    this.width,
-    this.height,
-    this.curve: Curves.linear,
-    this.duration
-  }) : super(key: key) {
-    assert(margin == null || margin.isNonNegative);
-    assert(padding == null || padding.isNonNegative);
-    assert(curve != null);
-    assert(duration != null);
-  }
-
-  final Widget child;
-
-  final BoxConstraints constraints;
-  final BoxDecoration decoration;
-  final BoxDecoration foregroundDecoration;
-  final EdgeDims margin;
-  final EdgeDims padding;
-  final Matrix4 transform;
-  final double width;
-  final double height;
-
-  final Curve curve;
-  final Duration duration;
-
-  _AnimatedContainerState createState() => new _AnimatedContainerState();
-}
-
-class _AnimatedContainerState extends State<AnimatedContainer> {
-  AnimatedBoxConstraintsValue _constraints;
-  AnimatedBoxDecorationValue _decoration;
-  AnimatedBoxDecorationValue _foregroundDecoration;
-  AnimatedEdgeDimsValue _margin;
-  AnimatedEdgeDimsValue _padding;
-  AnimatedMatrix4Value _transform;
-  AnimatedValue<double> _width;
-  AnimatedValue<double> _height;
-
-  Performance _performance;
-
-  void initState() {
-    super.initState();
-    _performance = new Performance(duration: config.duration, debugLabel: '${config.toStringShort()}')
-      ..timing = new AnimationTiming(curve: config.curve)
-      ..addListener(_updateAllVariables);
-    _configAllVariables();
-  }
-
-  void didUpdateConfig(AnimatedContainer oldConfig) {
-    _performance
-      ..duration = config.duration
-      ..timing.curve = config.curve;
-    if (_configAllVariables()) {
-      _performance.progress = 0.0;
-      _performance.play();
-    }
-  }
-
-  void dispose() {
-    _performance.stop();
-    super.dispose();
-  }
-
-  void _updateVariable(Animatable variable) {
-    if (variable != null)
-      _performance.updateVariable(variable);
-  }
-
-  void _updateAllVariables() {
-    setState(() {
-      _updateVariable(_constraints);
-      _updateVariable(_decoration);
-      _updateVariable(_foregroundDecoration);
-      _updateVariable(_margin);
-      _updateVariable(_padding);
-      _updateVariable(_transform);
-      _updateVariable(_width);
-      _updateVariable(_height);
-    });
-  }
-
-  bool _configVariable(AnimatedValue variable, dynamic targetValue) {
-    dynamic currentValue = variable.value;
-    variable.end = targetValue;
-    variable.begin = currentValue;
-    return currentValue != targetValue;
-  }
-
-  bool _configAllVariables() {
-    bool needsAnimation = false;
-    if (config.constraints != null) {
-      _constraints ??= new AnimatedBoxConstraintsValue(config.constraints);
-      if (_configVariable(_constraints, config.constraints))
-        needsAnimation = true;
-    } else {
-      _constraints = null;
-    }
-
-    if (config.decoration != null) {
-      _decoration ??= new AnimatedBoxDecorationValue(config.decoration);
-      if (_configVariable(_decoration, config.decoration))
-        needsAnimation = true;
-    } else {
-      _decoration = null;
-    }
-
-    if (config.foregroundDecoration != null) {
-      _foregroundDecoration ??= new AnimatedBoxDecorationValue(config.foregroundDecoration);
-      if (_configVariable(_foregroundDecoration, config.foregroundDecoration))
-        needsAnimation = true;
-    } else {
-      _foregroundDecoration = null;
-    }
-
-    if (config.margin != null) {
-      _margin ??= new AnimatedEdgeDimsValue(config.margin);
-      if (_configVariable(_margin, config.margin))
-        needsAnimation = true;
-    } else {
-      _margin = null;
-    }
-
-    if (config.padding != null) {
-      _padding ??= new AnimatedEdgeDimsValue(config.padding);
-      if (_configVariable(_padding, config.padding))
-        needsAnimation = true;
-    } else {
-      _padding = null;
-    }
-
-    if (config.transform != null) {
-      _transform ??= new AnimatedMatrix4Value(config.transform);
-      if (_configVariable(_transform, config.transform))
-        needsAnimation = true;
-    } else {
-      _transform = null;
-    }
-
-    if (config.width != null) {
-      _width ??= new AnimatedValue<double>(config.width);
-      if (_configVariable(_width, config.width))
-        needsAnimation = true;
-    } else {
-      _width = null;
-    }
-
-    if (config.height != null) {
-      _height ??= new AnimatedValue<double>(config.height);
-      if (_configVariable(_height, config.height))
-        needsAnimation = true;
-    } else {
-      _height = null;
-    }
-
-    return needsAnimation;
-  }
-
-  Widget build(BuildContext context) {
-    return new Container(
-      child: config.child,
-      constraints: _constraints?.value,
-      decoration: _decoration?.value,
-      foregroundDecoration: _foregroundDecoration?.value,
-      margin: _margin?.value,
-      padding: _padding?.value,
-      transform: _transform?.value,
-      width: _width?.value,
-      height: _height?.value
-    );
-  }
-
-  void debugFillDescription(List<String> description) {
-    super.debugFillDescription(description);
-    if (_constraints != null)
-      description.add('has constraints');
-    if (_decoration != null)
-      description.add('has background');
-    if (_foregroundDecoration != null)
-      description.add('has foreground');
-    if (_margin != null)
-      description.add('has margin');
-    if (_padding != null)
-      description.add('has padding');
-    if (_transform != null)
-      description.add('has transform');
-    if (_width != null)
-      description.add('has width');
-    if (_height != null)
-      description.add('has height');
-  }
-}
diff --git a/sky/packages/sky/lib/src/widgets/basic.dart b/sky/packages/sky/lib/src/widgets/basic.dart
deleted file mode 100644
index a99e007..0000000
--- a/sky/packages/sky/lib/src/widgets/basic.dart
+++ /dev/null
@@ -1,1304 +0,0 @@
-// Copyright 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 'dart:typed_data';
-import 'dart:ui' as ui;
-
-import 'package:flutter/rendering.dart';
-import 'package:flutter/services.dart';
-
-import 'framework.dart';
-
-export 'dart:typed_data' show Uint8List;
-export 'package:flutter/rendering.dart' show
-    BackgroundImage,
-    BlockDirection,
-    Border,
-    BorderSide,
-    BoxConstraints,
-    BoxDecoration,
-    BoxDecorationPosition,
-    BoxShadow,
-    Canvas,
-    Color,
-    ColorFilter,
-    EdgeDims,
-    FlexAlignItems,
-    FlexDirection,
-    FlexJustifyContent,
-    FontStyle,
-    FontWeight,
-    FractionalOffset,
-    Gradient,
-    HitTestBehavior,
-    ImageFit,
-    ImageRepeat,
-    InputEvent,
-    LinearGradient,
-    Matrix4,
-    Offset,
-    OneChildLayoutDelegate,
-    Paint,
-    Path,
-    PlainTextSpan,
-    Point,
-    PointerInputEvent,
-    RadialGradient,
-    Rect,
-    ScrollDirection,
-    Shape,
-    Size,
-    StyledTextSpan,
-    TextAlign,
-    TextBaseline,
-    TextDecoration,
-    TextDecorationStyle,
-    TextSpan,
-    TextStyle,
-    TransferMode,
-    ValueChanged,
-    VoidCallback,
-    bold,
-    normal,
-    underline,
-    overline,
-    lineThrough;
-
-
-// PAINTING NODES
-
-class Opacity extends OneChildRenderObjectWidget {
-  Opacity({ Key key, this.opacity, Widget child })
-    : super(key: key, child: child) {
-    assert(opacity >= 0.0 && opacity <= 1.0);
-  }
-
-  final double opacity;
-
-  RenderOpacity createRenderObject() => new RenderOpacity(opacity: opacity);
-
-  void updateRenderObject(RenderOpacity renderObject, Opacity oldWidget) {
-    renderObject.opacity = opacity;
-  }
-
-  void debugFillDescription(List<String> description) {
-    super.debugFillDescription(description);
-    description.add('opacity: $opacity');
-  }
-}
-
-class ShaderMask extends OneChildRenderObjectWidget {
-  ShaderMask({
-    Key key,
-    this.shaderCallback,
-    this.transferMode: TransferMode.modulate,
-    Widget child
-  }) : super(key: key, child: child) {
-    assert(shaderCallback != null);
-    assert(transferMode != null);
-  }
-
-  final ShaderCallback shaderCallback;
-  final TransferMode transferMode;
-
-  RenderShaderMask createRenderObject() {
-    return new RenderShaderMask(
-      shaderCallback: shaderCallback,
-      transferMode: transferMode
-    );
-  }
-
-  void updateRenderObject(RenderShaderMask renderObject, ShaderMask oldWidget) {
-    renderObject.shaderCallback = shaderCallback;
-    renderObject.transferMode = transferMode;
-  }
-}
-
-class DecoratedBox extends OneChildRenderObjectWidget {
-  DecoratedBox({
-    Key key,
-    this.decoration,
-    this.position: BoxDecorationPosition.background,
-    Widget child
-  }) : super(key: key, child: child) {
-    assert(decoration != null);
-    assert(position != null);
-  }
-
-  final BoxDecoration decoration;
-  final BoxDecorationPosition position;
-
-  RenderObject createRenderObject() => new RenderDecoratedBox(decoration: decoration, position: position);
-
-  void updateRenderObject(RenderDecoratedBox renderObject, DecoratedBox oldWidget) {
-    renderObject.decoration = decoration;
-    renderObject.position = position;
-  }
-}
-
-class CustomPaint extends OneChildRenderObjectWidget {
-  CustomPaint({ Key key, this.onPaint, this.onHitTest, this.token, Widget child })
-    : super(key: key, child: child) {
-    assert(onPaint != null);
-  }
-
-  /// This widget repaints whenver you supply a new onPaint callback.
-  ///
-  /// If you use an anonymous closure for the onPaint callback, you'll trigger
-  /// a repaint every time you build this widget, which might not be what you
-  /// intend. Instead, consider passing a reference to a member function, which
-  /// has a more stable identity.
-  final CustomPaintCallback onPaint;
-
-  final CustomHitTestCallback onHitTest;
-
-  /// This widget repaints whenever you supply a new token.
-  final Object token;
-
-  RenderCustomPaint createRenderObject() => new RenderCustomPaint(onPaint: onPaint, onHitTest: onHitTest);
-
-  void updateRenderObject(RenderCustomPaint renderObject, CustomPaint oldWidget) {
-    if (oldWidget.token != token)
-      renderObject.markNeedsPaint();
-    renderObject.onPaint = onPaint;
-    renderObject.onHitTest = onHitTest;
-  }
-
-  void didUnmountRenderObject(RenderCustomPaint renderObject) {
-    renderObject.onPaint = null;
-    renderObject.onHitTest = null;
-  }
-}
-
-class ClipRect extends OneChildRenderObjectWidget {
-  ClipRect({ Key key, Widget child }) : super(key: key, child: child);
-  RenderClipRect createRenderObject() => new RenderClipRect();
-}
-
-class ClipRRect extends OneChildRenderObjectWidget {
-  ClipRRect({ Key key, this.xRadius, this.yRadius, Widget child })
-    : super(key: key, child: child);
-
-  final double xRadius;
-  final double yRadius;
-
-  RenderClipRRect createRenderObject() => new RenderClipRRect(xRadius: xRadius, yRadius: yRadius);
-
-  void updateRenderObject(RenderClipRRect renderObject, ClipRRect oldWidget) {
-    renderObject.xRadius = xRadius;
-    renderObject.yRadius = yRadius;
-  }
-}
-
-class ClipOval extends OneChildRenderObjectWidget {
-  ClipOval({ Key key, Widget child }) : super(key: key, child: child);
-  RenderClipOval createRenderObject() => new RenderClipOval();
-}
-
-
-// POSITIONING AND SIZING NODES
-
-class Transform extends OneChildRenderObjectWidget {
-  Transform({ Key key, this.transform, this.origin, this.alignment, Widget child })
-    : super(key: key, child: child) {
-    assert(transform != null);
-  }
-
-  final Matrix4 transform;
-  final Offset origin;
-  final FractionalOffset alignment;
-
-  RenderTransform createRenderObject() => new RenderTransform(transform: transform, origin: origin, alignment: alignment);
-
-  void updateRenderObject(RenderTransform renderObject, Transform oldWidget) {
-    renderObject.transform = transform;
-    renderObject.origin = origin;
-    renderObject.alignment = alignment;
-  }
-}
-
-class Padding extends OneChildRenderObjectWidget {
-  Padding({ Key key, this.padding, Widget child })
-    : super(key: key, child: child) {
-    assert(padding != null);
-  }
-
-  final EdgeDims padding;
-
-  RenderPadding createRenderObject() => new RenderPadding(padding: padding);
-
-  void updateRenderObject(RenderPadding renderObject, Padding oldWidget) {
-    renderObject.padding = padding;
-  }
-}
-
-class Align extends OneChildRenderObjectWidget {
-  Align({
-    Key key,
-    this.alignment: const FractionalOffset(0.5, 0.5),
-    this.widthFactor,
-    this.heightFactor,
-    Widget child
-  }) : super(key: key, child: child);
-
-  final FractionalOffset alignment;
-  final double widthFactor;
-  final double heightFactor;
-
-  RenderPositionedBox createRenderObject() => new RenderPositionedBox(alignment: alignment, widthFactor: widthFactor, heightFactor: heightFactor);
-
-  void updateRenderObject(RenderPositionedBox renderObject, Align oldWidget) {
-    renderObject.alignment = alignment;
-    renderObject.widthFactor = widthFactor;
-    renderObject.heightFactor = heightFactor;
-  }
-}
-
-class Center extends Align {
-  Center({ Key key, widthFactor, heightFactor, Widget child })
-    : super(key: key, widthFactor: widthFactor, heightFactor: heightFactor, child: child);
-}
-
-class CustomOneChildLayout extends OneChildRenderObjectWidget {
-  CustomOneChildLayout({
-    Key key,
-    this.delegate,
-    this.token,
-    Widget child
-  }) : super(key: key, child: child) {
-    assert(delegate != null);
-  }
-
-  /// A long-lived delegate that controls the layout of this widget.
-  ///
-  /// Whenever the delegate changes, we need to recompute the layout of this
-  /// widget, which means you might not want to create a new delegate instance
-  /// every time you build this widget. Instead, consider using a long-lived
-  /// deletate (perhaps held in a component's state) that you re-use every time
-  /// you build this widget.
-  final OneChildLayoutDelegate delegate;
-  final Object token;
-
-  RenderCustomOneChildLayoutBox createRenderObject() => new RenderCustomOneChildLayoutBox(delegate: delegate);
-
-  void updateRenderObject(RenderCustomOneChildLayoutBox renderObject, CustomOneChildLayout oldWidget) {
-    if (oldWidget.token != token)
-      renderObject.markNeedsLayout();
-    renderObject.delegate = delegate;
-  }
-}
-
-class LayoutId extends ParentDataWidget {
-  LayoutId({
-    Key key,
-    Widget child,
-    this.id
-  }) : super(key: key, child: child);
-
-  final Object id;
-
-  void debugValidateAncestor(Widget ancestor) {
-    assert(() {
-      'LayoutId must placed inside a CustomMultiChildLayout';
-      return ancestor is CustomMultiChildLayout;
-    });
-  }
-
-  void applyParentData(RenderObject renderObject) {
-    assert(renderObject.parentData is MultiChildLayoutParentData);
-    final MultiChildLayoutParentData parentData = renderObject.parentData;
-    if (parentData.id != id) {
-      parentData.id = id;
-      AbstractNode targetParent = renderObject.parent;
-      if (targetParent is RenderObject)
-        targetParent.markNeedsLayout();
-    }
-  }
-
-  void debugFillDescription(List<String> description) {
-    super.debugFillDescription(description);
-    description.add('id: $id');
-  }
-}
-
-class CustomMultiChildLayout extends MultiChildRenderObjectWidget {
-  CustomMultiChildLayout(List<Widget> children, {
-    Key key,
-    this.delegate,
-    this.token
-  }) : super(key: key, children: children) {
-    assert(delegate != null);
-  }
-
-  final MultiChildLayoutDelegate delegate;
-  final Object token;
-
-  RenderCustomMultiChildLayoutBox createRenderObject() {
-    return new RenderCustomMultiChildLayoutBox(delegate: delegate);
-  }
-
-  void updateRenderObject(RenderCustomMultiChildLayoutBox renderObject, CustomMultiChildLayout oldWidget) {
-    if (oldWidget.token != token)
-      renderObject.markNeedsLayout();
-    renderObject.delegate = delegate;
-  }
-}
-
-class SizedBox extends OneChildRenderObjectWidget {
-  SizedBox({ Key key, this.width, this.height, Widget child })
-    : super(key: key, child: child);
-
-  final double width;
-  final double height;
-
-  RenderConstrainedBox createRenderObject() => new RenderConstrainedBox(
-    additionalConstraints: _additionalConstraints
-  );
-
-  BoxConstraints get _additionalConstraints {
-    BoxConstraints result = const BoxConstraints();
-    if (width != null)
-      result = result.tightenWidth(width);
-    if (height != null)
-      result = result.tightenHeight(height);
-    return result;
-  }
-
-  void updateRenderObject(RenderConstrainedBox renderObject, SizedBox oldWidget) {
-    renderObject.additionalConstraints = _additionalConstraints;
-  }
-
-  void debugFillDescription(List<String> description) {
-    super.debugFillDescription(description);
-    if (width != null)
-      description.add('width: $width');
-    if (height != null)
-      description.add('height: $height');
-  }
-}
-
-class ConstrainedBox extends OneChildRenderObjectWidget {
-  ConstrainedBox({ Key key, this.constraints, Widget child })
-    : super(key: key, child: child) {
-    assert(constraints != null);
-  }
-
-  final BoxConstraints constraints;
-
-  RenderConstrainedBox createRenderObject() => new RenderConstrainedBox(additionalConstraints: constraints);
-
-  void updateRenderObject(RenderConstrainedBox renderObject, ConstrainedBox oldWidget) {
-    renderObject.additionalConstraints = constraints;
-  }
-
-  void debugFillDescription(List<String> description) {
-    super.debugFillDescription(description);
-    description.add('$constraints');
-  }
-}
-
-class FractionallySizedBox extends OneChildRenderObjectWidget {
-  FractionallySizedBox({ Key key, this.width, this.height, Widget child })
-    : super(key: key, child: child);
-
-  final double width;
-  final double height;
-
-  RenderFractionallySizedBox createRenderObject() => new RenderFractionallySizedBox(
-    widthFactor: width,
-    heightFactor: height
-  );
-
-  void updateRenderObject(RenderFractionallySizedBox renderObject, FractionallySizedBox oldWidget) {
-    renderObject.widthFactor = width;
-    renderObject.heightFactor = height;
-  }
-
-  void debugFillDescription(List<String> description) {
-    super.debugFillDescription(description);
-    if (width != null)
-      description.add('width: $width');
-    if (height != null)
-      description.add('height: $height');
-  }
-}
-
-class OverflowBox extends OneChildRenderObjectWidget {
-  OverflowBox({ Key key, this.minWidth, this.maxWidth, this.minHeight, this.maxHeight, Widget child })
-    : super(key: key, child: child);
-
-  final double minWidth;
-  final double maxWidth;
-  final double minHeight;
-  final double maxHeight;
-
-  RenderOverflowBox createRenderObject() => new RenderOverflowBox(
-    minWidth: minWidth,
-    maxWidth: maxWidth,
-    minHeight: minHeight,
-    maxHeight: maxHeight
-  );
-
-  void updateRenderObject(RenderOverflowBox renderObject, OverflowBox oldWidget) {
-    renderObject.minWidth = minWidth;
-    renderObject.maxWidth = maxWidth;
-    renderObject.minHeight = minHeight;
-    renderObject.maxHeight = maxHeight;
-  }
-}
-
-class SizedOverflowBox extends OneChildRenderObjectWidget {
-  SizedOverflowBox({ Key key, this.size, Widget child })
-    : super(key: key, child: child);
-
-  final Size size;
-
-  RenderSizedOverflowBox createRenderObject() => new RenderSizedOverflowBox(requestedSize: size);
-
-  void updateRenderObject(RenderSizedOverflowBox renderObject, SizedOverflowBox oldWidget) {
-    renderObject.requestedSize = size;
-  }
-}
-
-class OffStage extends OneChildRenderObjectWidget {
-  OffStage({ Key key, Widget child })
-    : super(key: key, child: child);
-
-  RenderOffStage createRenderObject() => new RenderOffStage();
-}
-
-class AspectRatio extends OneChildRenderObjectWidget {
-  AspectRatio({ Key key, this.aspectRatio, Widget child })
-    : super(key: key, child: child) {
-    assert(aspectRatio != null);
-  }
-
-  final double aspectRatio;
-
-  RenderAspectRatio createRenderObject() => new RenderAspectRatio(aspectRatio: aspectRatio);
-
-  void updateRenderObject(RenderAspectRatio renderObject, AspectRatio oldWidget) {
-    renderObject.aspectRatio = aspectRatio;
-  }
-
-  void debugFillDescription(List<String> description) {
-    super.debugFillDescription(description);
-    description.add('aspectRatio: $aspectRatio');
-  }
-}
-
-class IntrinsicWidth extends OneChildRenderObjectWidget {
-  IntrinsicWidth({ Key key, this.stepWidth, this.stepHeight, Widget child })
-    : super(key: key, child: child);
-
-  final double stepWidth;
-  final double stepHeight;
-
-  RenderIntrinsicWidth createRenderObject() => new RenderIntrinsicWidth(stepWidth: stepWidth, stepHeight: stepHeight);
-
-  void updateRenderObject(RenderIntrinsicWidth renderObject, IntrinsicWidth oldWidget) {
-    renderObject.stepWidth = stepWidth;
-    renderObject.stepHeight = stepHeight;
-  }
-}
-
-class IntrinsicHeight extends OneChildRenderObjectWidget {
-  IntrinsicHeight({ Key key, Widget child }) : super(key: key, child: child);
-  RenderIntrinsicHeight createRenderObject() => new RenderIntrinsicHeight();
-}
-
-class Baseline extends OneChildRenderObjectWidget {
-  Baseline({ Key key, this.baseline, this.baselineType: TextBaseline.alphabetic, Widget child })
-    : super(key: key, child: child) {
-    assert(baseline != null);
-    assert(baselineType != null);
-  }
-
-  final double baseline; // in pixels
-  final TextBaseline baselineType;
-
-  RenderBaseline createRenderObject() => new RenderBaseline(baseline: baseline, baselineType: baselineType);
-
-  void updateRenderObject(RenderBaseline renderObject, Baseline oldWidget) {
-    renderObject.baseline = baseline;
-    renderObject.baselineType = baselineType;
-  }
-}
-
-class Viewport extends OneChildRenderObjectWidget {
-  Viewport({
-    Key key,
-    this.scrollDirection: ScrollDirection.vertical,
-    this.scrollOffset: Offset.zero,
-    Widget child
-  }) : super(key: key, child: child) {
-    assert(scrollDirection != null);
-    assert(scrollOffset != null);
-  }
-
-  final ScrollDirection scrollDirection;
-  final Offset scrollOffset;
-
-  RenderViewport createRenderObject() => new RenderViewport(scrollDirection: scrollDirection, scrollOffset: scrollOffset);
-
-  void updateRenderObject(RenderViewport renderObject, Viewport oldWidget) {
-    // Order dependency: RenderViewport validates scrollOffset based on scrollDirection.
-    renderObject.scrollDirection = scrollDirection;
-    renderObject.scrollOffset = scrollOffset;
-  }
-}
-
-class SizeObserver extends OneChildRenderObjectWidget {
-  SizeObserver({ Key key, this.onSizeChanged, Widget child })
-    : super(key: key, child: child) {
-    assert(onSizeChanged != null);
-  }
-
-  final SizeChangedCallback onSizeChanged;
-
-  RenderSizeObserver createRenderObject() => new RenderSizeObserver(onSizeChanged: onSizeChanged);
-
-  void updateRenderObject(RenderSizeObserver renderObject, SizeObserver oldWidget) {
-    renderObject.onSizeChanged = onSizeChanged;
-  }
-
-  void didUnmountRenderObject(RenderSizeObserver renderObject) {
-    renderObject.onSizeChanged = null;
-  }
-}
-
-
-// CONVENIENCE CLASS TO COMBINE COMMON PAINTING, POSITIONING, AND SIZING NODES
-
-class Container extends StatelessComponent {
-
-  Container({
-    Key key,
-    this.child,
-    this.constraints,
-    this.decoration,
-    this.foregroundDecoration,
-    this.margin,
-    this.padding,
-    this.transform,
-    this.width,
-    this.height
-  }) : super(key: key) {
-    assert(margin == null || margin.isNonNegative);
-    assert(padding == null || padding.isNonNegative);
-    assert(decoration == null || decoration.shape != Shape.circle || decoration.borderRadius == null); // can't have a border radius if you're a circle
-  }
-
-  final Widget child;
-  final BoxConstraints constraints;
-  final BoxDecoration decoration;
-  final BoxDecoration foregroundDecoration;
-  final EdgeDims margin;
-  final EdgeDims padding;
-  final Matrix4 transform;
-  final double width;
-  final double height;
-
-  EdgeDims get _paddingIncludingBorder {
-    if (decoration == null || decoration.border == null)
-      return padding;
-    EdgeDims borderPadding = decoration.border.dimensions;
-    if (padding == null)
-      return borderPadding;
-    return padding + borderPadding;
-  }
-
-  Widget build(BuildContext context) {
-    Widget current = child;
-
-    if (child == null && (width == null || height == null))
-      current = new ConstrainedBox(constraints: const BoxConstraints.expand());
-
-    EdgeDims effectivePadding = _paddingIncludingBorder;
-    if (effectivePadding != null)
-      current = new Padding(padding: effectivePadding, child: current);
-
-    if (decoration != null)
-      current = new DecoratedBox(decoration: decoration, child: current);
-
-    if (foregroundDecoration != null) {
-      current = new DecoratedBox(
-        decoration: foregroundDecoration,
-        position: BoxDecorationPosition.foreground,
-        child: current
-      );
-    }
-
-    if (width != null || height != null) {
-      current = new SizedBox(
-        width: width,
-        height: height,
-        child: current
-      );
-    }
-
-    if (constraints != null)
-      current = new ConstrainedBox(constraints: constraints, child: current);
-
-    if (margin != null)
-      current = new Padding(padding: margin, child: current);
-
-    if (transform != null)
-      current = new Transform(transform: transform, child: current);
-
-    return current;
-  }
-
-  void debugFillDescription(List<String> description) {
-    super.debugFillDescription(description);
-    if (constraints != null)
-      description.add('$constraints');
-    if (decoration != null)
-      description.add('has background');
-    if (foregroundDecoration != null)
-      description.add('has foreground');
-    if (margin != null)
-      description.add('margin: $margin');
-    if (padding != null)
-      description.add('padding: $padding');
-    if (transform != null)
-      description.add('has transform');
-    if (width != null)
-      description.add('width: $width');
-    if (height != null)
-      description.add('height: $height');
-  }
-
-}
-
-
-// LAYOUT NODES
-
-class BlockBody extends MultiChildRenderObjectWidget {
-  BlockBody(List<Widget> children, {
-    Key key,
-    this.direction: BlockDirection.vertical
-  }) : super(key: key, children: children) {
-    assert(direction != null);
-  }
-
-  final BlockDirection direction;
-
-  RenderBlock createRenderObject() => new RenderBlock(direction: direction);
-
-  void updateRenderObject(RenderBlock renderObject, BlockBody oldWidget) {
-    renderObject.direction = direction;
-  }
-}
-
-class Stack extends MultiChildRenderObjectWidget {
-  Stack(List<Widget> children, {
-    Key key,
-    this.alignment: const FractionalOffset(0.0, 0.0)
-  }) : super(key: key, children: children);
-
-  final FractionalOffset alignment;
-
-  RenderStack createRenderObject() => new RenderStack(alignment: alignment);
-
-  void updateRenderObject(RenderStack renderObject, Stack oldWidget) {
-    renderObject.alignment = alignment;
-  }
-}
-
-class IndexedStack extends MultiChildRenderObjectWidget {
-  IndexedStack(List<Widget> children, {
-    Key key,
-    this.alignment: const FractionalOffset(0.0, 0.0),
-    this.index: 0
-  }) : super(key: key, children: children);
-
-  final int index;
-  final FractionalOffset alignment;
-
-  RenderIndexedStack createRenderObject() => new RenderIndexedStack(index: index, alignment: alignment);
-
-  void updateRenderObject(RenderIndexedStack renderObject, IndexedStack oldWidget) {
-    super.updateRenderObject(renderObject, oldWidget);
-    renderObject.index = index;
-    renderObject.alignment = alignment;
-  }
-}
-
-class Positioned extends ParentDataWidget {
-  Positioned({
-    Key key,
-    Widget child,
-    this.top,
-    this.right,
-    this.bottom,
-    this.left
-  }) : super(key: key, child: child);
-
-  final double top;
-  final double right;
-  final double bottom;
-  final double left;
-
-  void debugValidateAncestor(Widget ancestor) {
-    assert(() {
-      'Positioned must placed inside a Stack';
-      return ancestor is Stack;
-    });
-  }
-
-  void applyParentData(RenderObject renderObject) {
-    assert(renderObject.parentData is StackParentData);
-    final StackParentData parentData = renderObject.parentData;
-    bool needsLayout = false;
-
-    if (parentData.top != top) {
-      parentData.top = top;
-      needsLayout = true;
-    }
-
-    if (parentData.right != right) {
-      parentData.right = right;
-      needsLayout = true;
-    }
-
-    if (parentData.bottom != bottom) {
-      parentData.bottom = bottom;
-      needsLayout = true;
-    }
-
-    if (parentData.left != left) {
-      parentData.left = left;
-      needsLayout = true;
-    }
-
-    if (needsLayout) {
-      AbstractNode targetParent = renderObject.parent;
-      if (targetParent is RenderObject)
-        targetParent.markNeedsLayout();
-    }
-  }
-
-  void debugFillDescription(List<String> description) {
-    super.debugFillDescription(description);
-    if (left != null)
-      description.add('left: $left');
-    if (top != null)
-      description.add('top: $top');
-    if (right != null)
-      description.add('right: $right');
-    if (bottom != null)
-      description.add('bottom: $bottom');
-  }
-}
-
-class Grid extends MultiChildRenderObjectWidget {
-  Grid(List<Widget> children, { Key key, this.maxChildExtent })
-    : super(key: key, children: children) {
-    assert(maxChildExtent != null);
-  }
-
-  final double maxChildExtent;
-
-  RenderGrid createRenderObject() => new RenderGrid(maxChildExtent: maxChildExtent);
-
-  void updateRenderObject(RenderGrid renderObject, Grid oldWidget) {
-    renderObject.maxChildExtent = maxChildExtent;
-  }
-}
-
-class Flex extends MultiChildRenderObjectWidget {
-  Flex(List<Widget> children, {
-    Key key,
-    this.direction: FlexDirection.horizontal,
-    this.justifyContent: FlexJustifyContent.start,
-    this.alignItems: FlexAlignItems.center,
-    this.textBaseline
-  }) : super(key: key, children: children) {
-    assert(direction != null);
-    assert(justifyContent != null);
-    assert(alignItems != null);
-  }
-
-  final FlexDirection direction;
-  final FlexJustifyContent justifyContent;
-  final FlexAlignItems alignItems;
-  final TextBaseline textBaseline;
-
-  RenderFlex createRenderObject() => new RenderFlex(direction: direction, justifyContent: justifyContent, alignItems: alignItems, textBaseline: textBaseline);
-
-  void updateRenderObject(RenderFlex renderObject, Flex oldWidget) {
-    renderObject.direction = direction;
-    renderObject.justifyContent = justifyContent;
-    renderObject.alignItems = alignItems;
-    renderObject.textBaseline = textBaseline;
-  }
-}
-
-class Row extends Flex {
-  Row(List<Widget> children, {
-    Key key,
-    justifyContent: FlexJustifyContent.start,
-    alignItems: FlexAlignItems.center,
-    textBaseline
-  }) : super(children, key: key, direction: FlexDirection.horizontal, justifyContent: justifyContent, alignItems: alignItems, textBaseline: textBaseline);
-}
-
-class Column extends Flex {
-  Column(List<Widget> children, {
-    Key key,
-    justifyContent: FlexJustifyContent.start,
-    alignItems: FlexAlignItems.center,
-    textBaseline
-  }) : super(children, key: key, direction: FlexDirection.vertical, justifyContent: justifyContent, alignItems: alignItems, textBaseline: textBaseline);
-}
-
-class Flexible extends ParentDataWidget {
-  Flexible({ Key key, this.flex: 1, Widget child })
-    : super(key: key, child: child);
-
-  final int flex;
-
-  void debugValidateAncestor(Widget ancestor) {
-    assert(() {
-      'Flexible must placed inside a Flex';
-      return ancestor is Flex;
-    });
-  }
-
-  void applyParentData(RenderObject renderObject) {
-    assert(renderObject.parentData is FlexParentData);
-    final FlexParentData parentData = renderObject.parentData;
-    if (parentData.flex != flex) {
-      parentData.flex = flex;
-      AbstractNode targetParent = renderObject.parent;
-      if (targetParent is RenderObject)
-        targetParent.markNeedsLayout();
-    }
-  }
-
-  void debugFillDescription(List<String> description) {
-    super.debugFillDescription(description);
-    description.add('flex: $flex');
-  }
-}
-
-class Paragraph extends LeafRenderObjectWidget {
-  Paragraph({ Key key, this.text }) : super(key: key) {
-    assert(text != null);
-  }
-
-  final TextSpan text;
-
-  RenderParagraph createRenderObject() => new RenderParagraph(text);
-
-  void updateRenderObject(RenderParagraph renderObject, Paragraph oldWidget) {
-    renderObject.text = text;
-  }
-}
-
-class StyledText extends StatelessComponent {
-  // elements ::= "string" | [<text-style> <elements>*]
-  // Where "string" is text to display and text-style is an instance of
-  // TextStyle. The text-style applies to all of the elements that follow.
-  StyledText({ this.elements, Key key }) : super(key: key) {
-    assert(_toSpan(elements) != null);
-  }
-
-  final dynamic elements;
-
-  TextSpan _toSpan(dynamic element) {
-    if (element is String)
-      return new PlainTextSpan(element);
-    if (element is Iterable) {
-      dynamic first = element.first;
-      if (first is! TextStyle)
-        throw new ArgumentError("First element of Iterable is a ${first.runtimeType} not a TextStyle");
-      return new StyledTextSpan(first, element.skip(1).map(_toSpan).toList());
-    }
-    throw new ArgumentError("Element is ${element.runtimeType} not a String or an Iterable");
-  }
-
-  Widget build(BuildContext context) {
-    return new Paragraph(text: _toSpan(elements));
-  }
-}
-
-class DefaultTextStyle extends InheritedWidget {
-  DefaultTextStyle({
-    Key key,
-    this.style,
-    Widget child
-  }) : super(key: key, child: child) {
-    assert(style != null);
-    assert(child != null);
-  }
-
-  final TextStyle style;
-
-  static TextStyle of(BuildContext context) {
-    DefaultTextStyle result = context.inheritedWidgetOfType(DefaultTextStyle);
-    return result?.style;
-  }
-
-  bool updateShouldNotify(DefaultTextStyle old) => style != old.style;
-
-  void debugFillDescription(List<String> description) {
-    super.debugFillDescription(description);
-    '$style'.split('\n').forEach(description.add);
-  }
-}
-
-class Text extends StatelessComponent {
-  Text(this.data, { Key key, this.style }) : super(key: key) {
-    assert(data != null);
-  }
-
-  final String data;
-  final TextStyle style;
-
-  Widget build(BuildContext context) {
-    TextSpan text = new PlainTextSpan(data);
-    TextStyle combinedStyle;
-    if (style == null || style.inherit) {
-      combinedStyle = DefaultTextStyle.of(context)?.merge(style) ?? style;
-    } else {
-      combinedStyle = style;
-    }
-    if (combinedStyle != null)
-      text = new StyledTextSpan(combinedStyle, <TextSpan>[text]);
-    return new Paragraph(text: text);
-  }
-
-  void debugFillDescription(List<String> description) {
-    super.debugFillDescription(description);
-    description.add('"$data"');
-    if (style != null)
-      '$style'.split('\n').forEach(description.add);
-  }
-}
-
-class Image extends LeafRenderObjectWidget {
-  Image({
-    Key key,
-    this.image,
-    this.width,
-    this.height,
-    this.colorFilter,
-    this.fit,
-    this.repeat: ImageRepeat.noRepeat,
-    this.centerSlice
-  }) : super(key: key);
-
-  final ui.Image image;
-  final double width;
-  final double height;
-  final ColorFilter colorFilter;
-  final ImageFit fit;
-  final ImageRepeat repeat;
-  final Rect centerSlice;
-
-  RenderImage createRenderObject() => new RenderImage(
-    image: image,
-    width: width,
-    height: height,
-    colorFilter: colorFilter,
-    fit: fit,
-    repeat: repeat,
-    centerSlice: centerSlice);
-
-  void updateRenderObject(RenderImage renderObject, Image oldWidget) {
-    renderObject.image = image;
-    renderObject.width = width;
-    renderObject.height = height;
-    renderObject.colorFilter = colorFilter;
-    renderObject.fit = fit;
-    renderObject.repeat = repeat;
-    renderObject.centerSlice = centerSlice;
-  }
-}
-
-class ImageListener extends StatefulComponent {
-  ImageListener({
-    Key key,
-    this.image,
-    this.width,
-    this.height,
-    this.colorFilter,
-    this.fit,
-    this.repeat: ImageRepeat.noRepeat,
-    this.centerSlice
-  }) : super(key: key) {
-    assert(image != null);
-  }
-
-  final ImageResource image;
-  final double width;
-  final double height;
-  final ColorFilter colorFilter;
-  final ImageFit fit;
-  final ImageRepeat repeat;
-  final Rect centerSlice;
-
-  _ImageListenerState createState() => new _ImageListenerState();
-}
-
-class _ImageListenerState extends State<ImageListener> {
-  void initState() {
-    super.initState();
-    config.image.addListener(_handleImageChanged);
-  }
-
-  ui.Image _resolvedImage;
-
-  void _handleImageChanged(ui.Image resolvedImage) {
-    setState(() {
-      _resolvedImage = resolvedImage;
-    });
-  }
-
-  void dispose() {
-    config.image.removeListener(_handleImageChanged);
-    super.dispose();
-  }
-
-  void didUpdateConfig(ImageListener oldConfig) {
-    if (config.image != oldConfig.image) {
-      oldConfig.image.removeListener(_handleImageChanged);
-      config.image.addListener(_handleImageChanged);
-    }
-  }
-
-  Widget build(BuildContext context) {
-    return new Image(
-      image: _resolvedImage,
-      width: config.width,
-      height: config.height,
-      colorFilter: config.colorFilter,
-      fit: config.fit,
-      repeat: config.repeat,
-      centerSlice: config.centerSlice
-    );
-  }
-}
-
-class NetworkImage extends StatelessComponent {
-  NetworkImage({
-    Key key,
-    this.src,
-    this.width,
-    this.height,
-    this.colorFilter,
-    this.fit,
-    this.repeat: ImageRepeat.noRepeat,
-    this.centerSlice
-  }) : super(key: key);
-
-  final String src;
-  final double width;
-  final double height;
-  final ColorFilter colorFilter;
-  final ImageFit fit;
-  final ImageRepeat repeat;
-  final Rect centerSlice;
-
-  Widget build(BuildContext context) {
-    return new ImageListener(
-      image: imageCache.load(src),
-      width: width,
-      height: height,
-      colorFilter: colorFilter,
-      fit: fit,
-      repeat: repeat,
-      centerSlice: centerSlice
-    );
-  }
-}
-
-class DefaultAssetBundle extends InheritedWidget {
-  DefaultAssetBundle({
-    Key key,
-    this.bundle,
-    Widget child
-  }) : super(key: key, child: child) {
-    assert(bundle != null);
-    assert(child != null);
-  }
-
-  final AssetBundle bundle;
-
-  static AssetBundle of(BuildContext context) {
-    DefaultAssetBundle result = context.inheritedWidgetOfType(DefaultAssetBundle);
-    return result?.bundle;
-  }
-
-  bool updateShouldNotify(DefaultAssetBundle old) => bundle != old.bundle;
-}
-
-class RawImage extends StatelessComponent {
-  RawImage({
-    Key key,
-    this.bytes,
-    this.width,
-    this.height,
-    this.colorFilter,
-    this.fit,
-    this.repeat: ImageRepeat.noRepeat,
-    this.centerSlice
-  }) : super(key: key);
-
-  final Uint8List bytes;
-  final double width;
-  final double height;
-  final ColorFilter colorFilter;
-  final ImageFit fit;
-  final ImageRepeat repeat;
-  final Rect centerSlice;
-
-  Widget build(BuildContext context) {
-    ImageResource image = new ImageResource(decodeImageFromList(bytes));
-    return new ImageListener(
-      image: image,
-      width: width,
-      height: height,
-      colorFilter: colorFilter,
-      fit: fit,
-      repeat: repeat,
-      centerSlice: centerSlice
-    );
-  }
-}
-
-class AssetImage extends StatelessComponent {
-  AssetImage({
-    Key key,
-    this.name,
-    this.bundle,
-    this.width,
-    this.height,
-    this.colorFilter,
-    this.fit,
-    this.repeat: ImageRepeat.noRepeat,
-    this.centerSlice
-  }) : super(key: key);
-
-  final String name;
-  final AssetBundle bundle;
-  final double width;
-  final double height;
-  final ColorFilter colorFilter;
-  final ImageFit fit;
-  final ImageRepeat repeat;
-  final Rect centerSlice;
-
-  Widget build(BuildContext context) {
-    return new ImageListener(
-      image: (bundle ?? DefaultAssetBundle.of(context)).loadImage(name),
-      width: width,
-      height: height,
-      colorFilter: colorFilter,
-      fit: fit,
-      repeat: repeat,
-      centerSlice: centerSlice
-    );
-  }
-}
-
-class WidgetToRenderBoxAdapter extends LeafRenderObjectWidget {
-  WidgetToRenderBoxAdapter(RenderBox renderBox)
-    : renderBox = renderBox,
-      // WidgetToRenderBoxAdapter objects are keyed to their render box. This
-      // prevents the widget being used in the widget hierarchy in two different
-      // places, which would cause the RenderBox to get inserted in multiple
-      // places in the RenderObject tree.
-      super(key: new GlobalObjectKey(renderBox)) {
-    assert(renderBox != null);
-  }
-
-  final RenderBox renderBox;
-
-  RenderBox createRenderObject() => renderBox;
-}
-
-
-// EVENT HANDLING
-
-class Listener extends OneChildRenderObjectWidget {
-  Listener({
-    Key key,
-    Widget child,
-    this.onPointerDown,
-    this.onPointerMove,
-    this.onPointerUp,
-    this.onPointerCancel,
-    this.behavior: HitTestBehavior.deferToChild
-  }) : super(key: key, child: child) {
-    assert(behavior != null);
-  }
-
-  final PointerEventListener onPointerDown;
-  final PointerEventListener onPointerMove;
-  final PointerEventListener onPointerUp;
-  final PointerEventListener onPointerCancel;
-  final HitTestBehavior behavior;
-
-  RenderPointerListener createRenderObject() => new RenderPointerListener(
-    onPointerDown: onPointerDown,
-    onPointerMove: onPointerMove,
-    onPointerUp: onPointerUp,
-    onPointerCancel: onPointerCancel,
-    behavior: behavior
-  );
-
-  void updateRenderObject(RenderPointerListener renderObject, Listener oldWidget) {
-    renderObject.onPointerDown = onPointerDown;
-    renderObject.onPointerMove = onPointerMove;
-    renderObject.onPointerUp = onPointerUp;
-    renderObject.onPointerCancel = onPointerCancel;
-    renderObject.behavior = behavior;
-  }
-}
-
-class IgnorePointer extends OneChildRenderObjectWidget {
-  IgnorePointer({ Key key, Widget child, this.ignoring: true })
-    : super(key: key, child: child);
-
-  final bool ignoring;
-
-  RenderIgnorePointer createRenderObject() => new RenderIgnorePointer(ignoring: ignoring);
-
-  void updateRenderObject(RenderIgnorePointer renderObject, IgnorePointer oldWidget) {
-    renderObject.ignoring = ignoring;
-  }
-}
-
-
-// UTILITY NODES
-
-class MetaData extends OneChildRenderObjectWidget {
-  MetaData({ Key key, Widget child, this.metaData })
-    : super(key: key, child: child);
-
-  final dynamic metaData;
-
-  RenderMetaData createRenderObject() => new RenderMetaData(metaData: metaData);
-
-  void updateRenderObject(RenderMetaData renderObject, MetaData oldWidget) {
-    renderObject.metaData = metaData;
-  }
-
-  void debugFillDescription(List<String> description) {
-    super.debugFillDescription(description);
-    description.add('$metaData');
-  }
-}
-
-class KeyedSubtree extends StatelessComponent {
-  KeyedSubtree({ Key key, this.child })
-    : super(key: key);
-
-  final Widget child;
-
-  Widget build(BuildContext context) => child;
-}
diff --git a/sky/packages/sky/lib/src/widgets/binding.dart b/sky/packages/sky/lib/src/widgets/binding.dart
deleted file mode 100644
index 5f9eb53..0000000
--- a/sky/packages/sky/lib/src/widgets/binding.dart
+++ /dev/null
@@ -1,173 +0,0 @@
-// Copyright 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:flutter/animation.dart';
-import 'package:flutter/rendering.dart';
-
-import 'framework.dart';
-
-class WidgetFlutterBinding extends FlutterBinding {
-
-  WidgetFlutterBinding() {
-    BuildableElement.scheduleBuildFor = scheduleBuildFor;
-  }
-
-  /// Ensures that there is a FlutterBinding object instantiated.
-  static void ensureInitialized() {
-    if (FlutterBinding.instance == null)
-      new WidgetFlutterBinding();
-    assert(FlutterBinding.instance is WidgetFlutterBinding);
-  }
-
-  static WidgetFlutterBinding get instance => FlutterBinding.instance;
-
-  void beginFrame() {
-    buildDirtyElements();
-    super.beginFrame();
-    Element.finalizeTree();
-  }
-
-  List<BuildableElement> _dirtyElements = <BuildableElement>[];
-
-  /// Adds an element to the dirty elements list so that it will be rebuilt
-  /// when buildDirtyElements is called.
-  void scheduleBuildFor(BuildableElement element) {
-    assert(!_dirtyElements.contains(element));
-    assert(element.dirty);
-    if (_dirtyElements.isEmpty)
-      scheduler.ensureVisualUpdate();
-    _dirtyElements.add(element);
-  }
-
-  /// Builds all the elements that were marked as dirty using schedule(), in depth order.
-  /// If elements are marked as dirty while this runs, they must be deeper than the algorithm
-  /// has yet reached.
-  /// This is called by beginFrame().
-  void buildDirtyElements() {
-    if (_dirtyElements.isEmpty)
-      return;
-    BuildableElement.lockState(() {
-      _dirtyElements.sort((BuildableElement a, BuildableElement b) => a.depth - b.depth);
-      int dirtyCount = _dirtyElements.length;
-      int index = 0;
-      while (index < dirtyCount) {
-        _dirtyElements[index].rebuild();
-        index += 1;
-        if (dirtyCount < _dirtyElements.length) {
-          _dirtyElements.sort((BuildableElement a, BuildableElement b) => a.depth - b.depth);
-          dirtyCount = _dirtyElements.length;
-        }
-      }
-      assert(!_dirtyElements.any((BuildableElement element) => element.dirty));
-      _dirtyElements.clear();
-    }, building: true);
-    assert(_dirtyElements.isEmpty);
-  }
-
-  /// The [Element] that is at the root of the hierarchy (and which wraps the
-  /// [RenderView] object at the root of the rendering hierarchy).
-  Element get renderViewElement => _renderViewElement;
-  Element _renderViewElement;
-  void _runApp(Widget app) {
-    _renderViewElement = new RenderObjectToWidgetAdapter<RenderBox>(
-      container: renderView,
-      child: app
-    ).attachToRenderTree(_renderViewElement);
-    beginFrame();
-  }
-}
-
-void runApp(Widget app) {
-  WidgetFlutterBinding.ensureInitialized();
-  WidgetFlutterBinding.instance._runApp(app);
-}
-
-void debugDumpApp() {
-  assert(WidgetFlutterBinding.instance != null);
-  assert(WidgetFlutterBinding.instance.renderViewElement != null);
-  String mode = 'RELEASE MODE';
-  assert(() { mode = 'CHECKED MODE'; return true; });
-  debugPrint('${WidgetFlutterBinding.instance.runtimeType} - $mode');
-  debugPrint(WidgetFlutterBinding.instance.renderViewElement.toStringDeep());
-}
-
-/// This class provides a bridge from a RenderObject to an Element tree. The
-/// given container is the RenderObject that the Element tree should be inserted
-/// into. It must be a RenderObject that implements the
-/// RenderObjectWithChildMixin protocol. The type argument T is the kind of
-/// RenderObject that the container expects as its child.
-class RenderObjectToWidgetAdapter<T extends RenderObject> extends RenderObjectWidget {
-  RenderObjectToWidgetAdapter({ this.child, RenderObjectWithChildMixin<T> container })
-    : container = container, super(key: new GlobalObjectKey(container));
-
-  final Widget child;
-  final RenderObjectWithChildMixin<T> container;
-
-  RenderObjectToWidgetElement<T> createElement() => new RenderObjectToWidgetElement<T>(this);
-
-  RenderObjectWithChildMixin<T> createRenderObject() => container;
-
-  void updateRenderObject(RenderObject renderObject, RenderObjectWidget oldWidget) { }
-
-  RenderObjectToWidgetElement<T> attachToRenderTree([RenderObjectToWidgetElement<T> element]) {
-    BuildableElement.lockState(() {
-      if (element == null) {
-        element = createElement();
-        element.mount(null, null);
-      } else {
-        element.update(this);
-      }
-    }, building: true);
-    return element;
-  }
-}
-
-/// This element class is the instantiation of a [RenderObjectToWidgetAdapter].
-/// It can only be used as the root of an Element tree (it cannot be mounted
-/// into another Element, it's parent must be null).
-///
-/// In typical usage, it will be instantiated for a RenderObjectToWidgetAdapter
-/// whose container is the RenderView that connects to the Flutter engine. In
-/// this usage, it is normally instantiated by the bootstrapping logic in the
-/// WidgetFlutterBinding singleton created by runApp().
-class RenderObjectToWidgetElement<T extends RenderObject> extends RenderObjectElement {
-  RenderObjectToWidgetElement(RenderObjectToWidgetAdapter<T> widget) : super(widget);
-
-  Element _child;
-
-  static const _rootChild = const Object();
-
-  void visitChildren(ElementVisitor visitor) {
-    if (_child != null)
-      visitor(_child);
-  }
-
-  void mount(Element parent, dynamic newSlot) {
-    assert(parent == null);
-    super.mount(parent, newSlot);
-    _child = updateChild(_child, widget.child, _rootChild);
-  }
-
-  void update(RenderObjectToWidgetAdapter<T> newWidget) {
-    super.update(newWidget);
-    assert(widget == newWidget);
-    _child = updateChild(_child, widget.child, _rootChild);
-  }
-
-  RenderObjectWithChildMixin<T> get renderObject => super.renderObject;
-
-  void insertChildRenderObject(RenderObject child, dynamic slot) {
-    assert(slot == _rootChild);
-    renderObject.child = child;
-  }
-
-  void moveChildRenderObject(RenderObject child, dynamic slot) {
-    assert(false);
-  }
-
-  void removeChildRenderObject(RenderObject child) {
-    assert(renderObject.child == child);
-    renderObject.child = null;
-  }
-}
diff --git a/sky/packages/sky/lib/src/widgets/dismissable.dart b/sky/packages/sky/lib/src/widgets/dismissable.dart
deleted file mode 100644
index 4b294cb..0000000
--- a/sky/packages/sky/lib/src/widgets/dismissable.dart
+++ /dev/null
@@ -1,264 +0,0 @@
-// Copyright 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 'dart:ui' as ui;
-
-import 'package:flutter/animation.dart';
-
-import 'basic.dart';
-import 'transitions.dart';
-import 'framework.dart';
-import 'gesture_detector.dart';
-
-const Duration _kCardDismissFadeout = const Duration(milliseconds: 200);
-const Duration _kCardDismissResize = const Duration(milliseconds: 300);
-const Curve _kCardDismissResizeCurve = const Interval(0.4, 1.0, curve: Curves.ease);
-const double _kMinFlingVelocity = 700.0;
-const double _kMinFlingVelocityDelta = 400.0;
-const double _kFlingVelocityScale = 1.0 / 300.0;
-const double _kDismissCardThreshold = 0.4;
-
-enum DismissDirection {
-  vertical,
-  horizontal,
-  left,
-  right,
-  up,
-  down
-}
-
-class Dismissable extends StatefulComponent {
-  Dismissable({
-    Key key,
-    this.child,
-    this.onResized,
-    this.onDismissed,
-    this.direction: DismissDirection.horizontal
-  }) : super(key: key);
-
-  final Widget child;
-  final VoidCallback onResized;
-  final VoidCallback onDismissed;
-  final DismissDirection direction;
-
-  _DismissableState createState() => new _DismissableState();
-}
-
-class _DismissableState extends State<Dismissable> {
-  void initState() {
-    super.initState();
-    _fadePerformance = new Performance(duration: _kCardDismissFadeout);
-    _fadePerformance.addStatusListener((PerformanceStatus status) {
-      if (status == PerformanceStatus.completed)
-        _handleFadeCompleted();
-    });
-  }
-
-  Performance _fadePerformance;
-  Performance _resizePerformance;
-
-  Size _size;
-  double _dragExtent = 0.0;
-  bool _dragUnderway = false;
-
-  void dispose() {
-    _fadePerformance?.stop();
-    _resizePerformance?.stop();
-    super.dispose();
-  }
-
-  bool get _directionIsYAxis {
-    return
-      config.direction == DismissDirection.vertical ||
-      config.direction == DismissDirection.up ||
-      config.direction == DismissDirection.down;
-  }
-
-  void _handleFadeCompleted() {
-    if (!_dragUnderway)
-      _startResizePerformance();
-  }
-
-  bool get _isActive {
-    return _size != null && (_dragUnderway || _fadePerformance.isAnimating);
-  }
-
-  void _maybeCallOnResized() {
-    if (config.onResized != null)
-      config.onResized();
-  }
-
-  void _maybeCallOnDismissed() {
-    if (config.onDismissed != null)
-      config.onDismissed();
-  }
-
-  void _startResizePerformance() {
-    assert(_size != null);
-    assert(_fadePerformance != null);
-    assert(_fadePerformance.isCompleted);
-    assert(_resizePerformance == null);
-
-    setState(() {
-      _resizePerformance = new Performance()
-        ..duration = _kCardDismissResize
-        ..addListener(_handleResizeProgressChanged);
-      _resizePerformance.play();
-    });
-  }
-
-  void _handleResizeProgressChanged() {
-    if (_resizePerformance.isCompleted)
-      _maybeCallOnDismissed();
-    else
-      _maybeCallOnResized();
-  }
-
-  void _handleDragStart(_) {
-    if (_fadePerformance.isAnimating)
-      return;
-    setState(() {
-      _dragUnderway = true;
-      _dragExtent = 0.0;
-      _fadePerformance.progress = 0.0;
-    });
-  }
-
-  void _handleDragUpdate(double delta) {
-    if (!_isActive || _fadePerformance.isAnimating)
-      return;
-
-    double oldDragExtent = _dragExtent;
-    switch(config.direction) {
-      case DismissDirection.horizontal:
-      case DismissDirection.vertical:
-        _dragExtent += delta;
-        break;
-
-      case DismissDirection.up:
-      case DismissDirection.left:
-        if (_dragExtent + delta < 0)
-          _dragExtent += delta;
-        break;
-
-      case DismissDirection.down:
-      case DismissDirection.right:
-        if (_dragExtent + delta > 0)
-          _dragExtent += delta;
-        break;
-    }
-
-    if (oldDragExtent.sign != _dragExtent.sign) {
-      setState(() {
-        // Rebuild to update the new drag endpoint.
-        // The sign of _dragExtent is part of our build state;
-        // the actual value is not, it's just used to configure
-        // the performances.
-      });
-    }
-    if (!_fadePerformance.isAnimating)
-      _fadePerformance.progress = _dragExtent.abs() / (_size.width * _kDismissCardThreshold);
-  }
-
-  bool _isFlingGesture(ui.Offset velocity) {
-    double vx = velocity.dx;
-    double vy = velocity.dy;
-    if (_directionIsYAxis) {
-      if (vy.abs() - vx.abs() < _kMinFlingVelocityDelta)
-        return false;
-      switch(config.direction) {
-        case DismissDirection.vertical:
-          return vy.abs() > _kMinFlingVelocity;
-        case DismissDirection.up:
-          return -vy > _kMinFlingVelocity;
-        default:
-          return vy > _kMinFlingVelocity;
-      }
-    } else {
-      if (vx.abs() - vy.abs() < _kMinFlingVelocityDelta)
-        return false;
-      switch(config.direction) {
-        case DismissDirection.horizontal:
-          return vx.abs() > _kMinFlingVelocity;
-        case DismissDirection.left:
-          return -vx > _kMinFlingVelocity;
-        default:
-          return vx > _kMinFlingVelocity;
-      }
-    }
-    return false;
-  }
-
-  void _handleDragEnd(ui.Offset velocity) {
-    if (!_isActive || _fadePerformance.isAnimating)
-      return;
-
-    setState(() {
-      _dragUnderway = false;
-      if (_fadePerformance.isCompleted) {
-        _startResizePerformance();
-      } else if (_isFlingGesture(velocity)) {
-        double flingVelocity = _directionIsYAxis ? velocity.dy : velocity.dx;
-        _dragExtent = flingVelocity.sign;
-        _fadePerformance.fling(velocity: flingVelocity.abs() * _kFlingVelocityScale);
-      } else {
-        _fadePerformance.reverse();
-      }
-    });
-  }
-
-  void _handleSizeChanged(Size newSize) {
-    setState(() {
-      _size = new Size.copy(newSize);
-    });
-  }
-
-  Point get _activeCardDragEndPoint {
-    if (!_isActive)
-      return Point.origin;
-    assert(_size != null);
-    double extent = _directionIsYAxis ? _size.height : _size.width;
-    return new Point(_dragExtent.sign * extent * _kDismissCardThreshold, 0.0);
-  }
-
-  Widget build(BuildContext context) {
-    if (_resizePerformance != null) {
-      // make sure you remove this widget once it's been dismissed!
-      assert(_resizePerformance.status == PerformanceStatus.forward);
-
-      AnimatedValue<double> squashAxisExtent = new AnimatedValue<double>(
-        _directionIsYAxis ? _size.width : _size.height,
-        end: 0.0,
-        curve: _kCardDismissResizeCurve
-      );
-
-      return new SquashTransition(
-        performance: _resizePerformance.view,
-        width: _directionIsYAxis ? squashAxisExtent : null,
-        height: !_directionIsYAxis ? squashAxisExtent : null
-      );
-    }
-
-    return new GestureDetector(
-      onHorizontalDragStart: _directionIsYAxis ? null : _handleDragStart,
-      onHorizontalDragUpdate: _directionIsYAxis ? null : _handleDragUpdate,
-      onHorizontalDragEnd: _directionIsYAxis ? null : _handleDragEnd,
-      onVerticalDragStart: _directionIsYAxis ? _handleDragStart : null,
-      onVerticalDragUpdate: _directionIsYAxis ? _handleDragUpdate : null,
-      onVerticalDragEnd: _directionIsYAxis ? _handleDragEnd : null,
-      child: new SizeObserver(
-        onSizeChanged: _handleSizeChanged,
-        child: new FadeTransition(
-          performance: _fadePerformance.view,
-          opacity: new AnimatedValue<double>(1.0, end: 0.0),
-          child: new SlideTransition(
-            performance: _fadePerformance.view,
-            position: new AnimatedValue<Point>(Point.origin, end: _activeCardDragEndPoint),
-            child: config.child
-          )
-        )
-      )
-    );
-  }
-}
diff --git a/sky/packages/sky/lib/src/widgets/drag_target.dart b/sky/packages/sky/lib/src/widgets/drag_target.dart
deleted file mode 100644
index 92a6be0..0000000
--- a/sky/packages/sky/lib/src/widgets/drag_target.dart
+++ /dev/null
@@ -1,361 +0,0 @@
-// Copyright 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 'dart:collection';
-
-import 'package:flutter/gestures.dart';
-import 'package:flutter/rendering.dart';
-import 'package:flutter/services.dart';
-
-import 'basic.dart';
-import 'binding.dart';
-import 'framework.dart';
-import 'navigator.dart';
-import 'overlay.dart';
-
-typedef bool DragTargetWillAccept<T>(T data);
-typedef void DragTargetAccept<T>(T data);
-typedef Widget DragTargetBuilder<T>(BuildContext context, List<T> candidateData, List<dynamic> rejectedData);
-typedef void DragStartCallback(Point position, int pointer);
-
-typedef DraggableBase<T> DraggableConstructor<T>({
-  Key key,
-  T data,
-  Widget child,
-  Widget feedback,
-  Offset feedbackOffset,
-  DragAnchor dragAnchor
-});
-
-enum DragAnchor {
-  /// Display the feedback anchored at the position of the original child. If
-  /// feedback is identical to the child, then this means the feedback will
-  /// exactly overlap the original child when the drag starts.
-  child,
-
-  /// Display the feedback anchored at the position of the touch that started
-  /// the drag. If feedback is identical to the child, then this means the top
-  /// left of the feedback will be under the finger when the drag starts. This
-  /// will likely not exactly overlap the original child, e.g. if the child is
-  /// big and the touch was not centered. This mode is useful when the feedback
-  /// is transformed so as to move the feedback to the left by half its width,
-  /// and up by half its width plus the height of the finger, since then it
-  /// appears as if putting the finger down makes the touch feedback appear
-  /// above the finger. (It feels weird for it to appear offset from the
-  /// original child if it's anchored to the child and not the finger.)
-  pointer,
-}
-
-abstract class DraggableBase<T> extends StatefulComponent {
-  DraggableBase({
-    Key key,
-    this.data,
-    this.child,
-    this.feedback,
-    this.feedbackOffset: Offset.zero,
-    this.dragAnchor: DragAnchor.child
-  }) : super(key: key) {
-    assert(child != null);
-    assert(feedback != null);
-  }
-
-  final T data;
-  final Widget child;
-  final Widget feedback;
-
-  /// The feedbackOffset can be used to set the hit test target point for the
-  /// purposes of finding a drag target. It is especially useful if the feedback
-  /// is transformed compared to the child.
-  final Offset feedbackOffset;
-  final DragAnchor dragAnchor;
-
-  /// Should return a GestureRecognizer instance that is configured to call the starter
-  /// argument when the drag is to begin. The arena for the pointer must not yet have
-  /// resolved at the time that the callback is invoked, because the draggable itself
-  /// is going to attempt to win the pointer's arena in that case.
-  GestureRecognizer createRecognizer(PointerRouter router, DragStartCallback starter);
-
-  _DraggableState<T> createState() => new _DraggableState<T>();
-}
-
-class Draggable<T> extends DraggableBase<T> {
-  Draggable({
-    Key key,
-    T data,
-    Widget child,
-    Widget feedback,
-    Offset feedbackOffset: Offset.zero,
-    DragAnchor dragAnchor: DragAnchor.child
-  }) : super(
-    key: key,
-    data: data,
-    child: child,
-    feedback: feedback,
-    feedbackOffset: feedbackOffset,
-    dragAnchor: dragAnchor
-  );
-
-  GestureRecognizer createRecognizer(PointerRouter router, DragStartCallback starter) {
-    return new MultiTapGestureRecognizer(
-      router: router,
-      onTapDown: starter
-    );
-  }
-}
-
-class LongPressDraggable<T> extends DraggableBase<T> {
-  LongPressDraggable({
-    Key key,
-    T data,
-    Widget child,
-    Widget feedback,
-    Offset feedbackOffset: Offset.zero,
-    DragAnchor dragAnchor: DragAnchor.child
-  }) : super(
-    key: key,
-    data: data,
-    child: child,
-    feedback: feedback,
-    feedbackOffset: feedbackOffset,
-    dragAnchor: dragAnchor
-  );
-
-  GestureRecognizer createRecognizer(PointerRouter router, DragStartCallback starter) {
-    return new MultiTapGestureRecognizer(
-      router: router,
-      longTapDelay: kLongPressTimeout,
-      onLongTapDown: (Point position, int pointer) {
-        userFeedback.performHapticFeedback(HapticFeedbackType.VIRTUAL_KEY);
-        starter(position, pointer);
-      }
-    );
-  }
-}
-
-class _DraggableState<T> extends State<DraggableBase<T>> implements GestureArenaMember {
-
-  PointerRouter get router => FlutterBinding.instance.pointerRouter;
-
-  void initState() {
-    super.initState();
-    _recognizer = config.createRecognizer(router, _startDrag);
-  }
-
-  GestureRecognizer _recognizer;
-  Map<int, GestureArenaEntry> _activePointers = <int, GestureArenaEntry>{};
-
-  void _routePointer(PointerInputEvent event) {
-    _activePointers[event.pointer] = GestureArena.instance.add(event.pointer, this);
-    _recognizer.addPointer(event);
-  }
-
-  void acceptGesture(int pointer) {
-    _activePointers.remove(pointer);
-  }
-
-  void rejectGesture(int pointer) {
-    _activePointers.remove(pointer);
-  }
-
-  void _startDrag(Point position, int pointer) {
-    assert(_activePointers.containsKey(pointer));
-    _activePointers[pointer].resolve(GestureDisposition.accepted);
-    Point dragStartPoint;
-    switch (config.dragAnchor) {
-      case DragAnchor.child:
-        final RenderBox renderObject = context.findRenderObject();
-        dragStartPoint = renderObject.globalToLocal(position);
-        break;
-      case DragAnchor.pointer:
-        dragStartPoint = Point.origin;
-      break;
-    }
-    new _DragAvatar<T>(
-      pointer: pointer,
-      router: router,
-      overlay: Navigator.of(context).overlay,
-      data: config.data,
-      initialPosition: position,
-      dragStartPoint: dragStartPoint,
-      feedback: config.feedback,
-      feedbackOffset: config.feedbackOffset
-    );
-  }
-
-  Widget build(BuildContext context) {
-    return new Listener(
-      onPointerDown: _routePointer,
-      child: config.child
-    );
-  }
-}
-
-
-class DragTarget<T> extends StatefulComponent {
-  const DragTarget({
-    Key key,
-    this.builder,
-    this.onWillAccept,
-    this.onAccept
-  }) : super(key: key);
-
-  final DragTargetBuilder<T> builder;
-  final DragTargetWillAccept<T> onWillAccept;
-  final DragTargetAccept<T> onAccept;
-
-  DragTargetState<T> createState() => new DragTargetState<T>();
-}
-
-class DragTargetState<T> extends State<DragTarget<T>> {
-  final List<T> _candidateData = new List<T>();
-  final List<dynamic> _rejectedData = new List<dynamic>();
-
-  bool didEnter(dynamic data) {
-    assert(!_candidateData.contains(data));
-    assert(!_rejectedData.contains(data));
-    if (data is T && (config.onWillAccept == null || config.onWillAccept(data))) {
-      setState(() {
-        _candidateData.add(data);
-      });
-      return true;
-    }
-    _rejectedData.add(data);
-    return false;
-  }
-
-  void didLeave(dynamic data) {
-    assert(_candidateData.contains(data) || _rejectedData.contains(data));
-    setState(() {
-      _candidateData.remove(data);
-      _rejectedData.remove(data);
-    });
-  }
-
-  void didDrop(dynamic data) {
-    assert(_candidateData.contains(data));
-    setState(() {
-      _candidateData.remove(data);
-    });
-    if (config.onAccept != null)
-      config.onAccept(data);
-  }
-
-  Widget build(BuildContext context) {
-    return new MetaData(
-      metaData: this,
-      child: config.builder(context,
-                            new UnmodifiableListView<T>(_candidateData),
-                            new UnmodifiableListView<dynamic>(_rejectedData)
-      )
-    );
-  }
-}
-
-
-enum _DragEndKind { dropped, canceled }
-
-// The lifetime of this object is a little dubious right now. Specifically, it
-// lives as long as the pointer is down. Arguably it should self-immolate if the
-// overlay goes away, or maybe even if the Draggable that created goes away.
-// This will probably need to be changed once we have more experience with using
-// this widget.
-class _DragAvatar<T> {
-  _DragAvatar({
-    this.pointer,
-    this.router,
-    OverlayState overlay,
-    this.data,
-    Point initialPosition,
-    this.dragStartPoint: Point.origin,
-    this.feedback,
-    this.feedbackOffset: Offset.zero
-  }) {
-    assert(pointer != null);
-    assert(router != null);
-    assert(overlay != null);
-    assert(dragStartPoint != null);
-    assert(feedbackOffset != null);
-    router.addRoute(pointer, handleEvent);
-    _entry = new OverlayEntry(builder: _build);
-    overlay.insert(_entry);
-    update(initialPosition);
-  }
-
-  final int pointer;
-  final PointerRouter router;
-  final T data;
-  final Point dragStartPoint;
-  final Widget feedback;
-  final Offset feedbackOffset;
-
-  DragTargetState _activeTarget;
-  bool _activeTargetWillAcceptDrop = false;
-  Offset _lastOffset;
-  OverlayEntry _entry;
-
-  void handleEvent(PointerInputEvent event) {
-    switch(event.type) {
-      case 'pointerup':
-        update(event.position);
-        finish(_DragEndKind.dropped);
-        break;
-      case 'pointercancel':
-        finish(_DragEndKind.canceled);
-        break;
-      case 'pointermove':
-        update(event.position);
-        break;
-    }
-  }
-
-  void update(Point globalPosition) {
-    _lastOffset = globalPosition - dragStartPoint;
-    _entry.markNeedsBuild();
-    HitTestResult result = WidgetFlutterBinding.instance.hitTest(globalPosition + feedbackOffset);
-    DragTargetState target = _getDragTarget(result.path);
-    if (target == _activeTarget)
-      return;
-    if (_activeTarget != null)
-      _activeTarget.didLeave(data);
-    _activeTarget = target;
-    _activeTargetWillAcceptDrop = _activeTarget != null && _activeTarget.didEnter(data);
-  }
-
-  DragTargetState _getDragTarget(List<HitTestEntry> path) {
-    // Look for the RenderBox that corresponds to the hit target (the hit target
-    // widget builds a RenderMetadata box for us for this purpose).
-    for (HitTestEntry entry in path) {
-      if (entry.target is RenderMetaData) {
-        RenderMetaData renderMetaData = entry.target;
-        if (renderMetaData.metaData is DragTargetState)
-          return renderMetaData.metaData;
-      }
-    }
-    return null;
-  }
-
-  void finish(_DragEndKind endKind) {
-    if (_activeTarget != null) {
-      if (endKind == _DragEndKind.dropped && _activeTargetWillAcceptDrop)
-        _activeTarget.didDrop(data);
-      else
-        _activeTarget.didLeave(data);
-    }
-    _activeTarget = null;
-    _activeTargetWillAcceptDrop = false;
-    _entry.remove();
-    _entry = null;
-    router.removeRoute(pointer, handleEvent);
-  }
-
-  Widget _build(BuildContext context) {
-    return new Positioned(
-      left: _lastOffset.dx,
-      top: _lastOffset.dy,
-      child: new IgnorePointer(
-        child: feedback
-      )
-    );
-  }
-}
diff --git a/sky/packages/sky/lib/src/widgets/editable_text.dart b/sky/packages/sky/lib/src/widgets/editable_text.dart
deleted file mode 100644
index f0281a9..0000000
--- a/sky/packages/sky/lib/src/widgets/editable_text.dart
+++ /dev/null
@@ -1,282 +0,0 @@
-// Copyright 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 'dart:async';
-import 'dart:math' as math;
-
-import 'package:mojo_services/keyboard/keyboard.mojom.dart';
-import 'package:flutter/painting.dart';
-import 'package:flutter/rendering.dart';
-
-import 'basic.dart';
-import 'framework.dart';
-
-const _kCursorBlinkHalfPeriod = 500; // milliseconds
-
-class TextRange {
-  const TextRange({ this.start, this.end });
-  const TextRange.collapsed(int position)
-    : start = position,
-      end = position;
-  const TextRange.empty()
-    : start = -1,
-      end = -1;
-
-  final int start;
-  final int end;
-
-  bool get isValid => start >= 0 && end >= 0;
-  bool get isCollapsed => start == end;
-}
-
-class EditableString implements KeyboardClient {
-  EditableString({this.text: '', this.onUpdated, this.onSubmitted}) {
-    assert(onUpdated != null);
-    assert(onSubmitted != null);
-    stub = new KeyboardClientStub.unbound()..impl = this;
-    selection = new TextRange(start: text.length, end: text.length);
-  }
-
-  String text;
-  TextRange composing = const TextRange.empty();
-  TextRange selection;
-
-  final VoidCallback onUpdated;
-  final VoidCallback onSubmitted;
-
-  KeyboardClientStub stub;
-
-  String textBefore(TextRange range) {
-    return text.substring(0, range.start);
-  }
-
-  String textAfter(TextRange range) {
-    return text.substring(range.end);
-  }
-
-  String textInside(TextRange range) {
-    return text.substring(range.start, range.end);
-  }
-
-  void _delete(TextRange range) {
-    if (range.isCollapsed || !range.isValid) return;
-    text = textBefore(range) + textAfter(range);
-  }
-
-  TextRange _append(String newText) {
-    int start = text.length;
-    text += newText;
-    return new TextRange(start: start, end: start + newText.length);
-  }
-
-  TextRange _replace(TextRange range, String newText) {
-    assert(range.isValid);
-
-    String before = textBefore(range);
-    String after = textAfter(range);
-
-    text = before + newText + after;
-    return new TextRange(
-        start: before.length, end: before.length + newText.length);
-  }
-
-  TextRange _replaceOrAppend(TextRange range, String newText) {
-    if (!range.isValid) return _append(newText);
-    return _replace(range, newText);
-  }
-
-  void commitCompletion(CompletionData completion) {
-    // TODO(abarth): Not implemented.
-  }
-
-  void commitCorrection(CorrectionData correction) {
-    // TODO(abarth): Not implemented.
-  }
-
-  void commitText(String text, int newCursorPosition) {
-    // TODO(abarth): Why is |newCursorPosition| always 1?
-    TextRange committedRange = _replaceOrAppend(composing, text);
-    selection = new TextRange.collapsed(committedRange.end);
-    composing = const TextRange.empty();
-    onUpdated();
-  }
-
-  void deleteSurroundingText(int beforeLength, int afterLength) {
-    TextRange beforeRange = new TextRange(
-        start: selection.start - beforeLength, end: selection.start);
-    TextRange afterRange =
-        new TextRange(start: selection.end, end: selection.end + afterLength);
-    _delete(afterRange);
-    _delete(beforeRange);
-    selection = new TextRange(
-      start: math.max(selection.start - beforeLength, 0),
-      end: math.max(selection.end - beforeLength, 0)
-    );
-    onUpdated();
-  }
-
-  void setComposingRegion(int start, int end) {
-    composing = new TextRange(start: start, end: end);
-    onUpdated();
-  }
-
-  void setComposingText(String text, int newCursorPosition) {
-    // TODO(abarth): Why is |newCursorPosition| always 1?
-    composing = _replaceOrAppend(composing, text);
-    selection = new TextRange.collapsed(composing.end);
-    onUpdated();
-  }
-
-  void setSelection(int start, int end) {
-    selection = new TextRange(start: start, end: end);
-    onUpdated();
-  }
-
-  void submit(SubmitAction action) {
-    onSubmitted();
-  }
-}
-
-class EditableText extends StatefulComponent {
-  EditableText({
-    Key key,
-    this.value,
-    this.focused: false,
-    this.style,
-    this.cursorColor,
-    this.onContentSizeChanged,
-    this.scrollOffset
-  }) : super(key: key);
-
-  final EditableString value;
-  final bool focused;
-  final TextStyle style;
-  final Color cursorColor;
-  final SizeChangedCallback onContentSizeChanged;
-  final Offset scrollOffset;
-
-  EditableTextState createState() => new EditableTextState();
-}
-
-class EditableTextState extends State<EditableText> {
-  Timer _cursorTimer;
-  bool _showCursor = false;
-
-  /// Whether the blinking cursor is actually visible at this precise moment
-  /// (it's hidden half the time, since it blinks).
-  bool get cursorCurrentlyVisible => _showCursor;
-
-  /// The cursor blink interval (the amount of time the cursor is in the "on"
-  /// state or the "off" state). A complete cursor blink period is twice this
-  /// value (half on, half off).
-  Duration get cursorBlinkInterval => new Duration(milliseconds: _kCursorBlinkHalfPeriod);
-
-  void _cursorTick(Timer timer) {
-    setState(() {
-      _showCursor = !_showCursor;
-    });
-  }
-
-  void _startCursorTimer() {
-    _showCursor = true;
-    _cursorTimer = new Timer.periodic(
-      new Duration(milliseconds: _kCursorBlinkHalfPeriod),
-      _cursorTick
-    );
-  }
-
-  void dispose() {
-    if (_cursorTimer != null)
-      _stopCursorTimer();
-    super.dispose();
-  }
-
-  void _stopCursorTimer() {
-    _cursorTimer.cancel();
-    _cursorTimer = null;
-    _showCursor = false;
-  }
-
-  Widget build(BuildContext context) {
-    assert(config.style != null);
-    assert(config.focused != null);
-    assert(config.cursorColor != null);
-
-    if (config.focused && _cursorTimer == null)
-      _startCursorTimer();
-    else if (!config.focused && _cursorTimer != null)
-      _stopCursorTimer();
-
-    return new SizedBox(
-      width: double.INFINITY,
-      child: new _EditableTextWidget(
-        value: config.value,
-        style: config.style,
-        cursorColor: config.cursorColor,
-        showCursor: _showCursor,
-        onContentSizeChanged: config.onContentSizeChanged,
-        scrollOffset: config.scrollOffset
-      )
-    );
-  }
-}
-
-class _EditableTextWidget extends LeafRenderObjectWidget {
-  _EditableTextWidget({
-    Key key,
-    this.value,
-    this.style,
-    this.cursorColor,
-    this.showCursor,
-    this.onContentSizeChanged,
-    this.scrollOffset
-  }) : super(key: key);
-
-  final EditableString value;
-  final TextStyle style;
-  final Color cursorColor;
-  final bool showCursor;
-  final SizeChangedCallback onContentSizeChanged;
-  final Offset scrollOffset;
-
-  RenderEditableParagraph createRenderObject() {
-    return new RenderEditableParagraph(
-      text: _buildTextSpan(),
-      cursorColor: cursorColor,
-      showCursor: showCursor,
-      onContentSizeChanged: onContentSizeChanged,
-      scrollOffset: scrollOffset
-    );
-  }
-
-  void updateRenderObject(RenderEditableParagraph renderObject,
-                          _EditableTextWidget oldWidget) {
-    renderObject.text = _buildTextSpan();
-    renderObject.cursorColor = cursorColor;
-    renderObject.showCursor = showCursor;
-    renderObject.onContentSizeChanged = onContentSizeChanged;
-    renderObject.scrollOffset = scrollOffset;
-  }
-
-  // Construct a TextSpan that renders the EditableString using the chosen style.
-  TextSpan _buildTextSpan() {
-    if (value.composing.isValid) {
-      TextStyle composingStyle = style.merge(
-        const TextStyle(decoration: underline)
-      );
-
-      return new StyledTextSpan(style, <TextSpan>[
-        new PlainTextSpan(value.textBefore(value.composing)),
-        new StyledTextSpan(composingStyle, <TextSpan>[
-          new PlainTextSpan(value.textInside(value.composing))
-        ]),
-        new PlainTextSpan(value.textAfter(value.composing))
-      ]);
-    }
-
-    return new StyledTextSpan(style, <TextSpan>[
-      new PlainTextSpan(value.text)
-    ]);
-  }
-}
diff --git a/sky/packages/sky/lib/src/widgets/enter_exit_transition.dart b/sky/packages/sky/lib/src/widgets/enter_exit_transition.dart
deleted file mode 100644
index 7b6dbee..0000000
--- a/sky/packages/sky/lib/src/widgets/enter_exit_transition.dart
+++ /dev/null
@@ -1,185 +0,0 @@
-// Copyright 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 'dart:async';
-
-import 'package:flutter/animation.dart';
-
-import 'basic.dart';
-import 'framework.dart';
-
-class SmoothlyResizingOverflowBox extends StatefulComponent {
-  SmoothlyResizingOverflowBox({
-    Key key,
-    this.child,
-    this.size,
-    this.duration,
-    this.curve: Curves.linear
-  }) : super(key: key) {
-    assert(duration != null);
-    assert(curve != null);
-  }
-
-  final Widget child;
-  final Size size;
-  final Duration duration;
-  final Curve curve;
-
-  _SmoothlyResizingOverflowBoxState createState() => new _SmoothlyResizingOverflowBoxState();
-}
-
-class _SmoothlyResizingOverflowBoxState extends State<SmoothlyResizingOverflowBox> {
-  ValuePerformance<Size> _size;
-
-  void initState() {
-    super.initState();
-    _size = new ValuePerformance(
-      variable: new AnimatedSizeValue(config.size, curve: config.curve),
-      duration: config.duration
-    )..addListener(() {
-      setState(() {});
-    });
-  }
-
-  void didUpdateConfig(SmoothlyResizingOverflowBox oldConfig) {
-    _size.duration = config.duration;
-    _size.variable.curve = config.curve;
-    if (config.size != oldConfig.size) {
-      AnimatedSizeValue variable = _size.variable;
-      variable.begin = variable.value;
-      variable.end = config.size;
-      _size.progress = 0.0;
-      _size.play();
-    }
-  }
-
-  void dispose() {
-    _size.stop();
-    super.dispose();
-  }
-
-  Widget build(BuildContext context) {
-    return new SizedOverflowBox(
-      size: _size.value,
-      child: config.child
-    );
-  }
-}
-
-class _Entry {
-  _Entry({
-    this.child,
-    this.enterPerformance,
-    this.enterTransition
-  });
-
-  final Widget child;
-  final Performance enterPerformance;
-  final Widget enterTransition;
-
-  Size childSize = Size.zero;
-
-  Performance exitPerformance;
-  Widget exitTransition;
-
-  Widget get currentTransition => exitTransition ?? enterTransition;
-
-  void dispose() {
-    enterPerformance?.stop();
-    exitPerformance?.stop();
-  }
-}
-
-typedef Widget TransitionBuilderCallback(PerformanceView performance, Widget child);
-
-class EnterExitTransition extends StatefulComponent {
-  EnterExitTransition({
-    Key key,
-    this.child,
-    this.duration,
-    this.curve: Curves.linear,
-    this.onEnter,
-    this.onExit
-  }) : super(key: key) {
-    assert(child != null);
-    assert(duration != null);
-    assert(curve != null);
-    assert(onEnter != null);
-    assert(onExit != null);
-  }
-
-  final Widget child;
-  final Duration duration;
-  final Curve curve;
-  final TransitionBuilderCallback onEnter;
-  final TransitionBuilderCallback onExit;
-
-  _EnterExitTransitionState createState() => new _EnterExitTransitionState();
-}
-
-class _EnterExitTransitionState extends State<EnterExitTransition> {
-  final List<_Entry> _entries = new List<_Entry>();
-
-  void initState() {
-    super.initState();
-    _entries.add(_createEnterTransition());
-  }
-
-  _Entry _createEnterTransition() {
-    Performance enterPerformance = new Performance(duration: config.duration)..play();
-    return new _Entry(
-      child: config.child,
-      enterPerformance: enterPerformance,
-      enterTransition: config.onEnter(enterPerformance, new KeyedSubtree(
-        key: new GlobalKey(),
-        child: config.child
-      ))
-    );
-  }
-
-  Future _createExitTransition(_Entry entry) async {
-    Performance exitPerformance = new Performance(duration: config.duration);
-    entry
-      ..exitPerformance = exitPerformance
-      ..exitTransition = config.onExit(exitPerformance, entry.enterTransition);
-    await exitPerformance.play();
-    if (!mounted)
-      return;
-    setState(() {
-      _entries.remove(entry);
-    });
-  }
-
-  void didUpdateConfig(EnterExitTransition oldConfig) {
-    if (config.child.key != oldConfig.child.key) {
-      _createExitTransition(_entries.last);
-      _entries.add(_createEnterTransition());
-    }
-  }
-
-  void dispose() {
-    for (_Entry entry in new List<_Entry>.from(_entries))
-      entry.dispose();
-    super.dispose();
-  }
-
-  Widget build(BuildContext context) {
-    return new SmoothlyResizingOverflowBox(
-      size: _entries.last.childSize,
-      duration: config.duration,
-      curve: config.curve,
-      child: new Stack(_entries.map((_Entry entry) {
-        return new SizeObserver(
-          key: new ObjectKey(entry),
-          onSizeChanged: (Size newSize) {
-            setState(() {
-              entry.childSize = newSize;
-            });
-          },
-          child: entry.currentTransition
-        );
-      }).toList())
-    );
-  }
-}
diff --git a/sky/packages/sky/lib/src/widgets/event_recorder.dart b/sky/packages/sky/lib/src/widgets/event_recorder.dart
deleted file mode 100644
index c5f82a2..0000000
--- a/sky/packages/sky/lib/src/widgets/event_recorder.dart
+++ /dev/null
@@ -1,71 +0,0 @@
-// Copyright 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:flutter/gestures.dart';
-import 'package:flutter/rendering.dart';
-
-import 'basic.dart';
-import 'framework.dart';
-
-enum EventRecorderMode {
-  stop,
-  record
-}
-
-typedef void EventsReadyCallback(List<PointerInputEvent> events);
-
-/// EventRecorder is a utility widget that allows input events occurring
-/// on the child to be recorded. The widget is initially in the "stop" state
-/// by default. When in the "record" state, all pointer input events
-/// occurring on the child are recorded into a buffer. When the "stop" state
-/// is entered again, the onEventsReady callback is invoked with a list of
-/// the recorded events.
-class EventRecorder extends StatefulComponent {
-  EventRecorder({
-    Key key,
-    this.child,
-    this.mode: EventRecorderMode.stop,
-    this.onEventsReady
-  });
-
-  final Widget child;
-  final EventRecorderMode mode;
-  final EventsReadyCallback onEventsReady;
-
-  _EventRecorderState createState() => new _EventRecorderState();
-}
-
-class _EventRecorderState extends State<EventRecorder> {
-
-  List<PointerInputEvent> _events = new List<PointerInputEvent>();
-
-  void initState() {
-    super.initState();
-  }
-
-  void didUpdateConfig(EventRecorder oldConfig) {
-    if (oldConfig.mode == EventRecorderMode.record &&
-        config.mode == EventRecorderMode.stop) {
-      config.onEventsReady(_events);
-      _events.clear();
-    }
-  }
-
-  void _recordEvent(PointerInputEvent event) {
-    if (config.mode == EventRecorderMode.record) {
-      _events.add(event);
-    }
-  }
-
-  Widget build(BuildContext context) {
-    return new Listener(
-      onPointerDown: _recordEvent,
-      onPointerMove: _recordEvent,
-      onPointerUp: _recordEvent,
-      onPointerCancel: _recordEvent,
-      child: config.child
-    );
-  }
-
-}
diff --git a/sky/packages/sky/lib/src/widgets/focus.dart b/sky/packages/sky/lib/src/widgets/focus.dart
deleted file mode 100644
index 7340668..0000000
--- a/sky/packages/sky/lib/src/widgets/focus.dart
+++ /dev/null
@@ -1,232 +0,0 @@
-// Copyright 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 'framework.dart';
-
-typedef void FocusChanged(GlobalKey key);
-
-// _noFocusedScope is used by Focus to track the case where none of the Focus
-// component's subscopes (e.g. dialogs) are focused. This is distinct from the
-// focused scope being null, which means that we haven't yet decided which scope
-// is focused and whichever is the first scope to ask for focus will get it.
-final GlobalKey _noFocusedScope = new GlobalKey();
-
-class _FocusScope extends InheritedWidget {
-  _FocusScope({
-    Key key,
-    this.focusState,
-    this.scopeFocused: true, // are we focused in our ancestor scope?
-    this.focusedScope, // which of our descendant scopes is focused, if any?
-    this.focusedWidget,
-    Widget child
-  }) : super(key: key, child: child);
-
-  final FocusState focusState;
-  final bool scopeFocused;
-
-  // These are mutable because we implicitly change them when they're null in
-  // certain cases, basically pretending retroactively that we were constructed
-  // with the right keys.
-  GlobalKey focusedScope;
-  GlobalKey focusedWidget;
-
-  // The ...IfUnset() methods don't need to notify descendants because by
-  // definition they are only going to make a change the very first time that
-  // our state is checked.
-
-  void _setFocusedWidgetIfUnset(GlobalKey key) {
-    focusState._setFocusedWidgetIfUnset(key);
-    focusedWidget = focusState._focusedWidget;
-    focusedScope = focusState._focusedScope == _noFocusedScope ? null : focusState._focusedScope;
-  }
-
-  void _setFocusedScopeIfUnset(GlobalKey key) {
-    focusState._setFocusedScopeIfUnset(key);
-    assert(focusedWidget == focusState._focusedWidget);
-    focusedScope = focusState._focusedScope == _noFocusedScope ? null : focusState._focusedScope;
-  }
-
-  bool updateShouldNotify(_FocusScope oldWidget) {
-    if (scopeFocused != oldWidget.scopeFocused)
-      return true;
-    if (!scopeFocused)
-      return false;
-    if (focusedScope != oldWidget.focusedScope)
-      return true;
-    if (focusedScope != null)
-      return false;
-    if (focusedWidget != oldWidget.focusedWidget)
-      return true;
-    return false;
-  }
-
-  void debugFillDescription(List<String> description) {
-    super.debugFillDescription(description);
-    if (scopeFocused)
-      description.add('this scope has focus');
-    if (focusedScope != null)
-      description.add('focused subscope: $focusedScope');
-    if (focusedWidget != null)
-      description.add('focused widget: $focusedWidget');
-  }
-}
-
-class Focus extends StatefulComponent {
-  Focus({
-    GlobalKey key, // key is required if this is a nested Focus scope
-    this.autofocus: false,
-    this.child
-  }) : super(key: key) {
-    assert(!autofocus || key != null);
-  }
-
-  final bool autofocus;
-  final Widget child;
-
-  static bool at(BuildContext context, Widget widget, { bool autofocus: true }) {
-    assert(widget != null);
-    assert(widget.key is GlobalKey);
-    _FocusScope focusScope = context.inheritedWidgetOfType(_FocusScope);
-    if (focusScope != null) {
-      if (autofocus)
-        focusScope._setFocusedWidgetIfUnset(widget.key);
-      return focusScope.scopeFocused &&
-             focusScope.focusedScope == null &&
-             focusScope.focusedWidget == widget.key;
-    }
-    return true;
-  }
-
-  static bool _atScope(BuildContext context, Widget widget, { bool autofocus: true }) {
-    assert(widget != null);
-    _FocusScope focusScope = context.inheritedWidgetOfType(_FocusScope);
-    if (focusScope != null) {
-      if (autofocus)
-        focusScope._setFocusedScopeIfUnset(widget.key);
-      assert(widget.key != null);
-      return focusScope.scopeFocused &&
-             focusScope.focusedScope == widget.key;
-    }
-    return true;
-  }
-
-  // Don't call moveTo() and moveScopeTo() from your build()
-  // functions, it's intended to be called from event listeners, e.g.
-  // in response to a finger tap or tab key.
-
-  static void moveTo(BuildContext context, Widget widget) {
-    assert(widget != null);
-    assert(widget.key is GlobalKey);
-    _FocusScope focusScope = context.inheritedWidgetOfType(_FocusScope);
-    if (focusScope != null)
-      focusScope.focusState._setFocusedWidget(widget.key);
-  }
-
-  static void moveScopeTo(BuildContext context, Focus component) {
-    assert(component != null);
-    assert(component.key != null);
-    _FocusScope focusScope = context.inheritedWidgetOfType(_FocusScope);
-    if (focusScope != null)
-      focusScope.focusState._setFocusedScope(component.key);
-  }
-
-  FocusState createState() => new FocusState();
-}
-
-class FocusState extends State<Focus> {
-  GlobalKey _focusedWidget; // when null, the first component to ask if it's focused will get the focus
-  GlobalKey _currentlyRegisteredWidgetRemovalListenerKey;
-
-  void _setFocusedWidget(GlobalKey key) {
-    setState(() {
-      _focusedWidget = key;
-      if (_focusedScope == null)
-        _focusedScope = _noFocusedScope;
-    });
-    _updateWidgetRemovalListener(key);
-  }
-
-  void _setFocusedWidgetIfUnset(GlobalKey key) {
-    if (_focusedWidget == null && (_focusedScope == null || _focusedScope == _noFocusedScope)) {
-      _focusedWidget = key;
-      _focusedScope = _noFocusedScope;
-      _updateWidgetRemovalListener(key);
-    }
-  }
-
-  void _handleWidgetRemoved(GlobalKey key) {
-    assert(_focusedWidget == key);
-    _updateWidgetRemovalListener(null);
-    setState(() {
-      _focusedWidget = null;
-    });
-  }
-
-  void _updateWidgetRemovalListener(GlobalKey key) {
-    if (_currentlyRegisteredWidgetRemovalListenerKey != key) {
-      if (_currentlyRegisteredWidgetRemovalListenerKey != null)
-        GlobalKey.unregisterRemoveListener(_currentlyRegisteredWidgetRemovalListenerKey, _handleWidgetRemoved);
-      if (key != null)
-        GlobalKey.registerRemoveListener(key, _handleWidgetRemoved);
-      _currentlyRegisteredWidgetRemovalListenerKey = key;
-    }
-  }
-
-  GlobalKey _focusedScope; // when null, the first scope to ask if it's focused will get the focus
-  GlobalKey _currentlyRegisteredScopeRemovalListenerKey;
-
-  void _setFocusedScope(GlobalKey key) {
-    setState(() {
-      _focusedScope = key;
-    });
-    _updateScopeRemovalListener(key);
-  }
-
-  void _setFocusedScopeIfUnset(GlobalKey key) {
-    if (_focusedScope == null) {
-      _focusedScope = key;
-      _updateScopeRemovalListener(key);
-    }
-  }
-
-  void _scopeRemoved(GlobalKey key) {
-    assert(_focusedScope == key);
-    _currentlyRegisteredScopeRemovalListenerKey = null;
-    setState(() {
-      _focusedScope = null;
-    });
-  }
-
-  void _updateScopeRemovalListener(GlobalKey key) {
-    if (_currentlyRegisteredScopeRemovalListenerKey != key) {
-      if (_currentlyRegisteredScopeRemovalListenerKey != null)
-        GlobalKey.unregisterRemoveListener(_currentlyRegisteredScopeRemovalListenerKey, _scopeRemoved);
-      if (key != null)
-        GlobalKey.registerRemoveListener(key, _scopeRemoved);
-      _currentlyRegisteredScopeRemovalListenerKey = key;
-    }
-  }
-
-  void initState() {
-    super.initState();
-    _updateWidgetRemovalListener(_focusedWidget);
-    _updateScopeRemovalListener(_focusedScope);
-  }
-
-  void dispose() {
-    _updateWidgetRemovalListener(null);
-    _updateScopeRemovalListener(null);
-    super.dispose();
-  }
-
-  Widget build(BuildContext context) {
-    return new _FocusScope(
-      focusState: this,
-      scopeFocused: Focus._atScope(context, config),
-      focusedScope: _focusedScope == _noFocusedScope ? null : _focusedScope,
-      focusedWidget: _focusedWidget,
-      child: config.child
-    );
-  }
-}
diff --git a/sky/packages/sky/lib/src/widgets/framework.dart b/sky/packages/sky/lib/src/widgets/framework.dart
deleted file mode 100644
index 8d278b6..0000000
--- a/sky/packages/sky/lib/src/widgets/framework.dart
+++ /dev/null
@@ -1,1666 +0,0 @@
-// Copyright 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 'dart:async';
-import 'dart:collection';
-
-import 'package:flutter/rendering.dart';
-
-export 'package:flutter/rendering.dart' show debugPrint;
-
-// KEYS
-
-/// A Key is an identifier for [Widget]s and [Element]s. A new Widget will only
-/// be used to reconfigure an existing Element if its Key is the same as its
-/// original Widget's Key.
-///
-/// Keys must be unique amongst the Elements with the same parent.
-abstract class Key {
-  /// Default constructor, used by subclasses.
-  const Key.constructor(); // so that subclasses can call us, since the Key() factory constructor shadows the implicit constructor
-
-  /// Construct a ValueKey<String> with the given String.
-  /// This is the simplest way to create keys.
-  factory Key(String value) => new ValueKey<String>(value);
-}
-
-/// A kind of [Key] that uses a value of a particular type to identify itself.
-///
-/// For example, a ValueKey<String> is equal to another ValueKey<String> if
-/// their values match.
-class ValueKey<T> extends Key {
-  const ValueKey(this.value) : super.constructor();
-  final T value;
-  bool operator ==(dynamic other) {
-    if (other is! ValueKey<T>)
-      return false;
-    final ValueKey<T> typedOther = other;
-    return value == typedOther.value;
-  }
-  int get hashCode => value.hashCode;
-  String toString() => '[\'$value\']';
-}
-
-/// A [Key] that is only equal to itself.
-class UniqueKey extends Key {
-  const UniqueKey() : super.constructor();
-  String toString() => '[$hashCode]';
-}
-
-/// A kind of [Key] that takes its identity from the object used as its value.
-///
-/// Used to tie the identity of a Widget to the identity of an object used to
-/// generate that Widget.
-class ObjectKey extends Key {
-  const ObjectKey(this.value) : super.constructor();
-  final Object value;
-  bool operator ==(dynamic other) {
-    if (other is! ObjectKey)
-      return false;
-    final ObjectKey typedOther = other;
-    return identical(value, typedOther.value);
-  }
-  int get hashCode => identityHashCode(value);
-  String toString() => '[${value.runtimeType}(${value.hashCode})]';
-}
-
-typedef void GlobalKeyRemoveListener(GlobalKey key);
-
-/// A GlobalKey is one that must be unique across the entire application. It is
-/// used by components that need to communicate with other components across the
-/// application's element tree.
-abstract class GlobalKey<T extends State<StatefulComponent>> extends Key {
-  const GlobalKey.constructor() : super.constructor(); // so that subclasses can call us, since the Key() factory constructor shadows the implicit constructor
-
-  /// Constructs a LabeledGlobalKey, which is a GlobalKey with a label used for debugging.
-  /// The label is not used for comparing the identity of the key.
-  factory GlobalKey({ String label }) => new LabeledGlobalKey<T>(label); // the label is purely for debugging purposes and is otherwise ignored
-
-  static final Map<GlobalKey, Element> _registry = new Map<GlobalKey, Element>();
-  static final Map<GlobalKey, int> _debugDuplicates = new Map<GlobalKey, int>();
-  static final Map<GlobalKey, Set<GlobalKeyRemoveListener>> _removeListeners = new Map<GlobalKey, Set<GlobalKeyRemoveListener>>();
-  static final Set<GlobalKey> _removedKeys = new Set<GlobalKey>();
-
-  void _register(Element element) {
-    assert(() {
-      if (_registry.containsKey(this)) {
-        int oldCount = _debugDuplicates.putIfAbsent(this, () => 1);
-        assert(oldCount >= 1);
-        _debugDuplicates[this] = oldCount + 1;
-      }
-      return true;
-    });
-    _registry[this] = element;
-  }
-
-  void _unregister(Element element) {
-    assert(() {
-      if (_registry.containsKey(this) && _debugDuplicates.containsKey(this)) {
-        int oldCount = _debugDuplicates[this];
-        assert(oldCount >= 2);
-        if (oldCount == 2) {
-          _debugDuplicates.remove(this);
-        } else {
-          _debugDuplicates[this] = oldCount - 1;
-        }
-      }
-      return true;
-    });
-    if (_registry[this] == element) {
-      _registry.remove(this);
-      _removedKeys.add(this);
-    }
-  }
-
-  Element get _currentElement => _registry[this];
-  BuildContext get currentContext => _currentElement;
-  Widget get currentWidget => _currentElement?.widget;
-  T get currentState {
-    Element element = _currentElement;
-    if (element is StatefulComponentElement<StatefulComponent, T>) {
-      StatefulComponentElement<StatefulComponent, T> statefulElement = element;
-      return statefulElement.state;
-    }
-    return null;
-  }
-
-  static void registerRemoveListener(GlobalKey key, GlobalKeyRemoveListener listener) {
-    assert(key != null);
-    Set<GlobalKeyRemoveListener> listeners =
-        _removeListeners.putIfAbsent(key, () => new Set<GlobalKeyRemoveListener>());
-    bool added = listeners.add(listener);
-    assert(added);
-  }
-
-  static void unregisterRemoveListener(GlobalKey key, GlobalKeyRemoveListener listener) {
-    assert(key != null);
-    assert(_removeListeners.containsKey(key));
-    bool removed = _removeListeners[key].remove(listener);
-    if (_removeListeners[key].isEmpty)
-      _removeListeners.remove(key);
-    assert(removed);
-  }
-
-  static bool _debugCheckForDuplicates() {
-    String message = '';
-    for (GlobalKey key in _debugDuplicates.keys) {
-      message += 'Duplicate GlobalKey found amongst mounted elements: $key (${_debugDuplicates[key]} instances)\n';
-      message += 'Most recently registered instance is:\n${_registry[key]}\n';
-    }
-    if (!_debugDuplicates.isEmpty)
-      throw message;
-    return true;
-  }
-
-  static void _notifyListeners() {
-    if (_removedKeys.isEmpty)
-      return;
-    try {
-      for (GlobalKey key in _removedKeys) {
-        if (!_registry.containsKey(key) && _removeListeners.containsKey(key)) {
-          Set<GlobalKeyRemoveListener> localListeners = new Set<GlobalKeyRemoveListener>.from(_removeListeners[key]);
-          for (GlobalKeyRemoveListener listener in localListeners)
-            listener(key);
-        }
-      }
-    } finally {
-      _removedKeys.clear();
-    }
-  }
-
-}
-
-/// Each LabeledGlobalKey instance is a unique key.
-/// The optional label can be used for documentary purposes. It does not affect
-/// the key's identity.
-class LabeledGlobalKey<T extends State<StatefulComponent>> extends GlobalKey<T> {
-  const LabeledGlobalKey(this._label) : super.constructor();
-  final String _label;
-  String toString() => '[GlobalKey ${_label != null ? _label : hashCode}]';
-}
-
-/// A kind of [GlobalKey] that takes its identity from the object used as its value.
-///
-/// Used to tie the identity of a Widget to the identity of an object used to
-/// generate that Widget.
-class GlobalObjectKey extends GlobalKey {
-  const GlobalObjectKey(this.value) : super.constructor();
-  final Object value;
-  bool operator ==(dynamic other) {
-    if (other is! GlobalObjectKey)
-      return false;
-    final GlobalObjectKey typedOther = other;
-    return identical(value, typedOther.value);
-  }
-  int get hashCode => identityHashCode(value);
-  String toString() => '[$runtimeType ${value.runtimeType}(${value.hashCode})]';
-}
-
-
-// WIDGETS
-
-/// A Widget object describes the configuration for an [Element].
-/// Widget subclasses should be immutable with const constructors.
-/// Widgets form a tree that is then inflated into an Element tree.
-abstract class Widget {
-  const Widget({ this.key });
-  final Key key;
-
-  /// Inflates this configuration to a concrete instance.
-  Element createElement();
-
-  String toStringShort() {
-    return key == null ? '$runtimeType' : '$runtimeType-$key';
-  }
-
-  String toString() {
-    final String name = toStringShort();
-    final List<String> data = <String>[];
-    debugFillDescription(data);
-    if (data.isEmpty)
-      return '$name';
-    return '$name(${data.join("; ")})';
-  }
-
-  void debugFillDescription(List<String> description) { }
-}
-
-// TODO(ianh): move the next four classes to below InheritedWidget
-
-/// RenderObjectWidgets provide the configuration for [RenderObjectElement]s,
-/// which wrap [RenderObject]s, which provide the actual rendering of the
-/// application.
-abstract class RenderObjectWidget extends Widget {
-  const RenderObjectWidget({ Key key }) : super(key: key);
-
-  /// RenderObjectWidgets always inflate to a RenderObjectElement subclass.
-  RenderObjectElement createElement();
-
-  /// Constructs an instance of the RenderObject class that this
-  /// RenderObjectWidget represents, using the configuration described by this
-  /// RenderObjectWidget.
-  RenderObject createRenderObject();
-
-  /// Copies the configuration described by this RenderObjectWidget to the given
-  /// RenderObject, which must be of the same type as returned by this class'
-  /// createRenderObject().
-  void updateRenderObject(RenderObject renderObject, RenderObjectWidget oldWidget) { }
-
-  void didUnmountRenderObject(RenderObject renderObject) { }
-}
-
-/// A superclass for RenderObjectWidgets that configure RenderObject subclasses
-/// that have no children.
-abstract class LeafRenderObjectWidget extends RenderObjectWidget {
-  const LeafRenderObjectWidget({ Key key }) : super(key: key);
-
-  LeafRenderObjectElement createElement() => new LeafRenderObjectElement(this);
-}
-
-/// A superclass for RenderObjectWidgets that configure RenderObject subclasses
-/// that have a single child slot. (This superclass only provides the storage
-/// for that child, it doesn't actually provide the updating logic.)
-abstract class OneChildRenderObjectWidget extends RenderObjectWidget {
-  const OneChildRenderObjectWidget({ Key key, this.child }) : super(key: key);
-
-  final Widget child;
-
-  OneChildRenderObjectElement createElement() => new OneChildRenderObjectElement(this);
-}
-
-/// A superclass for RenderObjectWidgets that configure RenderObject subclasses
-/// that have a single list of children. (This superclass only provides the
-/// storage for that child list, it doesn't actually provide the updating
-/// logic.)
-abstract class MultiChildRenderObjectWidget extends RenderObjectWidget {
-  MultiChildRenderObjectWidget({ Key key, this.children })
-    : super(key: key) {
-    assert(!children.any((Widget child) => child == null));
-  }
-
-  final List<Widget> children;
-
-  MultiChildRenderObjectElement createElement() => new MultiChildRenderObjectElement(this);
-}
-
-/// StatelessComponents describe a way to compose other Widgets to form reusable
-/// parts, which doesn't depend on anything other than the configuration
-/// information in the object itself. (For compositions that can change
-/// dynamically, e.g. due to having an internal clock-driven state, or depending
-/// on some system state, use [StatefulComponent].)
-abstract class StatelessComponent extends Widget {
-  const StatelessComponent({ Key key }) : super(key: key);
-
-  /// StatelessComponents always use StatelessComponentElements to represent
-  /// themselves in the Element tree.
-  StatelessComponentElement createElement() => new StatelessComponentElement(this);
-
-  /// Returns another Widget out of which this StatelessComponent is built.
-  /// Typically that Widget will have been configured with further children,
-  /// such that really this function returns a tree of configuration.
-  ///
-  /// The given build context object contains information about the location in
-  /// the tree at which this component is being built. For example, the context
-  /// provides the set of inherited widgets for this location in the tree.
-  Widget build(BuildContext context);
-}
-
-/// StatefulComponents provide the configuration for
-/// [StatefulComponentElement]s, which wrap [State]s, which hold mutable state
-/// and can dynamically and spontaneously ask to be rebuilt.
-abstract class StatefulComponent extends Widget {
-  const StatefulComponent({ Key key }) : super(key: key);
-
-  /// StatefulComponents always use StatefulComponentElements to represent
-  /// themselves in the Element tree.
-  StatefulComponentElement createElement() => new StatefulComponentElement(this);
-
-  /// Returns an instance of the state to which this StatefulComponent is
-  /// related, using this object as the configuration. Subclasses should
-  /// override this to return a new instance of the State class associated with
-  /// this StatefulComponent class, like this:
-  ///
-  ///   MyState createState() => new MyState(this);
-  State createState();
-}
-
-enum _StateLifecycle {
-  created,
-  initialized,
-  ready,
-  defunct,
-}
-
-/// The logic and internal state for a StatefulComponent.
-abstract class State<T extends StatefulComponent> {
-  /// The current configuration (an instance of the corresponding
-  /// StatefulComponent class).
-  T get config => _config;
-  T _config;
-
-  /// This is used to verify that State objects move through life in an orderly fashion.
-  _StateLifecycle _debugLifecycleState = _StateLifecycle.created;
-
-  /// Verifies that the State that was created is one that expects to be created
-  /// for that particular Widget.
-  bool _debugTypesAreRight(widget) => widget is T;
-
-  /// Pointer to the owner Element object
-  StatefulComponentElement _element;
-
-  /// The context in which this object will be built
-  BuildContext get context => _element;
-
-  bool get mounted => _element != null;
-
-  /// Called when this object is inserted into the tree. Override this function
-  /// to perform initialization that depends on the location at which this
-  /// object was inserted into the tree or on the widget configuration object.
-  ///
-  /// If you override this, make sure your method starts with a call to
-  /// super.initState().
-  void initState() {
-    assert(_debugLifecycleState == _StateLifecycle.created);
-    assert(() { _debugLifecycleState = _StateLifecycle.initialized; return true; });
-  }
-
-  /// Called whenever the configuration changes. Override this method to update
-  /// additional state when the config field's value is changed.
-  void didUpdateConfig(T oldConfig) { }
-
-  /// Whenever you need to change internal state for a State object, make the
-  /// change in a function that you pass to setState(), as in:
-  ///
-  ///    setState(() { myState = newValue });
-  ///
-  /// If you just change the state directly without calling setState(), then the
-  /// component will not be scheduled for rebuilding, meaning that its rendering
-  /// will not be updated.
-  void setState(void fn()) {
-    assert(_debugLifecycleState != _StateLifecycle.defunct);
-    fn();
-    _element.markNeedsBuild();
-  }
-
-  /// Called when this object is removed from the tree. Override this to clean
-  /// up any resources allocated by this object.
-  ///
-  /// If you override this, make sure to end your method with a call to
-  /// super.dispose().
-  void dispose() {
-    assert(_debugLifecycleState == _StateLifecycle.ready);
-    assert(() { _debugLifecycleState = _StateLifecycle.defunct; return true; });
-  }
-
-  /// Returns another Widget out of which this StatefulComponent is built.
-  /// Typically that Widget will have been configured with further children,
-  /// such that really this function returns a tree of configuration.
-  ///
-  /// The given build context object contains information about the location in
-  /// the tree at which this component is being built. For example, the context
-  /// provides the set of inherited widgets for this location in the tree.
-  Widget build(BuildContext context);
-
-  String toString() {
-    final List<String> data = <String>[];
-    debugFillDescription(data);
-    return '$runtimeType(${data.join("; ")})';
-  }
-
-  void debugFillDescription(List<String> description) {
-    description.add('$hashCode');
-    assert(() {
-      if (_debugLifecycleState != _StateLifecycle.ready)
-        description.add('$_debugLifecycleState');
-      return true;
-    });
-    if (_config == null)
-      description.add('no config');
-    if (_element == null)
-      description.add('not mounted');
-  }
-}
-
-abstract class ProxyComponent extends Widget {
-  const ProxyComponent({ Key key, this.child }) : super(key: key);
-
-  final Widget child;
-}
-
-abstract class ParentDataWidget extends ProxyComponent {
-  const ParentDataWidget({ Key key, Widget child })
-    : super(key: key, child: child);
-
-  ParentDataElement createElement() => new ParentDataElement(this);
-
-  /// Subclasses should override this function to ensure that they are placed
-  /// inside widgets that expect them.
-  ///
-  /// The given ancestor is the first RenderObjectWidget ancestor of this widget.
-  void debugValidateAncestor(RenderObjectWidget ancestor);
-
-  void applyParentData(RenderObject renderObject);
-}
-
-abstract class InheritedWidget extends ProxyComponent {
-  const InheritedWidget({ Key key, Widget child })
-    : super(key: key, child: child);
-
-  InheritedElement createElement() => new InheritedElement(this);
-
-  bool updateShouldNotify(InheritedWidget oldWidget);
-}
-
-
-// ELEMENTS
-
-bool _canUpdate(Widget oldWidget, Widget newWidget) {
-  return oldWidget.runtimeType == newWidget.runtimeType &&
-         oldWidget.key == newWidget.key;
-}
-
-enum _ElementLifecycle {
-  initial,
-  active,
-  inactive,
-  defunct,
-}
-
-class _InactiveElements {
-  bool _locked = false;
-  final Set<Element> _elements = new Set<Element>();
-
-  void _unmount(Element element) {
-    assert(element._debugLifecycleState == _ElementLifecycle.inactive);
-    element.unmount();
-    assert(element._debugLifecycleState == _ElementLifecycle.defunct);
-    element.visitChildren((Element child) {
-      assert(child._parent == element);
-      _unmount(child);
-    });
-  }
-
-  void unmountAll() {
-    BuildableElement.lockState(() {
-      try {
-        _locked = true;
-        for (Element element in _elements)
-          _unmount(element);
-      } finally {
-        _elements.clear();
-        _locked = false;
-      }
-    });
-  }
-
-  void _deactivate(Element element) {
-    assert(element._debugLifecycleState == _ElementLifecycle.active);
-    element.deactivate();
-    assert(element._debugLifecycleState == _ElementLifecycle.inactive);
-    element.visitChildren(_deactivate);
-  }
-
-  void add(Element element) {
-    assert(!_locked);
-    assert(!_elements.contains(element));
-    assert(element._parent == null);
-    if (element._active)
-      _deactivate(element);
-    _elements.add(element);
-  }
-
-  void _reactivate(Element element) {
-    assert(element._debugLifecycleState == _ElementLifecycle.inactive);
-    element.reactivate();
-    assert(element._debugLifecycleState == _ElementLifecycle.active);
-    element.visitChildren(_reactivate);
-  }
-
-  void remove(Element element) {
-    assert(!_locked);
-    assert(_elements.contains(element));
-    assert(element._parent == null);
-    _elements.remove(element);
-    assert(!element._active);
-    _reactivate(element);
-  }
-}
-
-final _InactiveElements _inactiveElements = new _InactiveElements();
-
-typedef void ElementVisitor(Element element);
-
-abstract class BuildContext {
-  Widget get widget;
-  RenderObject findRenderObject();
-  InheritedWidget inheritedWidgetOfType(Type targetType);
-  void visitAncestorElements(bool visitor(Element element));
-  void visitChildElements(void visitor(Element element));
-}
-
-/// Elements are the instantiations of Widget configurations.
-///
-/// Elements can, in principle, have children. Only subclasses of
-/// RenderObjectElement are allowed to have more than one child.
-abstract class Element<T extends Widget> implements BuildContext {
-  Element(T widget) : _widget = widget {
-    assert(widget != null);
-  }
-
-  Element _parent;
-
-  /// Information set by parent to define where this child fits in its parent's
-  /// child list.
-  ///
-  /// Subclasses of Element that only have one child should use null for
-  /// the slot for that child.
-  dynamic get slot => _slot;
-  dynamic _slot;
-
-  /// An integer that is guaranteed to be greater than the parent's, if any.
-  /// The element at the root of the tree must have a depth greater than 0.
-  int get depth => _depth;
-  int _depth;
-
-  /// The configuration for this element.
-  T get widget => _widget;
-  T _widget;
-
-  bool _active = false;
-
-  RenderObject get renderObject {
-    RenderObject result;
-    void visit(Element element) {
-      assert(result == null); // this verifies that there's only one child
-      if (element is RenderObjectElement)
-        result = element.renderObject;
-      else
-        element.visitChildren(visit);
-    }
-    visit(this);
-    return result;
-  }
-
-  /// This is used to verify that Element objects move through life in an orderly fashion.
-  _ElementLifecycle _debugLifecycleState = _ElementLifecycle.initial;
-
-  /// Calls the argument for each child. Must be overridden by subclasses that support having children.
-  void visitChildren(ElementVisitor visitor) { }
-
-  /// Wrapper around visitChildren for BuildContext.
-  void visitChildElements(void visitor(Element element)) {
-    // don't allow visitChildElements() during build, since children aren't necessarily built yet
-    assert(!BuildableElement._debugStateLocked);
-    visitChildren(visitor);
-  }
-
-  bool detachChild(Element child) => false;
-
-  /// This method is the core of the system.
-  ///
-  /// It is called each time we are to add, update, or remove a child based on
-  /// an updated configuration.
-  ///
-  /// If the child is null, and the newWidget is not null, then we have a new
-  /// child for which we need to create an Element, configured with newWidget.
-  ///
-  /// If the newWidget is null, and the child is not null, then we need to
-  /// remove it because it no longer has a configuration.
-  ///
-  /// If neither are null, then we need to update the child's configuration to
-  /// be the new configuration given by newWidget. If newWidget can be given to
-  /// the existing child, then it is so given. Otherwise, the old child needs
-  /// to be disposed and a new child created for the new configuration.
-  ///
-  /// If both are null, then we don't have a child and won't have a child, so
-  /// we do nothing.
-  ///
-  /// The updateChild() method returns the new child, if it had to create one,
-  /// or the child that was passed in, if it just had to update the child, or
-  /// null, if it removed the child and did not replace it.
-  Element updateChild(Element child, Widget newWidget, dynamic newSlot) {
-    if (newWidget == null) {
-      if (child != null)
-        _deactivateChild(child);
-      return null;
-    }
-    if (child != null) {
-      if (child.widget == newWidget) {
-        if (child.slot != newSlot)
-          updateSlotForChild(child, newSlot);
-        return child;
-      }
-      if (_canUpdate(child.widget, newWidget)) {
-        if (child.slot != newSlot)
-          updateSlotForChild(child, newSlot);
-        child.update(newWidget);
-        assert(child.widget == newWidget);
-        return child;
-      }
-      _deactivateChild(child);
-      assert(child._parent == null);
-    }
-    return _inflateWidget(newWidget, newSlot);
-  }
-
-  static void finalizeTree() {
-    _inactiveElements.unmountAll();
-    assert(GlobalKey._debugCheckForDuplicates);
-    scheduleMicrotask(GlobalKey._notifyListeners);
-  }
-
-  /// Called when an Element is given a new parent shortly after having been
-  /// created. Use this to initialize state that depends on having a parent. For
-  /// state that is independent of the position in the tree, it's better to just
-  /// initialize the Element in the constructor.
-  void mount(Element parent, dynamic newSlot) {
-    assert(_debugLifecycleState == _ElementLifecycle.initial);
-    assert(widget != null);
-    assert(_parent == null);
-    assert(parent == null || parent._debugLifecycleState == _ElementLifecycle.active);
-    assert(slot == null);
-    assert(depth == null);
-    assert(!_active);
-    _parent = parent;
-    _slot = newSlot;
-    _depth = _parent != null ? _parent.depth + 1 : 1;
-    _active = true;
-    if (widget.key is GlobalKey) {
-      final GlobalKey key = widget.key;
-      key._register(this);
-    }
-    assert(() { _debugLifecycleState = _ElementLifecycle.active; return true; });
-  }
-
-  /// Called when an Element receives a new configuration widget.
-  void update(T newWidget) {
-    assert(_debugLifecycleState == _ElementLifecycle.active);
-    assert(widget != null);
-    assert(newWidget != null);
-    assert(newWidget != widget);
-    assert(depth != null);
-    assert(_active);
-    assert(_canUpdate(widget, newWidget));
-    _widget = newWidget;
-  }
-
-  /// Called by MultiChildRenderObjectElement, and other RenderObjectElement
-  /// subclasses that have multiple children, to update the slot of a particular
-  /// child when the child is moved in its child list.
-  void updateSlotForChild(Element child, dynamic newSlot) {
-    assert(_debugLifecycleState == _ElementLifecycle.active);
-    assert(child != null);
-    assert(child._parent == this);
-    void visit(Element element) {
-      element._updateSlot(newSlot);
-      if (element is! RenderObjectElement)
-        element.visitChildren(visit);
-    }
-    visit(child);
-  }
-
-  void _updateSlot(dynamic newSlot) {
-    assert(_debugLifecycleState == _ElementLifecycle.active);
-    assert(widget != null);
-    assert(_parent != null);
-    assert(_parent._debugLifecycleState == _ElementLifecycle.active);
-    assert(depth != null);
-    _slot = newSlot;
-  }
-
-  void _updateDepth() {
-    int expectedDepth = _parent.depth + 1;
-    if (_depth < expectedDepth) {
-      _depth = expectedDepth;
-      visitChildren((Element child) {
-        child._updateDepth();
-      });
-    }
-  }
-
-  void detachRenderObject() {
-    visitChildren((Element child) {
-      child.detachRenderObject();
-    });
-    _slot = null;
-  }
-
-  void attachRenderObject(dynamic newSlot) {
-    assert(_slot == null);
-    visitChildren((Element child) {
-      child.attachRenderObject(newSlot);
-    });
-    _slot = newSlot;
-  }
-
-  Element _findAndActivateElement(GlobalKey key, Widget newWidget) {
-    Element element = key._currentElement;
-    if (element == null)
-      return null;
-    if (!_canUpdate(element.widget, newWidget))
-      return null;
-    if (element._parent != null && !element._parent.detachChild(element))
-      return null;
-    assert(element._parent == null);
-    _inactiveElements.remove(element);
-    return element;
-  }
-
-  Element _inflateWidget(Widget newWidget, dynamic newSlot) {
-    Key key = newWidget.key;
-    if (key is GlobalKey) {
-      Element newChild = _findAndActivateElement(key, newWidget);
-      if (newChild != null) {
-        assert(newChild._parent == null);
-        newChild._parent = this;
-        newChild._updateDepth();
-        newChild.attachRenderObject(newSlot);
-        Element updatedChild = updateChild(newChild, newWidget, newSlot);
-        assert(newChild == updatedChild);
-        return updatedChild;
-      }
-    }
-    Element newChild = newWidget.createElement();
-    newChild.mount(this, newSlot);
-    assert(newChild._debugLifecycleState == _ElementLifecycle.active);
-    return newChild;
-  }
-
-  void _deactivateChild(Element child) {
-    assert(child != null);
-    assert(child._parent == this);
-    child._parent = null;
-    child.detachRenderObject();
-    _inactiveElements.add(child);
-  }
-
-  void deactivate() {
-    assert(_debugLifecycleState == _ElementLifecycle.active);
-    assert(widget != null);
-    assert(depth != null);
-    assert(_active);
-    _active = false;
-    assert(() { _debugLifecycleState = _ElementLifecycle.inactive; return true; });
-  }
-
-  void reactivate() {
-    assert(_debugLifecycleState == _ElementLifecycle.inactive);
-    assert(widget != null);
-    assert(depth != null);
-    assert(!_active);
-    _active = true;
-    assert(() { _debugLifecycleState = _ElementLifecycle.active; return true; });
-  }
-
-  /// Called when an Element is removed from the tree permanently.
-  void unmount() {
-    assert(_debugLifecycleState == _ElementLifecycle.inactive);
-    assert(widget != null);
-    assert(depth != null);
-    assert(!_active);
-    if (widget.key is GlobalKey) {
-      final GlobalKey key = widget.key;
-      key._unregister(this);
-    }
-    assert(() { _debugLifecycleState = _ElementLifecycle.defunct; return true; });
-  }
-
-  Set<Type> _dependencies;
-  InheritedWidget inheritedWidgetOfType(Type targetType) {
-    if (_dependencies == null)
-      _dependencies = new Set<Type>();
-    _dependencies.add(targetType);
-    Element ancestor = _parent;
-    while (ancestor != null && ancestor.widget.runtimeType != targetType)
-      ancestor = ancestor._parent;
-    return ancestor?.widget;
-  }
-
-  RenderObject findRenderObject() => renderObject;
-
-  void visitAncestorElements(bool visitor(Element element)) {
-    Element ancestor = _parent;
-    while (ancestor != null && visitor(ancestor))
-      ancestor = ancestor._parent;
-  }
-
-  void dependenciesChanged() {
-    assert(false);
-  }
-
-  String toStringShort() {
-    return widget != null ? '${widget.toStringShort()}' : '[$runtimeType]';
-  }
-
-  String toString() {
-    final List<String> data = <String>[];
-    debugFillDescription(data);
-    final String name = widget != null ? '${widget.runtimeType}' : '[$runtimeType]';
-    return '$name(${data.join("; ")})';
-  }
-
-  void debugFillDescription(List<String> description) {
-    if (depth == null)
-      description.add('no depth');
-    if (widget == null) {
-      description.add('no widget');
-    } else {
-      if (widget.key != null)
-        description.add('${widget.key}');
-      widget.debugFillDescription(description);
-    }
-  }
-
-  String toStringDeep([String prefixLineOne = '', String prefixOtherLines = '']) {
-    String result = '$prefixLineOne$this\n';
-    List<Element> children = <Element>[];
-    visitChildren(children.add);
-    if (children.length > 0) {
-      Element last = children.removeLast();
-      for (Element child in children)
-        result += '${child.toStringDeep("$prefixOtherLines \u251C", "$prefixOtherLines \u2502")}';
-      result += '${last.toStringDeep("$prefixOtherLines \u2514", "$prefixOtherLines  ")}';
-    }
-    return result;
-  }
-}
-
-class ErrorWidget extends LeafRenderObjectWidget {
-  RenderBox createRenderObject() => new RenderErrorBox();
-}
-
-typedef void BuildScheduler(BuildableElement element);
-
-/// Base class for instantiations of widgets that have builders and can be
-/// marked dirty.
-abstract class BuildableElement<T extends Widget> extends Element<T> {
-  BuildableElement(T widget) : super(widget);
-
-  /// Returns true if the element has been marked as needing rebuilding.
-  bool get dirty => _dirty;
-  bool _dirty = true;
-
-  // We let component authors call setState from initState, didUpdateConfig, and
-  // build even when state is locked because its convenient and a no-op anyway.
-  // This flag ensures that this convenience is only allowed on the element
-  // currently undergoing initState, didUpdateConfig, or build.
-  bool _debugAllowIgnoredCallsToMarkNeedsBuild = false;
-  bool _debugSetAllowIgnoredCallsToMarkNeedsBuild(bool value) {
-    assert(_debugAllowIgnoredCallsToMarkNeedsBuild == !value);
-    _debugAllowIgnoredCallsToMarkNeedsBuild = value;
-    return true;
-  }
-
-  static BuildScheduler scheduleBuildFor;
-
-  static int _debugStateLockLevel = 0;
-  static bool get _debugStateLocked => _debugStateLockLevel > 0;
-  static bool _debugBuilding = false;
-  static BuildableElement _debugCurrentBuildTarget;
-
-  /// Establishes a scope in which component build functions can run.
-  ///
-  /// Inside a build scope, component build functions are allowed to run, but
-  /// State.setState() is forbidden. This mechanism prevents build functions
-  /// from transitively requiring other build functions to run, potentially
-  /// causing infinite loops.
-  ///
-  /// After unwinding the last build scope on the stack, the framework verifies
-  /// that each global key is used at most once and notifies listeners about
-  /// changes to global keys.
-  static void lockState(void callback(), { bool building: false }) {
-    assert(_debugStateLockLevel >= 0);
-    assert(() {
-      if (building) {
-        assert(!_debugBuilding);
-        assert(_debugCurrentBuildTarget == null);
-        _debugBuilding = true;
-      }
-      _debugStateLockLevel += 1;
-      return true;
-    });
-    try {
-      callback();
-    } finally {
-      assert(() {
-        _debugStateLockLevel -= 1;
-        if (building) {
-          assert(_debugBuilding);
-          assert(_debugCurrentBuildTarget == null);
-          _debugBuilding = false;
-        }
-        return true;
-      });
-    }
-    assert(_debugStateLockLevel >= 0);
-  }
-
-  /// Marks the element as dirty and adds it to the global list of widgets to
-  /// rebuild in the next frame.
-  ///
-  /// Since it is inefficient to build an element twice in one frame,
-  /// applications and components should be structured so as to only mark
-  /// components dirty during event handlers before the frame begins, not during
-  /// the build itself.
-  void markNeedsBuild() {
-    assert(_debugLifecycleState != _ElementLifecycle.defunct);
-    if (!_active)
-      return;
-    assert(_debugLifecycleState == _ElementLifecycle.active);
-    assert(() {
-      if (_debugBuilding) {
-        bool foundTarget = false;
-        visitAncestorElements((Element element) {
-          if (element == _debugCurrentBuildTarget) {
-            foundTarget = true;
-            return false;
-          }
-          return true;
-        });
-        if (foundTarget)
-          return true;
-      }
-      return !_debugStateLocked || (_debugAllowIgnoredCallsToMarkNeedsBuild && dirty);
-    });
-    if (dirty)
-      return;
-    _dirty = true;
-    assert(scheduleBuildFor != null);
-    scheduleBuildFor(this);
-  }
-
-  /// Called by the binding when scheduleBuild() has been called to mark this
-  /// element dirty, and, in Components, by update() when the Widget has
-  /// changed.
-  void rebuild() {
-    assert(_debugLifecycleState != _ElementLifecycle.initial);
-    if (!_active || !_dirty) {
-      _dirty = false;
-      return;
-    }
-    assert(_debugLifecycleState == _ElementLifecycle.active);
-    assert(_debugStateLocked);
-    BuildableElement debugPreviousBuildTarget;
-    assert(() {
-      debugPreviousBuildTarget = _debugCurrentBuildTarget;
-      _debugCurrentBuildTarget = this;
-     return true;
-    });
-    try {
-      performRebuild();
-    } catch (e, stack) {
-      _debugReportException('rebuilding $this', e, stack);
-    } finally {
-      assert(() {
-        assert(_debugCurrentBuildTarget == this);
-        _debugCurrentBuildTarget = debugPreviousBuildTarget;
-        return true;
-      });
-    }
-    assert(!_dirty);
-  }
-
-  /// Called by rebuild() after the appropriate checks have been made.
-  void performRebuild();
-
-  void dependenciesChanged() {
-    markNeedsBuild();
-  }
-
-  void debugFillDescription(List<String> description) {
-    super.debugFillDescription(description);
-    if (dirty)
-      description.add('dirty');
-  }
-}
-
-typedef Widget WidgetBuilder(BuildContext context);
-
-/// Base class for the instantiation of StatelessComponent, StatefulComponent,
-/// and ProxyComponent widgets.
-abstract class ComponentElement<T extends Widget> extends BuildableElement<T> {
-  ComponentElement(T widget) : super(widget);
-
-  WidgetBuilder _builder;
-  Element _child;
-
-  void mount(Element parent, dynamic newSlot) {
-    super.mount(parent, newSlot);
-    assert(_child == null);
-    assert(_active);
-    _firstBuild();
-    assert(_child != null);
-  }
-
-  void _firstBuild() {
-    rebuild();
-  }
-
-  /// Reinvokes the build() method of the StatelessComponent object (for
-  /// stateless components) or the State object (for stateful components) and
-  /// then updates the widget tree.
-  ///
-  /// Called automatically during mount() to generate the first build, and by
-  /// rebuild() when the element needs updating.
-  void performRebuild() {
-    assert(_debugSetAllowIgnoredCallsToMarkNeedsBuild(true));
-    Widget built;
-    try {
-      built = _builder(this);
-      assert(built != null);
-    } catch (e, stack) {
-      _debugReportException('building $_widget', e, stack);
-      built = new ErrorWidget();
-    } finally {
-      // We delay marking the element as clean until after calling _builder so
-      // that attempts to markNeedsBuild() during build() will be ignored.
-      _dirty = false;
-      assert(_debugSetAllowIgnoredCallsToMarkNeedsBuild(false));
-    }
-    try {
-      _child = updateChild(_child, built, slot);
-      assert(_child != null);
-    } catch (e, stack) {
-      _debugReportException('building $_widget', e, stack);
-      built = new ErrorWidget();
-      _child = updateChild(null, built, slot);
-    }
-  }
-
-  void visitChildren(ElementVisitor visitor) {
-    if (_child != null)
-      visitor(_child);
-  }
-
-  bool detachChild(Element child) {
-    assert(child == _child);
-    _deactivateChild(_child);
-    _child = null;
-    return true;
-  }
-}
-
-/// Instantiation of StatelessComponent widgets.
-class StatelessComponentElement<T extends StatelessComponent> extends ComponentElement<T> {
-  StatelessComponentElement(T widget) : super(widget) {
-    _builder = widget.build;
-  }
-
-  void update(T newWidget) {
-    super.update(newWidget);
-    assert(widget == newWidget);
-    _builder = widget.build;
-    _dirty = true;
-    rebuild();
-  }
-}
-
-/// Instantiation of StatefulComponent widgets.
-class StatefulComponentElement<T extends StatefulComponent, U extends State<T>> extends ComponentElement<T> {
-  StatefulComponentElement(T widget)
-    : _state = widget.createState(), super(widget) {
-    assert(_state._debugTypesAreRight(widget)); // can't use T and U, since normally we don't actually set those
-    assert(_state._element == null);
-    _state._element = this;
-    assert(_builder == null);
-    _builder = _state.build;
-    assert(_state._config == null);
-    _state._config = widget;
-    assert(_state._debugLifecycleState == _StateLifecycle.created);
-  }
-
-  U get state => _state;
-  U _state;
-
-  void _firstBuild() {
-    assert(_state._debugLifecycleState == _StateLifecycle.created);
-    try {
-      _debugSetAllowIgnoredCallsToMarkNeedsBuild(true);
-      _state.initState();
-    } finally {
-      _debugSetAllowIgnoredCallsToMarkNeedsBuild(false);
-    }
-    assert(() {
-      if (_state._debugLifecycleState == _StateLifecycle.initialized)
-        return true;
-      debugPrint('${_state.runtimeType}.initState failed to call super.initState');
-      return false;
-    });
-    assert(() { _state._debugLifecycleState = _StateLifecycle.ready; return true; });
-    super._firstBuild();
-  }
-
-  void update(T newWidget) {
-    super.update(newWidget);
-    assert(widget == newWidget);
-    StatefulComponent oldConfig = _state._config;
-    // Notice that we mark ourselves as dirty before calling didUpdateConfig to
-    // let authors call setState from within didUpdateConfig without triggering
-    // asserts.
-    _dirty = true;
-    _state._config = widget;
-    try {
-      _debugSetAllowIgnoredCallsToMarkNeedsBuild(true);
-      _state.didUpdateConfig(oldConfig);
-    } finally {
-      _debugSetAllowIgnoredCallsToMarkNeedsBuild(false);
-    }
-    rebuild();
-  }
-
-  void unmount() {
-    super.unmount();
-    _state.dispose();
-    assert(() {
-      if (_state._debugLifecycleState == _StateLifecycle.defunct)
-        return true;
-      debugPrint('${_state.runtimeType}.dispose failed to call super.dispose');
-      return false;
-    });
-    assert(!dirty); // See BuildableElement.unmount for why this is important.
-    _state._element = null;
-    _state = null;
-  }
-
-  void debugFillDescription(List<String> description) {
-    super.debugFillDescription(description);
-    if (state != null)
-      description.add('state: $state');
-  }
-}
-
-abstract class ProxyElement<T extends ProxyComponent> extends ComponentElement<T> {
-  ProxyElement(T widget) : super(widget) {
-    _builder = (BuildContext context) => this.widget.child;
-  }
-
-  void update(T newWidget) {
-    T oldWidget = widget;
-    assert(widget != null);
-    assert(widget != newWidget);
-    super.update(newWidget);
-    assert(widget == newWidget);
-    notifyDescendants(oldWidget);
-    _dirty = true;
-    rebuild();
-  }
-
-  void notifyDescendants(T oldWidget);
-}
-
-class ParentDataElement extends ProxyElement<ParentDataWidget> {
-  ParentDataElement(ParentDataWidget widget) : super(widget);
-
-  void mount(Element parent, dynamic slot) {
-    assert(() {
-      Element ancestor = parent;
-      while (ancestor is! RenderObjectElement) {
-        assert(ancestor != null);
-        assert(() {
-          'You cannot nest parent data widgets inside one another.';
-          return ancestor is! ParentDataElement;
-        });
-        ancestor = ancestor._parent;
-      }
-      _widget.debugValidateAncestor(ancestor._widget);
-      return true;
-    });
-    super.mount(parent, slot);
-  }
-
-  void notifyDescendants(ParentDataWidget oldWidget) {
-    void notifyChildren(Element child) {
-      if (child is RenderObjectElement)
-        child.updateParentData(widget);
-      else if (child is! ParentDataElement)
-        child.visitChildren(notifyChildren);
-    }
-    visitChildren(notifyChildren);
-  }
-}
-
-
-
-class InheritedElement extends ProxyElement<InheritedWidget> {
-  InheritedElement(InheritedWidget widget) : super(widget);
-
-  void notifyDescendants(InheritedWidget oldWidget) {
-    if (!widget.updateShouldNotify(oldWidget))
-      return;
-    final Type ourRuntimeType = widget.runtimeType;
-    void notifyChildren(Element child) {
-      if (child._dependencies != null &&
-          child._dependencies.contains(ourRuntimeType)) {
-        child.dependenciesChanged();
-      }
-      if (child.runtimeType != ourRuntimeType)
-        child.visitChildren(notifyChildren);
-    }
-    visitChildren(notifyChildren);
-  }
-}
-
-/// Base class for instantiations of RenderObjectWidget subclasses
-abstract class RenderObjectElement<T extends RenderObjectWidget> extends BuildableElement<T> {
-  RenderObjectElement(T widget)
-    : _renderObject = widget.createRenderObject(), super(widget) {
-    assert(() { debugUpdateRenderObjectOwner(); return true; });
-  }
-
-  /// The underlying [RenderObject] for this element
-  RenderObject get renderObject => _renderObject;
-  final RenderObject _renderObject;
-
-  RenderObjectElement _ancestorRenderObjectElement;
-
-  RenderObjectElement _findAncestorRenderObjectElement() {
-    Element ancestor = _parent;
-    while (ancestor != null && ancestor is! RenderObjectElement)
-      ancestor = ancestor._parent;
-    return ancestor;
-  }
-
-  ParentDataElement _findAncestorParentDataElement() {
-    Element ancestor = _parent;
-    while (ancestor != null && ancestor is! RenderObjectElement) {
-      if (ancestor is ParentDataElement)
-        return ancestor;
-      ancestor = ancestor._parent;
-    }
-    return null;
-  }
-
-  void mount(Element parent, dynamic newSlot) {
-    super.mount(parent, newSlot);
-    assert(_slot == newSlot);
-    attachRenderObject(newSlot);
-    ParentDataElement parentDataElement = _findAncestorParentDataElement();
-    if (parentDataElement != null)
-      updateParentData(parentDataElement.widget);
-    _dirty = false;
-  }
-
-  void update(T newWidget) {
-    T oldWidget = widget;
-    super.update(newWidget);
-    assert(widget == newWidget);
-    assert(() { debugUpdateRenderObjectOwner(); return true; });
-    widget.updateRenderObject(renderObject, oldWidget);
-    _dirty = false;
-  }
-
-  void debugUpdateRenderObjectOwner() {
-    List<String> chain = <String>[];
-    Element node = this;
-    while (chain.length < 4 && node != null) {
-      chain.add(node.toStringShort());
-      node = node._parent;
-    }
-    if (node != null)
-      chain.add('\u22EF');
-    _renderObject.debugOwner = chain.join(' \u2190 ');
-  }
-
-  void performRebuild() {
-    reinvokeBuilders();
-    _dirty = false;
-  }
-
-  void reinvokeBuilders() {
-    // There's no way to mark a normal RenderObjectElement dirty.
-    // We inherit from BuildableElement so that subclasses can themselves
-    // implement reinvokeBuilders() if they do provide a way to mark themeselves
-    // dirty, e.g. if they have a builder callback. (Builder callbacks have a
-    // 'BuildContext' argument which you can pass to Theme.of() and other
-    // InheritedWidget APIs which eventually trigger a rebuild.)
-    debugPrint('$runtimeType failed to implement reinvokeBuilders(), but got marked dirty');
-    assert(() {
-      'reinvokeBuilders() not implemented';
-      return false;
-    });
-  }
-
-  /// Utility function for subclasses that have one or more lists of children.
-  /// Attempts to update the given old children list using the given new
-  /// widgets, removing obsolete elements and introducing new ones as necessary,
-  /// and then returns the new child list.
-  List<Element> updateChildren(List<Element> oldChildren, List<Widget> newWidgets) {
-    assert(oldChildren != null);
-    assert(newWidgets != null);
-
-    // This attempts to diff the new child list (this.children) with
-    // the old child list (old.children), and update our renderObject
-    // accordingly.
-
-    // The cases it tries to optimise for are:
-    //  - the old list is empty
-    //  - the lists are identical
-    //  - there is an insertion or removal of one or more widgets in
-    //    only one place in the list
-    // If a widget with a key is in both lists, it will be synced.
-    // Widgets without keys might be synced but there is no guarantee.
-
-    // The general approach is to sync the entire new list backwards, as follows:
-    // 1. Walk the lists from the top until you no longer have
-    //    matching nodes. We don't sync these yet, but we now know to
-    //    skip them below. We do this because at each sync we need to
-    //    pass the pointer to the new next widget as the slot, which
-    //    we can't do until we've synced the next child.
-    // 2. Walk the lists from the bottom, syncing nodes, until you no
-    //    longer have matching nodes.
-    // At this point we narrowed the old and new lists to the point
-    // where the nodes no longer match.
-    // 3. Walk the narrowed part of the old list to get the list of
-    //    keys and sync null with non-keyed items.
-    // 4. Walk the narrowed part of the new list backwards:
-    //     * Sync unkeyed items with null
-    //     * Sync keyed items with the source if it exists, else with null.
-    // 5. Walk the top list again but backwards, syncing the nodes.
-    // 6. Sync null with any items in the list of keys that are still
-    //    mounted.
-
-    int childrenTop = 0;
-    int newChildrenBottom = newWidgets.length - 1;
-    int oldChildrenBottom = oldChildren.length - 1;
-
-    // top of the lists
-    while ((childrenTop <= oldChildrenBottom) && (childrenTop <= newChildrenBottom)) {
-      Element oldChild = oldChildren[childrenTop];
-      Widget newWidget = newWidgets[childrenTop];
-      assert(oldChild._debugLifecycleState == _ElementLifecycle.active);
-      if (!_canUpdate(oldChild.widget, newWidget))
-        break;
-      childrenTop += 1;
-    }
-
-    List<Element> newChildren = oldChildren.length == newWidgets.length ?
-        oldChildren : new List<Element>(newWidgets.length);
-
-    Element nextSibling;
-
-    // bottom of the lists
-    while ((childrenTop <= oldChildrenBottom) && (childrenTop <= newChildrenBottom)) {
-      Element oldChild = oldChildren[oldChildrenBottom];
-      Widget newWidget = newWidgets[newChildrenBottom];
-      assert(oldChild._debugLifecycleState == _ElementLifecycle.active);
-      if (!_canUpdate(oldChild.widget, newWidget))
-        break;
-      Element newChild = updateChild(oldChild, newWidget, nextSibling);
-      assert(newChild._debugLifecycleState == _ElementLifecycle.active);
-      newChildren[newChildrenBottom] = newChild;
-      nextSibling = newChild;
-      oldChildrenBottom -= 1;
-      newChildrenBottom -= 1;
-    }
-
-    // middle of the lists - old list
-    bool haveOldNodes = childrenTop <= oldChildrenBottom;
-    Map<Key, Element> oldKeyedChildren;
-    if (haveOldNodes) {
-      oldKeyedChildren = new Map<Key, Element>();
-      while (childrenTop <= oldChildrenBottom) {
-        Element oldChild = oldChildren[oldChildrenBottom];
-        assert(oldChild._debugLifecycleState == _ElementLifecycle.active);
-        if (oldChild.widget.key != null)
-          oldKeyedChildren[oldChild.widget.key] = oldChild;
-        else
-          _deactivateChild(oldChild);
-        oldChildrenBottom -= 1;
-      }
-    }
-
-    // middle of the lists - new list
-    while (childrenTop <= newChildrenBottom) {
-      Element oldChild;
-      Widget newWidget = newWidgets[newChildrenBottom];
-      if (haveOldNodes) {
-        Key key = newWidget.key;
-        if (key != null) {
-          oldChild = oldKeyedChildren[newWidget.key];
-          if (oldChild != null) {
-            if (_canUpdate(oldChild.widget, newWidget)) {
-              // we found a match!
-              // remove it from oldKeyedChildren so we don't unsync it later
-              oldKeyedChildren.remove(key);
-            } else {
-              // Not a match, let's pretend we didn't see it for now.
-              oldChild = null;
-            }
-          }
-        }
-      }
-      assert(oldChild == null || _canUpdate(oldChild.widget, newWidget));
-      Element newChild = updateChild(oldChild, newWidget, nextSibling);
-      assert(newChild._debugLifecycleState == _ElementLifecycle.active);
-      assert(oldChild == newChild || oldChild == null || oldChild._debugLifecycleState != _ElementLifecycle.active);
-      newChildren[newChildrenBottom] = newChild;
-      nextSibling = newChild;
-      newChildrenBottom -= 1;
-    }
-    assert(oldChildrenBottom == newChildrenBottom);
-    assert(childrenTop == newChildrenBottom + 1);
-
-    // now sync the top of the list
-    while (childrenTop > 0) {
-      childrenTop -= 1;
-      Element oldChild = oldChildren[childrenTop];
-      assert(oldChild._debugLifecycleState == _ElementLifecycle.active);
-      Widget newWidget = newWidgets[childrenTop];
-      assert(_canUpdate(oldChild.widget, newWidget));
-      Element newChild = updateChild(oldChild, newWidget, nextSibling);
-      assert(newChild._debugLifecycleState == _ElementLifecycle.active);
-      assert(oldChild == newChild || oldChild == null || oldChild._debugLifecycleState != _ElementLifecycle.active);
-      newChildren[childrenTop] = newChild;
-      nextSibling = newChild;
-    }
-
-    // clean up any of the remaining middle nodes from the old list
-    if (haveOldNodes && !oldKeyedChildren.isEmpty) {
-      for (Element oldChild in oldKeyedChildren.values)
-        _deactivateChild(oldChild);
-    }
-
-    return newChildren;
-  }
-
-  void deactivate() {
-    super.deactivate();
-    assert(!renderObject.attached);
-  }
-
-  void unmount() {
-    super.unmount();
-    assert(!renderObject.attached);
-    widget.didUnmountRenderObject(renderObject);
-  }
-
-  void updateParentData(ParentDataWidget parentData) {
-    parentData.applyParentData(renderObject);
-  }
-
-  void _updateSlot(dynamic newSlot) {
-    assert(slot != newSlot);
-    super._updateSlot(newSlot);
-    assert(slot == newSlot);
-    _ancestorRenderObjectElement.moveChildRenderObject(renderObject, slot);
-  }
-
-  void attachRenderObject(dynamic newSlot) {
-    assert(_ancestorRenderObjectElement == null);
-    _slot = newSlot;
-    _ancestorRenderObjectElement = _findAncestorRenderObjectElement();
-    _ancestorRenderObjectElement?.insertChildRenderObject(renderObject, newSlot);
-  }
-
-  void detachRenderObject() {
-    if (_ancestorRenderObjectElement != null) {
-      _ancestorRenderObjectElement.removeChildRenderObject(renderObject);
-      _ancestorRenderObjectElement = null;
-    }
-    _slot = null;
-  }
-
-  void insertChildRenderObject(RenderObject child, dynamic slot);
-  void moveChildRenderObject(RenderObject child, dynamic slot);
-  void removeChildRenderObject(RenderObject child);
-
-  void debugFillDescription(List<String> description) {
-    super.debugFillDescription(description);
-    if (renderObject != null)
-      description.add('renderObject: $renderObject');
-  }
-}
-
-/// Instantiation of RenderObjectWidgets that have no children
-class LeafRenderObjectElement<T extends RenderObjectWidget> extends RenderObjectElement<T> {
-  LeafRenderObjectElement(T widget): super(widget);
-
-  void insertChildRenderObject(RenderObject child, dynamic slot) {
-    assert(false);
-  }
-
-  void moveChildRenderObject(RenderObject child, dynamic slot) {
-    assert(false);
-  }
-
-  void removeChildRenderObject(RenderObject child) {
-    assert(false);
-  }
-}
-
-/// Instantiation of RenderObjectWidgets that have up to one child
-class OneChildRenderObjectElement<T extends OneChildRenderObjectWidget> extends RenderObjectElement<T> {
-  OneChildRenderObjectElement(T widget) : super(widget);
-
-  Element _child;
-
-  void visitChildren(ElementVisitor visitor) {
-    if (_child != null)
-      visitor(_child);
-  }
-
-  bool detachChild(Element child) {
-    assert(child == _child);
-    _deactivateChild(_child);
-    _child = null;
-    return true;
-  }
-
-  void mount(Element parent, dynamic newSlot) {
-    super.mount(parent, newSlot);
-    _child = updateChild(_child, widget.child, null);
-  }
-
-  void update(T newWidget) {
-    super.update(newWidget);
-    assert(widget == newWidget);
-    _child = updateChild(_child, widget.child, null);
-  }
-
-  void insertChildRenderObject(RenderObject child, dynamic slot) {
-    final RenderObjectWithChildMixin renderObject = this.renderObject;
-    assert(slot == null);
-    renderObject.child = child;
-    assert(renderObject == this.renderObject);
-  }
-
-  void moveChildRenderObject(RenderObject child, dynamic slot) {
-    assert(false);
-  }
-
-  void removeChildRenderObject(RenderObject child) {
-    final RenderObjectWithChildMixin renderObject = this.renderObject;
-    assert(renderObject.child == child);
-    renderObject.child = null;
-    assert(renderObject == this.renderObject);
-  }
-}
-
-/// Instantiation of RenderObjectWidgets that can have a list of children
-class MultiChildRenderObjectElement<T extends MultiChildRenderObjectWidget> extends RenderObjectElement<T> {
-  MultiChildRenderObjectElement(T widget) : super(widget) {
-    assert(!_debugHasDuplicateIds());
-  }
-
-  List<Element> _children;
-
-  void insertChildRenderObject(RenderObject child, Element slot) {
-    final ContainerRenderObjectMixin renderObject = this.renderObject;
-    final RenderObject nextSibling = slot?.renderObject;
-    renderObject.add(child, before: nextSibling);
-    assert(renderObject == this.renderObject);
-  }
-
-  void moveChildRenderObject(RenderObject child, dynamic slot) {
-    final ContainerRenderObjectMixin renderObject = this.renderObject;
-    final RenderObject nextSibling = slot?.renderObject;
-    renderObject.move(child, before: nextSibling);
-    assert(renderObject == this.renderObject);
-  }
-
-  void removeChildRenderObject(RenderObject child) {
-    final ContainerRenderObjectMixin renderObject = this.renderObject;
-    assert(child.parent == renderObject);
-    renderObject.remove(child);
-    assert(renderObject == this.renderObject);
-  }
-
-  bool _debugHasDuplicateIds() {
-    var idSet = new HashSet<Key>();
-    for (Widget child in widget.children) {
-      assert(child != null);
-      if (child.key == null)
-        continue; // when these nodes are reordered, we just reassign the data
-
-      if (!idSet.add(child.key)) {
-        throw 'If multiple keyed nodes exist as children of another node, they must have unique keys. $widget has multiple children with key "${child.key}".';
-      }
-    }
-    return false;
-  }
-
-  void visitChildren(ElementVisitor visitor) {
-    for (Element child in _children)
-      visitor(child);
-  }
-
-  void mount(Element parent, dynamic newSlot) {
-    super.mount(parent, newSlot);
-    _children = new List<Element>(widget.children.length);
-    Element previousChild;
-    for (int i = _children.length - 1; i >= 0; --i) {
-      Element newChild = _inflateWidget(widget.children[i], previousChild);
-      _children[i] = newChild;
-      previousChild = newChild;
-    }
-  }
-
-  void update(T newWidget) {
-    super.update(newWidget);
-    assert(widget == newWidget);
-    _children = updateChildren(_children, widget.children);
-  }
-}
-
-typedef void WidgetsExceptionHandler(String context, dynamic exception, StackTrace stack);
-/// This callback is invoked whenever an exception is caught by the widget
-/// system. The 'context' argument is a description of what was happening when
-/// the exception occurred, and may include additional details such as
-/// descriptions of the objects involved. The 'exception' argument contains the
-/// object that was thrown, and the 'stack' argument contains the stack trace.
-/// If no callback is set, then a default behaviour consisting of dumping the
-/// context, exception, and stack trace to the console is used instead.
-WidgetsExceptionHandler debugWidgetsExceptionHandler;
-void _debugReportException(String context, dynamic exception, StackTrace stack) {
-  if (debugWidgetsExceptionHandler != null) {
-    debugWidgetsExceptionHandler(context, exception, stack);
-  } else {
-    debugPrint('------------------------------------------------------------------------');
-    debugPrint('Exception caught while $context');
-    debugPrint('$exception');
-    debugPrint('Stack trace:');
-    debugPrint('$stack');
-    debugPrint('------------------------------------------------------------------------');
-  }
-}
diff --git a/sky/packages/sky/lib/src/widgets/gesture_detector.dart b/sky/packages/sky/lib/src/widgets/gesture_detector.dart
deleted file mode 100644
index e62764e..0000000
--- a/sky/packages/sky/lib/src/widgets/gesture_detector.dart
+++ /dev/null
@@ -1,263 +0,0 @@
-// Copyright 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:flutter/gestures.dart';
-import 'package:flutter/rendering.dart';
-
-import 'basic.dart';
-import 'framework.dart';
-
-export 'package:flutter/gestures.dart' show
-  GestureTapDownCallback,
-  GestureTapUpCallback,
-  GestureTapCallback,
-  GestureTapCancelCallback,
-  GestureLongPressCallback,
-  GestureDragStartCallback,
-  GestureDragUpdateCallback,
-  GestureDragEndCallback,
-  GestureDragStartCallback,
-  GestureDragUpdateCallback,
-  GestureDragEndCallback,
-  GesturePanStartCallback,
-  GesturePanUpdateCallback,
-  GesturePanEndCallback,
-  GestureScaleStartCallback,
-  GestureScaleUpdateCallback,
-  GestureScaleEndCallback;
-
-class GestureDetector extends StatefulComponent {
-  const GestureDetector({
-    Key key,
-    this.child,
-    this.onTapDown,
-    this.onTapUp,
-    this.onTap,
-    this.onTapCancel,
-    this.onDoubleTap,
-    this.onLongPress,
-    this.onVerticalDragStart,
-    this.onVerticalDragUpdate,
-    this.onVerticalDragEnd,
-    this.onHorizontalDragStart,
-    this.onHorizontalDragUpdate,
-    this.onHorizontalDragEnd,
-    this.onPanStart,
-    this.onPanUpdate,
-    this.onPanEnd,
-    this.onScaleStart,
-    this.onScaleUpdate,
-    this.onScaleEnd,
-    this.behavior
-  }) : super(key: key);
-
-  final Widget child;
-
-  final GestureTapDownCallback onTapDown;
-  final GestureTapDownCallback onTapUp;
-  final GestureTapCallback onTap;
-  final GestureTapCancelCallback onTapCancel;
-  final GestureTapCallback onDoubleTap;
-
-  final GestureLongPressCallback onLongPress;
-
-  final GestureDragStartCallback onVerticalDragStart;
-  final GestureDragUpdateCallback onVerticalDragUpdate;
-  final GestureDragEndCallback onVerticalDragEnd;
-
-  final GestureDragStartCallback onHorizontalDragStart;
-  final GestureDragUpdateCallback onHorizontalDragUpdate;
-  final GestureDragEndCallback onHorizontalDragEnd;
-
-  final GesturePanStartCallback onPanStart;
-  final GesturePanUpdateCallback onPanUpdate;
-  final GesturePanEndCallback onPanEnd;
-
-  final GestureScaleStartCallback onScaleStart;
-  final GestureScaleUpdateCallback onScaleUpdate;
-  final GestureScaleEndCallback onScaleEnd;
-
-  final HitTestBehavior behavior;
-
-  _GestureDetectorState createState() => new _GestureDetectorState();
-}
-
-class _GestureDetectorState extends State<GestureDetector> {
-  PointerRouter get _router => FlutterBinding.instance.pointerRouter;
-
-  TapGestureRecognizer _tap;
-  DoubleTapGestureRecognizer _doubleTap;
-  LongPressGestureRecognizer _longPress;
-  VerticalDragGestureRecognizer _verticalDrag;
-  HorizontalDragGestureRecognizer _horizontalDrag;
-  PanGestureRecognizer _pan;
-  ScaleGestureRecognizer _scale;
-
-  void initState() {
-    super.initState();
-    _syncAll();
-  }
-
-  void didUpdateConfig(GestureDetector oldConfig) {
-    _syncAll();
-  }
-
-  void dispose() {
-    _tap = _ensureDisposed(_tap);
-    _doubleTap = _ensureDisposed(_doubleTap);
-    _longPress = _ensureDisposed(_longPress);
-    _verticalDrag = _ensureDisposed(_verticalDrag);
-    _horizontalDrag = _ensureDisposed(_horizontalDrag);
-    _pan = _ensureDisposed(_pan);
-    _scale = _ensureDisposed(_scale);
-    super.dispose();
-  }
-
-  void _syncAll() {
-    _syncTap();
-    _syncDoubleTap();
-    _syncLongPress();
-    _syncVerticalDrag();
-    _syncHorizontalDrag();
-    _syncPan();
-    _syncScale();
-  }
-
-  void _syncTap() {
-    if (config.onTapDown == null && config.onTapUp == null && config.onTap == null && config.onTapCancel == null) {
-      _tap = _ensureDisposed(_tap);
-    } else {
-      _tap ??= new TapGestureRecognizer(router: _router);
-      _tap
-        ..onTapDown = config.onTapDown
-        ..onTapUp = config.onTapUp
-        ..onTap = config.onTap
-        ..onTapCancel = config.onTapCancel;
-    }
-  }
-
-  void _syncDoubleTap() {
-    if (config.onDoubleTap == null) {
-      _doubleTap = _ensureDisposed(_doubleTap);
-    } else {
-      _doubleTap ??= new DoubleTapGestureRecognizer(router: _router);
-      _doubleTap.onDoubleTap = config.onDoubleTap;
-    }
-  }
-
-  void _syncLongPress() {
-    if (config.onLongPress == null) {
-      _longPress = _ensureDisposed(_longPress);
-    } else {
-      _longPress ??= new LongPressGestureRecognizer(router: _router);
-      _longPress.onLongPress = config.onLongPress;
-    }
-  }
-
-  void _syncVerticalDrag() {
-    if (config.onVerticalDragStart == null && config.onVerticalDragUpdate == null && config.onVerticalDragEnd == null) {
-      _verticalDrag = _ensureDisposed(_verticalDrag);
-    } else {
-      _verticalDrag ??= new VerticalDragGestureRecognizer(router: _router);
-      _verticalDrag
-        ..onStart = config.onVerticalDragStart
-        ..onUpdate = config.onVerticalDragUpdate
-        ..onEnd = config.onVerticalDragEnd;
-    }
-  }
-
-  void _syncHorizontalDrag() {
-    if (config.onHorizontalDragStart == null && config.onHorizontalDragUpdate == null && config.onHorizontalDragEnd == null) {
-      _horizontalDrag = _ensureDisposed(_horizontalDrag);
-    } else {
-      _horizontalDrag ??= new HorizontalDragGestureRecognizer(router: _router);
-      _horizontalDrag
-        ..onStart = config.onHorizontalDragStart
-        ..onUpdate = config.onHorizontalDragUpdate
-        ..onEnd = config.onHorizontalDragEnd;
-    }
-  }
-
-  void _syncPan() {
-    if (config.onPanStart == null && config.onPanUpdate == null && config.onPanEnd == null) {
-      _pan = _ensureDisposed(_pan);
-    } else {
-      assert(_scale == null);  // Scale is a superset of pan; just use scale
-      _pan ??= new PanGestureRecognizer(router: _router);
-      _pan
-        ..onStart = config.onPanStart
-        ..onUpdate = config.onPanUpdate
-        ..onEnd = config.onPanEnd;
-    }
-  }
-
-  void _syncScale() {
-    if (config.onScaleStart == null && config.onScaleUpdate == null && config.onScaleEnd == null) {
-      _scale = _ensureDisposed(_scale);
-    } else {
-      assert(_pan == null);  // Scale is a superset of pan; just use scale
-      _scale ??= new ScaleGestureRecognizer(router: _router);
-      _scale
-        ..onStart = config.onScaleStart
-        ..onUpdate = config.onScaleUpdate
-        ..onEnd = config.onScaleEnd;
-    }
-  }
-
-  GestureRecognizer _ensureDisposed(GestureRecognizer recognizer) {
-    recognizer?.dispose();
-    return null;
-  }
-
-  void _handlePointerDown(PointerInputEvent event) {
-    if (_tap != null)
-      _tap.addPointer(event);
-    if (_doubleTap != null)
-      _doubleTap.addPointer(event);
-    if (_longPress != null)
-      _longPress.addPointer(event);
-    if (_verticalDrag != null)
-      _verticalDrag.addPointer(event);
-    if (_horizontalDrag != null)
-      _horizontalDrag.addPointer(event);
-    if (_pan != null)
-      _pan.addPointer(event);
-    if (_scale != null)
-      _scale.addPointer(event);
-  }
-
-  HitTestBehavior get _defaultBehavior {
-    return config.child == null ? HitTestBehavior.translucent : HitTestBehavior.deferToChild;
-  }
-
-  Widget build(BuildContext context) {
-    return new Listener(
-      onPointerDown: _handlePointerDown,
-      behavior: config.behavior ?? _defaultBehavior,
-      child: config.child
-    );
-  }
-
-  void debugFillDescription(List<String> description) {
-    super.debugFillDescription(description);
-    List<String> gestures = <String>[];
-    if (_tap != null)
-      gestures.add('tap');
-    if (_doubleTap != null)
-      gestures.add('double tap');
-    if (_longPress != null)
-      gestures.add('long press');
-    if (_verticalDrag != null)
-      gestures.add('vertical drag');
-    if (_horizontalDrag != null)
-      gestures.add('horizontal drag');
-    if (_pan != null)
-      gestures.add('pan');
-    if (_scale != null)
-      gestures.add('scale');
-    if (gestures.isEmpty)
-      gestures.add('<none>');
-    description.add('gestures: ${gestures.join(", ")}');
-  }
-}
diff --git a/sky/packages/sky/lib/src/widgets/gridpaper.dart b/sky/packages/sky/lib/src/widgets/gridpaper.dart
deleted file mode 100644
index 25d22e3..0000000
--- a/sky/packages/sky/lib/src/widgets/gridpaper.dart
+++ /dev/null
@@ -1,36 +0,0 @@
-// Copyright 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:flutter/rendering.dart';
-
-import 'basic.dart';
-import 'framework.dart';
-
-class GridPaper extends StatelessComponent {
-  GridPaper({
-    Key key,
-    this.color: const Color(0xFF000000),
-    this.interval: 100.0
-  }) : super(key: key);
-
-  final Color color;
-  final double interval;
-
-  Widget build(BuildContext context) {
-    return new IgnorePointer(child: new CustomPaint(
-      onPaint: (PaintingCanvas canvas, Size size) {
-        Paint linePaint = new Paint()
-          ..color = color;
-        for (double x = 0.0; x <= size.width; x += interval / 10.0) {
-          linePaint.strokeWidth = (x % interval == 0.0) ? 1.0 : (x % (interval / 2.0) == 0.0) ? 0.5: 0.25;
-          canvas.drawLine(new Point(x, 0.0), new Point(x, size.height), linePaint);
-        }
-        for (double y = 0.0; y <= size.height; y += interval / 10.0) {
-          linePaint.strokeWidth = (y % interval == 0.0) ? 1.0 : (y % (interval / 2.0) == 0.0) ? 0.5: 0.25;
-          canvas.drawLine(new Point(0.0, y), new Point(size.width, y), linePaint);
-        }
-      })
-    );
-  }
-}
diff --git a/sky/packages/sky/lib/src/widgets/hero_controller.dart b/sky/packages/sky/lib/src/widgets/hero_controller.dart
deleted file mode 100644
index fb44db9..0000000
--- a/sky/packages/sky/lib/src/widgets/hero_controller.dart
+++ /dev/null
@@ -1,145 +0,0 @@
-// Copyright 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:flutter/animation.dart';
-import 'package:flutter/rendering.dart';
-
-import 'basic.dart';
-import 'framework.dart';
-import 'heroes.dart';
-import 'navigator.dart';
-import 'overlay.dart';
-import 'page.dart';
-
-class HeroPageRoute extends PageRoute {
-  HeroPageRoute({
-    WidgetBuilder builder,
-    NamedRouteSettings settings: const NamedRouteSettings(),
-    this.heroController
-  }) : super(builder: builder, settings: settings);
-
-  final HeroController heroController;
-  NavigatorState _navigator;
-
-  void didPush(OverlayState overlay, OverlayEntry insertionPoint) {
-    super.didPush(overlay, insertionPoint);
-    // TODO(abarth): Pass the NavigatorState explicitly.
-    if (overlay != null) {
-      _navigator = Navigator.of(overlay.context);
-      heroController?.didPush(_navigator, this);
-    }
-  }
-
-  void didPop(dynamic result) {
-    super.didPop(result);
-    if (_navigator != null) {
-      heroController?.didPop(_navigator, this);
-      _navigator = null;
-    }
-  }
-}
-
-class HeroController {
-  HeroController() {
-    _party = new HeroParty(onQuestFinished: _handleQuestFinished);
-  }
-
-  HeroParty _party;
-  PerformanceView _performance;
-  HeroPageRoute _from;
-  HeroPageRoute _to;
-
-  final List<OverlayEntry> _overlayEntries = new List<OverlayEntry>();
-
-  void didPush(NavigatorState navigator, HeroPageRoute route) {
-    assert(route != null);
-    assert(route.performance != null);
-    Route from = navigator.currentRoute;
-    if (from is HeroPageRoute)
-      _from = from;
-    _to = route;
-    _performance = route.performance;
-    _checkForHeroQuest();
-  }
-
-  void didPop(NavigatorState navigator, HeroPageRoute route) {
-    assert(route != null);
-    assert(route.performance != null);
-    Route to = navigator.currentRoute;
-    if (to is HeroPageRoute) {
-      _to = to;
-      _from = route;
-      _performance = route.performance;
-      _checkForHeroQuest();
-    }
-  }
-
-  void _checkForHeroQuest() {
-    if (_from != null && _to != null && _from != _to) {
-      _to.offstage = _to.performance.status != PerformanceStatus.completed;
-      scheduler.requestPostFrameCallback(_updateQuest);
-    }
-  }
-
-  void _handleQuestFinished() {
-    _removeHeroesFromOverlay();
-    _from = null;
-    _to = null;
-    _performance = null;
-  }
-
-  Rect _getAnimationArea(BuildContext context) {
-    RenderBox box = context.findRenderObject();
-    Point topLeft = box.localToGlobal(Point.origin);
-    Point bottomRight = box.localToGlobal(box.size.bottomRight(Point.origin));
-    return new Rect.fromLTRB(topLeft.x, topLeft.y, bottomRight.x, bottomRight.y);
-  }
-
-  void _removeHeroesFromOverlay() {
-    for (OverlayEntry entry in _overlayEntries)
-      entry.remove();
-    _overlayEntries.clear();
-  }
-
-  void _addHeroesToOverlay(Iterable<Widget> heroes, OverlayState overlay) {
-    for (Widget hero in heroes) {
-      OverlayEntry entry = new OverlayEntry(builder: (_) => hero);
-      overlay.insert(entry);
-      _overlayEntries.add(entry);
-    }
-  }
-
-  Set<Key> _getMostValuableKeys() {
-    Set<Key> result = new Set<Key>();
-    if (_from.settings.mostValuableKeys != null)
-      result.addAll(_from.settings.mostValuableKeys);
-    if (_to.settings.mostValuableKeys != null)
-      result.addAll(_to.settings.mostValuableKeys);
-    return result;
-  }
-
-  void _updateQuest(Duration timeStamp) {
-    Set<Key> mostValuableKeys = _getMostValuableKeys();
-
-    Map<Object, HeroHandle> heroesFrom = _party.isEmpty ?
-        Hero.of(_from.pageKey.currentContext, mostValuableKeys) : _party.getHeroesToAnimate();
-
-    BuildContext context = _to.pageKey.currentContext;
-    Map<Object, HeroHandle> heroesTo = Hero.of(context, mostValuableKeys);
-    _to.offstage = false;
-
-    PerformanceView performance = _performance;
-    Curve curve = Curves.ease;
-    if (performance.status == PerformanceStatus.reverse) {
-      performance = new ReversePerformance(performance);
-      curve = new Interval(performance.progress, 1.0, curve: curve);
-    }
-
-    NavigatorState navigator = Navigator.of(context);
-    _party.animate(heroesFrom, heroesTo, _getAnimationArea(navigator.context), curve);
-    _removeHeroesFromOverlay();
-    Iterable<Widget> heroes = _party.getWidgets(navigator.context, performance);
-    _addHeroesToOverlay(heroes, navigator.overlay);
-  }
-}
diff --git a/sky/packages/sky/lib/src/widgets/heroes.dart b/sky/packages/sky/lib/src/widgets/heroes.dart
deleted file mode 100644
index d0b826a..0000000
--- a/sky/packages/sky/lib/src/widgets/heroes.dart
+++ /dev/null
@@ -1,402 +0,0 @@
-// Copyright 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:flutter/animation.dart';
-import 'package:flutter/rendering.dart';
-
-import 'basic.dart';
-import 'framework.dart';
-import 'transitions.dart';
-
-// Heroes are the parts of an application's screen-to-screen transitions where a
-// component from one screen shifts to a position on the other. For example,
-// album art from a list of albums growing to become the centerpiece of the
-// album's details view. In this context, a screen is a navigator Route.
-
-// To get this effect, all you have to do is wrap each hero on each route with a
-// Hero widget, and give each hero a tag. Tag must either be unique within the
-// current route's widget subtree, or all the Heroes with that tag on a
-// particular route must have a key. When the app transitions from one route to
-// another, each tag present is animated. When there's exactly one hero with
-// that tag, that hero will be animated for that tag. When there are multiple
-// heroes in a route with the same tag, then whichever hero has a key that
-// matches one of the keys in the "most important key" list given to the
-// navigator when the route was pushed will be animated. If a hero is only
-// present on one of the routes and not the other, then it will be made to
-// appear or disappear as needed.
-
-// TODO(ianh): Make the appear/disappear animations pretty. Right now they're
-// pretty crude (just rotate and shrink the constraints). They should probably
-// involve actually scaling and fading, at a minimum.
-
-// Heroes and the Navigator's Stack must be axis-aligned for all this to work.
-// The top left and bottom right coordinates of each animated Hero will be
-// converted to global coordinates and then from there converted to the
-// Navigator Stack's coordinate space, and the entire Hero subtree will, for the
-// duration of the animation, be lifted out of its original place, and
-// positioned on that stack. If the Hero isn't axis aligned, this is going to
-// fail in a rather ugly fashion. Don't rotate your heroes!
-
-// To make the animations look good, it's critical that the widget tree for the
-// hero in both locations be essentially identical. The widget of the target is
-// used to do the transition: when going from route A to route B, route B's
-// hero's widget is placed over route A's hero's widget, and route A's hero is
-// hidden. Then the widget is animated to route B's hero's position, and then
-// the widget is inserted into route B. When going back from B to A, route A's
-// hero's widget is placed over where route B's hero's widget was, and then the
-// animation goes the other way.
-
-// TODO(ianh): If the widgets use Inherited properties, they are taken from the
-// Navigator's position in the widget hierarchy, not the source or target. We
-// should interpolate the inherited properties from their value at the source to
-// their value at the target. See: https://github.com/flutter/engine/issues/1698
-
-final Object centerOfAttentionHeroTag = new Object();
-
-class _HeroManifest {
-  const _HeroManifest({
-    this.key,
-    this.config,
-    this.sourceStates,
-    this.currentRect,
-    this.currentTurns
-  });
-  final GlobalKey key;
-  final Widget config;
-  final Set<HeroState> sourceStates;
-  final RelativeRect currentRect;
-  final double currentTurns;
-}
-
-abstract class HeroHandle {
-  bool get alwaysAnimate;
-  _HeroManifest _takeChild(Rect animationArea);
-}
-
-class Hero extends StatefulComponent {
-  Hero({
-    Key key,
-    this.tag,
-    this.child,
-    this.turns: 1,
-    this.alwaysAnimate: false
-  }) : super(key: key) {
-    assert(tag != null);
-  }
-
-  final Object tag;
-  final Widget child;
-  final int turns;
-
-  /// If true, the hero will always animate, even if it has no matching hero to
-  /// animate to or from. (This only applies if the hero is relevant; if there
-  /// are multiple heroes with the same tag, only the one whose key matches the
-  /// "most valuable keys" will be used.)
-  final bool alwaysAnimate;
-
-  static Map<Object, HeroHandle> of(BuildContext context, Set<Key> mostValuableKeys) {
-    mostValuableKeys ??= new Set<Key>();
-    assert(!mostValuableKeys.contains(null));
-    // first we collect ALL the heroes, sorted by their tags
-    Map<Object, Map<Key, HeroState>> heroes = <Object, Map<Key, HeroState>>{};
-    void visitor(Element element) {
-      if (element.widget is Hero) {
-        StatefulComponentElement<Hero, HeroState> hero = element;
-        Object tag = hero.widget.tag;
-        assert(tag != null);
-        Key key = hero.widget.key;
-        final Map<Key, HeroState> tagHeroes = heroes.putIfAbsent(tag, () => <Key, HeroState>{});
-        assert(!tagHeroes.containsKey(key));
-        tagHeroes[key] = hero.state;
-      }
-      element.visitChildren(visitor);
-    }
-    context.visitChildElements(visitor);
-    // next, for each tag, we're going to decide on the one hero we care about for that tag
-    Map<Object, HeroHandle> result = <Object, HeroHandle>{};
-    for (Object tag in heroes.keys) {
-      assert(tag != null);
-      if (heroes[tag].length == 1) {
-        result[tag] = heroes[tag].values.first;
-      } else {
-        assert(heroes[tag].length > 1);
-        assert(!heroes[tag].containsKey(null));
-        assert(heroes[tag].keys.where((Key key) => mostValuableKeys.contains(key)).length <= 1);
-        Key mostValuableKey = mostValuableKeys.firstWhere((Key key) => heroes[tag].containsKey(key), orElse: () => null);
-        if (mostValuableKey != null)
-          result[tag] = heroes[tag][mostValuableKey];
-      }
-    }
-    assert(!result.containsKey(null));
-    return result;
-  }
-
-  HeroState createState() => new HeroState();
-}
-
-enum _HeroMode { constructing, initialized, measured, taken }
-
-class HeroState extends State<Hero> implements HeroHandle {
-
-  void initState() {
-    assert(_mode == _HeroMode.constructing);
-    super.initState();
-    _key = new GlobalKey();
-    _mode = _HeroMode.initialized;
-  }
-
-  GlobalKey _key;
-
-  _HeroMode _mode = _HeroMode.constructing;
-  Size _size;
-
-  bool get alwaysAnimate => config.alwaysAnimate;
-
-  _HeroManifest _takeChild(Rect animationArea) {
-    assert(_mode == _HeroMode.measured || _mode == _HeroMode.taken);
-    final RenderBox renderObject = context.findRenderObject();
-    final Point heroTopLeft = renderObject.localToGlobal(Point.origin);
-    final Point heroBottomRight = renderObject.localToGlobal(renderObject.size.bottomRight(Point.origin));
-    final Rect heroArea = new Rect.fromLTRB(heroTopLeft.x, heroTopLeft.y, heroBottomRight.x, heroBottomRight.y);
-    final RelativeRect startRect = new RelativeRect.fromRect(heroArea, animationArea);
-    _HeroManifest result = new _HeroManifest(
-      key: _key,
-      config: config,
-      sourceStates: new Set<HeroState>.from(<HeroState>[this]),
-      currentRect: startRect,
-      currentTurns: config.turns.toDouble()
-    );
-    setState(() {
-      _key = null;
-      _mode = _HeroMode.taken;
-    });
-    return result;
-  }
-
-  void _setChild(GlobalKey value) {
-    assert(_mode == _HeroMode.taken);
-    assert(_key == null);
-    assert(_size != null);
-    if (mounted)
-      setState(() { _key = value; });
-    _size = null;
-    _mode = _HeroMode.initialized;
-  }
-
-  void _resetChild() {
-    assert(_mode == _HeroMode.taken);
-    assert(_key == null);
-    assert(_size != null);
-    if (mounted)
-      setState(() { _key = new GlobalKey(); });
-    _size = null;
-    _mode = _HeroMode.initialized;
-  }
-
-  Widget build(BuildContext context) {
-    switch (_mode) {
-      case _HeroMode.constructing:
-        assert(false);
-        return null;
-      case _HeroMode.initialized:
-      case _HeroMode.measured:
-        return new SizeObserver(
-          onSizeChanged: (Size size) {
-            assert(_mode == _HeroMode.initialized || _mode == _HeroMode.measured);
-            _size = size;
-            _mode = _HeroMode.measured;
-          },
-          child: new KeyedSubtree(
-            key: _key,
-            child: config.child
-          )
-        );
-      case _HeroMode.taken:
-        return new SizedBox(width: _size.width, height: _size.height);
-    }
-  }
-
-}
-
-
-class _HeroQuestState implements HeroHandle {
-  _HeroQuestState({
-    this.tag,
-    this.key,
-    this.child,
-    this.sourceStates,
-    this.targetRect,
-    this.targetTurns,
-    this.targetState,
-    this.currentRect,
-    this.currentTurns
-  }) {
-    assert(tag != null);
-  }
-
-  final Object tag;
-  final GlobalKey key;
-  final Widget child;
-  final Set<HeroState> sourceStates;
-  final RelativeRect targetRect;
-  final int targetTurns;
-  final HeroState targetState;
-  final AnimatedRelativeRectValue currentRect;
-  final AnimatedValue<double> currentTurns;
-
-  bool get alwaysAnimate => true;
-
-  bool get taken => _taken;
-  bool _taken = false;
-  _HeroManifest _takeChild(Rect animationArea) {
-    assert(!taken);
-    _taken = true;
-    Set<HeroState> states = sourceStates;
-    if (targetState != null)
-      states = states.union(new Set<HeroState>.from(<HeroState>[targetState]));
-    return new _HeroManifest(
-      key: key,
-      config: child,
-      sourceStates: states,
-      currentRect: currentRect.value,
-      currentTurns: currentTurns.value
-    );
-  }
-
-  Widget build(BuildContext context, PerformanceView performance) {
-    return new PositionedTransition(
-      rect: currentRect,
-      performance: performance,
-      child: new RotationTransition(
-        turns: currentTurns,
-        performance: performance,
-        child: new KeyedSubtree(
-          key: key,
-          child: child
-        )
-      )
-    );
-  }
-}
-
-class _HeroMatch {
-  const _HeroMatch(this.from, this.to, this.tag);
-  final HeroHandle from;
-  final HeroHandle to;
-  final Object tag;
-}
-
-class HeroParty {
-  HeroParty({ this.onQuestFinished });
-
-  final VoidCallback onQuestFinished;
-
-  List<_HeroQuestState> _heroes = <_HeroQuestState>[];
-  bool get isEmpty => _heroes.isEmpty;
-
-  Map<Object, HeroHandle> getHeroesToAnimate() {
-    Map<Object, HeroHandle> result = new Map<Object, HeroHandle>();
-    for (_HeroQuestState hero in _heroes)
-      result[hero.tag] = hero;
-    assert(!result.containsKey(null));
-    return result;
-  }
-
-  AnimatedRelativeRectValue createAnimatedRelativeRect(RelativeRect begin, RelativeRect end, Curve curve) {
-    return new AnimatedRelativeRectValue(begin, end: end, curve: curve);
-  }
-
-  AnimatedValue<double> createAnimatedTurns(double begin, double end, Curve curve) {
-    assert(end.floor() == end);
-    return new AnimatedValue<double>(begin, end: end, curve: curve);
-  }
-
-  void animate(Map<Object, HeroHandle> heroesFrom, Map<Object, HeroHandle> heroesTo, Rect animationArea, Curve curve) {
-    assert(!heroesFrom.containsKey(null));
-    assert(!heroesTo.containsKey(null));
-
-    // make a list of pairs of heroes, based on the from and to lists
-    Map<Object, _HeroMatch> heroes = <Object, _HeroMatch>{};
-    for (Object tag in heroesFrom.keys)
-      heroes[tag] = new _HeroMatch(heroesFrom[tag], heroesTo[tag], tag);
-    for (Object tag in heroesTo.keys) {
-      if (!heroes.containsKey(tag))
-        heroes[tag] = new _HeroMatch(heroesFrom[tag], heroesTo[tag], tag);
-    }
-
-    // create a heroating hero out of each pair
-    final List<_HeroQuestState> _newHeroes = <_HeroQuestState>[];
-    for (_HeroMatch heroPair in heroes.values) {
-      assert(heroPair.from != null || heroPair.to != null);
-      if ((heroPair.from == null && !heroPair.to.alwaysAnimate) ||
-          (heroPair.to == null && !heroPair.from.alwaysAnimate))
-        continue;
-      _HeroManifest from = heroPair.from?._takeChild(animationArea);
-      assert(heroPair.to == null || heroPair.to is HeroState);
-      _HeroManifest to = heroPair.to?._takeChild(animationArea);
-      assert(from != null || to != null);
-      assert(to == null || to.sourceStates.length == 1);
-      assert(to == null || to.currentTurns.floor() == to.currentTurns);
-      HeroState targetState = to != null ? to.sourceStates.elementAt(0) : null;
-      Set<HeroState> sourceStates = from != null ? from.sourceStates : new Set<HeroState>();
-      sourceStates.remove(targetState);
-      RelativeRect sourceRect = from != null ? from.currentRect :
-        new RelativeRect.fromRect(to.currentRect.toRect(animationArea).center & Size.zero, animationArea);
-      RelativeRect targetRect = to != null ? to.currentRect :
-        new RelativeRect.fromRect(from.currentRect.toRect(animationArea).center & Size.zero, animationArea);
-      double sourceTurns = from != null ? from.currentTurns : 0.0;
-      double targetTurns = to != null ? to.currentTurns : 0.0;
-      _newHeroes.add(new _HeroQuestState(
-        tag: heroPair.tag,
-        key: from != null ? from.key : to.key,
-        child: to != null ? to.config : from.config,
-        sourceStates: sourceStates,
-        targetRect: targetRect,
-        targetTurns: targetTurns.floor(),
-        targetState: targetState,
-        currentRect: createAnimatedRelativeRect(sourceRect, targetRect, curve),
-        currentTurns: createAnimatedTurns(sourceTurns, targetTurns, curve)
-      ));
-    }
-
-    assert(!_heroes.any((_HeroQuestState hero) => !hero.taken));
-    _heroes = _newHeroes;
-  }
-
-  PerformanceView _currentPerformance;
-
-  void _clearCurrentPerformance() {
-    _currentPerformance?.removeStatusListener(_handleUpdate);
-    _currentPerformance = null;
-  }
-
-  Iterable<Widget> getWidgets(BuildContext context, PerformanceView performance) sync* {
-    assert(performance != null || _heroes.length == 0);
-    if (performance != _currentPerformance) {
-      _clearCurrentPerformance();
-      _currentPerformance = performance;
-      _currentPerformance?.addStatusListener(_handleUpdate);
-    }
-    for (_HeroQuestState hero in _heroes)
-      yield hero.build(context, performance);
-  }
-
-  void _handleUpdate(PerformanceStatus status) {
-    if (status == PerformanceStatus.completed ||
-        status == PerformanceStatus.dismissed) {
-      for (_HeroQuestState hero in _heroes) {
-        if (hero.targetState != null)
-          hero.targetState._setChild(hero.key);
-        for (HeroState source in hero.sourceStates)
-          source._resetChild();
-      }
-      _heroes.clear();
-      _clearCurrentPerformance();
-      if (onQuestFinished != null)
-        onQuestFinished();
-    }
-  }
-
-  String toString() => '$_heroes';
-}
diff --git a/sky/packages/sky/lib/src/widgets/homogeneous_viewport.dart b/sky/packages/sky/lib/src/widgets/homogeneous_viewport.dart
deleted file mode 100644
index db8e0f3..0000000
--- a/sky/packages/sky/lib/src/widgets/homogeneous_viewport.dart
+++ /dev/null
@@ -1,188 +0,0 @@
-// Copyright 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 'dart:math' as math;
-
-import 'package:flutter/rendering.dart';
-
-import 'framework.dart';
-import 'basic.dart';
-
-typedef List<Widget> ListBuilder(BuildContext context, int startIndex, int count);
-
-class HomogeneousViewport extends RenderObjectWidget {
-  HomogeneousViewport({
-    Key key,
-    this.builder,
-    this.itemsWrap: false,
-    this.itemExtent, // required
-    this.itemCount, // optional, but you cannot shrink-wrap this class or otherwise use its intrinsic dimensions if you don't specify it
-    this.direction: ScrollDirection.vertical,
-    this.startOffset: 0.0,
-    this.overlayPainter
-  }) : super(key: key) {
-    assert(itemExtent != null);
-  }
-
-  final ListBuilder builder;
-  final bool itemsWrap;
-  final double itemExtent;
-  final int itemCount;
-  final ScrollDirection direction;
-  final double startOffset;
-  final Painter overlayPainter;
-
-  _HomogeneousViewportElement createElement() => new _HomogeneousViewportElement(this);
-
-  // we don't pass constructor arguments to the RenderBlockViewport() because until
-  // we know our children, the constructor arguments we could give have no effect
-  RenderBlockViewport createRenderObject() => new RenderBlockViewport();
-
-  bool isLayoutDifferentThan(HomogeneousViewport oldWidget) {
-    // changing the builder doesn't imply the layout changed
-    return itemsWrap != oldWidget.itemsWrap ||
-           itemExtent != oldWidget.itemExtent ||
-           itemCount != oldWidget.itemCount ||
-           direction != oldWidget.direction ||
-           startOffset != oldWidget.startOffset;
-  }
-
-  // all the actual work is done in the element
-}
-
-class _HomogeneousViewportElement extends RenderObjectElement<HomogeneousViewport> {
-  _HomogeneousViewportElement(HomogeneousViewport widget) : super(widget);
-
-  List<Element> _children = const <Element>[];
-  int _layoutFirstIndex;
-  int _layoutItemCount;
-
-  RenderBlockViewport get renderObject => super.renderObject;
-
-  void visitChildren(ElementVisitor visitor) {
-    if (_children == null)
-      return;
-    for (Element child in _children)
-      visitor(child);
-  }
-
-  void mount(Element parent, dynamic newSlot) {
-    super.mount(parent, newSlot);
-    renderObject.callback = layout;
-    renderObject.totalExtentCallback = getTotalExtent;
-    renderObject.minCrossAxisExtentCallback = getMinCrossAxisExtent;
-    renderObject.maxCrossAxisExtentCallback = getMaxCrossAxisExtent;
-    renderObject.overlayPainter = widget.overlayPainter;
-  }
-
-  void unmount() {
-    renderObject.callback = null;
-    renderObject.totalExtentCallback = null;
-    renderObject.minCrossAxisExtentCallback = null;
-    renderObject.maxCrossAxisExtentCallback = null;
-    renderObject.overlayPainter = null;
-    super.unmount();
-  }
-
-  void update(HomogeneousViewport newWidget) {
-    bool needLayout = newWidget.isLayoutDifferentThan(widget);
-    super.update(newWidget);
-    if (needLayout)
-      renderObject.markNeedsLayout();
-    else
-      _updateChildren();
-  }
-
-  void reinvokeBuilders() {
-    _updateChildren();
-  }
-
-  void layout(BoxConstraints constraints) {
-    // We enter a build scope (meaning that markNeedsBuild() is forbidden)
-    // because we are in the middle of layout and if we allowed people to set
-    // state, they'd expect to have that state reflected immediately, which, if
-    // we were to try to honour it, would potentially result in assertions
-    // because you can't normally mutate the render object tree during layout.
-    // (If there were a way to limit these writes to descendants of this, it'd
-    // be ok because we are exempt from that assert since we are still actively
-    // doing our own layout.)
-    BuildableElement.lockState(() {
-      double mainAxisExtent = widget.direction == ScrollDirection.vertical ? constraints.maxHeight : constraints.maxWidth;
-      double offset;
-      if (widget.startOffset <= 0.0 && !widget.itemsWrap) {
-        _layoutFirstIndex = 0;
-        offset = -widget.startOffset;
-      } else {
-        _layoutFirstIndex = (widget.startOffset / widget.itemExtent).floor();
-        offset = -(widget.startOffset % widget.itemExtent);
-      }
-      if (mainAxisExtent < double.INFINITY) {
-        _layoutItemCount = ((mainAxisExtent - offset) / widget.itemExtent).ceil();
-        if (widget.itemCount != null && !widget.itemsWrap)
-          _layoutItemCount = math.min(_layoutItemCount, widget.itemCount - _layoutFirstIndex);
-      } else {
-        assert(() {
-          'This HomogeneousViewport has no specified number of items (meaning it has infinite items), ' +
-          'and has been placed in an unconstrained environment where all items can be rendered. ' +
-          'It is most likely that you have placed your HomogeneousViewport (which is an internal ' +
-          'component of several scrollable widgets) inside either another scrolling box, a flexible ' +
-          'box (Row, Column), or a Stack, without giving it a specific size.';
-          return widget.itemCount != null;
-        });
-        _layoutItemCount = widget.itemCount - _layoutFirstIndex;
-      }
-      _layoutItemCount = math.max(0, _layoutItemCount);
-      _updateChildren();
-      // Update the renderObject configuration
-      renderObject.direction = widget.direction == ScrollDirection.vertical ? BlockDirection.vertical : BlockDirection.horizontal;
-      renderObject.itemExtent = widget.itemExtent;
-      renderObject.minExtent = getTotalExtent(null);
-      renderObject.startOffset = offset;
-      renderObject.overlayPainter = widget.overlayPainter;
-    }, building: true);
-  }
-
-  void _updateChildren() {
-    assert(_layoutFirstIndex != null);
-    assert(_layoutItemCount != null);
-    List<Widget> newWidgets;
-    if (_layoutItemCount > 0)
-      newWidgets = widget.builder(this, _layoutFirstIndex, _layoutItemCount);
-    else
-      newWidgets = <Widget>[];
-    _children = updateChildren(_children, newWidgets);
-  }
-
-  double getTotalExtent(BoxConstraints constraints) {
-    // constraints is null when called by layout() above
-    return widget.itemCount != null ? widget.itemCount * widget.itemExtent : double.INFINITY;
-  }
-
-  double getMinCrossAxisExtent(BoxConstraints constraints) {
-    return 0.0;
-  }
-
-  double getMaxCrossAxisExtent(BoxConstraints constraints) {
-    if (widget.direction == ScrollDirection.vertical)
-      return constraints.maxWidth;
-    return constraints.maxHeight;
-  }
-
-  void insertChildRenderObject(RenderObject child, Element slot) {
-    RenderObject nextSibling = slot?.renderObject;
-    renderObject.add(child, before: nextSibling);
-  }
-
-  void moveChildRenderObject(RenderObject child, Element slot) {
-    assert(child.parent == renderObject);
-    RenderObject nextSibling = slot?.renderObject;
-    renderObject.move(child, before: nextSibling);
-  }
-
-  void removeChildRenderObject(RenderObject child) {
-    assert(child.parent == renderObject);
-    renderObject.remove(child);
-  }
-
-}
diff --git a/sky/packages/sky/lib/src/widgets/media_query.dart b/sky/packages/sky/lib/src/widgets/media_query.dart
deleted file mode 100644
index 5640c47..0000000
--- a/sky/packages/sky/lib/src/widgets/media_query.dart
+++ /dev/null
@@ -1,55 +0,0 @@
-// Copyright 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 'basic.dart';
-import 'framework.dart';
-
-enum Orientation { portrait, landscape }
-
-class MediaQueryData {
-
-  const MediaQueryData({ this.size });
-
-  final Size size;
-
-  Orientation get orientation {
-    return size.width > size.height ? Orientation.landscape : Orientation.portrait;
-  }
-
-  bool operator==(Object other) {
-    if (other.runtimeType != runtimeType)
-      return false;
-    MediaQueryData typedOther = other;
-    return typedOther.size == size;
-  }
-
-  int get hashCode => size.hashCode;
-
-  String toString() => '$runtimeType($size, $orientation)';
-}
-
-class MediaQuery extends InheritedWidget {
-  MediaQuery({
-    Key key,
-    this.data,
-    Widget child
-  }) : super(key: key, child: child) {
-    assert(child != null);
-    assert(data != null);
-  }
-
-  final MediaQueryData data;
-
-  static MediaQueryData of(BuildContext context) {
-    MediaQuery query = context.inheritedWidgetOfType(MediaQuery);
-    return query == null ? null : query.data;
-  }
-
-  bool updateShouldNotify(MediaQuery old) => data != old.data;
-
-  void debugFillDescription(List<String> description) {
-    super.debugFillDescription(description);
-    description.add('$data');
-  }
-}
diff --git a/sky/packages/sky/lib/src/widgets/mimic.dart b/sky/packages/sky/lib/src/widgets/mimic.dart
deleted file mode 100644
index d3419e9..0000000
--- a/sky/packages/sky/lib/src/widgets/mimic.dart
+++ /dev/null
@@ -1,88 +0,0 @@
-// Copyright 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:flutter/rendering.dart';
-
-import 'basic.dart';
-import 'framework.dart';
-
-class MimicableKey {
-  MimicableKey._(this._state);
-
-  final MimicableState _state;
-
-  Rect get globalBounds => _state._globalBounds;
-
-  void stopMimic() {
-    _state._stopMimic();
-  }
-}
-
-class Mimic extends StatelessComponent {
-  Mimic({ Key key, this.original }) : super(key: key);
-
-  final MimicableKey original;
-
-  Widget build(BuildContext context) {
-    if (original != null && original._state._beingMimicked)
-      return original._state.config.child;
-    return new Container();
-  }
-}
-
-class Mimicable extends StatefulComponent {
-  Mimicable({ Key key, this.child }) : super(key: key);
-
-  final Widget child;
-
-  MimicableState createState() => new MimicableState();
-}
-
-class MimicableState extends State<Mimicable> {
-  Size _size;
-  bool _beingMimicked = false;
-
-  MimicableKey startMimic() {
-    assert(!_beingMimicked);
-    assert(_size != null);
-    setState(() {
-      _beingMimicked = true;
-    });
-    return new MimicableKey._(this);
-  }
-
-  void _stopMimic() {
-    assert(_beingMimicked);
-    if (!mounted) {
-      _beingMimicked = false;
-      return;
-    }
-    setState(() {
-      _beingMimicked = false;
-    });
-  }
-
-  Rect get _globalBounds {
-    RenderBox box = context.findRenderObject();
-    return box.localToGlobal(Point.origin) & box.size;
-  }
-
-  void _handleSizeChanged(Size size) {
-    setState(() {
-      _size = size;
-    });
-  }
-
-  Widget build(BuildContext context) {
-    if (_beingMimicked) {
-      return new ConstrainedBox(
-        constraints: new BoxConstraints.tight(_size)
-      );
-    }
-    return new SizeObserver(
-      onSizeChanged: _handleSizeChanged,
-      child: config.child
-    );
-  }
-}
diff --git a/sky/packages/sky/lib/src/widgets/mixed_viewport.dart b/sky/packages/sky/lib/src/widgets/mixed_viewport.dart
deleted file mode 100644
index 1758250..0000000
--- a/sky/packages/sky/lib/src/widgets/mixed_viewport.dart
+++ /dev/null
@@ -1,615 +0,0 @@
-// Copyright 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:flutter/rendering.dart';
-
-import 'framework.dart';
-import 'basic.dart';
-
-typedef Widget IndexedBuilder(BuildContext context, int index); // return null if index is greater than index of last entry
-typedef void ExtentsUpdateCallback(double newExtents);
-typedef void InvalidatorCallback(Iterable<int> indices);
-typedef void InvalidatorAvailableCallback(InvalidatorCallback invalidator);
-
-enum _ChangeDescription { none, scrolled, resized }
-
-class MixedViewport extends RenderObjectWidget {
-  MixedViewport({
-    Key key,
-    this.startOffset: 0.0,
-    this.direction: ScrollDirection.vertical,
-    this.builder,
-    this.token,
-    this.onExtentsUpdate,
-    this.onInvalidatorAvailable
-  }) : super(key: key);
-
-  final double startOffset;
-  final ScrollDirection direction;
-  final IndexedBuilder builder;
-  final Object token; // change this if the list changed (i.e. there are added, removed, or resorted items)
-  final ExtentsUpdateCallback onExtentsUpdate;
-  final InvalidatorAvailableCallback onInvalidatorAvailable; // call the callback this gives to invalidate sizes
-
-  _MixedViewportElement createElement() => new _MixedViewportElement(this);
-
-  // we don't pass constructor arguments to the RenderBlockViewport() because until
-  // we know our children, the constructor arguments we could give have no effect
-  RenderBlockViewport createRenderObject() => new RenderBlockViewport();
-
-  _ChangeDescription evaluateChangesFrom(MixedViewport oldWidget) {
-    if (direction != oldWidget.direction ||
-        builder != oldWidget.builder ||
-        token != oldWidget.token)
-      return _ChangeDescription.resized;
-    if (startOffset != oldWidget.startOffset)
-      return _ChangeDescription.scrolled;
-    return _ChangeDescription.none;
-  }
-
-  // all the actual work is done in the element
-}
-
-class _ChildKey {
-  const _ChildKey(this.type, this.key);
-  factory _ChildKey.fromWidget(Widget widget) => new _ChildKey(widget.runtimeType, widget.key);
-  final Type type;
-  final Key key;
-  bool operator ==(dynamic other) {
-    if (other is! _ChildKey)
-      return false;
-    final _ChildKey typedOther = other;
-    return type == typedOther.type &&
-           key == typedOther.key;
-  }
-  int get hashCode => ((373 * 37) + type.hashCode) * 37 + key.hashCode;
-  String toString() => "_ChildKey(type: $type, key: $key)";
-}
-
-class _MixedViewportElement extends RenderObjectElement<MixedViewport> {
-  _MixedViewportElement(MixedViewport widget) : super(widget) {
-    if (widget.onInvalidatorAvailable != null)
-      widget.onInvalidatorAvailable(invalidate);
-  }
-
-  /// _childExtents contains the extents of each child from the top of the list
-  /// up to the last one we've ever created.
-  final List<double> _childExtents = <double>[];
-
-  /// _childOffsets contains the offsets of the top of each child from the top
-  /// of the list up to the last one we've ever created, and the offset of the
-  /// end of the last one. The first value is always 0.0. If there are no
-  /// children, that is the only value. The offset of the end of the last child
-  /// created (the actual last child, if didReachLastChild is true), is also the
-  /// distance from the top (left) of the first child to the bottom (right) of
-  /// the last child created.
-  final List<double> _childOffsets = <double>[0.0];
-
-  /// Whether childOffsets includes the offset of the last child.
-  bool _didReachLastChild = false;
-
-  /// The index of the first child whose bottom edge is below the top of the
-  /// viewport.
-  int _firstVisibleChildIndex;
-
-  /// The currently visibly children.
-  Map<_ChildKey, Element> _childrenByKey = new Map<_ChildKey, Element>();
-
-  /// The child offsets that we've been told are invalid.
-  final Set<int> _invalidIndices = new Set<int>();
-
-  /// Returns false if any of the previously-cached offsets have been marked as
-  /// invalid and need to be updated.
-  bool get isValid => _invalidIndices.length == 0;
-
-  /// The constraints for which the current offsets are valid.
-  BoxConstraints _lastLayoutConstraints;
-
-  /// The last value that was sent to onExtentsUpdate.
-  double _lastReportedExtents;
-
-  RenderBlockViewport get renderObject => super.renderObject;
-
-  /// Notify the BlockViewport that the children at indices have, or might have,
-  /// changed size. Call this whenever the dimensions of a particular child
-  /// change, so that the rendering will be updated accordingly. A pointer to
-  /// this method is provided via the onInvalidatorAvailable callback.
-  void invalidate(Iterable<int> indices) {
-    assert(indices.length > 0);
-    _invalidIndices.addAll(indices);
-    renderObject.markNeedsLayout();
-  }
-
-  /// Forget all the known child offsets.
-  void _resetCache() {
-    _childExtents.clear();
-    _childOffsets.clear();
-    _childOffsets.add(0.0);
-    _didReachLastChild = false;
-    _invalidIndices.clear();
-  }
-
-  void visitChildren(ElementVisitor visitor) {
-    for (Element child in _childrenByKey.values)
-      visitor(child);
-  }
-
-  void mount(Element parent, dynamic newSlot) {
-    super.mount(parent, newSlot);
-    renderObject.callback = layout;
-    renderObject.totalExtentCallback = _noIntrinsicExtent;
-    renderObject.maxCrossAxisExtentCallback = _noIntrinsicExtent;
-    renderObject.minCrossAxisExtentCallback = _noIntrinsicExtent;
-  }
-
-  void unmount() {
-    renderObject.callback = null;
-    renderObject.totalExtentCallback = null;
-    renderObject.minCrossAxisExtentCallback = null;
-    renderObject.maxCrossAxisExtentCallback = null;
-    super.unmount();
-  }
-
-  double _noIntrinsicExtent(BoxConstraints constraints) {
-    assert(() {
-      'MixedViewport does not support returning intrinsic dimensions. ' +
-      'Calculating the intrinsic dimensions would require walking the entire child list, ' +
-      'which defeats the entire point of having a lazily-built list of children.';
-      return false;
-    });
-    return null;
-  }
-
-  static const Object _omit = const Object(); // used as a slot when it's not yet time to attach the child
-
-  void update(MixedViewport newWidget) {
-    _ChangeDescription changes = newWidget.evaluateChangesFrom(widget);
-    super.update(newWidget);
-    if (changes == _ChangeDescription.resized)
-      _resetCache();
-    if (changes != _ChangeDescription.none || !isValid) {
-      renderObject.markNeedsLayout();
-    } else {
-      // We have to reinvoke our builders because they might return new data.
-      // Consider a stateful component that owns us. The builder it gives us
-      // includes some of the state from that component. The component calls
-      // setState() on itself. It rebuilds. Part of that involves rebuilding
-      // us, but now what? If we don't reinvoke the builders. then they will
-      // not be rebuilt, and so the new state won't be used.
-      // Note that if the builders are to change so much that the _sizes_ of
-      // the children would change, then the parent must change the 'token'.
-      if (!renderObject.needsLayout)
-        reinvokeBuilders();
-    }
-  }
-
-  void reinvokeBuilders() {
-    // we just need to redraw our existing widgets as-is
-    if (_childrenByKey.length > 0) {
-      assert(_firstVisibleChildIndex >= 0);
-      assert(renderObject != null);
-      final int startIndex = _firstVisibleChildIndex;
-      int lastIndex = startIndex + _childrenByKey.length - 1;
-      Element nextSibling = null;
-      for (int index = lastIndex; index >= startIndex; index -= 1) {
-        final Widget newWidget = _buildWidgetAt(index);
-        final _ChildKey key = new _ChildKey.fromWidget(newWidget);
-        final Element oldElement = _childrenByKey[key];
-        assert(oldElement != null);
-        final Element newElement = updateChild(oldElement, newWidget, nextSibling);
-        assert(newElement != null);
-        _childrenByKey[key] = newElement;
-        // Verify that it hasn't changed size.
-        // If this assertion fires, it means you didn't call "invalidate"
-        // before changing the size of one of your items.
-        assert(_debugIsSameSize(newElement, index, _lastLayoutConstraints));
-        nextSibling = newElement;
-      }
-    }
-  }
-
-  void layout(BoxConstraints constraints) {
-    if (constraints != _lastLayoutConstraints) {
-      _resetCache();
-      _lastLayoutConstraints = constraints;
-    }
-    BuildableElement.lockState(() {
-      _doLayout(constraints);
-    }, building: true);
-    if (widget.onExtentsUpdate != null) {
-      final double newExtents = _didReachLastChild ? _childOffsets.last : null;
-      if (newExtents != _lastReportedExtents) {
-        _lastReportedExtents = newExtents;
-        widget.onExtentsUpdate(_lastReportedExtents);
-      }
-    }
-  }
-
-  /// Binary search to find the index of the child responsible for rendering a given pixel
-  int _findIndexForOffsetBeforeOrAt(double offset) {
-    int left = 0;
-    int right = _childOffsets.length - 1;
-    while (right >= left) {
-      int middle = left + ((right - left) ~/ 2);
-      if (_childOffsets[middle] < offset) {
-        left = middle + 1;
-      } else if (_childOffsets[middle] > offset) {
-        right = middle - 1;
-      } else {
-        return middle;
-      }
-    }
-    return right;
-  }
-
-  /// Calls the builder. This is for the case where you don't know if you have a child at this index.
-  Widget _maybeBuildWidgetAt(int index) {
-    if (widget.builder == null)
-      return null;
-    final Widget newWidget = widget.builder(this, index);
-    assert(() {
-      'Every widget in a list must have a list-unique key.';
-      return newWidget == null || newWidget.key != null;
-    });
-    return newWidget;
-  }
-
-  /// Calls the builder. This is for the case where you know that you should have a child there.
-  Widget _buildWidgetAt(int index) {
-    final Widget newWidget = widget.builder(this, index);
-    assert(newWidget != null);
-    assert(newWidget.key != null); // every widget in a list must have a list-unique key
-    return newWidget;
-  }
-
-  /// Given an element configuration, inflates the element, updating the existing one if there was one.
-  /// Returns the resulting element.
-  Element _inflateOrUpdateWidget(Widget newWidget) {
-    final _ChildKey key = new _ChildKey.fromWidget(newWidget);
-    final Element oldElement = _childrenByKey[key];
-    final Element newElement = updateChild(oldElement, newWidget, _omit);
-    assert(newElement != null);
-    return newElement;
-  }
-
-  // Build the widget at index.
-  Element _getElement(int index, BoxConstraints innerConstraints) {
-    assert(index <= _childOffsets.length - 1);
-    final Widget newWidget = _buildWidgetAt(index);
-    final Element newElement = _inflateOrUpdateWidget(newWidget);
-    return newElement;
-  }
-
-  // Build the widget at index.
-  Element _maybeGetElement(int index, BoxConstraints innerConstraints) {
-    assert(index <= _childOffsets.length - 1);
-    final Widget newWidget = _maybeBuildWidgetAt(index);
-    if (newWidget == null)
-      return null;
-    final Element newElement = _inflateOrUpdateWidget(newWidget);
-    return newElement;
-  }
-
-  // Build the widget at index, handling the case where there is no such widget.
-  // Update the offset for that widget.
-  Element _getElementAtLastKnownOffset(int index, BoxConstraints innerConstraints) {
-
-    // Inflate the new widget; if there isn't one, abort early.
-    assert(index == _childOffsets.length - 1);
-    final Widget newWidget = _maybeBuildWidgetAt(index);
-    if (newWidget == null)
-      return null;
-    final Element newElement = _inflateOrUpdateWidget(newWidget);
-
-    // Update the offsets based on the newElement's dimensions.
-    final double newExtent = _getElementExtent(newElement, innerConstraints);
-    _childExtents.add(newExtent);
-    _childOffsets.add(_childOffsets[index] + newExtent);
-    assert(_childExtents.length == _childOffsets.length - 1);
-
-    return newElement;
-  }
-
-  /// Returns the intrinsic size of the given element in the scroll direction
-  double _getElementExtent(Element element, BoxConstraints innerConstraints) {
-    final RenderBox childRenderObject = element.renderObject;
-    switch (widget.direction) {
-      case ScrollDirection.vertical:
-        return childRenderObject.getMaxIntrinsicHeight(innerConstraints);
-      case ScrollDirection.horizontal:
-        return childRenderObject.getMaxIntrinsicWidth(innerConstraints);
-      case ScrollDirection.both:
-        assert(false); // we don't support ScrollDirection.both, see issue 888
-        return double.NAN;
-    }
-  }
-
-  BoxConstraints _getInnerConstraints(BoxConstraints constraints) {
-    switch (widget.direction) {
-      case ScrollDirection.vertical:
-        return new BoxConstraints.tightFor(width: constraints.constrainWidth());
-      case ScrollDirection.horizontal:
-        return new BoxConstraints.tightFor(height: constraints.constrainHeight());
-      case ScrollDirection.both:
-        assert(false); // we don't support ScrollDirection.both, see issue 888
-        return null;
-    }
-  }
-
-  /// This compares the offsets we had for an element with its current
-  /// intrinsic dimensions.
-  bool _debugIsSameSize(Element element, int index, BoxConstraints constraints) {
-    assert(_invalidIndices.isEmpty);
-    BoxConstraints innerConstraints = _getInnerConstraints(constraints);
-    double newExtent = _getElementExtent(element, innerConstraints);
-    bool result = _childExtents[index] == newExtent;
-    if (!result)
-      debugPrint("Element $element at index $index was size ${_childExtents[index]} but is now size $newExtent yet no invalidate() was received to that effect");
-    return result;
-  }
-
-  /// This is the core lazy-build algorithm. It builds widgets incrementally
-  /// from index 0 until it has built enough widgets to cover itself, and
-  /// discards any widgets that are not displayed.
-  void _doLayout(BoxConstraints constraints) {
-    Map<_ChildKey, Element> newChildren = new Map<_ChildKey, Element>();
-    Map<int, Element> builtChildren = new Map<int, Element>();
-
-    // Establish the start and end offsets based on our current constraints.
-    double extent;
-    switch (widget.direction) {
-      case ScrollDirection.vertical:
-        extent = constraints.maxHeight;
-        assert(extent < double.INFINITY &&
-          'There is no point putting a lazily-built vertical MixedViewport inside a box with infinite internal ' +
-          'height (e.g. inside something else that scrolls vertically), because it would then just eagerly build ' +
-          'all the children. You probably want to put the MixedViewport inside a Container with a fixed height.' is String);
-        break;
-      case ScrollDirection.horizontal:
-        extent = constraints.maxWidth;
-        assert(extent < double.INFINITY &&
-          'There is no point putting a lazily-built horizontal MixedViewport inside a box with infinite internal ' +
-          'width (e.g. inside something else that scrolls horizontally), because it would then just eagerly build ' +
-          'all the children. You probably want to put the MixedViewport inside a Container with a fixed width.' is String);
-        break;
-      case ScrollDirection.both: assert(false); // we don't support ScrollDirection.both, see issue 888
-    }
-    final double endOffset = widget.startOffset + extent;
-
-    // Create the constraints that we will use to measure the children.
-    final BoxConstraints innerConstraints = _getInnerConstraints(constraints);
-
-    // Before doing the actual layout, fix the offsets for the widgets whose
-    // size has apparently changed.
-    if (!isValid) {
-      assert(_childOffsets.length > 0);
-      assert(_childOffsets.length == _childExtents.length + 1);
-      List<int> invalidIndices = _invalidIndices.toList();
-      invalidIndices.sort();
-      for (int i = 0; i < invalidIndices.length; i += 1) {
-
-        // Determine the indices for this pass.
-        final int widgetIndex = invalidIndices[i];
-        if (widgetIndex >= _childExtents.length)
-          break; // we don't have that child, so there's nothing to invalidate
-        int endIndex; // the last index into _childOffsets that we want to update this round
-        if (i == invalidIndices.length - 1) {
-          // This is the last invalid index. Update all the remaining entries in _childOffsets.
-          endIndex = _childOffsets.length - 1;
-        } else {
-          endIndex = invalidIndices[i + 1];
-          if (endIndex > _childOffsets.length - 1)
-            endIndex = _childOffsets.length - 1; // no point updating beyond the last offset we know of
-        }
-        assert(widgetIndex >= 0);
-        assert(endIndex < _childOffsets.length);
-        assert(widgetIndex < endIndex);
-
-        // Inflate the widget or update the existing element, as necessary.
-        final Element newElement = _getElement(widgetIndex, innerConstraints);
-
-        // Update the offsets based on the newElement's dimensions.
-        _childExtents[widgetIndex] = _getElementExtent(newElement, innerConstraints);
-        for (int j = widgetIndex + 1; j <= endIndex; j++)
-          _childOffsets[j] = _childOffsets[j - 1] + _childExtents[j - 1];
-        assert(_childOffsets.length == _childExtents.length + 1);
-
-        // Decide if it's visible.
-        final _ChildKey key = new _ChildKey.fromWidget(newElement.widget);
-        final bool isVisible = _childOffsets[widgetIndex] < endOffset && _childOffsets[widgetIndex + 1] >= widget.startOffset;
-        if (isVisible) {
-          // Keep it.
-          newChildren[key] = newElement;
-          builtChildren[widgetIndex] = newElement;
-        } else {
-          // Drop it.
-          _childrenByKey.remove(key);
-          updateChild(newElement, null, null);
-        }
-
-      }
-      _invalidIndices.clear();
-    }
-
-    // Decide what the first child to render should be (startIndex), if any (haveChildren).
-    int startIndex;
-    bool haveChildren;
-    if (endOffset < 0.0) {
-      // We're so far scrolled up that nothing is visible.
-      haveChildren = false;
-    } else if (widget.startOffset <= 0.0) {
-      startIndex = 0;
-      // If we're scrolled up past the top, then our first visible widget, if
-      // any, is the first widget.
-      if (_childExtents.length > 0) {
-        haveChildren = true;
-      } else {
-        final Element element = _getElementAtLastKnownOffset(startIndex, innerConstraints);
-        if (element != null) {
-          newChildren[new _ChildKey.fromWidget(element.widget)] = element;
-          builtChildren[startIndex] = element;
-          haveChildren = true;
-        } else {
-          haveChildren = false;
-          _didReachLastChild = true;
-        }
-      }
-    } else {
-      // We're at some sane (not higher than the top) scroll offset.
-      // See if we can already find the offset in our cache.
-      startIndex = _findIndexForOffsetBeforeOrAt(widget.startOffset);
-      if (startIndex < _childExtents.length) {
-        // We already know of a child that would be visible at this offset.
-        haveChildren = true;
-      } else {
-        // We don't have an offset on the list that is beyond the start offset.
-        assert(_childOffsets.last <= widget.startOffset);
-        // Fill the list until this isn't true or until we know that the
-        // list is complete (and thus we are overscrolled).
-        while (true) {
-          // Get the next element and cache its offset.
-          final Element element = _getElementAtLastKnownOffset(startIndex, innerConstraints);
-          if (element == null) {
-            // Reached the end of the list. We are so far overscrolled, there's nothing to show.
-            _didReachLastChild = true;
-            haveChildren = false;
-            break;
-          }
-          final _ChildKey key = new _ChildKey.fromWidget(element.widget);
-          if (_childOffsets.last > widget.startOffset) {
-            // This element is visible! It must thus be our first visible child.
-            newChildren[key] = element;
-            builtChildren[startIndex] = element;
-            haveChildren = true;
-            break;
-          }
-          // This element is not visible. Drop the inflated element.
-          // (We've already cached its offset for later use.)
-          _childrenByKey.remove(key);
-          updateChild(element, null, null);
-          startIndex += 1;
-          assert(startIndex == _childExtents.length);
-        }
-        assert(haveChildren == _childOffsets.last > widget.startOffset);
-        assert(() {
-          if (haveChildren) {
-            // We found a child to render. It's the last one for which we have an
-            // offset in _childOffsets.
-            // If we're here, we have at least one child, so our list has
-            // at least two offsets, the top of the child and the bottom
-            // of the child.
-            assert(_childExtents.length >= 1);
-            assert(_childOffsets.length == _childExtents.length + 1);
-            assert(startIndex == _childExtents.length - 1);
-          }
-          return true;
-        });
-      }
-    }
-    assert(haveChildren != null);
-    assert(haveChildren || _didReachLastChild || endOffset < 0.0);
-    assert(startIndex >= 0);
-    assert(!haveChildren || startIndex < _childExtents.length);
-
-    // Build the other widgets that are visible.
-    int index = startIndex;
-    if (haveChildren) {
-      // Update the renderObject configuration
-      switch (widget.direction) {
-        case ScrollDirection.vertical:
-          renderObject.direction = BlockDirection.vertical;
-          break;
-        case ScrollDirection.horizontal:
-          renderObject.direction = BlockDirection.horizontal;
-          break;
-        case ScrollDirection.both: assert(false); // we don't support ScrollDirection.both, see issue 888
-      }
-      renderObject.startOffset = _childOffsets[index] - widget.startOffset;
-      // Build all the widgets we still need.
-      while (_childOffsets[index] < endOffset) {
-        if (!builtChildren.containsKey(index)) {
-          Element element = _maybeGetElement(index, innerConstraints);
-          if (element == null) {
-            _didReachLastChild = true;
-            break;
-          }
-          if (index == _childExtents.length) {
-            // Remember this element's offset.
-            final double newExtent = _getElementExtent(element, innerConstraints);
-            _childExtents.add(newExtent);
-            _childOffsets.add(_childOffsets[index] + newExtent);
-            assert(_childOffsets.length == _childExtents.length + 1);
-          } else {
-            // Verify that it hasn't changed size.
-            // If this assertion fires, it means you didn't call "invalidate"
-            // before changing the size of one of your items.
-            assert(_debugIsSameSize(element, index, constraints));
-          }
-          // Remember the element for when we place the children.
-          final _ChildKey key = new _ChildKey.fromWidget(element.widget);
-          newChildren[key] = element;
-          builtChildren[index] = element;
-        }
-        assert(builtChildren[index] != null);
-        index += 1;
-      }
-    }
-
-    // Remove any old children.
-    for (_ChildKey oldChildKey in _childrenByKey.keys) {
-      if (!newChildren.containsKey(oldChildKey))
-        updateChild(_childrenByKey[oldChildKey], null, null);
-    }
-
-    if (haveChildren) {
-      // Place all our children in our RenderObject.
-      // All the children we are placing are in builtChildren and newChildren.
-      // We will walk them backwards so we can set the slots at the same time.
-      Element nextSibling = null;
-      while (index > startIndex) {
-        index -= 1;
-        final Element element = builtChildren[index];
-        if (element.slot != nextSibling)
-          updateSlotForChild(element, nextSibling);
-        nextSibling = element;
-      }
-    }
-
-    // Update our internal state.
-    _childrenByKey = newChildren;
-    _firstVisibleChildIndex = startIndex;
-  }
-
-  void updateSlotForChild(Element element, dynamic newSlot) {
-    assert(newSlot == null || newSlot == _omit || newSlot is Element);
-    super.updateSlotForChild(element, newSlot);
-  }
-
-  void insertChildRenderObject(RenderObject child, dynamic slot) {
-    if (slot == _omit)
-      return;
-    assert(slot == null || slot is Element);
-    RenderObject nextSibling = slot?.renderObject;
-    renderObject.add(child, before: nextSibling);
-  }
-
-  void moveChildRenderObject(RenderObject child, dynamic slot) {
-    if (slot == _omit)
-      return;
-    assert(slot == null || slot is Element);
-    RenderObject nextSibling = slot?.renderObject;
-    assert(nextSibling == null || nextSibling.parent == renderObject);
-    if (child.parent == renderObject)
-      renderObject.move(child, before: nextSibling);
-    else
-      renderObject.add(child, before: nextSibling);
-  }
-
-  void removeChildRenderObject(RenderObject child) {
-    if (child.parent != renderObject)
-      return; // probably had slot == _omit when inserted
-    renderObject.remove(child);
-  }
-
-}
diff --git a/sky/packages/sky/lib/src/widgets/modal_barrier.dart b/sky/packages/sky/lib/src/widgets/modal_barrier.dart
deleted file mode 100644
index d11ab19..0000000
--- a/sky/packages/sky/lib/src/widgets/modal_barrier.dart
+++ /dev/null
@@ -1,122 +0,0 @@
-// Copyright 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:flutter/animation.dart';
-
-import 'basic.dart';
-import 'focus.dart';
-import 'framework.dart';
-import 'navigator.dart';
-import 'routes.dart';
-import 'status_transitions.dart';
-import 'transitions.dart';
-
-const Color _kTransparent = const Color(0x00000000);
-
-class ModalBarrier extends StatelessComponent {
-  ModalBarrier({
-    Key key,
-    this.color: _kTransparent
-  }) : super(key: key);
-
-  final Color color;
-
-  Widget build(BuildContext context) {
-    return new Listener(
-      onPointerDown: (_) {
-        Navigator.of(context).pop();
-      },
-      child: new ConstrainedBox(
-        constraints: const BoxConstraints.expand(),
-        child: new DecoratedBox(
-          decoration: new BoxDecoration(
-            backgroundColor: color
-          )
-        )
-      )
-    );
-  }
-}
-
-class _AnimatedModalBarrier extends StatelessComponent {
-  _AnimatedModalBarrier({
-    Key key,
-    this.color,
-    this.performance
-  }) : super(key: key);
-
-  final AnimatedColorValue color;
-  final PerformanceView performance;
-
-  Widget build(BuildContext context) {
-    return new BuilderTransition(
-      performance: performance,
-      variables: <AnimatedColorValue>[color],
-      builder: (BuildContext context) {
-        return new IgnorePointer(
-          ignoring: performance.status == PerformanceStatus.reverse,
-          child: new ModalBarrier(color: color.value)
-        );
-      }
-    );
-  }
-}
-
-class _ModalScope extends StatusTransitionComponent {
-  _ModalScope({
-    Key key,
-    ModalRoute route,
-    this.child
-  }) : route = route, super(key: key, performance: route.performance);
-
-  final ModalRoute route;
-  final Widget child;
-
-  Widget build(BuildContext context) {
-    Widget focus = new Focus(
-      key: new GlobalObjectKey(route),
-      child: new IgnorePointer(
-        ignoring: route.performance.status == PerformanceStatus.reverse,
-        child: child
-      )
-    );
-    ModalPosition position = route.position;
-    if (position == null)
-      return focus;
-    return new Positioned(
-      top: position.top,
-      right: position.right,
-      bottom: position.bottom,
-      left: position.left,
-      child: focus
-    );
-  }
-}
-
-class ModalPosition {
-  const ModalPosition({ this.top, this.right, this.bottom, this.left });
-  final double top;
-  final double right;
-  final double bottom;
-  final double left;
-}
-
-abstract class ModalRoute extends TransitionRoute {
-  ModalPosition get position => null;
-  Color get barrierColor => _kTransparent;
-  Widget buildModalWidget(BuildContext context);
-
-  Widget _buildModalBarrier(BuildContext context) {
-    return new _AnimatedModalBarrier(
-      color: new AnimatedColorValue(_kTransparent, end: barrierColor, curve: Curves.ease),
-      performance: performance
-    );
-  }
-
-  Widget _buildModalScope(BuildContext context) {
-    return new _ModalScope(route: this, child: buildModalWidget(context));
-  }
-
-  List<WidgetBuilder> get builders => <WidgetBuilder>[ _buildModalBarrier, _buildModalScope ];
-}
diff --git a/sky/packages/sky/lib/src/widgets/navigator.dart b/sky/packages/sky/lib/src/widgets/navigator.dart
deleted file mode 100644
index 8223aac..0000000
--- a/sky/packages/sky/lib/src/widgets/navigator.dart
+++ /dev/null
@@ -1,122 +0,0 @@
-// Copyright 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 'framework.dart';
-import 'overlay.dart';
-
-abstract class Route {
-  List<OverlayEntry> get overlayEntries;
-
-  void didPush(OverlayState overlay, OverlayEntry insertionPoint);
-  void didPop(dynamic result);
-}
-
-class NamedRouteSettings {
-  const NamedRouteSettings({ this.name, this.mostValuableKeys });
-
-  final String name;
-  final Set<Key> mostValuableKeys;
-}
-
-typedef Route RouteFactory(NamedRouteSettings settings);
-
-class Navigator extends StatefulComponent {
-  Navigator({
-    Key key,
-    this.onGenerateRoute,
-    this.onUnknownRoute
-  }) : super(key: key) {
-    assert(onGenerateRoute != null);
-  }
-
-  final RouteFactory onGenerateRoute;
-  final RouteFactory onUnknownRoute;
-
-  static const String defaultRouteName = '/';
-
-  static NavigatorState of(BuildContext context) {
-    NavigatorState result;
-    context.visitAncestorElements((Element element) {
-      if (element is StatefulComponentElement && element.state is NavigatorState) {
-        result = element.state;
-        return false;
-      }
-      return true;
-    });
-    return result;
-  }
-
-  NavigatorState createState() => new NavigatorState();
-}
-
-class NavigatorState extends State<Navigator> {
-  final GlobalKey<OverlayState> _overlayKey = new GlobalKey<OverlayState>();
-  final List<Route> _ephemeral = new List<Route>();
-  final List<Route> _modal = new List<Route>();
-
-  void initState() {
-    super.initState();
-    push(config.onGenerateRoute(new NamedRouteSettings(name: Navigator.defaultRouteName)));
-  }
-
-  bool get hasPreviousRoute => _modal.length > 1;
-  OverlayState get overlay => _overlayKey.currentState;
-
-  OverlayEntry get _currentOverlay {
-    for (Route route in _ephemeral.reversed) {
-      if (route.overlayEntries.isNotEmpty)
-        return route.overlayEntries.last;
-    }
-    for (Route route in _modal.reversed) {
-      if (route.overlayEntries.isNotEmpty)
-        return route.overlayEntries.last;
-    }
-    return null;
-  }
-
-  Route get currentRoute => _ephemeral.isNotEmpty ? _ephemeral.last : _modal.last;
-
-  Route _removeCurrentRoute() {
-    return _ephemeral.isNotEmpty ? _ephemeral.removeLast() : _modal.removeLast();
-  }
-
-  void pushNamed(String name, { Set<Key> mostValuableKeys }) {
-    assert(name != null);
-    NamedRouteSettings settings = new NamedRouteSettings(
-      name: name,
-      mostValuableKeys: mostValuableKeys
-    );
-    push(config.onGenerateRoute(settings) ?? config.onUnknownRoute(settings));
-  }
-
-  void push(Route route) {
-    _popAllEphemeralRoutes();
-    route.didPush(overlay, _currentOverlay);
-    _modal.add(route);
-  }
-
-  void pushEphemeral(Route route) {
-    route.didPush(overlay, _currentOverlay);
-    _ephemeral.add(route);
-  }
-
-  void _popAllEphemeralRoutes() {
-    List<Route> localEphemeral = new List<Route>.from(_ephemeral);
-    _ephemeral.clear();
-    for (Route route in localEphemeral)
-      route.didPop(null);
-    assert(_ephemeral.isEmpty);
-  }
-
-  void pop([dynamic result]) {
-    _removeCurrentRoute().didPop(result);
-  }
-
-  Widget build(BuildContext context) {
-    return new Overlay(
-      key: _overlayKey,
-      initialEntries: _modal.first.overlayEntries
-    );
-  }
-}
diff --git a/sky/packages/sky/lib/src/widgets/overlay.dart b/sky/packages/sky/lib/src/widgets/overlay.dart
deleted file mode 100644
index 048a65d..0000000
--- a/sky/packages/sky/lib/src/widgets/overlay.dart
+++ /dev/null
@@ -1,90 +0,0 @@
-// Copyright 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 'basic.dart';
-import 'framework.dart';
-
-class OverlayEntry {
-  OverlayEntry({
-    this.builder,
-    bool opaque: false
-  }) : _opaque = opaque;
-
-  final WidgetBuilder builder;
-
-  bool get opaque => _opaque;
-  bool _opaque;
-  void set opaque (bool value) {
-    if (_opaque == value)
-      return;
-    _opaque = value;
-    markNeedsBuild();
-  }
-
-  OverlayState _state;
-
-  /// Remove the entry from the overlay.
-  void remove() {
-    _state?._remove(this);
-    _state = null;
-  }
-
-  void markNeedsBuild() {
-    // TODO(ianh): find a way to make this not rebuild the entire overlay
-    _state?.setState(() {});
-  }
-}
-
-class Overlay extends StatefulComponent {
-  Overlay({
-    Key key,
-    this.initialEntries
-  }) : super(key: key);
-
-  final List<OverlayEntry> initialEntries;
-
-  OverlayState createState() => new OverlayState();
-}
-
-class OverlayState extends State<Overlay> {
-  final List<OverlayEntry> _entries = new List<OverlayEntry>();
-
-  void initState() {
-    super.initState();
-    for (OverlayEntry entry in config.initialEntries)
-      insert(entry);
-  }
-
-  void insert(OverlayEntry entry, { OverlayEntry above }) {
-    assert(entry._state == null);
-    assert(above == null || (above._state == this && _entries.contains(above)));
-    entry._state = this;
-    setState(() {
-      int index = above == null ? _entries.length : _entries.indexOf(above) + 1;
-      _entries.insert(index, entry);
-    });
-  }
-
-  void _remove(OverlayEntry entry) {
-    setState(() {
-      _entries.remove(entry);
-    });
-  }
-
-  Widget build(BuildContext context) {
-    List<Widget> backwardsChildren = <Widget>[];
-
-    for (int i = _entries.length - 1; i >= 0; --i) {
-      OverlayEntry entry = _entries[i];
-      backwardsChildren.add(new KeyedSubtree(
-        key: new ObjectKey(entry),
-        child: entry.builder(context)
-      ));
-      if (entry.opaque)
-        break;
-    }
-
-    return new Stack(backwardsChildren.reversed.toList(growable: false));
-  }
-}
diff --git a/sky/packages/sky/lib/src/widgets/page.dart b/sky/packages/sky/lib/src/widgets/page.dart
deleted file mode 100644
index 8833778..0000000
--- a/sky/packages/sky/lib/src/widgets/page.dart
+++ /dev/null
@@ -1,122 +0,0 @@
-// Copyright 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:flutter/animation.dart';
-
-import 'basic.dart';
-import 'framework.dart';
-import 'modal_barrier.dart';
-import 'navigator.dart';
-import 'page_storage.dart';
-import 'transitions.dart';
-
-class _PageTransition extends TransitionWithChild {
-  _PageTransition({
-    Key key,
-    PerformanceView performance,
-    Widget child
-  }) : super(key: key,
-             performance: performance,
-             child: child);
-
-  final AnimatedValue<Point> _position =
-     new AnimatedValue<Point>(const Point(0.0, 75.0), end: Point.origin, curve: Curves.easeOut);
-
-  final AnimatedValue<double> _opacity =
-     new AnimatedValue<double>(0.0, end: 1.0, curve: Curves.easeOut);
-
-  Widget buildWithChild(BuildContext context, Widget child) {
-    performance.updateVariable(_position);
-    performance.updateVariable(_opacity);
-    Matrix4 transform = new Matrix4.identity()
-      ..translate(_position.value.x, _position.value.y);
-    return new Transform(
-      transform: transform,
-      child: new Opacity(
-        opacity: _opacity.value,
-        child: child
-      )
-    );
-  }
-}
-
-class _Page extends StatefulComponent {
-  _Page({
-    Key key,
-    this.route
-  }) : super(key: key);
-
-  final PageRoute route;
-
-  _PageState createState() => new _PageState();
-}
-
-class _PageState extends State<_Page> {
-  final GlobalKey _subtreeKey = new GlobalKey();
-
-  Widget build(BuildContext context) {
-    if (config.route._offstage) {
-      return new OffStage(
-        child: new PageStorage(
-          key: _subtreeKey,
-          bucket: config.route._storageBucket,
-          child: _invokeBuilder()
-        )
-      );
-    }
-    return new _PageTransition(
-      performance: config.route.performance,
-      child: new PageStorage(
-        key: _subtreeKey,
-        bucket: config.route._storageBucket,
-        child: _invokeBuilder()
-      )
-    );
-  }
-
-  Widget _invokeBuilder() {
-    Widget result = config.route.builder(context);
-    assert(() {
-      if (result == null)
-        debugPrint('The builder for route \'${config.route.name}\' returned null. Route builders must never return null.');
-      assert(result != null && 'A route builder returned null. See the previous log message for details.' is String);
-      return true;
-    });
-    return result;
-  }
-}
-
-class PageRoute extends ModalRoute {
-  PageRoute({
-    this.builder,
-    this.settings: const NamedRouteSettings()
-  }) {
-    assert(builder != null);
-    assert(opaque);
-  }
-
-  final WidgetBuilder builder;
-  final NamedRouteSettings settings;
-
-  final GlobalKey<_PageState> pageKey = new GlobalKey<_PageState>();
-
-  bool get opaque => true;
-
-  String get name => settings.name;
-  Duration get transitionDuration => const Duration(milliseconds: 150);
-  Widget buildModalWidget(BuildContext context) => new _Page(key: pageKey, route: this);
-
-  final PageStorageBucket _storageBucket = new PageStorageBucket();
-
-  bool get offstage => _offstage;
-  bool _offstage = false;
-  void set offstage (bool value) {
-    if (_offstage == value)
-      return;
-    _offstage = value;
-    pageKey.currentState?.setState(() { });
-  }
-
-  String get debugLabel => '${super.debugLabel}($name)';
-}
diff --git a/sky/packages/sky/lib/src/widgets/page_storage.dart b/sky/packages/sky/lib/src/widgets/page_storage.dart
deleted file mode 100644
index 051c765..0000000
--- a/sky/packages/sky/lib/src/widgets/page_storage.dart
+++ /dev/null
@@ -1,102 +0,0 @@
-// Copyright 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 'framework.dart';
-
-class _StorageEntryIdentifier {
-  Type clientType;
-  List<Key> keys;
-  void addKey(Key key) {
-    assert(key != null);
-    assert(key is! GlobalKey);
-    keys ??= <Key>[];
-    keys.add(key);
-  }
-  GlobalKey scopeKey;
-  bool operator ==(dynamic other) {
-    if (other is! _StorageEntryIdentifier)
-      return false;
-    final _StorageEntryIdentifier typedOther = other;
-    if (clientType != typedOther.clientType ||
-        scopeKey != typedOther.scopeKey ||
-        keys?.length != typedOther.keys?.length)
-      return false;
-    if (keys != null) {
-      for (int index = 0; index < keys.length; index += 1) {
-        if (keys[index] != typedOther.keys[index])
-          return false;
-      }
-    }
-    return true;
-  }
-  int get hashCode {
-    int value = 373;
-    value = 37 * value + clientType.hashCode;
-    value = 37 * value + scopeKey.hashCode;
-    if (keys != null) {
-      for (Key key in keys)
-        value = 37 * value + key.hashCode;
-    }
-    return value;
-  }
-}
-
-class PageStorageBucket {
-  _StorageEntryIdentifier _computeStorageIdentifier(BuildContext context) {
-    _StorageEntryIdentifier result = new _StorageEntryIdentifier();
-    result.clientType = context.widget.runtimeType;
-    Key lastKey = context.widget.key;
-    if (lastKey is! GlobalKey) {
-      context.visitAncestorElements((Element element) {
-        if (element.widget.key is GlobalKey) {
-          lastKey = element.widget.key;
-          return false;
-        } else if (element.widget.key != null) {
-          result.addKey(element.widget.key);
-        }
-        return true;
-      });
-      return result;
-    }
-    assert(lastKey is GlobalKey);
-    result.scopeKey = lastKey;
-    return result;
-  }
-
-  Map<_StorageEntryIdentifier, dynamic> _storage;
-  void writeState(BuildContext context, dynamic data) {
-    _storage ??= <_StorageEntryIdentifier, dynamic>{};
-    _storage[_computeStorageIdentifier(context)] = data;
-  }
-  dynamic readState(BuildContext context) {
-    return _storage != null ? _storage[_computeStorageIdentifier(context)] : null;
-  }
-}
-
-class PageStorage extends StatelessComponent {
-  PageStorage({
-    Key key,
-    this.child,
-    this.bucket
-  }) : super(key: key);
-
-  final Widget child;
-  final PageStorageBucket bucket;
-
-  /// Might return null if there is no PageStorage in this context.
-  static PageStorageBucket of(BuildContext context) {
-    PageStorageBucket result;
-    context.visitAncestorElements((Element element) {
-      Widget widget = element.widget;
-      if (widget is PageStorage) {
-        result = widget.bucket;
-        return false;
-      }
-      return true;
-    });
-    return result;
-  }
-
-  Widget build(BuildContext context) => child;
-}
diff --git a/sky/packages/sky/lib/src/widgets/placeholder.dart b/sky/packages/sky/lib/src/widgets/placeholder.dart
deleted file mode 100644
index 79da8dc..0000000
--- a/sky/packages/sky/lib/src/widgets/placeholder.dart
+++ /dev/null
@@ -1,30 +0,0 @@
-// Copyright 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 'basic.dart';
-import 'framework.dart';
-
-class Placeholder extends StatefulComponent {
-  Placeholder({ Key key }) : super(key: key);
-
-  PlaceholderState createState() => new PlaceholderState();
-}
-
-class PlaceholderState extends State<Placeholder> {
-  Widget get child => _child;
-  Widget _child;
-  void set child(Widget child) {
-    if (_child == child)
-      return;
-    setState(() {
-      _child = child;
-    });
-  }
-
-  Widget build(BuildContext context) {
-    if (_child != null)
-      return child;
-    return new SizedBox(width: 0.0, height: 0.0);
-  }
-}
diff --git a/sky/packages/sky/lib/src/widgets/routes.dart b/sky/packages/sky/lib/src/widgets/routes.dart
deleted file mode 100644
index 98ec21a..0000000
--- a/sky/packages/sky/lib/src/widgets/routes.dart
+++ /dev/null
@@ -1,94 +0,0 @@
-// Copyright 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:flutter/animation.dart';
-
-import 'basic.dart';
-import 'framework.dart';
-import 'navigator.dart';
-import 'overlay.dart';
-
-class StateRoute extends Route {
-  StateRoute({ this.onPop });
-
-  final VoidCallback onPop;
-
-  List<OverlayEntry> get overlayEntries => const <OverlayEntry>[];
-
-  void didPush(OverlayState overlay, OverlayEntry insertionPoint) { }
-  void didPop(dynamic result) {
-    if (onPop != null)
-      onPop();
-  }
-}
-
-class OverlayRoute extends Route {
-  List<WidgetBuilder> get builders => const <WidgetBuilder>[];
-
-  List<OverlayEntry> get overlayEntries => _overlayEntries;
-  final List<OverlayEntry> _overlayEntries = new List<OverlayEntry>();
-
-  void didPush(OverlayState overlay, OverlayEntry insertionPoint) {
-    for (WidgetBuilder builder in builders) {
-      _overlayEntries.add(new OverlayEntry(builder: builder));
-      overlay?.insert(_overlayEntries.last, above: insertionPoint);
-      insertionPoint = _overlayEntries.last;
-    }
-  }
-
-  void didPop(dynamic result) {
-    for (OverlayEntry entry in _overlayEntries)
-      entry.remove();
-    _overlayEntries.clear();
-  }
-}
-
-// TODO(abarth): Should we add a type for the result?
-abstract class TransitionRoute extends OverlayRoute {
-  Duration get transitionDuration;
-  bool get opaque;
-
-  PerformanceView get performance => _performance?.view;
-  Performance _performance;
-
-  Performance createPerformance() {
-    Duration duration = transitionDuration;
-    assert(duration != null && duration >= Duration.ZERO);
-    return new Performance(duration: duration, debugLabel: debugLabel);
-  }
-
-  dynamic _result;
-
-  void _handleStatusChanged(PerformanceStatus status) {
-    switch (status) {
-      case PerformanceStatus.completed:
-        if (overlayEntries.isNotEmpty)
-          overlayEntries.first.opaque = opaque;
-        break;
-      case PerformanceStatus.forward:
-      case PerformanceStatus.reverse:
-        if (overlayEntries.isNotEmpty)
-          overlayEntries.first.opaque = false;
-        break;
-      case PerformanceStatus.dismissed:
-        super.didPop(_result);
-        break;
-    }
-  }
-
-  void didPush(OverlayState overlay, OverlayEntry insertionPoint) {
-    _performance = createPerformance()
-      ..addStatusListener(_handleStatusChanged)
-      ..forward();
-    super.didPush(overlay, insertionPoint);
-  }
-
-  void didPop(dynamic result) {
-    _result = result;
-    _performance.reverse();
-  }
-
-  String get debugLabel => '$runtimeType';
-  String toString() => '$runtimeType(performance: $_performance)';
-}
diff --git a/sky/packages/sky/lib/src/widgets/scrollable.dart b/sky/packages/sky/lib/src/widgets/scrollable.dart
deleted file mode 100644
index b5223e1..0000000
--- a/sky/packages/sky/lib/src/widgets/scrollable.dart
+++ /dev/null
@@ -1,843 +0,0 @@
-// Copyright 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 'dart:async';
-import 'dart:math' as math;
-import 'dart:ui' as ui;
-
-import 'package:newton/newton.dart';
-import 'package:flutter/animation.dart';
-import 'package:flutter/gestures.dart';
-import 'package:flutter/rendering.dart';
-
-import 'basic.dart';
-import 'framework.dart';
-import 'gesture_detector.dart';
-import 'homogeneous_viewport.dart';
-import 'mixed_viewport.dart';
-import 'page_storage.dart';
-
-// The gesture velocity properties are pixels/second, config min,max limits are pixels/ms
-const double _kMillisecondsPerSecond = 1000.0;
-const double _kMinFlingVelocity = -kMaxFlingVelocity * _kMillisecondsPerSecond;
-const double _kMaxFlingVelocity = kMaxFlingVelocity * _kMillisecondsPerSecond;
-
-typedef void ScrollListener(double scrollOffset);
-typedef double SnapOffsetCallback(double scrollOffset);
-
-/// A base class for scrollable widgets that reacts to user input and generates
-/// a scrollOffset.
-abstract class Scrollable extends StatefulComponent {
-  Scrollable({
-    Key key,
-    this.initialScrollOffset,
-    this.scrollDirection: ScrollDirection.vertical,
-    this.onScrollStart,
-    this.onScroll,
-    this.onScrollEnd,
-    this.snapOffsetCallback,
-    this.snapAlignmentOffset: 0.0
-  }) : super(key: key) {
-    assert(scrollDirection == ScrollDirection.vertical ||
-           scrollDirection == ScrollDirection.horizontal);
-  }
-
-  final double initialScrollOffset;
-  final ScrollDirection scrollDirection;
-  final ScrollListener onScrollStart;
-  final ScrollListener onScroll;
-  final ScrollListener onScrollEnd;
-  final SnapOffsetCallback snapOffsetCallback;
-  final double snapAlignmentOffset;
-}
-
-abstract class ScrollableState<T extends Scrollable> extends State<T> {
-  void initState() {
-    super.initState();
-    _animation = new SimulationStepper(_setScrollOffset);
-    _scrollOffset = PageStorage.of(context)?.readState(context) ?? config.initialScrollOffset ?? 0.0;
-  }
-
-  SimulationStepper _animation;
-
-  double get scrollOffset => _scrollOffset;
-  double _scrollOffset;
-
-  Offset get scrollOffsetVector {
-    if (config.scrollDirection == ScrollDirection.horizontal)
-      return new Offset(scrollOffset, 0.0);
-    return new Offset(0.0, scrollOffset);
-  }
-
-  ScrollBehavior _scrollBehavior;
-  ScrollBehavior createScrollBehavior();
-  ScrollBehavior get scrollBehavior {
-    if (_scrollBehavior == null)
-      _scrollBehavior = createScrollBehavior();
-    return _scrollBehavior;
-  }
-
-  GestureDragStartCallback _getDragStartHandler(ScrollDirection direction) {
-    if (config.scrollDirection != direction || !scrollBehavior.isScrollable)
-      return null;
-    return _handleDragStart;
-  }
-
-  GestureDragUpdateCallback _getDragUpdateHandler(ScrollDirection direction) {
-    if (config.scrollDirection != direction || !scrollBehavior.isScrollable)
-      return null;
-    return _handleDragUpdate;
-  }
-
-  GestureDragEndCallback _getDragEndHandler(ScrollDirection direction) {
-    if (config.scrollDirection != direction || !scrollBehavior.isScrollable)
-      return null;
-    return _handleDragEnd;
-  }
-
-  Widget build(BuildContext context) {
-    return new GestureDetector(
-      onVerticalDragStart: _getDragStartHandler(ScrollDirection.vertical),
-      onVerticalDragUpdate: _getDragUpdateHandler(ScrollDirection.vertical),
-      onVerticalDragEnd: _getDragEndHandler(ScrollDirection.vertical),
-      onHorizontalDragStart: _getDragStartHandler(ScrollDirection.horizontal),
-      onHorizontalDragUpdate: _getDragUpdateHandler(ScrollDirection.horizontal),
-      onHorizontalDragEnd: _getDragEndHandler(ScrollDirection.horizontal),
-      child: new Listener(
-        child: buildContent(context),
-        onPointerDown: _handlePointerDown
-      )
-    );
-  }
-
-  Widget buildContent(BuildContext context);
-
-  Future _animateTo(double newScrollOffset, Duration duration, Curve curve) {
-    _animation.stop();
-    _animation.value = scrollOffset;
-    return _animation.animateTo(newScrollOffset, duration: duration, curve: curve);
-  }
-
-  bool _scrollOffsetIsInBounds(double offset) {
-    if (scrollBehavior is! ExtentScrollBehavior)
-      return false;
-    ExtentScrollBehavior behavior = scrollBehavior;
-    return offset >= behavior.minScrollOffset && offset < behavior.maxScrollOffset;
-  }
-
-  Simulation _createFlingSimulation(double velocity) {
-    return scrollBehavior.createFlingScrollSimulation(scrollOffset, velocity);
-  }
-
-  Simulation _createSnapSimulation(double velocity) {
-    if (velocity == null || config.snapOffsetCallback == null || !_scrollOffsetIsInBounds(scrollOffset))
-      return null;
-
-    Simulation simulation = _createFlingSimulation(velocity);
-    if (simulation == null)
-        return null;
-
-    double endScrollOffset = simulation.x(double.INFINITY);
-    if (endScrollOffset.isNaN)
-      return null;
-
-    double snappedScrollOffset = config.snapOffsetCallback(endScrollOffset + config.snapAlignmentOffset);
-    double alignedScrollOffset = snappedScrollOffset - config.snapAlignmentOffset;
-    if (!_scrollOffsetIsInBounds(alignedScrollOffset))
-      return null;
-
-    double snapVelocity = velocity.abs() * (alignedScrollOffset - scrollOffset).sign;
-    Simulation toSnapSimulation =
-      scrollBehavior.createSnapScrollSimulation(scrollOffset, alignedScrollOffset, snapVelocity);
-    if (toSnapSimulation == null)
-      return null;
-
-    double offsetMin = math.min(scrollOffset, alignedScrollOffset);
-    double offsetMax = math.max(scrollOffset, alignedScrollOffset);
-    return new ClampedSimulation(toSnapSimulation, xMin: offsetMin, xMax: offsetMax);
-  }
-
-  Future _startToEndAnimation({ double velocity }) {
-    _animation.stop();
-    Simulation simulation =
-      _createSnapSimulation(velocity) ?? _createFlingSimulation(velocity ?? 0.0);
-    if (simulation == null)
-      return new Future.value();
-    return _animation.animateWith(simulation);
-  }
-
-  void dispose() {
-    _animation.stop();
-    super.dispose();
-  }
-
-  void _setScrollOffset(double newScrollOffset) {
-    if (_scrollOffset == newScrollOffset)
-      return;
-    setState(() {
-      _scrollOffset = newScrollOffset;
-    });
-    PageStorage.of(context)?.writeState(context, _scrollOffset);
-    dispatchOnScroll();
-  }
-
-  Future scrollTo(double newScrollOffset, { Duration duration, Curve curve: Curves.ease }) {
-    if (newScrollOffset == _scrollOffset)
-      return new Future.value();
-
-    if (duration == null) {
-      _animation.stop();
-      _setScrollOffset(newScrollOffset);
-      return new Future.value();
-    }
-
-    return _animateTo(newScrollOffset, duration, curve);
-  }
-
-  Future scrollBy(double scrollDelta, { Duration duration, Curve curve }) {
-    double newScrollOffset = scrollBehavior.applyCurve(_scrollOffset, scrollDelta);
-    return scrollTo(newScrollOffset, duration: duration, curve: curve);
-  }
-
-  Future fling(Offset velocity) {
-    if (velocity != Offset.zero)
-      return _startToEndAnimation(velocity: _scrollVelocity(velocity));
-    if (!_animation.isAnimating)
-      return settleScrollOffset();
-    return new Future.value();
-  }
-
-  Future settleScrollOffset() {
-    return _startToEndAnimation();
-  }
-
-  void dispatchOnScrollStart() {
-    if (config.onScrollStart != null)
-      config.onScrollStart(_scrollOffset);
-  }
-
-  // Derived classes can override this method and call super.dispatchOnScroll()
-  void dispatchOnScroll() {
-    if (config.onScroll != null)
-      config.onScroll(_scrollOffset);
-  }
-
-  void dispatchOnScrollEnd() {
-    if (config.onScrollEnd != null)
-      config.onScrollEnd(_scrollOffset);
-  }
-
-  double _scrollVelocity(ui.Offset velocity) {
-    double scrollVelocity = config.scrollDirection == ScrollDirection.horizontal
-      ? -velocity.dx
-      : -velocity.dy;
-    return scrollVelocity.clamp(_kMinFlingVelocity, _kMaxFlingVelocity) / _kMillisecondsPerSecond;
-  }
-
-  void _handlePointerDown(_) {
-    _animation.stop();
-  }
-
-  void _handleDragStart(_) {
-    scheduleMicrotask(dispatchOnScrollStart);
-  }
-
-  void _handleDragUpdate(double delta) {
-    // We negate the delta here because a positive scroll offset moves the
-    // the content up (or to the left) rather than down (or the right).
-    scrollBy(-delta);
-  }
-
-  Future _handleDragEnd(Offset velocity) {
-    return fling(velocity).then((_) {
-        dispatchOnScrollEnd();
-    });
-  }
-}
-
-ScrollableState findScrollableAncestor(BuildContext context) {
-  ScrollableState result;
-  context.visitAncestorElements((Element element) {
-    if (element is StatefulComponentElement) {
-      if (element.state is ScrollableState) {
-        result = element.state;
-        return false;
-      }
-    }
-    return true;
-  });
-  return result;
-}
-
-Future ensureWidgetIsVisible(BuildContext context, { Duration duration, Curve curve }) {
-  assert(context.findRenderObject() is RenderBox);
-  // TODO(abarth): This function doesn't handle nested scrollable widgets.
-
-  ScrollableState scrollable = findScrollableAncestor(context);
-  if (scrollable == null)
-    return new Future.value();
-
-  RenderBox targetBox = context.findRenderObject();
-  assert(targetBox.attached);
-  Size targetSize = targetBox.size;
-
-  RenderBox scrollableBox = scrollable.context.findRenderObject();
-  assert(scrollableBox.attached);
-  Size scrollableSize = scrollableBox.size;
-
-  double scrollOffsetDelta;
-  switch (scrollable.config.scrollDirection) {
-    case ScrollDirection.vertical:
-      Point targetCenter = targetBox.localToGlobal(new Point(0.0, targetSize.height / 2.0));
-      Point scrollableCenter = scrollableBox.localToGlobal(new Point(0.0, scrollableSize.height / 2.0));
-      scrollOffsetDelta = targetCenter.y - scrollableCenter.y;
-      break;
-    case ScrollDirection.horizontal:
-      Point targetCenter = targetBox.localToGlobal(new Point(targetSize.width / 2.0, 0.0));
-      Point scrollableCenter = scrollableBox.localToGlobal(new Point(scrollableSize.width / 2.0, 0.0));
-      scrollOffsetDelta = targetCenter.x - scrollableCenter.x;
-      break;
-    case ScrollDirection.both:
-      assert(false); // See https://github.com/flutter/engine/issues/888
-      break;
-  }
-
-  ExtentScrollBehavior scrollBehavior = scrollable.scrollBehavior;
-  double scrollOffset = (scrollable.scrollOffset + scrollOffsetDelta)
-    .clamp(scrollBehavior.minScrollOffset, scrollBehavior.maxScrollOffset);
-
-  if (scrollOffset != scrollable.scrollOffset)
-    return scrollable.scrollTo(scrollOffset, duration: duration, curve: curve);
-
-  return new Future.value();
-}
-
-/// A simple scrollable widget that has a single child. Use this component if
-/// you are not worried about offscreen widgets consuming resources.
-class ScrollableViewport extends Scrollable {
-  ScrollableViewport({
-    Key key,
-    this.child,
-    double initialScrollOffset,
-    ScrollDirection scrollDirection: ScrollDirection.vertical,
-    ScrollListener onScroll
-  }) : super(
-    key: key,
-    scrollDirection: scrollDirection,
-    initialScrollOffset: initialScrollOffset,
-    onScroll: onScroll
-  );
-
-  final Widget child;
-
-  ScrollableViewportState createState() => new ScrollableViewportState();
-}
-
-class ScrollableViewportState extends ScrollableState<ScrollableViewport> {
-  ScrollBehavior createScrollBehavior() => new OverscrollWhenScrollableBehavior();
-  OverscrollWhenScrollableBehavior get scrollBehavior => super.scrollBehavior;
-
-  double _viewportSize = 0.0;
-  double _childSize = 0.0;
-  void _handleViewportSizeChanged(Size newSize) {
-    _viewportSize = config.scrollDirection == ScrollDirection.vertical ? newSize.height : newSize.width;
-    setState(() {
-      _updateScrollBehaviour();
-    });
-  }
-  void _handleChildSizeChanged(Size newSize) {
-    _childSize = config.scrollDirection == ScrollDirection.vertical ? newSize.height : newSize.width;
-    setState(() {
-      _updateScrollBehaviour();
-    });
-  }
-  void _updateScrollBehaviour() {
-    // if you don't call this from build(), you must call it from setState().
-    scrollTo(scrollBehavior.updateExtents(
-      contentExtent: _childSize,
-      containerExtent: _viewportSize,
-      scrollOffset: scrollOffset
-    ));
-  }
-
-  Widget buildContent(BuildContext context) {
-    return new SizeObserver(
-      onSizeChanged: _handleViewportSizeChanged,
-      child: new Viewport(
-        scrollOffset: scrollOffsetVector,
-        scrollDirection: config.scrollDirection,
-        child: new SizeObserver(
-          onSizeChanged: _handleChildSizeChanged,
-          child: config.child
-        )
-      )
-    );
-  }
-}
-
-/// A mashup of [ScrollableViewport] and [BlockBody]. Useful when you have a small,
-/// fixed number of children that you wish to arrange in a block layout and that
-/// might exceed the height of its container (and therefore need to scroll).
-class Block extends StatelessComponent {
-  Block(this.children, {
-    Key key,
-    this.padding,
-    this.initialScrollOffset,
-    this.scrollDirection: ScrollDirection.vertical,
-    this.onScroll
-  }) : super(key: key) {
-    assert(!children.any((Widget child) => child == null));
-  }
-
-  final List<Widget> children;
-  final EdgeDims padding;
-  final double initialScrollOffset;
-  final ScrollDirection scrollDirection;
-  final ScrollListener onScroll;
-
-  BlockDirection get _direction {
-    if (scrollDirection == ScrollDirection.vertical)
-      return BlockDirection.vertical;
-    return BlockDirection.horizontal;
-  }
-
-  Widget build(BuildContext context) {
-    Widget contents = new BlockBody(children, direction: _direction);
-    if (padding != null)
-      contents = new Padding(padding: padding, child: contents);
-    return new ScrollableViewport(
-      initialScrollOffset: initialScrollOffset,
-      scrollDirection: scrollDirection,
-      onScroll: onScroll,
-      child: contents
-    );
-  }
-}
-
-abstract class ScrollableListPainter extends Painter {
-  void attach(RenderObject renderObject) {
-    assert(renderObject is RenderBlockViewport);
-    super.attach(renderObject);
-  }
-
-  RenderBlockViewport get renderer => renderObject;
-
-  bool get isVertical => renderer.isVertical;
-
-  Size get viewportSize => renderer.size;
-
-  double get contentExtent => _contentExtent;
-  double _contentExtent = 0.0;
-  void set contentExtent (double value) {
-    assert(value != null);
-    assert(value >= 0.0);
-    if (_contentExtent == value)
-      return;
-    _contentExtent = value;
-    renderer?.markNeedsPaint();
-  }
-
-  double get scrollOffset => _scrollOffset;
-  double _scrollOffset = 0.0;
-  void set scrollOffset (double value) {
-    assert(value != null);
-    if (_scrollOffset == value)
-      return;
-    _scrollOffset = value;
-    renderer?.markNeedsPaint();
-  }
-
-  /// Called when a scroll starts. Subclasses may override this method to
-  /// initialize some state or to play an animation. The returned Future should
-  /// complete when the computation triggered by this method has finished.
-  Future scrollStarted() => new Future.value();
-
-
-  /// Similar to scrollStarted(). Called when a scroll ends. For fling scrolls
-  /// "ended" means that the scroll animation either stopped of its own accord
-  /// or was canceled  by the user.
-  Future scrollEnded() => new Future.value();
-}
-
-/// An optimized scrollable widget for a large number of children that are all
-/// the same size (extent) in the scrollDirection. For example for
-/// ScrollDirection.vertical itemExtent is the height of each item. Use this
-/// widget when you have a large number of children or when you are concerned
-// about offscreen widgets consuming resources.
-abstract class ScrollableWidgetList extends Scrollable {
-  ScrollableWidgetList({
-    Key key,
-    double initialScrollOffset,
-    ScrollDirection scrollDirection: ScrollDirection.vertical,
-    ScrollListener onScroll,
-    SnapOffsetCallback snapOffsetCallback,
-    double snapAlignmentOffset: 0.0,
-    this.itemsWrap: false,
-    this.itemExtent,
-    this.padding,
-    this.scrollableListPainter
-  }) : super(
-    key: key,
-    initialScrollOffset: initialScrollOffset,
-    scrollDirection: scrollDirection,
-    onScroll: onScroll,
-    snapOffsetCallback: snapOffsetCallback,
-    snapAlignmentOffset: snapAlignmentOffset
-  ) {
-    assert(itemExtent != null);
-  }
-
-  final bool itemsWrap;
-  final double itemExtent;
-  final EdgeDims padding;
-  final ScrollableListPainter scrollableListPainter;
-}
-
-abstract class ScrollableWidgetListState<T extends ScrollableWidgetList> extends ScrollableState<T> {
-  /// Subclasses must implement `get itemCount` to tell ScrollableWidgetList
-  /// how many items there are in the list.
-  int get itemCount;
-  int _previousItemCount;
-
-  Size _containerSize = Size.zero;
-
-  void didUpdateConfig(T oldConfig) {
-    super.didUpdateConfig(oldConfig);
-
-    bool scrollBehaviorUpdateNeeded =
-      config.padding != oldConfig.padding ||
-      config.itemExtent != oldConfig.itemExtent ||
-      config.scrollDirection != oldConfig.scrollDirection;
-
-    if (config.itemsWrap != oldConfig.itemsWrap) {
-      _scrollBehavior = null;
-      scrollBehaviorUpdateNeeded = true;
-    }
-
-    if (itemCount != _previousItemCount) {
-      _previousItemCount = itemCount;
-      scrollBehaviorUpdateNeeded = true;
-    }
-
-    if (scrollBehaviorUpdateNeeded)
-      _updateScrollBehavior();
-  }
-
-  ScrollBehavior createScrollBehavior() => new OverscrollBehavior();
-  ExtentScrollBehavior get scrollBehavior => super.scrollBehavior;
-
-  double get _containerExtent {
-    return config.scrollDirection == ScrollDirection.vertical
-      ? _containerSize.height
-      : _containerSize.width;
-  }
-
-  void _handleSizeChanged(Size newSize) {
-    setState(() {
-      _containerSize = newSize;
-      _updateScrollBehavior();
-    });
-  }
-
-  double get _leadingPadding {
-    EdgeDims padding = config.padding;
-    if (config.scrollDirection == ScrollDirection.vertical)
-      return padding != null ? padding.top : 0.0;
-    return padding != null ? padding.left : -.0;
-  }
-
-  double get _trailingPadding {
-    EdgeDims padding = config.padding;
-    if (config.scrollDirection == ScrollDirection.vertical)
-      return padding != null ? padding.bottom : 0.0;
-    return padding != null ? padding.right : 0.0;
-  }
-
-  EdgeDims get _crossAxisPadding {
-    EdgeDims padding = config.padding;
-    if (padding == null)
-      return null;
-    if (config.scrollDirection == ScrollDirection.vertical)
-      return new EdgeDims.only(left: padding.left, right: padding.right);
-    return new EdgeDims.only(top: padding.top, bottom: padding.bottom);
-  }
-
-  double get _contentExtent {
-    if (itemCount == null)
-      return null;
-    double contentExtent = config.itemExtent * itemCount;
-    if (config.padding != null)
-      contentExtent += _leadingPadding + _trailingPadding;
-    return contentExtent;
-  }
-
-  void _updateScrollBehavior() {
-    // if you don't call this from build(), you must call it from setState().
-    if (config.scrollableListPainter != null)
-      config.scrollableListPainter.contentExtent = _contentExtent;
-    scrollTo(scrollBehavior.updateExtents(
-      contentExtent: _contentExtent,
-      containerExtent: _containerExtent,
-      scrollOffset: scrollOffset
-    ));
-  }
-
-  void dispatchOnScrollStart() {
-    super.dispatchOnScrollStart();
-    config.scrollableListPainter?.scrollStarted();
-  }
-
-  void dispatchOnScroll() {
-    super.dispatchOnScroll();
-    if (config.scrollableListPainter != null)
-      config.scrollableListPainter.scrollOffset = scrollOffset;
-  }
-
-  void dispatchOnScrollEnd() {
-    super.dispatchOnScrollEnd();
-    config.scrollableListPainter?.scrollEnded();
-  }
-
-  Widget buildContent(BuildContext context) {
-    if (itemCount != _previousItemCount) {
-      _previousItemCount = itemCount;
-      _updateScrollBehavior();
-    }
-
-    return new SizeObserver(
-      onSizeChanged: _handleSizeChanged,
-      child: new Container(
-        padding: _crossAxisPadding,
-        child: new HomogeneousViewport(
-          builder: _buildItems,
-          itemsWrap: config.itemsWrap,
-          itemExtent: config.itemExtent,
-          itemCount: itemCount,
-          direction: config.scrollDirection,
-          startOffset: scrollOffset - _leadingPadding,
-          overlayPainter: config.scrollableListPainter
-        )
-      )
-    );
-  }
-
-  List<Widget> _buildItems(BuildContext context, int start, int count) {
-    List<Widget> result = buildItems(context, start, count);
-    assert(result.every((Widget item) => item.key != null));
-    return result;
-  }
-
-  List<Widget> buildItems(BuildContext context, int start, int count);
-
-}
-
-typedef Widget ItemBuilder<T>(BuildContext context, T item);
-
-/// A wrapper around [ScrollableWidgetList] that helps you translate a list of
-/// model objects into a scrollable list of widgets. Assumes all the widgets
-/// have the same height.
-class ScrollableList<T> extends ScrollableWidgetList {
-  ScrollableList({
-    Key key,
-    double initialScrollOffset,
-    ScrollDirection scrollDirection: ScrollDirection.vertical,
-    ScrollListener onScroll,
-    SnapOffsetCallback snapOffsetCallback,
-    double snapAlignmentOffset: 0.0,
-    this.items,
-    this.itemBuilder,
-    itemsWrap: false,
-    double itemExtent,
-    EdgeDims padding,
-    ScrollableListPainter scrollableListPainter
-  }) : super(
-    key: key,
-    initialScrollOffset: initialScrollOffset,
-    scrollDirection: scrollDirection,
-    onScroll: onScroll,
-    snapOffsetCallback: snapOffsetCallback,
-    snapAlignmentOffset: snapAlignmentOffset,
-    itemsWrap: itemsWrap,
-    itemExtent: itemExtent,
-    padding: padding,
-    scrollableListPainter: scrollableListPainter
-  );
-
-  final List<T> items;
-  final ItemBuilder<T> itemBuilder;
-
-  ScrollableListState<T, ScrollableList<T>> createState() => new ScrollableListState<T, ScrollableList<T>>();
-}
-
-class ScrollableListState<T, Config extends ScrollableList<T>> extends ScrollableWidgetListState<Config> {
-  ScrollBehavior createScrollBehavior() {
-    return config.itemsWrap ? new UnboundedBehavior() : super.createScrollBehavior();
-  }
-
-  int get itemCount => config.items.length;
-
-  List<Widget> buildItems(BuildContext context, int start, int count) {
-    List<Widget> result = new List<Widget>();
-    int begin = config.itemsWrap ? start : math.max(0, start);
-    int end = config.itemsWrap ? begin + count : math.min(begin + count, config.items.length);
-    for (int i = begin; i < end; ++i)
-      result.add(config.itemBuilder(context, config.items[i % itemCount]));
-    return result;
-  }
-}
-
-typedef void PageChangedCallback(int newPage);
-
-class PageableList<T> extends ScrollableList<T> {
-  PageableList({
-    Key key,
-    int initialPage,
-    ScrollDirection scrollDirection: ScrollDirection.horizontal,
-    ScrollListener onScroll,
-    List<T> items,
-    ItemBuilder<T> itemBuilder,
-    bool itemsWrap: false,
-    double itemExtent,
-    this.onPageChanged,
-    EdgeDims padding,
-    this.duration: const Duration(milliseconds: 200),
-    this.curve: Curves.ease
-  }) : super(
-    key: key,
-    initialScrollOffset: initialPage == null ? null : initialPage * itemExtent,
-    scrollDirection: scrollDirection,
-    onScroll: onScroll,
-    items: items,
-    itemBuilder: itemBuilder,
-    itemsWrap: itemsWrap,
-    itemExtent: itemExtent,
-    padding: padding
-  );
-
-  final Duration duration;
-  final Curve curve;
-  final PageChangedCallback onPageChanged;
-
-  PageableListState<T> createState() => new PageableListState<T>();
-}
-
-class PageableListState<T> extends ScrollableListState<T, PageableList<T>> {
-  double _snapScrollOffset(double newScrollOffset) {
-    double scaledScrollOffset = newScrollOffset / config.itemExtent;
-    double previousScrollOffset = scaledScrollOffset.floor() * config.itemExtent;
-    double nextScrollOffset = scaledScrollOffset.ceil() * config.itemExtent;
-    double delta = newScrollOffset - previousScrollOffset;
-    return (delta < config.itemExtent / 2.0 ? previousScrollOffset : nextScrollOffset)
-      .clamp(scrollBehavior.minScrollOffset, scrollBehavior.maxScrollOffset);
-  }
-
-  Future fling(ui.Offset velocity) {
-    double scrollVelocity = _scrollVelocity(velocity);
-    double newScrollOffset = _snapScrollOffset(scrollOffset + scrollVelocity.sign * config.itemExtent)
-      .clamp(_snapScrollOffset(scrollOffset - config.itemExtent / 2.0),
-             _snapScrollOffset(scrollOffset + config.itemExtent / 2.0));
-    return scrollTo(newScrollOffset, duration: config.duration, curve: config.curve).then(_notifyPageChanged);
-  }
-
-  int get currentPage => (scrollOffset / config.itemExtent).floor() % itemCount;
-
-  void _notifyPageChanged(_) {
-    if (config.onPageChanged != null)
-      config.onPageChanged(currentPage);
-  }
-
-  Future settleScrollOffset() {
-    return scrollTo(_snapScrollOffset(scrollOffset), duration: config.duration, curve: config.curve).then(_notifyPageChanged);
-  }
-}
-
-/// A general scrollable list for a large number of children that might not all
-/// have the same height. Prefer [ScrollableWidgetList] when all the children
-/// have the same height because it can use that property to be more efficient.
-/// Prefer [ScrollableViewport] with a single child.
-class ScrollableMixedWidgetList extends Scrollable {
-  ScrollableMixedWidgetList({
-    Key key,
-    double initialScrollOffset,
-    ScrollListener onScroll,
-    SnapOffsetCallback snapOffsetCallback,
-    double snapAlignmentOffset: 0.0,
-    this.builder,
-    this.token,
-    this.onInvalidatorAvailable
-  }) : super(
-    key: key,
-    initialScrollOffset: initialScrollOffset,
-    onScroll: onScroll,
-    snapOffsetCallback: snapOffsetCallback,
-    snapAlignmentOffset: snapAlignmentOffset
-  );
-
-  final IndexedBuilder builder;
-  final Object token;
-  final InvalidatorAvailableCallback onInvalidatorAvailable;
-
-  ScrollableMixedWidgetListState createState() => new ScrollableMixedWidgetListState();
-}
-
-class ScrollableMixedWidgetListState extends ScrollableState<ScrollableMixedWidgetList> {
-  void initState() {
-    super.initState();
-    scrollBehavior.updateExtents(
-      contentExtent: double.INFINITY
-    );
-  }
-
-  ScrollBehavior createScrollBehavior() => new OverscrollBehavior();
-  OverscrollBehavior get scrollBehavior => super.scrollBehavior;
-
-  void _handleSizeChanged(Size newSize) {
-    setState(() {
-      scrollBy(scrollBehavior.updateExtents(
-        containerExtent: newSize.height,
-        scrollOffset: scrollOffset
-      ));
-    });
-  }
-
-  bool _contentChanged = false;
-
-  void didUpdateConfig(ScrollableMixedWidgetList oldConfig) {
-    super.didUpdateConfig(oldConfig);
-    if (config.token != oldConfig.token) {
-      // When the token changes the scrollable's contents may have changed.
-      // Remember as much so that after the new contents have been laid out we
-      // can adjust the scrollOffset so that the last page of content is still
-      // visible.
-      _contentChanged = true;
-    }
-  }
-
-  void _handleExtentsUpdate(double newExtents) {
-    double newScrollOffset;
-    setState(() {
-      newScrollOffset = scrollBehavior.updateExtents(
-        contentExtent: newExtents ?? double.INFINITY,
-        scrollOffset: scrollOffset
-      );
-    });
-    if (_contentChanged) {
-      _contentChanged = false;
-      scrollTo(newScrollOffset);
-    }
-  }
-
-  Widget buildContent(BuildContext context) {
-    return new SizeObserver(
-      onSizeChanged: _handleSizeChanged,
-      child: new MixedViewport(
-        startOffset: scrollOffset,
-        builder: config.builder,
-        token: config.token,
-        onInvalidatorAvailable: config.onInvalidatorAvailable,
-        onExtentsUpdate: _handleExtentsUpdate
-      )
-    );
-  }
-}
diff --git a/sky/packages/sky/lib/src/widgets/statistics_overlay.dart b/sky/packages/sky/lib/src/widgets/statistics_overlay.dart
deleted file mode 100644
index 090dbb4..0000000
--- a/sky/packages/sky/lib/src/widgets/statistics_overlay.dart
+++ /dev/null
@@ -1,95 +0,0 @@
-// Copyright 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:flutter/rendering.dart';
-
-import 'framework.dart';
-
-/// The options that control whether the statistics overlay displays certain
-/// aspects of the compositor
-enum StatisticsOption {
-  /// Display the frame time and FPS of the last frame rendered. This field is
-  /// updated every frame.
-  ///
-  /// This is the time spent by the rasterizer as it tries
-  /// to convert the layer tree obtained from the widgets into OpenGL commands
-  /// and tries to flush them onto the screen. When the total time taken by this
-  /// step exceeds the frame slice, a frame is lost.
-  displayRasterizerStatistics,
-  /// Display the rasterizer frame times as they change over a set period of
-  /// time in the form of a graph. The y axis of the graph denotes the total
-  /// time spent by the rasterizer as a fraction of the total frame slice. When
-  /// the bar turns red, a frame is lost.
-  visualizeRasterizerStatistics,
-  /// Display the frame time and FPS at which the interface can construct a
-  /// layer tree for the rasterizer (whose behavior is described above) to
-  /// consume.
-  ///
-  /// This involves all layout, animations, etc. When the total time taken by
-  /// this step exceeds the frame slice, a frame is lost.
-  displayEngineStatistics,
-  /// Display the engine frame times as they change over a set period of time
-  /// in the form of a graph. The y axis of the graph denotes the total time
-  /// spent by the eninge as a fraction of the total frame slice. When the bar
-  /// turns red, a frame is lost.
-  visualizeEngineStatistics,
-}
-
-class StatisticsOverlay extends LeafRenderObjectWidget {
-
-  /// Create a statistics overlay that only displays specific statistics. The
-  /// mask is created by shifting 1 by the index of the specific StatisticOption
-  /// to enable.
-  StatisticsOverlay({ this.optionsMask, this.rasterizerThreshold: 0, Key key }) : super(key: key);
-
-  /// Create a statistics overaly that displays all available statistics
-  StatisticsOverlay.allEnabled({ Key key, this.rasterizerThreshold: 0 })
-    : optionsMask = (
-        1 << StatisticsOption.displayRasterizerStatistics.index |
-        1 << StatisticsOption.visualizeRasterizerStatistics.index |
-        1 << StatisticsOption.displayEngineStatistics.index |
-        1 << StatisticsOption.visualizeEngineStatistics.index
-      ),
-      super(key: key);
-
-  final int optionsMask;
-
-  /// The rasterizer threshold is an integer specifying the number of frame
-  /// intervals that the rasterizer must miss before it decides that the frame
-  /// is suitable for capturing an SkPicture trace from for further analysis.
-  ///
-  /// For example, if you want a trace of all pictures that could not be
-  /// renderered by the rasterizer within the frame boundary (and hence caused
-  /// jank), specify 1. Specifying 2 will trace all pictures that took more
-  /// more than 2 frame intervals to render. Adjust this value to only capture
-  /// the particularly expensive pictures while skipping the others. Specifying
-  /// 0 disables all capture.
-  ///
-  /// Captured traces are placed on your device in the application documents
-  /// directory in this form "trace_<collection_time>.skp". These can
-  /// be viewed in the Skia debugger.
-  ///
-  /// Notes:
-  /// The rasterizer only takes into account the time it took to render
-  /// the already constructed picture. This include the Skia calls (which is
-  /// also why an SkPicture trace is generated) but not any of the time spent in
-  /// dart to construct that picture. To profile that part of your code, use
-  /// the instrumentation available in observatory.
-  ///
-  /// To decide what threshold interval to use, count the number of horizontal
-  /// lines displayed in the statistics overlay for the rasterizer (not the
-  /// engine). That should give an idea of how often frames are skipped (and by
-  /// how many frame intervals).
-  final int rasterizerThreshold;
-
-  StatisticsBox createRenderObject() => new StatisticsBox(
-    optionsMask: optionsMask,
-    rasterizerThreshold: rasterizerThreshold
-  );
-
-  void updateRenderObject(StatisticsBox renderObject, RenderObjectWidget oldWidget) {
-    renderObject.optionsMask = optionsMask;
-    renderObject.rasterizerThreshold = rasterizerThreshold;
-  }
-}
diff --git a/sky/packages/sky/lib/src/widgets/status_transitions.dart b/sky/packages/sky/lib/src/widgets/status_transitions.dart
deleted file mode 100644
index 8b3fe3a..0000000
--- a/sky/packages/sky/lib/src/widgets/status_transitions.dart
+++ /dev/null
@@ -1,51 +0,0 @@
-// Copyright 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:flutter/animation.dart';
-
-import 'framework.dart';
-
-abstract class StatusTransitionComponent extends StatefulComponent {
-  StatusTransitionComponent({
-    Key key,
-    this.performance
-  }) : super(key: key) {
-    assert(performance != null);
-  }
-
-  final PerformanceView performance;
-
-  Widget build(BuildContext context);
-
-  _StatusTransitionState createState() => new _StatusTransitionState();
-}
-
-class _StatusTransitionState extends State<StatusTransitionComponent> {
-  void initState() {
-    super.initState();
-    config.performance.addStatusListener(_performanceStatusChanged);
-  }
-
-  void didUpdateConfig(StatusTransitionComponent oldConfig) {
-    if (config.performance != oldConfig.performance) {
-      oldConfig.performance.removeStatusListener(_performanceStatusChanged);
-      config.performance.addStatusListener(_performanceStatusChanged);
-    }
-  }
-
-  void dispose() {
-    config.performance.removeStatusListener(_performanceStatusChanged);
-    super.dispose();
-  }
-
-  void _performanceStatusChanged(PerformanceStatus status) {
-    setState(() {
-      // The performance's state is our build state, and it changed already.
-    });
-  }
-
-  Widget build(BuildContext context) {
-    return config.build(context);
-  }
-}
diff --git a/sky/packages/sky/lib/src/widgets/transitions.dart b/sky/packages/sky/lib/src/widgets/transitions.dart
deleted file mode 100644
index 333f87d..0000000
--- a/sky/packages/sky/lib/src/widgets/transitions.dart
+++ /dev/null
@@ -1,271 +0,0 @@
-// Copyright 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 'dart:math' as math;
-
-import 'package:flutter/animation.dart';
-import 'package:flutter/rendering.dart';
-import 'package:vector_math/vector_math_64.dart' show Matrix4;
-
-import 'basic.dart';
-import 'framework.dart';
-
-export 'package:flutter/animation.dart' show AnimationDirection;
-export 'package:flutter/rendering.dart' show RelativeRect;
-
-abstract class TransitionComponent extends StatefulComponent {
-  TransitionComponent({
-    Key key,
-    this.performance
-  }) : super(key: key) {
-    assert(performance != null);
-  }
-
-  final PerformanceView performance;
-
-  Widget build(BuildContext context);
-
-  _TransitionState createState() => new _TransitionState();
-}
-
-class _TransitionState extends State<TransitionComponent> {
-  void initState() {
-    super.initState();
-    config.performance.addListener(_performanceChanged);
-  }
-
-  void didUpdateConfig(TransitionComponent oldConfig) {
-    if (config.performance != oldConfig.performance) {
-      oldConfig.performance.removeListener(_performanceChanged);
-      config.performance.addListener(_performanceChanged);
-    }
-  }
-
-  void dispose() {
-    config.performance.removeListener(_performanceChanged);
-    super.dispose();
-  }
-
-  void _performanceChanged() {
-    setState(() {
-      // The performance's state is our build state, and it changed already.
-    });
-  }
-
-  Widget build(BuildContext context) {
-    return config.build(context);
-  }
-}
-
-abstract class TransitionWithChild extends TransitionComponent {
-  TransitionWithChild({
-    Key key,
-    this.child,
-    PerformanceView performance
-  }) : super(key: key, performance: performance);
-
-  final Widget child;
-
-  Widget build(BuildContext context) => buildWithChild(context, child);
-
-  Widget buildWithChild(BuildContext context, Widget child);
-}
-
-class SlideTransition extends TransitionWithChild {
-  SlideTransition({
-    Key key,
-    this.position,
-    PerformanceView performance,
-    Widget child
-  }) : super(key: key,
-             performance: performance,
-             child: child);
-
-  final AnimatedValue<Point> position;
-
-  Widget buildWithChild(BuildContext context, Widget child) {
-    performance.updateVariable(position);
-    Matrix4 transform = new Matrix4.identity()
-      ..translate(position.value.x, position.value.y);
-    return new Transform(transform: transform, child: child);
-  }
-}
-
-class RotationTransition extends TransitionWithChild {
-  RotationTransition({
-    Key key,
-    this.turns,
-    PerformanceView performance,
-    Widget child
-  }) : super(key: key,
-             performance: performance,
-             child: child);
-
-  final AnimatedValue<double> turns;
-
-  Widget buildWithChild(BuildContext context, Widget child) {
-    performance.updateVariable(turns);
-    Matrix4 transform = new Matrix4.rotationZ(turns.value * math.PI * 2.0);
-    return new Transform(
-      transform: transform,
-      alignment: const FractionalOffset(0.5, 0.5),
-      child: child
-    );
-  }
-}
-
-class FadeTransition extends TransitionWithChild {
-  FadeTransition({
-    Key key,
-    this.opacity,
-    PerformanceView performance,
-    Widget child
-  }) : super(key: key,
-             performance: performance,
-             child: child);
-
-  final AnimatedValue<double> opacity;
-
-  Widget buildWithChild(BuildContext context, Widget child) {
-    performance.updateVariable(opacity);
-    return new Opacity(opacity: opacity.value, child: child);
-  }
-}
-
-class ColorTransition extends TransitionWithChild {
-  ColorTransition({
-    Key key,
-    this.color,
-    PerformanceView performance,
-    Widget child
-  }) : super(key: key,
-             performance: performance,
-             child: child);
-
-  final AnimatedColorValue color;
-
-  Widget buildWithChild(BuildContext context, Widget child) {
-    performance.updateVariable(color);
-    return new DecoratedBox(
-      decoration: new BoxDecoration(backgroundColor: color.value),
-      child: child
-    );
-  }
-}
-
-class SquashTransition extends TransitionWithChild {
-  SquashTransition({
-    Key key,
-    this.width,
-    this.height,
-    PerformanceView performance,
-    Widget child
-  }) : super(key: key,
-             performance: performance,
-             child: child);
-
-  final AnimatedValue<double> width;
-  final AnimatedValue<double> height;
-
-  Widget buildWithChild(BuildContext context, Widget child) {
-    if (width != null)
-      performance.updateVariable(width);
-    if (height != null)
-      performance.updateVariable(height);
-    return new SizedBox(width: width?.value, height: height?.value, child: child);
-  }
-}
-
-class AlignTransition extends TransitionWithChild {
-  AlignTransition({
-    Key key,
-    this.alignment,
-    this.widthFactor,
-    this.heightFactor,
-    PerformanceView performance,
-    Widget child
-  }) : super(key: key,
-             performance: performance,
-             child: child);
-
-  final AnimatedValue<FractionalOffset> alignment;
-  final AnimatedValue<double> widthFactor;
-  final AnimatedValue<double> heightFactor;
-
-  Widget buildWithChild(BuildContext context, Widget child) {
-    if (alignment != null)
-      performance.updateVariable(alignment);
-    if (widthFactor != null)
-      performance.updateVariable(widthFactor);
-    if (heightFactor != null)
-      performance.updateVariable(heightFactor);
-    return new Align(
-      alignment: alignment?.value,
-      widthFactor: widthFactor?.value,
-      heightFactor: heightFactor?.value,
-      child: child);
-  }
-}
-
-/// An animated variable containing a RelativeRectangle
-///
-/// This class specializes the interpolation of AnimatedValue<RelativeRect> to
-/// be appropriate for rectangles that are described in terms of offsets from
-/// other rectangles.
-class AnimatedRelativeRectValue extends AnimatedValue<RelativeRect> {
-  AnimatedRelativeRectValue(RelativeRect begin, { RelativeRect end, Curve curve, Curve reverseCurve })
-    : super(begin, end: end, curve: curve, reverseCurve: reverseCurve);
-
-  RelativeRect lerp(double t) => RelativeRect.lerp(begin, end, t);
-}
-
-/// Animated version of [Positioned].
-/// Only works if it's the child of a [Stack].
-class PositionedTransition extends TransitionWithChild {
-  PositionedTransition({
-    Key key,
-    this.rect,
-    PerformanceView performance,
-    Widget child
-  }) : super(key: key,
-             performance: performance,
-             child: child) {
-    assert(rect != null);
-  }
-
-  final AnimatedRelativeRectValue rect;
-
-  Widget buildWithChild(BuildContext context, Widget child) {
-    performance.updateVariable(rect);
-    return new Positioned(
-      top: rect.value.top,
-      right: rect.value.right,
-      bottom: rect.value.bottom,
-      left: rect.value.left,
-      child: child
-    );
-  }
-}
-
-
-typedef Widget BuilderFunction(BuildContext context);
-
-class BuilderTransition extends TransitionComponent {
-  BuilderTransition({
-    Key key,
-    this.variables,
-    this.builder,
-    PerformanceView performance
-  }) : super(key: key,
-             performance: performance);
-
-  final List<AnimatedValue> variables;
-  final BuilderFunction builder;
-
-  Widget build(BuildContext context) {
-    for (int i = 0; i < variables.length; ++i)
-      performance.updateVariable(variables[i]);
-    return builder(context);
-  }
-}
diff --git a/sky/packages/sky/lib/src/widgets/unique_component.dart b/sky/packages/sky/lib/src/widgets/unique_component.dart
deleted file mode 100644
index 73b2cc3..0000000
--- a/sky/packages/sky/lib/src/widgets/unique_component.dart
+++ /dev/null
@@ -1,18 +0,0 @@
-// Copyright 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 'framework.dart';
-
-abstract class UniqueComponent<T extends State> extends StatefulComponent {
-  UniqueComponent({ GlobalKey key }) : super(key: key) {
-    assert(key != null);
-  }
-
-  T createState();
-
-  T get currentState {
-    GlobalKey globalKey = key;
-    return globalKey.currentState;
-  }
-}
diff --git a/sky/packages/sky/lib/widgets.dart b/sky/packages/sky/lib/widgets.dart
deleted file mode 100644
index da9c320..0000000
--- a/sky/packages/sky/lib/widgets.dart
+++ /dev/null
@@ -1,39 +0,0 @@
-// Copyright 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.
-
-/// The Flutter widget framework.
-library widgets;
-
-export 'src/widgets/animated_container.dart';
-export 'src/widgets/basic.dart';
-export 'src/widgets/binding.dart';
-export 'src/widgets/dismissable.dart';
-export 'src/widgets/drag_target.dart';
-export 'src/widgets/editable_text.dart';
-export 'src/widgets/enter_exit_transition.dart';
-export 'src/widgets/event_recorder.dart';
-export 'src/widgets/focus.dart';
-export 'src/widgets/framework.dart';
-export 'src/widgets/gesture_detector.dart';
-export 'src/widgets/gridpaper.dart';
-export 'src/widgets/hero_controller.dart';
-export 'src/widgets/heroes.dart';
-export 'src/widgets/homogeneous_viewport.dart';
-export 'src/widgets/media_query.dart';
-export 'src/widgets/mimic.dart';
-export 'src/widgets/mixed_viewport.dart';
-export 'src/widgets/modal_barrier.dart';
-export 'src/widgets/navigator.dart';
-export 'src/widgets/overlay.dart';
-export 'src/widgets/page_storage.dart';
-export 'src/widgets/page.dart';
-export 'src/widgets/placeholder.dart';
-export 'src/widgets/routes.dart';
-export 'src/widgets/scrollable.dart';
-export 'src/widgets/statistics_overlay.dart';
-export 'src/widgets/status_transitions.dart';
-export 'src/widgets/transitions.dart';
-export 'src/widgets/unique_component.dart';
-
-export 'package:vector_math/vector_math_64.dart' show Matrix4;
diff --git a/sky/packages/sky/pubspec.yaml b/sky/packages/sky/pubspec.yaml
deleted file mode 100644
index e334c21..0000000
--- a/sky/packages/sky/pubspec.yaml
+++ /dev/null
@@ -1,21 +0,0 @@
-name: flutter
-version: 0.0.18
-author: Flutter Authors <flutter-dev@googlegroups.com>
-description: A framework for writing Flutter applications
-homepage: http://flutter.io
-dependencies:
-  cassowary: '>=0.1.7 <0.2.0'
-  intl: '>=0.12.4+2 <0.13.0'
-  material_design_icons: '>=0.0.3 <0.1.0'
-  newton: '>=0.1.4 <0.2.0'
-  sky_engine: 
-    '0.0.49'
-  sky_services: 
-    '0.0.50'
-  sky_tools: '>=0.0.37 <0.1.0'
-  vector_math: '>=1.4.3 <2.0.0'
-environment:
-  sdk: '>=1.12.0 <2.0.0'
-
-executables:
-  flutter:
diff --git a/sky/packages/updater/.gitignore b/sky/packages/updater/.gitignore
deleted file mode 100644
index b9a62f7..0000000
--- a/sky/packages/updater/.gitignore
+++ /dev/null
@@ -1,3 +0,0 @@
-.idea
-.pub/
-pubspec.lock
diff --git a/sky/packages/updater/BUILD.gn b/sky/packages/updater/BUILD.gn
deleted file mode 100644
index 65185a6..0000000
--- a/sky/packages/updater/BUILD.gn
+++ /dev/null
@@ -1,32 +0,0 @@
-# Copyright 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.
-
-action("updater") {
-  snapshot = "$target_gen_dir/updater_snapshot.bin"
-  main_dart = "lib/main.dart"
-
-  inputs = [
-    main_dart,
-  ]
-  outputs = [
-    snapshot,
-  ]
-
-  sky_snapshot_dir =
-      get_label_info("//sky/tools/sky_snapshot($host_toolchain)", "root_out_dir")
-  script = "//sky/tools/run_sky_snapshot.py"
-
-  args = [
-    "--compiler", rebase_path("$sky_snapshot_dir/sky_snapshot", root_build_dir),
-    "--package-root", rebase_path("packages", root_build_dir),
-    "--snapshot", rebase_path(snapshot, root_build_dir),
-    "--main", rebase_path(main_dart, root_build_dir),
-  ]
-
-  deps = [
-    "//sky/services/activity:interfaces",
-    "//sky/services/updater:interfaces",
-    "//sky/tools/sky_snapshot($host_toolchain)",
-  ]
-}
diff --git a/sky/packages/updater/lib/main.dart b/sky/packages/updater/lib/main.dart
deleted file mode 100644
index c363bad..0000000
--- a/sky/packages/updater/lib/main.dart
+++ /dev/null
@@ -1,128 +0,0 @@
-// Copyright 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 'dart:async';
-import 'dart:convert';
-import 'dart:math';
-import 'dart:io';
-import 'dart:typed_data';
-
-import 'package:mojo/core.dart';
-import 'package:flutter/services.dart';
-import 'package:flx/bundle.dart';
-import 'package:sky_services/updater/update_service.mojom.dart';
-import 'package:path/path.dart' as path;
-import 'package:yaml/yaml.dart' as yaml;
-
-import 'pipe_to_file.dart';
-import 'version.dart';
-
-const String kManifestFile = 'flutter.yaml';
-const String kBundleFile = 'app.flx';
-
-UpdateServiceProxy _initUpdateService() {
-  UpdateServiceProxy updateService = new UpdateServiceProxy.unbound();
-  shell.connectToService(null, updateService);
-  return updateService;
-}
-
-final UpdateServiceProxy _updateService = _initUpdateService();
-
-String cachedDataDir = null;
-Future<String> getDataDir() async {
-  if (cachedDataDir == null)
-    cachedDataDir = await getAppDataDir();
-  return cachedDataDir;
-}
-
-class UpdateFailure extends Error {
-  UpdateFailure(this._message);
-  String _message;
-  String toString() => _message;
-}
-
-class UpdateTask {
-  UpdateTask();
-
-  Future run() async {
-    try {
-      await _runImpl();
-    } on UpdateFailure catch (e) {
-      print('Update failed: $e');
-    } catch (e, stackTrace) {
-      print('Update failed: $e');
-      print('Stack: $stackTrace');
-    } finally {
-      _updateService.ptr.notifyUpdateCheckComplete();
-    }
-  }
-
-  Future _runImpl() async {
-    _dataDir = await getDataDir();
-
-    await _readLocalManifest();
-    yaml.YamlMap remoteManifest = await _fetchManifest();
-    if (!_shouldUpdate(remoteManifest)) {
-      print('Update skipped. No new version.');
-      return;
-    }
-    await _fetchBundle();
-    await _validateBundle();
-    await _replaceBundle();
-    print('Update success.');
-  }
-
-  Map _currentManifest;
-  String _dataDir;
-  String _tempPath;
-
-  Future _readLocalManifest() async {
-    String bundlePath = path.join(_dataDir, kBundleFile);
-    Bundle bundle = await Bundle.readHeader(bundlePath);
-    _currentManifest = bundle.manifest;
-  }
-
-  Future<yaml.YamlMap> _fetchManifest() async {
-    String manifestUrl = _currentManifest['update-url'] + '/' + kManifestFile;
-    String manifestData = await fetchString(manifestUrl);
-    return yaml.loadYaml(manifestData, sourceUrl: manifestUrl);
-  }
-
-  bool _shouldUpdate(yaml.YamlMap remoteManifest) {
-    Version currentVersion = new Version(_currentManifest['version']);
-    Version remoteVersion = new Version(remoteManifest['version']);
-    return (currentVersion < remoteVersion);
-  }
-
-  Future _fetchBundle() async {
-    // TODO(mpcomplete): Use the cache dir. We need an equivalent of mkstemp().
-    _tempPath = path.join(_dataDir, 'tmp.skyx');
-    String bundleUrl = _currentManifest['update-url'] + '/' + kBundleFile;
-    UrlResponse response = await fetchUrl(bundleUrl);
-    MojoResult result = await PipeToFile.copyToFile(response.body, _tempPath);
-    if (!result.isOk)
-      throw new UpdateFailure('Failure fetching new package: ${response.statusLine}');
-  }
-
-  Future _validateBundle() async {
-    Bundle bundle = await Bundle.readHeader(_tempPath);
-
-    if (bundle == null)
-      throw new UpdateFailure('Remote package not a valid FLX file.');
-    if (bundle.manifest['key'] != _currentManifest['key'])
-      throw new UpdateFailure('Remote package key does not match.');
-    if (!await bundle.verifyContent())
-      throw new UpdateFailure('Invalid package signature or hash. This package has been tampered with.');
-  }
-
-  Future _replaceBundle() async {
-    String bundlePath = path.join(_dataDir, kBundleFile);
-    await new File(_tempPath).rename(bundlePath);
-  }
-}
-
-void main() {
-  UpdateTask task = new UpdateTask();
-  task.run();
-}
diff --git a/sky/packages/updater/lib/pipe_to_file.dart b/sky/packages/updater/lib/pipe_to_file.dart
deleted file mode 100644
index 511a7a3..0000000
--- a/sky/packages/updater/lib/pipe_to_file.dart
+++ /dev/null
@@ -1,64 +0,0 @@
-// Copyright 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 'dart:async';
-import 'dart:io';
-import 'dart:typed_data';
-
-import 'package:mojo/core.dart';
-
-// Helper class to drain the contents of a mojo data pipe to a file.
-class PipeToFile {
-  MojoDataPipeConsumer _consumer;
-  MojoEventStream _eventStream;
-  IOSink _outputStream;
-
-  PipeToFile(this._consumer, String outputPath) {
-    _eventStream = new MojoEventStream(_consumer.handle);
-    _outputStream = new File(outputPath).openWrite();
-  }
-
-  Future<MojoResult> _doRead() async {
-    ByteData thisRead = _consumer.beginRead();
-    if (thisRead == null) {
-      throw 'Data pipe beginRead failed: ${_consumer.status}';
-    }
-    // TODO(mpcomplete): Should I worry about the _eventStream listen callback
-    // being invoked again before this completes?
-    await _outputStream.add(thisRead.buffer.asUint8List());
-    return _consumer.endRead(thisRead.lengthInBytes);
-  }
-
-  Future drain() async {
-    Completer completer = new Completer();
-    // TODO(mpcomplete): Is it legit to pass an async callback to listen?
-    _eventStream.listen((List<int> event) async {
-      MojoHandleSignals mojoSignals = new MojoHandleSignals(event[1]);
-      if (mojoSignals.isReadable) {
-        MojoResult result = await _doRead();
-        if (!result.isOk) {
-          _eventStream.close();
-          _eventStream = null;
-          _outputStream.close();
-          completer.complete(result);
-        } else {
-          _eventStream.enableReadEvents();
-        }
-      } else if (mojoSignals.isPeerClosed) {
-        _eventStream.close();
-        _eventStream = null;
-        _outputStream.close();
-        completer.complete(MojoResult.OK);
-      } else {
-        throw 'Unexpected handle event: $mojoSignals';
-      }
-    });
-    return completer.future;
-  }
-
-  static Future<MojoResult> copyToFile(MojoDataPipeConsumer consumer, String outputPath) {
-    PipeToFile drainer = new PipeToFile(consumer, outputPath);
-    return drainer.drain();
-  }
-}
diff --git a/sky/packages/updater/lib/version.dart b/sky/packages/updater/lib/version.dart
deleted file mode 100644
index 15c1ab7..0000000
--- a/sky/packages/updater/lib/version.dart
+++ /dev/null
@@ -1,32 +0,0 @@
-// Copyright 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 'dart:math';
-
-// This class represents a dot-separated version string. Used for comparing
-// versions.
-// Usage: assert(new Version('1.1.0') < new Version('1.2.1'));
-class Version {
-  Version(String versionStr) :
-    _parts = versionStr.split('.').map((String val) => int.parse(val)).toList();
-
-  List<int> _parts;
-
-  bool operator<(Version other) => _compare(other) < 0;
-  bool operator==(dynamic other) => other is Version && _compare(other) == 0;
-  bool operator>(Version other) => _compare(other) > 0;
-
-  int _compare(Version other) {
-    int length = min(_parts.length, other._parts.length);
-    for (int i = 0; i < length; ++i) {
-      if (_parts[i] < other._parts[i])
-        return -1;
-      if (_parts[i] > other._parts[i])
-        return 1;
-    }
-    return _parts.length - other._parts.length;  // results in 1.0 < 1.0.0
-  }
-
-  int get hashCode => _parts.fold(373, (int acc, int part) => 37*acc + part);
-}
diff --git a/sky/packages/updater/pubspec.yaml b/sky/packages/updater/pubspec.yaml
deleted file mode 100644
index b8a3bd6..0000000
--- a/sky/packages/updater/pubspec.yaml
+++ /dev/null
@@ -1,16 +0,0 @@
-name: updater
-author: Flutter Authors <flutter-dev@googlegroups.com>
-description: The autoupdater for flutter
-homepage: http://flutter.io
-dependencies:
-  flutter: '0.0.18'
-  yaml: ^2.1.3
-  path: ^1.3.0
-  flx: 0.0.1
-dependency_overrides:
-  flutter:
-    path: ../sky
-  flx:
-    path: ../flx
-environment:
-  sdk: '>=1.12.0 <2.0.0'
diff --git a/sky/packages/workbench/.gitignore b/sky/packages/workbench/.gitignore
deleted file mode 100644
index 47c1956..0000000
--- a/sky/packages/workbench/.gitignore
+++ /dev/null
@@ -1,3 +0,0 @@
-.pub
-packages
-pubspec.lock
diff --git a/sky/packages/workbench/README.md b/sky/packages/workbench/README.md
deleted file mode 100644
index 4c3f7e3..0000000
--- a/sky/packages/workbench/README.md
+++ /dev/null
@@ -1,7 +0,0 @@
-Workbench
-=========
-
-The workbench package is a synthetic package that lets us use `pub` to pull in
-some packages from `pub.dartlang.org` and some packages from within the source
-tree. The workbench package is intended to reflect a typical environment for
-developing a Sky application. 
diff --git a/sky/packages/workbench/pubspec.yaml b/sky/packages/workbench/pubspec.yaml
deleted file mode 100644
index 8e113ce..0000000
--- a/sky/packages/workbench/pubspec.yaml
+++ /dev/null
@@ -1,30 +0,0 @@
-name: workbench
-version: 0.0.1
-author: Flutter Authors <flutter-dev@googlegroups.com>
-description: A workspace to host pub packages
-homepage: https://github.com/flutter/engine/tree/master/sky/packages/workbench
-dependencies:
-  flutter: 
-    '0.0.16'
-  sky_tools: any
-  cipher: any
-  asn1lib: any
-  flutter_rendering_examples: any
-  flutter_sprites: 
-    '0.0.13'
-  playfair: any
-  flx: 
-    '0.0.5'
-dependency_overrides:
-  material_design_icons:
-    path: ../material_design_icons
-  flutter:
-    path: ../sky
-  flutter_rendering_examples:
-    path: ../../../examples/rendering
-  flutter_sprites:
-    path: ../../../skysprites
-  flx:
-    path: ../flx
-environment:
-  sdk: '>=1.8.0 <2.0.0'
diff --git a/sky/shell/android/update_service_android.cc b/sky/shell/android/update_service_android.cc
index 86f13c5..9b601dd 100644
--- a/sky/shell/android/update_service_android.cc
+++ b/sky/shell/android/update_service_android.cc
@@ -7,7 +7,6 @@
 #include "base/logging.h"
 #include "base/task_runner_util.h"
 #include "jni/UpdateService_jni.h"
-#include "sky/engine/bindings/updater_snapshot.h"
 #include "sky/engine/public/sky/sky_headless.h"
 #include "sky/shell/shell.h"
 #include "sky/shell/ui/internals.h"
@@ -47,8 +46,7 @@
 
 void UpdateTaskAndroid::RunDartOnUIThread() {
   headless_->Init("sky:updater");
-  headless_->RunFromSnapshotBuffer(kUpdaterSnapshotBuffer,
-                                   kUpdaterSnapshotBufferSize);
+  // TODO(abarth): Run updater from FLX.
 }
 
 void UpdateTaskAndroid::Destroy(JNIEnv* env, jobject jcaller) {
diff --git a/sky/tools/download_sky_shell.py b/sky/tools/download_sky_shell.py
deleted file mode 100755
index 328ae0d..0000000
--- a/sky/tools/download_sky_shell.py
+++ /dev/null
@@ -1,40 +0,0 @@
-#!/usr/bin/env python
-# Copyright 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 argparse
-import os
-import subprocess
-import sys
-
-def download(base_url, out_dir, name):
-    url = '%s/%s' % (base_url, name)
-    dst = os.path.join(out_dir, name)
-    print 'Downloading', url
-    subprocess.call([ 'curl', '-o', dst, url ])
-
-def main():
-    parser = argparse.ArgumentParser(description='Downloads sky_shell from Google storage')
-    parser.add_argument('revision_file')
-    parser.add_argument('out_dir')
-    args = parser.parse_args()
-
-    out_dir = args.out_dir
-    if not os.path.exists(out_dir):
-        os.makedirs(out_dir)
-
-    revision = None
-    with open(args.revision_file, 'r') as f:
-        revision = f.read()
-
-    base_url = 'https://storage.googleapis.com/mojo/sky/shell/linux-x64/%s' % revision
-    download(base_url, out_dir, 'sky_shell')
-    download(base_url, out_dir, 'icudtl.dat')
-    download(base_url, out_dir, 'sky_snapshot')
-
-    subprocess.call([ 'chmod', 'a+x', os.path.join(out_dir, 'sky_shell' )])
-    subprocess.call([ 'chmod', 'a+x', os.path.join(out_dir, 'sky_snapshot' )])
-
-if __name__ == '__main__':
-    sys.exit(main())
diff --git a/sky/tools/release_packages.py b/sky/tools/release_packages.py
deleted file mode 100755
index 32a5eb8..0000000
--- a/sky/tools/release_packages.py
+++ /dev/null
@@ -1,27 +0,0 @@
-#!/usr/bin/env python
-# Copyright 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.
-
-# See https://github.com/domokit/sky_engine/wiki/Release-process
-
-import os
-import subprocess
-import sys
-
-
-def main():
-    engine_root = os.path.abspath('.')
-    if not os.path.exists(os.path.join(engine_root, 'sky')):
-        print "Cannot find //sky. Is %s the Flutter engine repository?" % engine_root
-        return 1
-
-    pub_path = os.path.join(engine_root, 'third_party/dart-sdk/dart-sdk/bin/pub')
-
-    subprocess.check_call([pub_path, 'publish', '--force'], cwd=os.path.join(engine_root, 'sky/packages/sky'))
-    subprocess.check_call([pub_path, 'publish', '--force'], cwd=os.path.join(engine_root, 'sky/packages/flx'))
-    subprocess.check_call([pub_path, 'publish', '--force'], cwd=os.path.join(engine_root, 'skysprites'))
-
-
-if __name__ == '__main__':
-    sys.exit(main())
diff --git a/sky/tools/run_tests b/sky/tools/run_tests
deleted file mode 100755
index 2a8073d..0000000
--- a/sky/tools/run_tests
+++ /dev/null
@@ -1,52 +0,0 @@
-#!/usr/bin/env python
-# Copyright 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 os
-import sys
-import subprocess
-import argparse
-
-SKY_TOOLS_DIR = os.path.dirname(os.path.abspath(__file__))
-SKY_ROOT = os.path.dirname(SKY_TOOLS_DIR)
-SRC_ROOT = os.path.dirname(SKY_ROOT)
-
-DART_SDK = os.path.join(SRC_ROOT, 'third_party', 'dart-sdk', 'dart-sdk', 'bin')
-PUB = os.path.join(DART_SDK, 'pub')
-
-UNIT_DIR = os.path.join(SRC_ROOT, 'sky', 'unit')
-PACKAGES_DIR = os.path.join(UNIT_DIR, 'packages')
-TESTS_DIR = os.path.join(UNIT_DIR, 'test')
-
-def main():
-    parser = argparse.ArgumentParser(description='Runs Sky tests')
-    parser.add_argument('--config', default='Debug')
-    parser.add_argument('--debug', dest='config', action='store_const', const='Debug')
-    parser.add_argument('--release', dest='config', action='store_const', const='Release')
-    args, remaining = parser.parse_known_args()
-
-    build_dir = os.path.join(SRC_ROOT, 'out', args.config)
-
-    sky_shell = None
-    if sys.platform == 'linux2':
-        sky_shell = os.path.join(build_dir, 'sky_shell')
-    elif sys.platform == 'darwin':
-        sky_shell = os.path.join(build_dir, 'SkyShell.app', 'Contents', 'MacOS', 'SkyShell')
-
-    if not remaining:
-        for root, dirs, files in os.walk(TESTS_DIR):
-            remaining.extend(os.path.join(root, f)
-                             for f in files if f.endswith("_test.dart"))
-
-    env = os.environ.copy()
-    env['SKY_SHELL'] = sky_shell
-    if env['TERM'] == 'dumb':
-        remaining = [ '--no-color' ] + remaining
-
-    return subprocess.call([
-        PUB, 'run', '--checked', 'sky_tools:sky_test',
-    ] + remaining, cwd=UNIT_DIR, env=env)
-
-if __name__ == '__main__':
-  sys.exit(main())
diff --git a/sky/unit/.gitignore b/sky/unit/.gitignore
deleted file mode 100644
index 47c1956..0000000
--- a/sky/unit/.gitignore
+++ /dev/null
@@ -1,3 +0,0 @@
-.pub
-packages
-pubspec.lock
diff --git a/sky/unit/benchmark/README.md b/sky/unit/benchmark/README.md
deleted file mode 100644
index e112735..0000000
--- a/sky/unit/benchmark/README.md
+++ /dev/null
@@ -1,13 +0,0 @@
-Benchmarks
-==========
-This directory (and its sub-directories) contain benchmarks for Flutter.
-The reporting format for benchmarks is not standardized yet, so benchmarks
-here are typically run by hand. To run a particular benchmark, use a command
-similar to that used to run individual unit tests. For example:
-
-```
-sky/tools/run_tests --debug -r expanded benchmark/gestures/velocity_tracker_bench.dart
-```
-
-(The `-r expanded` flag prints one line per test, which can be more helpful
-than the default format when running individual tests.)
diff --git a/sky/unit/benchmark/gestures/velocity_tracker_bench.dart b/sky/unit/benchmark/gestures/velocity_tracker_bench.dart
deleted file mode 100644
index cf89561..0000000
--- a/sky/unit/benchmark/gestures/velocity_tracker_bench.dart
+++ /dev/null
@@ -1,64 +0,0 @@
-import 'dart:ui' as ui;
-
-import 'package:flutter/gestures.dart';
-import 'package:test/test.dart';
-import 'velocity_tracker_data.dart';
-
-const int kNumIters = 10000;
-const int kBatchSize = 1000;
-const int kBatchOffset = 50;
-const int kNumMarks = 130;
-
-List<PointerInputEvent> _eventFromMap(List<Map> intermediate) {
-  List<PointerInputEvent> events = new List<PointerInputEvent>();
-  for (Map entry in intermediate)
-    events.add(_eventFor(entry));
-  return events;
-}
-
-PointerInputEvent _eventFor(Map entry) {
-  PointerInputEvent result = new PointerInputEvent(
-    type: entry['type'],
-    timeStamp: entry['timeStamp'],
-    pointer: entry['pointer'],
-    x: entry['x'],
-    y: entry['y']
-  );
-  return result;
-}
-
-void main() {
-  List<PointerInputEvent> events = _eventFromMap(velocityEventData);
-
-  test('Dart velocity tracker performance', () {
-    VelocityTracker tracker = new VelocityTracker();
-    Stopwatch watch = new Stopwatch();
-    watch.start();
-    for (int i = 0; i < kNumIters; i++) {
-      for (PointerInputEvent event in events) {
-        if (event.type == 'pointerdown' || event.type == 'pointermove')
-          tracker.addPosition(event.timeStamp, event.x, event.y);
-        if (event.type == 'pointerup')
-          tracker.getVelocity();
-      }
-    }
-    watch.stop();
-    print("Dart tracker: " + watch.elapsed.toString());
-  });
-
-  test('Native velocity tracker performance', () {
-    ui.VelocityTracker tracker = new ui.VelocityTracker();
-    Stopwatch watch = new Stopwatch();
-    watch.start();
-    for (int i = 0; i < kNumIters; i++) {
-      for (PointerInputEvent event in events) {
-        if (event.type == 'pointerdown' || event.type == 'pointermove')
-          tracker.addPosition((event.timeStamp*1000.0).toInt(), event.x, event.y);
-        if (event.type == 'pointerup')
-          tracker.getVelocity();
-      }
-    }
-    watch.stop();
-    print("Native tracker: " + watch.elapsed.toString());
-  });
-}
diff --git a/sky/unit/benchmark/gestures/velocity_tracker_data.dart b/sky/unit/benchmark/gestures/velocity_tracker_data.dart
deleted file mode 100644
index baa6c14..0000000
--- a/sky/unit/benchmark/gestures/velocity_tracker_data.dart
+++ /dev/null
@@ -1,2144 +0,0 @@
-final List<Map> velocityEventData = [
-  {
-    "type":"pointerdown",
-    "timeStamp":216690896.0,
-    "pointer":1,
-    "x":270.0,
-    "y":538.2857055664062
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216690906.0,
-    "pointer":1,
-    "x":270.0,
-    "y":538.2857055664062
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216690951.0,
-    "pointer":1,
-    "x":270.0,
-    "y":530.8571166992188
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216690959.0,
-    "pointer":1,
-    "x":270.0,
-    "y":526.8571166992188
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216690967.0,
-    "pointer":1,
-    "x":270.0,
-    "y":521.4285888671875
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216690975.0,
-    "pointer":1,
-    "x":270.0,
-    "y":515.4285888671875
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216690983.0,
-    "pointer":1,
-    "x":270.0,
-    "y":506.8571472167969
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216690991.0,
-    "pointer":1,
-    "x":268.8571472167969,
-    "y":496.0
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216690998.0,
-    "pointer":1,
-    "x":267.4285583496094,
-    "y":483.1428527832031
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216691006.0,
-    "pointer":1,
-    "x":266.28570556640625,
-    "y":469.71429443359375
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216691014.0,
-    "pointer":1,
-    "x":265.4285583496094,
-    "y":456.8571472167969
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216691021.0,
-    "pointer":1,
-    "x":264.28570556640625,
-    "y":443.71429443359375
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216691029.0,
-    "pointer":1,
-    "x":264.0,
-    "y":431.71429443359375
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216691036.0,
-    "pointer":1,
-    "x":263.4285583496094,
-    "y":421.1428527832031
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216691044.0,
-    "pointer":1,
-    "x":263.4285583496094,
-    "y":412.5714416503906
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216691052.0,
-    "pointer":1,
-    "x":263.4285583496094,
-    "y":404.5714416503906
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216691060.0,
-    "pointer":1,
-    "x":263.4285583496094,
-    "y":396.5714416503906
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216691068.0,
-    "pointer":1,
-    "x":264.5714416503906,
-    "y":390.0
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216691075.0,
-    "pointer":1,
-    "x":265.1428527832031,
-    "y":384.8571472167969
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216691083.0,
-    "pointer":1,
-    "x":266.0,
-    "y":380.28570556640625
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216691091.0,
-    "pointer":1,
-    "x":266.5714416503906,
-    "y":376.28570556640625
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216691098.0,
-    "pointer":1,
-    "x":267.1428527832031,
-    "y":373.1428527832031
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216691106.0,
-    "pointer":1,
-    "x":267.71429443359375,
-    "y":370.28570556640625
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216691114.0,
-    "pointer":1,
-    "x":268.28570556640625,
-    "y":367.71429443359375
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216691121.0,
-    "pointer":1,
-    "x":268.5714416503906,
-    "y":366.0
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216691130.0,
-    "pointer":1,
-    "x":268.8571472167969,
-    "y":364.5714416503906
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216691137.0,
-    "pointer":1,
-    "x":269.1428527832031,
-    "y":363.71429443359375
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216691145.0,
-    "pointer":1,
-    "x":269.1428527832031,
-    "y":362.8571472167969
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216691153.0,
-    "pointer":1,
-    "x":269.4285583496094,
-    "y":362.8571472167969
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216691168.0,
-    "pointer":1,
-    "x":268.5714416503906,
-    "y":365.4285583496094
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216691176.0,
-    "pointer":1,
-    "x":267.1428527832031,
-    "y":370.28570556640625
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216691183.0,
-    "pointer":1,
-    "x":265.4285583496094,
-    "y":376.8571472167969
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216691191.0,
-    "pointer":1,
-    "x":263.1428527832031,
-    "y":385.71429443359375
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216691199.0,
-    "pointer":1,
-    "x":261.4285583496094,
-    "y":396.5714416503906
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216691207.0,
-    "pointer":1,
-    "x":259.71429443359375,
-    "y":408.5714416503906
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216691215.0,
-    "pointer":1,
-    "x":258.28570556640625,
-    "y":419.4285583496094
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216691222.0,
-    "pointer":1,
-    "x":257.4285583496094,
-    "y":428.5714416503906
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216691230.0,
-    "pointer":1,
-    "x":256.28570556640625,
-    "y":436.0
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216691238.0,
-    "pointer":1,
-    "x":255.7142791748047,
-    "y":442.0
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216691245.0,
-    "pointer":1,
-    "x":255.14285278320312,
-    "y":447.71429443359375
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216691253.0,
-    "pointer":1,
-    "x":254.85714721679688,
-    "y":453.1428527832031
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216691261.0,
-    "pointer":1,
-    "x":254.57142639160156,
-    "y":458.5714416503906
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216691268.0,
-    "pointer":1,
-    "x":254.2857208251953,
-    "y":463.71429443359375
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216691276.0,
-    "pointer":1,
-    "x":254.2857208251953,
-    "y":470.28570556640625
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216691284.0,
-    "pointer":1,
-    "x":254.2857208251953,
-    "y":477.71429443359375
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216691292.0,
-    "pointer":1,
-    "x":255.7142791748047,
-    "y":487.1428527832031
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216691300.0,
-    "pointer":1,
-    "x":256.8571472167969,
-    "y":498.5714416503906
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216691307.0,
-    "pointer":1,
-    "x":258.28570556640625,
-    "y":507.71429443359375
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216691315.0,
-    "pointer":1,
-    "x":259.4285583496094,
-    "y":516.0
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216691323.0,
-    "pointer":1,
-    "x":260.28570556640625,
-    "y":521.7142944335938
-  },
-  {
-    "type":"pointerup",
-    "timeStamp":216691338.0,
-    "pointer":1,
-    "x":260.28570556640625,
-    "y":521.7142944335938
-  },
-  {
-    "type":"pointerdown",
-    "timeStamp":216691573.0,
-    "pointer":2,
-    "x":266.0,
-    "y":327.4285583496094
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216691588.0,
-    "pointer":2,
-    "x":266.0,
-    "y":327.4285583496094
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216691626.0,
-    "pointer":2,
-    "x":261.1428527832031,
-    "y":337.1428527832031
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216691634.0,
-    "pointer":2,
-    "x":258.28570556640625,
-    "y":343.1428527832031
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216691642.0,
-    "pointer":2,
-    "x":254.57142639160156,
-    "y":354.0
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216691650.0,
-    "pointer":2,
-    "x":250.2857208251953,
-    "y":368.28570556640625
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216691657.0,
-    "pointer":2,
-    "x":247.42857360839844,
-    "y":382.8571472167969
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216691665.0,
-    "pointer":2,
-    "x":245.14285278320312,
-    "y":397.4285583496094
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216691673.0,
-    "pointer":2,
-    "x":243.14285278320312,
-    "y":411.71429443359375
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216691680.0,
-    "pointer":2,
-    "x":242.2857208251953,
-    "y":426.28570556640625
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216691688.0,
-    "pointer":2,
-    "x":241.7142791748047,
-    "y":440.5714416503906
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216691696.0,
-    "pointer":2,
-    "x":241.7142791748047,
-    "y":454.5714416503906
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216691703.0,
-    "pointer":2,
-    "x":242.57142639160156,
-    "y":467.71429443359375
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216691712.0,
-    "pointer":2,
-    "x":243.42857360839844,
-    "y":477.4285583496094
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216691720.0,
-    "pointer":2,
-    "x":244.85714721679688,
-    "y":485.71429443359375
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216691727.0,
-    "pointer":2,
-    "x":246.2857208251953,
-    "y":493.1428527832031
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216691735.0,
-    "pointer":2,
-    "x":248.0,
-    "y":499.71429443359375
-  },
-  {
-    "type":"pointerup",
-    "timeStamp":216691750.0,
-    "pointer":2,
-    "x":248.0,
-    "y":499.71429443359375
-  },
-  {
-    "type":"pointerdown",
-    "timeStamp":216692255.0,
-    "pointer":3,
-    "x":249.42857360839844,
-    "y":351.4285583496094
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216692270.0,
-    "pointer":3,
-    "x":249.42857360839844,
-    "y":351.4285583496094
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216692309.0,
-    "pointer":3,
-    "x":246.2857208251953,
-    "y":361.71429443359375
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216692317.0,
-    "pointer":3,
-    "x":244.0,
-    "y":368.5714416503906
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216692325.0,
-    "pointer":3,
-    "x":241.42857360839844,
-    "y":377.71429443359375
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216692333.0,
-    "pointer":3,
-    "x":237.7142791748047,
-    "y":391.71429443359375
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216692340.0,
-    "pointer":3,
-    "x":235.14285278320312,
-    "y":406.5714416503906
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216692348.0,
-    "pointer":3,
-    "x":232.57142639160156,
-    "y":421.4285583496094
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216692356.0,
-    "pointer":3,
-    "x":230.2857208251953,
-    "y":436.5714416503906
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216692363.0,
-    "pointer":3,
-    "x":228.2857208251953,
-    "y":451.71429443359375
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216692371.0,
-    "pointer":3,
-    "x":227.42857360839844,
-    "y":466.0
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216692378.0,
-    "pointer":3,
-    "x":226.2857208251953,
-    "y":479.71429443359375
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216692387.0,
-    "pointer":3,
-    "x":225.7142791748047,
-    "y":491.71429443359375
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216692395.0,
-    "pointer":3,
-    "x":225.14285278320312,
-    "y":501.71429443359375
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216692402.0,
-    "pointer":3,
-    "x":224.85714721679688,
-    "y":509.1428527832031
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216692410.0,
-    "pointer":3,
-    "x":224.57142639160156,
-    "y":514.8571166992188
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216692418.0,
-    "pointer":3,
-    "x":224.2857208251953,
-    "y":519.4285888671875
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216692425.0,
-    "pointer":3,
-    "x":224.0,
-    "y":523.4285888671875
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216692433.0,
-    "pointer":3,
-    "x":224.0,
-    "y":527.1428833007812
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216692441.0,
-    "pointer":3,
-    "x":224.0,
-    "y":530.5714111328125
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216692448.0,
-    "pointer":3,
-    "x":224.0,
-    "y":533.1428833007812
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216692456.0,
-    "pointer":3,
-    "x":224.0,
-    "y":535.4285888671875
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216692464.0,
-    "pointer":3,
-    "x":223.7142791748047,
-    "y":536.8571166992188
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216692472.0,
-    "pointer":3,
-    "x":223.7142791748047,
-    "y":538.2857055664062
-  },
-  {
-    "type":"pointerup",
-    "timeStamp":216692487.0,
-    "pointer":3,
-    "x":223.7142791748047,
-    "y":538.2857055664062
-  },
-  {
-    "type":"pointerdown",
-    "timeStamp":216692678.0,
-    "pointer":4,
-    "x":221.42857360839844,
-    "y":526.2857055664062
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216692701.0,
-    "pointer":4,
-    "x":220.57142639160156,
-    "y":514.8571166992188
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216692708.0,
-    "pointer":4,
-    "x":220.2857208251953,
-    "y":508.0
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216692716.0,
-    "pointer":4,
-    "x":220.2857208251953,
-    "y":498.0
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216692724.0,
-    "pointer":4,
-    "x":221.14285278320312,
-    "y":484.28570556640625
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216692732.0,
-    "pointer":4,
-    "x":221.7142791748047,
-    "y":469.4285583496094
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216692740.0,
-    "pointer":4,
-    "x":223.42857360839844,
-    "y":453.1428527832031
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216692748.0,
-    "pointer":4,
-    "x":225.7142791748047,
-    "y":436.28570556640625
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216692755.0,
-    "pointer":4,
-    "x":229.14285278320312,
-    "y":418.28570556640625
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216692763.0,
-    "pointer":4,
-    "x":232.85714721679688,
-    "y":400.28570556640625
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216692770.0,
-    "pointer":4,
-    "x":236.85714721679688,
-    "y":382.5714416503906
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216692778.0,
-    "pointer":4,
-    "x":241.14285278320312,
-    "y":366.0
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216692786.0,
-    "pointer":4,
-    "x":244.85714721679688,
-    "y":350.28570556640625
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216692793.0,
-    "pointer":4,
-    "x":249.14285278320312,
-    "y":335.4285583496094
-  },
-  {
-    "type":"pointerup",
-    "timeStamp":216692809.0,
-    "pointer":4,
-    "x":249.14285278320312,
-    "y":335.4285583496094
-  },
-  {
-    "type":"pointerdown",
-    "timeStamp":216693222.0,
-    "pointer":5,
-    "x":224.0,
-    "y":545.4285888671875
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216693245.0,
-    "pointer":5,
-    "x":224.0,
-    "y":545.4285888671875
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216693275.0,
-    "pointer":5,
-    "x":222.85714721679688,
-    "y":535.1428833007812
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216693284.0,
-    "pointer":5,
-    "x":222.85714721679688,
-    "y":528.8571166992188
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216693291.0,
-    "pointer":5,
-    "x":222.2857208251953,
-    "y":518.5714111328125
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216693299.0,
-    "pointer":5,
-    "x":222.0,
-    "y":503.4285583496094
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216693307.0,
-    "pointer":5,
-    "x":222.0,
-    "y":485.4285583496094
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216693314.0,
-    "pointer":5,
-    "x":221.7142791748047,
-    "y":464.0
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216693322.0,
-    "pointer":5,
-    "x":222.2857208251953,
-    "y":440.28570556640625
-  },
-  {
-    "type":"pointerup",
-    "timeStamp":216693337.0,
-    "pointer":5,
-    "x":222.2857208251953,
-    "y":440.28570556640625
-  },
-  {
-    "type":"pointerdown",
-    "timeStamp":216693985.0,
-    "pointer":6,
-    "x":208.0,
-    "y":544.0
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216694047.0,
-    "pointer":6,
-    "x":208.57142639160156,
-    "y":532.2857055664062
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216694054.0,
-    "pointer":6,
-    "x":208.85714721679688,
-    "y":525.7142944335938
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216694062.0,
-    "pointer":6,
-    "x":208.85714721679688,
-    "y":515.1428833007812
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216694070.0,
-    "pointer":6,
-    "x":208.0,
-    "y":501.4285583496094
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216694077.0,
-    "pointer":6,
-    "x":207.42857360839844,
-    "y":487.1428527832031
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216694085.0,
-    "pointer":6,
-    "x":206.57142639160156,
-    "y":472.8571472167969
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216694092.0,
-    "pointer":6,
-    "x":206.57142639160156,
-    "y":458.8571472167969
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216694100.0,
-    "pointer":6,
-    "x":206.57142639160156,
-    "y":446.0
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216694108.0,
-    "pointer":6,
-    "x":206.57142639160156,
-    "y":434.28570556640625
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216694116.0,
-    "pointer":6,
-    "x":207.14285278320312,
-    "y":423.71429443359375
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216694124.0,
-    "pointer":6,
-    "x":208.57142639160156,
-    "y":412.8571472167969
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216694131.0,
-    "pointer":6,
-    "x":209.7142791748047,
-    "y":402.28570556640625
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216694139.0,
-    "pointer":6,
-    "x":211.7142791748047,
-    "y":393.1428527832031
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216694147.0,
-    "pointer":6,
-    "x":213.42857360839844,
-    "y":385.1428527832031
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216694154.0,
-    "pointer":6,
-    "x":215.42857360839844,
-    "y":378.28570556640625
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216694162.0,
-    "pointer":6,
-    "x":217.42857360839844,
-    "y":371.71429443359375
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216694169.0,
-    "pointer":6,
-    "x":219.42857360839844,
-    "y":366.0
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216694177.0,
-    "pointer":6,
-    "x":221.42857360839844,
-    "y":360.8571472167969
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216694185.0,
-    "pointer":6,
-    "x":223.42857360839844,
-    "y":356.5714416503906
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216694193.0,
-    "pointer":6,
-    "x":225.14285278320312,
-    "y":352.28570556640625
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216694201.0,
-    "pointer":6,
-    "x":226.85714721679688,
-    "y":348.5714416503906
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216694209.0,
-    "pointer":6,
-    "x":228.2857208251953,
-    "y":346.0
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216694216.0,
-    "pointer":6,
-    "x":229.14285278320312,
-    "y":343.71429443359375
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216694224.0,
-    "pointer":6,
-    "x":230.0,
-    "y":342.0
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216694232.0,
-    "pointer":6,
-    "x":230.57142639160156,
-    "y":340.5714416503906
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216694239.0,
-    "pointer":6,
-    "x":230.85714721679688,
-    "y":339.71429443359375
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216694247.0,
-    "pointer":6,
-    "x":230.85714721679688,
-    "y":339.4285583496094
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216694262.0,
-    "pointer":6,
-    "x":230.2857208251953,
-    "y":342.0
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216694270.0,
-    "pointer":6,
-    "x":228.85714721679688,
-    "y":346.28570556640625
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216694278.0,
-    "pointer":6,
-    "x":227.14285278320312,
-    "y":352.5714416503906
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216694286.0,
-    "pointer":6,
-    "x":225.42857360839844,
-    "y":359.4285583496094
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216694294.0,
-    "pointer":6,
-    "x":223.7142791748047,
-    "y":367.71429443359375
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216694301.0,
-    "pointer":6,
-    "x":222.57142639160156,
-    "y":376.0
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216694309.0,
-    "pointer":6,
-    "x":221.42857360839844,
-    "y":384.28570556640625
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216694317.0,
-    "pointer":6,
-    "x":220.85714721679688,
-    "y":392.28570556640625
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216694324.0,
-    "pointer":6,
-    "x":220.0,
-    "y":400.5714416503906
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216694332.0,
-    "pointer":6,
-    "x":219.14285278320312,
-    "y":409.71429443359375
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216694339.0,
-    "pointer":6,
-    "x":218.85714721679688,
-    "y":419.1428527832031
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216694348.0,
-    "pointer":6,
-    "x":218.2857208251953,
-    "y":428.8571472167969
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216694356.0,
-    "pointer":6,
-    "x":218.2857208251953,
-    "y":438.8571472167969
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216694363.0,
-    "pointer":6,
-    "x":218.2857208251953,
-    "y":447.71429443359375
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216694371.0,
-    "pointer":6,
-    "x":218.2857208251953,
-    "y":455.71429443359375
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216694379.0,
-    "pointer":6,
-    "x":219.14285278320312,
-    "y":462.8571472167969
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216694386.0,
-    "pointer":6,
-    "x":220.0,
-    "y":469.4285583496094
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216694394.0,
-    "pointer":6,
-    "x":221.14285278320312,
-    "y":475.4285583496094
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216694401.0,
-    "pointer":6,
-    "x":222.0,
-    "y":480.5714416503906
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216694409.0,
-    "pointer":6,
-    "x":222.85714721679688,
-    "y":485.4285583496094
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216694417.0,
-    "pointer":6,
-    "x":224.0,
-    "y":489.71429443359375
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216694425.0,
-    "pointer":6,
-    "x":224.85714721679688,
-    "y":492.8571472167969
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216694433.0,
-    "pointer":6,
-    "x":225.42857360839844,
-    "y":495.4285583496094
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216694440.0,
-    "pointer":6,
-    "x":226.0,
-    "y":497.1428527832031
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216694448.0,
-    "pointer":6,
-    "x":226.2857208251953,
-    "y":498.28570556640625
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216694456.0,
-    "pointer":6,
-    "x":226.2857208251953,
-    "y":498.8571472167969
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216694471.0,
-    "pointer":6,
-    "x":226.2857208251953,
-    "y":498.28570556640625
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216694479.0,
-    "pointer":6,
-    "x":226.2857208251953,
-    "y":496.5714416503906
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216694486.0,
-    "pointer":6,
-    "x":226.2857208251953,
-    "y":493.71429443359375
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216694494.0,
-    "pointer":6,
-    "x":226.2857208251953,
-    "y":490.0
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216694502.0,
-    "pointer":6,
-    "x":226.2857208251953,
-    "y":486.0
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216694510.0,
-    "pointer":6,
-    "x":226.2857208251953,
-    "y":480.5714416503906
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216694518.0,
-    "pointer":6,
-    "x":226.2857208251953,
-    "y":475.71429443359375
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216694525.0,
-    "pointer":6,
-    "x":226.2857208251953,
-    "y":468.8571472167969
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216694533.0,
-    "pointer":6,
-    "x":226.2857208251953,
-    "y":461.4285583496094
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216694541.0,
-    "pointer":6,
-    "x":226.2857208251953,
-    "y":452.5714416503906
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216694548.0,
-    "pointer":6,
-    "x":226.57142639160156,
-    "y":442.28570556640625
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216694556.0,
-    "pointer":6,
-    "x":226.57142639160156,
-    "y":432.28570556640625
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216694564.0,
-    "pointer":6,
-    "x":226.85714721679688,
-    "y":423.4285583496094
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216694571.0,
-    "pointer":6,
-    "x":227.42857360839844,
-    "y":416.0
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216694580.0,
-    "pointer":6,
-    "x":227.7142791748047,
-    "y":410.0
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216694587.0,
-    "pointer":6,
-    "x":228.2857208251953,
-    "y":404.28570556640625
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216694595.0,
-    "pointer":6,
-    "x":228.85714721679688,
-    "y":399.71429443359375
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216694603.0,
-    "pointer":6,
-    "x":229.14285278320312,
-    "y":395.4285583496094
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216694610.0,
-    "pointer":6,
-    "x":229.42857360839844,
-    "y":392.28570556640625
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216694618.0,
-    "pointer":6,
-    "x":229.7142791748047,
-    "y":390.0
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216694625.0,
-    "pointer":6,
-    "x":229.7142791748047,
-    "y":388.0
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216694633.0,
-    "pointer":6,
-    "x":229.7142791748047,
-    "y":386.8571472167969
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216694641.0,
-    "pointer":6,
-    "x":229.7142791748047,
-    "y":386.28570556640625
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216694648.0,
-    "pointer":6,
-    "x":229.7142791748047,
-    "y":386.0
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216694657.0,
-    "pointer":6,
-    "x":228.85714721679688,
-    "y":386.0
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216694665.0,
-    "pointer":6,
-    "x":228.0,
-    "y":388.0
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216694672.0,
-    "pointer":6,
-    "x":226.0,
-    "y":392.5714416503906
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216694680.0,
-    "pointer":6,
-    "x":224.0,
-    "y":397.71429443359375
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216694688.0,
-    "pointer":6,
-    "x":222.0,
-    "y":404.28570556640625
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216694695.0,
-    "pointer":6,
-    "x":219.7142791748047,
-    "y":411.1428527832031
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216694703.0,
-    "pointer":6,
-    "x":218.2857208251953,
-    "y":418.0
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216694710.0,
-    "pointer":6,
-    "x":217.14285278320312,
-    "y":425.4285583496094
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216694718.0,
-    "pointer":6,
-    "x":215.7142791748047,
-    "y":433.4285583496094
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216694726.0,
-    "pointer":6,
-    "x":214.85714721679688,
-    "y":442.28570556640625
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216694734.0,
-    "pointer":6,
-    "x":214.0,
-    "y":454.0
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216694742.0,
-    "pointer":6,
-    "x":214.0,
-    "y":469.4285583496094
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216694749.0,
-    "pointer":6,
-    "x":215.42857360839844,
-    "y":485.4285583496094
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216694757.0,
-    "pointer":6,
-    "x":217.7142791748047,
-    "y":502.8571472167969
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216694765.0,
-    "pointer":6,
-    "x":221.14285278320312,
-    "y":521.4285888671875
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216694772.0,
-    "pointer":6,
-    "x":224.57142639160156,
-    "y":541.1428833007812
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216694780.0,
-    "pointer":6,
-    "x":229.14285278320312,
-    "y":561.1428833007812
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216694788.0,
-    "pointer":6,
-    "x":233.42857360839844,
-    "y":578.8571166992188
-  },
-  {
-    "type":"pointerup",
-    "timeStamp":216694802.0,
-    "pointer":6,
-    "x":233.42857360839844,
-    "y":578.8571166992188
-  },
-  {
-    "type":"pointerdown",
-    "timeStamp":216695344.0,
-    "pointer":7,
-    "x":253.42857360839844,
-    "y":310.5714416503906
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216695352.0,
-    "pointer":7,
-    "x":253.42857360839844,
-    "y":310.5714416503906
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216695359.0,
-    "pointer":7,
-    "x":252.85714721679688,
-    "y":318.0
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216695367.0,
-    "pointer":7,
-    "x":251.14285278320312,
-    "y":322.0
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216695375.0,
-    "pointer":7,
-    "x":248.85714721679688,
-    "y":327.1428527832031
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216695382.0,
-    "pointer":7,
-    "x":246.0,
-    "y":334.8571472167969
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216695390.0,
-    "pointer":7,
-    "x":242.57142639160156,
-    "y":344.5714416503906
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216695397.0,
-    "pointer":7,
-    "x":238.85714721679688,
-    "y":357.4285583496094
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216695406.0,
-    "pointer":7,
-    "x":235.7142791748047,
-    "y":371.71429443359375
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216695414.0,
-    "pointer":7,
-    "x":232.2857208251953,
-    "y":386.8571472167969
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216695421.0,
-    "pointer":7,
-    "x":229.42857360839844,
-    "y":402.0
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216695429.0,
-    "pointer":7,
-    "x":227.42857360839844,
-    "y":416.8571472167969
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216695437.0,
-    "pointer":7,
-    "x":226.2857208251953,
-    "y":431.4285583496094
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216695444.0,
-    "pointer":7,
-    "x":226.2857208251953,
-    "y":446.0
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216695452.0,
-    "pointer":7,
-    "x":227.7142791748047,
-    "y":460.28570556640625
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216695459.0,
-    "pointer":7,
-    "x":230.0,
-    "y":475.1428527832031
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216695467.0,
-    "pointer":7,
-    "x":232.2857208251953,
-    "y":489.71429443359375
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216695475.0,
-    "pointer":7,
-    "x":235.7142791748047,
-    "y":504.0
-  },
-  {
-    "type":"pointerup",
-    "timeStamp":216695490.0,
-    "pointer":7,
-    "x":235.7142791748047,
-    "y":504.0
-  },
-  {
-    "type":"pointerdown",
-    "timeStamp":216695885.0,
-    "pointer":8,
-    "x":238.85714721679688,
-    "y":524.0
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216695908.0,
-    "pointer":8,
-    "x":236.2857208251953,
-    "y":515.7142944335938
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216695916.0,
-    "pointer":8,
-    "x":234.85714721679688,
-    "y":509.1428527832031
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216695924.0,
-    "pointer":8,
-    "x":232.57142639160156,
-    "y":498.5714416503906
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216695931.0,
-    "pointer":8,
-    "x":230.57142639160156,
-    "y":483.71429443359375
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216695939.0,
-    "pointer":8,
-    "x":229.14285278320312,
-    "y":466.5714416503906
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216695947.0,
-    "pointer":8,
-    "x":229.14285278320312,
-    "y":446.5714416503906
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216695955.0,
-    "pointer":8,
-    "x":230.57142639160156,
-    "y":424.8571472167969
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216695963.0,
-    "pointer":8,
-    "x":232.57142639160156,
-    "y":402.28570556640625
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216695970.0,
-    "pointer":8,
-    "x":235.14285278320312,
-    "y":380.0
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216695978.0,
-    "pointer":8,
-    "x":238.57142639160156,
-    "y":359.4285583496094
-  },
-  {
-    "type":"pointerup",
-    "timeStamp":216695993.0,
-    "pointer":8,
-    "x":238.57142639160156,
-    "y":359.4285583496094
-  },
-  {
-    "type":"pointerdown",
-    "timeStamp":216696429.0,
-    "pointer":9,
-    "x":238.2857208251953,
-    "y":568.5714111328125
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216696459.0,
-    "pointer":9,
-    "x":234.0,
-    "y":560.0
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216696467.0,
-    "pointer":9,
-    "x":231.42857360839844,
-    "y":553.1428833007812
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216696475.0,
-    "pointer":9,
-    "x":228.2857208251953,
-    "y":543.1428833007812
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216696483.0,
-    "pointer":9,
-    "x":225.42857360839844,
-    "y":528.8571166992188
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216696491.0,
-    "pointer":9,
-    "x":223.14285278320312,
-    "y":512.2857055664062
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216696498.0,
-    "pointer":9,
-    "x":222.0,
-    "y":495.4285583496094
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216696506.0,
-    "pointer":9,
-    "x":221.7142791748047,
-    "y":477.4285583496094
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216696514.0,
-    "pointer":9,
-    "x":221.7142791748047,
-    "y":458.28570556640625
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216696521.0,
-    "pointer":9,
-    "x":223.14285278320312,
-    "y":438.0
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216696529.0,
-    "pointer":9,
-    "x":224.2857208251953,
-    "y":416.28570556640625
-  },
-  {
-    "type":"pointerup",
-    "timeStamp":216696544.0,
-    "pointer":9,
-    "x":224.2857208251953,
-    "y":416.28570556640625
-  },
-  {
-    "type":"pointerdown",
-    "timeStamp":216696974.0,
-    "pointer":10,
-    "x":218.57142639160156,
-    "y":530.5714111328125
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216697012.0,
-    "pointer":10,
-    "x":220.2857208251953,
-    "y":522.0
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216697020.0,
-    "pointer":10,
-    "x":221.14285278320312,
-    "y":517.7142944335938
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216697028.0,
-    "pointer":10,
-    "x":222.2857208251953,
-    "y":511.71429443359375
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216697036.0,
-    "pointer":10,
-    "x":224.0,
-    "y":504.28570556640625
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216697044.0,
-    "pointer":10,
-    "x":227.14285278320312,
-    "y":490.5714416503906
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216697052.0,
-    "pointer":10,
-    "x":229.42857360839844,
-    "y":474.0
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216697059.0,
-    "pointer":10,
-    "x":231.42857360839844,
-    "y":454.5714416503906
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216697067.0,
-    "pointer":10,
-    "x":233.7142791748047,
-    "y":431.1428527832031
-  },
-  {
-    "type":"pointerup",
-    "timeStamp":216697082.0,
-    "pointer":10,
-    "x":233.7142791748047,
-    "y":431.1428527832031
-  },
-  {
-    "type":"pointerdown",
-    "timeStamp":216697435.0,
-    "pointer":11,
-    "x":257.1428527832031,
-    "y":285.1428527832031
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216697465.0,
-    "pointer":11,
-    "x":251.7142791748047,
-    "y":296.8571472167969
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216697473.0,
-    "pointer":11,
-    "x":248.2857208251953,
-    "y":304.0
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216697481.0,
-    "pointer":11,
-    "x":244.57142639160156,
-    "y":314.8571472167969
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216697489.0,
-    "pointer":11,
-    "x":240.2857208251953,
-    "y":329.1428527832031
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216697497.0,
-    "pointer":11,
-    "x":236.85714721679688,
-    "y":345.1428527832031
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216697505.0,
-    "pointer":11,
-    "x":233.7142791748047,
-    "y":361.4285583496094
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216697512.0,
-    "pointer":11,
-    "x":231.14285278320312,
-    "y":378.28570556640625
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216697520.0,
-    "pointer":11,
-    "x":229.42857360839844,
-    "y":395.4285583496094
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216697528.0,
-    "pointer":11,
-    "x":229.42857360839844,
-    "y":412.8571472167969
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216697535.0,
-    "pointer":11,
-    "x":230.85714721679688,
-    "y":430.8571472167969
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216697543.0,
-    "pointer":11,
-    "x":233.42857360839844,
-    "y":449.71429443359375
-  },
-  {
-    "type":"pointerup",
-    "timeStamp":216697558.0,
-    "pointer":11,
-    "x":233.42857360839844,
-    "y":449.71429443359375
-  },
-  {
-    "type":"pointerdown",
-    "timeStamp":216697749.0,
-    "pointer":12,
-    "x":246.0,
-    "y":311.4285583496094
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216697780.0,
-    "pointer":12,
-    "x":244.57142639160156,
-    "y":318.28570556640625
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216697787.0,
-    "pointer":12,
-    "x":243.14285278320312,
-    "y":325.4285583496094
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216697795.0,
-    "pointer":12,
-    "x":241.42857360839844,
-    "y":336.0
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216697803.0,
-    "pointer":12,
-    "x":239.7142791748047,
-    "y":351.1428527832031
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216697811.0,
-    "pointer":12,
-    "x":238.2857208251953,
-    "y":368.5714416503906
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216697819.0,
-    "pointer":12,
-    "x":238.0,
-    "y":389.4285583496094
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216697826.0,
-    "pointer":12,
-    "x":239.14285278320312,
-    "y":412.0
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216697834.0,
-    "pointer":12,
-    "x":242.2857208251953,
-    "y":438.0
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216697842.0,
-    "pointer":12,
-    "x":247.42857360839844,
-    "y":466.8571472167969
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216697849.0,
-    "pointer":12,
-    "x":254.2857208251953,
-    "y":497.71429443359375
-  },
-  {
-    "type":"pointerup",
-    "timeStamp":216697864.0,
-    "pointer":12,
-    "x":254.2857208251953,
-    "y":497.71429443359375
-  },
-  {
-    "type":"pointerdown",
-    "timeStamp":216698321.0,
-    "pointer":13,
-    "x":250.0,
-    "y":306.0
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216698328.0,
-    "pointer":13,
-    "x":250.0,
-    "y":306.0
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216698344.0,
-    "pointer":13,
-    "x":249.14285278320312,
-    "y":314.0
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216698351.0,
-    "pointer":13,
-    "x":247.42857360839844,
-    "y":319.4285583496094
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216698359.0,
-    "pointer":13,
-    "x":245.14285278320312,
-    "y":326.8571472167969
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216698366.0,
-    "pointer":13,
-    "x":241.7142791748047,
-    "y":339.4285583496094
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216698374.0,
-    "pointer":13,
-    "x":238.57142639160156,
-    "y":355.71429443359375
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216698382.0,
-    "pointer":13,
-    "x":236.2857208251953,
-    "y":374.28570556640625
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216698390.0,
-    "pointer":13,
-    "x":235.14285278320312,
-    "y":396.5714416503906
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216698398.0,
-    "pointer":13,
-    "x":236.57142639160156,
-    "y":421.4285583496094
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216698406.0,
-    "pointer":13,
-    "x":241.14285278320312,
-    "y":451.4285583496094
-  },
-  {
-    "type":"pointerup",
-    "timeStamp":216698421.0,
-    "pointer":13,
-    "x":241.14285278320312,
-    "y":451.4285583496094
-  }
-];
diff --git a/sky/unit/pubspec.yaml b/sky/unit/pubspec.yaml
deleted file mode 100644
index 71e5c88..0000000
--- a/sky/unit/pubspec.yaml
+++ /dev/null
@@ -1,15 +0,0 @@
-name: sky_unit_tests
-dependencies:
-  flutter: 
-    '0.0.16'
-  sky_tools: any
-  test: any
-  quiver: any
-  flx: ^0.0.2
-dependency_overrides:
-  material_design_icons:
-    path: ../packages/material_design_icons
-  flutter:
-    path: ../packages/sky
-  flx:
-    path: ../packages/flx
diff --git a/sky/unit/test/animation/scheduler_test.dart b/sky/unit/test/animation/scheduler_test.dart
deleted file mode 100644
index dbfe1b5..0000000
--- a/sky/unit/test/animation/scheduler_test.dart
+++ /dev/null
@@ -1,42 +0,0 @@
-import 'package:flutter/animation.dart';
-import 'package:test/test.dart';
-
-void main() {
-  test("Can cancel queued callback", () {
-    int secondId;
-
-    bool firstCallbackRan = false;
-    bool secondCallbackRan = false;
-
-    void firstCallback(Duration timeStamp) {
-      expect(firstCallbackRan, isFalse);
-      expect(secondCallbackRan, isFalse);
-      expect(timeStamp.inMilliseconds, equals(16));
-      firstCallbackRan = true;
-      scheduler.cancelAnimationFrame(secondId);
-    }
-
-    void secondCallback(Duration timeStamp) {
-      expect(firstCallbackRan, isTrue);
-      expect(secondCallbackRan, isFalse);
-      expect(timeStamp.inMilliseconds, equals(16));
-      secondCallbackRan = true;
-    }
-
-    scheduler.requestAnimationFrame(firstCallback);
-    secondId = scheduler.requestAnimationFrame(secondCallback);
-
-    scheduler.beginFrame(const Duration(milliseconds: 16));
-
-    expect(firstCallbackRan, isTrue);
-    expect(secondCallbackRan, isFalse);
-
-    firstCallbackRan = false;
-    secondCallbackRan = false;
-
-    scheduler.beginFrame(const Duration(milliseconds: 32));
-
-    expect(firstCallbackRan, isFalse);
-    expect(secondCallbackRan, isFalse);
-  });
-}
diff --git a/sky/unit/test/engine/canvas_test_disabled.dart b/sky/unit/test/engine/canvas_test_disabled.dart
deleted file mode 100644
index d8fe050..0000000
--- a/sky/unit/test/engine/canvas_test_disabled.dart
+++ /dev/null
@@ -1,25 +0,0 @@
-import 'dart:ui' as ui;
-import 'dart:ui' show Rect, Color, Paint;
-
-import 'package:test/test.dart';
-import 'package:vector_math/vector_math_64.dart';
-
-void main() {
-
-  ui.PictureRecorder recorder = new ui.PictureRecorder();
-  ui.Canvas canvas = new ui.Canvas(recorder, new Rect.fromLTRB(0.0, 0.0, 100.0, 100.0));
-
-  test("matrix access should work", () {
-    // Matrix equality doesn't work!
-    // https://github.com/google/vector_math.dart/issues/147
-    expect(canvas.getTotalMatrix(), equals(new Matrix4.identity().storage));
-    Matrix4 matrix = new Matrix4.identity();
-    // Round-tripping through getTotalMatrix will lose the z value
-    // So only scale to 1x in the z direction.
-    matrix.scale(2.0, 2.0, 1.0);
-    canvas.setMatrix(matrix.storage);
-    canvas.drawPaint(new Paint()..color = const Color(0xFF00FF00));
-    expect(canvas.getTotalMatrix(), equals(matrix.storage));
-  });
-
-}
diff --git a/sky/unit/test/engine/color_test.dart b/sky/unit/test/engine/color_test.dart
deleted file mode 100644
index 2a5c33f..0000000
--- a/sky/unit/test/engine/color_test.dart
+++ /dev/null
@@ -1,40 +0,0 @@
-import 'dart:ui';
-
-import 'package:test/test.dart';
-
-void main() {
-  test("color accessors should work", () {
-    Color foo = new Color(0x12345678);
-    expect(foo.alpha, equals(0x12));
-    expect(foo.red, equals(0x34));
-    expect(foo.green, equals(0x56));
-    expect(foo.blue, equals(0x78));
-  });
-
-  test("paint set to black", () {
-    Color c = new Color(0x00000000);
-    Paint p = new Paint();
-    p.color = c;
-    expect(c.toString(), equals('Color(0x00000000)'));
-  });
-
-  test("color created with out of bounds value", () {
-    try {
-      Color c = new Color(0x100 << 24);
-      Paint p = new Paint();
-      p.color = c;
-    } catch (e) {
-      expect(e != null, equals(true));
-    }
-  });
-
-  test("color created with wildly out of bounds value", () {
-    try {
-      Color c = new Color(1 << 1000000);
-      Paint p = new Paint();
-      p.color = c;
-    } catch (e) {
-      expect(e != null, equals(true));
-    }
-  });
-}
diff --git a/sky/unit/test/engine/mock_events.dart b/sky/unit/test/engine/mock_events.dart
deleted file mode 100644
index ffb8bef..0000000
--- a/sky/unit/test/engine/mock_events.dart
+++ /dev/null
@@ -1,62 +0,0 @@
-import 'dart:ui' as ui;
-
-import 'package:flutter/gestures.dart';
-
-export 'dart:ui' show Point;
-
-class TestPointer {
-  TestPointer([ this.pointer = 1 ]);
-
-  int pointer;
-  bool isDown = false;
-  ui.Point location;
-
-  PointerInputEvent down([ui.Point newLocation = ui.Point.origin ]) {
-    assert(!isDown);
-    isDown = true;
-    location = newLocation;
-    return new PointerInputEvent(
-      type: 'pointerdown',
-      pointer: pointer,
-      x: location.x,
-      y: location.y
-    );
-  }
-
-  PointerInputEvent move([ui.Point newLocation = ui.Point.origin ]) {
-    assert(isDown);
-    ui.Offset delta = newLocation - location;
-    location = newLocation;
-    return new PointerInputEvent(
-      type: 'pointermove',
-      pointer: pointer,
-      x: newLocation.x,
-      y: newLocation.y,
-      dx: delta.dx,
-      dy: delta.dy
-    );
-  }
-
-  PointerInputEvent up() {
-    assert(isDown);
-    isDown = false;
-    return new PointerInputEvent(
-      type: 'pointerup',
-      pointer: pointer,
-      x: location.x,
-      y: location.y
-    );
-  }
-
-  PointerInputEvent cancel() {
-    assert(isDown);
-    isDown = false;
-    return new PointerInputEvent(
-      type: 'pointercancel',
-      pointer: pointer,
-      x: location.x,
-      y: location.y
-    );
-  }
-
-}
diff --git a/sky/unit/test/engine/paragraph_builder_test.dart b/sky/unit/test/engine/paragraph_builder_test.dart
deleted file mode 100644
index 7d88d40..0000000
--- a/sky/unit/test/engine/paragraph_builder_test.dart
+++ /dev/null
@@ -1,21 +0,0 @@
-import 'dart:ui';
-
-import 'package:test/test.dart';
-
-void main() {
-  test("Should be able to build and layout a paragraph", () {
-    ParagraphBuilder builder = new ParagraphBuilder();
-    builder.addText('Hello');
-    Paragraph paragraph = builder.build(new ParagraphStyle());
-    expect(paragraph, isNotNull);
-
-    paragraph.minWidth = 0.0;
-    paragraph.maxWidth = 800.0;
-    paragraph.minHeight = 0.0;
-    paragraph.maxHeight = 600.0;
-
-    paragraph.layout();
-    expect(paragraph.width, isNonZero);
-    expect(paragraph.height, isNonZero);
-  });
-}
diff --git a/sky/unit/test/engine/rect_test.dart b/sky/unit/test/engine/rect_test.dart
deleted file mode 100644
index 6f9ec1a..0000000
--- a/sky/unit/test/engine/rect_test.dart
+++ /dev/null
@@ -1,33 +0,0 @@
-import 'dart:ui';
-
-import 'package:test/test.dart';
-
-void main() {
-  test("rect accessors", () {
-    Rect r = new Rect.fromLTRB(1.0, 3.0, 5.0, 7.0);
-    expect(r.left, equals(1.0));
-    expect(r.top, equals(3.0));
-    expect(r.right, equals(5.0));
-    expect(r.bottom, equals(7.0));
-  });
-
-  test("rect created by width and height", () {
-    Rect r = new Rect.fromLTWH(1.0, 3.0, 5.0, 7.0);
-    expect(r.left, equals(1.0));
-    expect(r.top, equals(3.0));
-    expect(r.right, equals(6.0));
-    expect(r.bottom, equals(10.0));
-  });
-
-  test("rect intersection", () {
-    Rect r1 = new Rect.fromLTRB(0.0, 0.0, 100.0, 100.0);
-    Rect r2 = new Rect.fromLTRB(50.0, 50.0, 200.0, 200.0);
-    Rect r3 = r1.intersect(r2);
-    expect(r3.left, equals(50.0));
-    expect(r3.top, equals(50.0));
-    expect(r3.right, equals(100.0));
-    expect(r3.bottom, equals(100.0));
-    Rect r4 = r2.intersect(r1);
-    expect(r4, equals(r3));
-  });
-}
diff --git a/sky/unit/test/examples/sector_layout_test.dart b/sky/unit/test/examples/sector_layout_test.dart
deleted file mode 100644
index fd5a056..0000000
--- a/sky/unit/test/examples/sector_layout_test.dart
+++ /dev/null
@@ -1,10 +0,0 @@
-import 'package:test/test.dart';
-
-import '../rendering/rendering_tester.dart';
-import '../../../../examples/rendering/sector_layout.dart';
-
-void main() {
-  test('Sector layout can paint', () {
-    layout(buildSectorExample(), phase: EnginePhase.composite);
-  });
-}
diff --git a/sky/unit/test/flx/bundle_test.dart b/sky/unit/test/flx/bundle_test.dart
deleted file mode 100644
index 5521ddc..0000000
--- a/sky/unit/test/flx/bundle_test.dart
+++ /dev/null
@@ -1,71 +0,0 @@
-import 'dart:convert' hide BASE64;
-import 'dart:typed_data';
-import 'dart:io';
-
-import 'package:crypto/crypto.dart';
-import 'package:flx/signing.dart';
-import 'package:flx/bundle.dart';
-import 'package:path/path.dart' as path;
-import 'package:test/test.dart';
-
-main() async {
-  // The following constant was generated via the openssl shell commands:
-  // openssl ecparam -genkey -name prime256v1 -out privatekey.pem
-  // openssl ec -in privatekey.pem -outform DER | base64
-  const String kPrivateKeyBase64 = 'MHcCAQEEIG4Xt+MgsdP/o89kAHz7EVVLKkN+DUfpaBtZfMyFGbUgoAoGCCqGSM49AwEHoUQDQgAElPtbBVPPqKHYXYAgHaxB2hL6sXeFc99YLijTAuAPe2Nbhywan+v4k+nFm0TJJW/mkV+nH+fyBZ98t4UcFCqkOg==';
-  final List<int> kPrivateKeyDER = BASE64.decode(kPrivateKeyBase64);
-
-  // Test manifest.
-  final Map<String, dynamic> kManifest = <String, dynamic>{
-    'name': 'test app',
-    'version': '1.0.0'
-  };
-
-  // Simple test byte pattern.
-  final Uint8List kTestBytes = new Uint8List.fromList(<int>[1, 2, 3]);
-
-  // Create a temp dir and file for the bundle.
-  Directory tempDir = await Directory.systemTemp.createTempSync('bundle_test');
-  String bundlePath = path.join(tempDir.path, 'bundle.flx');
-
-  AsymmetricKeyPair keyPair = keyPairFromPrivateKeyBytes(kPrivateKeyDER);
-  Map<String, dynamic> manifest = JSON.decode(UTF8.decode(
-      serializeManifest(kManifest, keyPair.publicKey, kTestBytes)));
-
-  test('verifyContent works', () async {
-    Bundle bundle = new Bundle.fromContent(
-      path: bundlePath,
-      manifest: manifest,
-      contentBytes: kTestBytes,
-      keyPair: keyPair
-    );
-
-    bool verifies = await bundle.verifyContent();
-    expect(verifies, equals(true));
-  });
-
-  test('write/read works', () async {
-    Bundle bundle = new Bundle.fromContent(
-      path: bundlePath,
-      manifest: manifest,
-      contentBytes: kTestBytes,
-      keyPair: keyPair
-    );
-
-    bundle.writeSync();
-
-    Bundle diskBundle = await Bundle.readHeader(bundlePath);
-    expect(diskBundle != null, equals(true));
-    expect(diskBundle.manifestBytes, equals(bundle.manifestBytes));
-    expect(diskBundle.signatureBytes, equals(bundle.signatureBytes));
-    expect(diskBundle.manifest['key'], equals(bundle.manifest['key']));
-    expect(diskBundle.manifest['key'], equals(manifest['key']));
-
-    bool verifies = await diskBundle.verifyContent();
-    expect(verifies, equals(true));
-  });
-
-  test('cleanup', () async {
-    tempDir.deleteSync(recursive: true);
-  });
-}
diff --git a/sky/unit/test/flx/signing_test.dart b/sky/unit/test/flx/signing_test.dart
deleted file mode 100644
index d660bee..0000000
--- a/sky/unit/test/flx/signing_test.dart
+++ /dev/null
@@ -1,114 +0,0 @@
-import 'dart:async';
-import 'dart:convert' hide BASE64;
-import 'dart:typed_data';
-
-import 'package:bignum/bignum.dart';
-import 'package:cipher/cipher.dart' hide CipherParameters;
-import 'package:crypto/crypto.dart';
-import 'package:flx/signing.dart';
-import 'package:test/test.dart';
-
-main() async {
-  // The following constant was generated via the openssl shell commands:
-  // openssl ecparam -genkey -name prime256v1 -out privatekey.pem
-  // openssl ec -in privatekey.pem -outform DER | base64
-  const String kPrivateKeyBase64 = 'MHcCAQEEIG4Xt+MgsdP/o89kAHz7EVVLKkN+DUfpaBtZfMyFGbUgoAoGCCqGSM49AwEHoUQDQgAElPtbBVPPqKHYXYAgHaxB2hL6sXeFc99YLijTAuAPe2Nbhywan+v4k+nFm0TJJW/mkV+nH+fyBZ98t4UcFCqkOg==';
-  final List<int> kPrivateKeyDER = BASE64.decode(kPrivateKeyBase64);
-
-  // Unpacked values of the above private key.
-  const int kPrivateKeyD = 0x6e17b7e320b1d3ffa3cf64007cfb11554b2a437e0d47e9681b597ccc8519b520;
-  const int kPublicKeyQx = 0x94fb5b0553cfa8a1d85d80201dac41da12fab1778573df582e28d302e00f7b63;
-  const int kPublicKeyQy = 0x5b872c1a9febf893e9c59b44c9256fe6915fa71fe7f2059f7cb7851c142aa43a;
-
-  // Test manifest.
-  final Map<String, dynamic> kManifest = <String, dynamic>{
-    'name': 'test app',
-    'version': '1.0.0'
-  };
-
-  // Simple test byte pattern (flat and in chunked form) and its SHA-256 hash.
-  final Uint8List kTestBytes = new Uint8List.fromList(<int>[1, 2, 3]);
-  final List<Uint8List> kTestBytesList = <Uint8List>[
-    new Uint8List.fromList(<int>[1, 2]), new Uint8List.fromList(<int>[3])];
-  final int kTestHash = 0x039058c6f2c0cb492c533b0a4d14ef77cc0f78abccced5287d84a1a2011cfb81;
-
-  // Set up a key generator.
-  CipherParameters cipher = CipherParameters.get();
-  await cipher.seedRandom();
-  ECKeyGeneratorParameters ecParams = new ECKeyGeneratorParameters(cipher.domain);
-  ParametersWithRandom<ECKeyGeneratorParameters> keyGeneratorParams =
-    new ParametersWithRandom<ECKeyGeneratorParameters>(ecParams, cipher.random);
-  KeyGenerator keyGenerator = new KeyGenerator('EC');
-  keyGenerator.init(keyGeneratorParams);
-
-  test('can read openssl key pair', () {
-    AsymmetricKeyPair keyPair = keyPairFromPrivateKeyBytes(kPrivateKeyDER);
-    expect(keyPair != null, equals(true));
-    expect(keyPair.privateKey.d.intValue(), equals(kPrivateKeyD));
-    expect(keyPair.publicKey.Q.x.toBigInteger().intValue(), equals(kPublicKeyQx));
-    expect(keyPair.publicKey.Q.y.toBigInteger().intValue(), equals(kPublicKeyQy));
-  });
-
-  test('serializeManifest adds key and content-hash', () {
-    AsymmetricKeyPair keyPair = keyPairFromPrivateKeyBytes(kPrivateKeyDER);
-    Uint8List manifestBytes = serializeManifest(kManifest, keyPair.publicKey, kTestBytes);
-    Map<String, dynamic> decodedManifest = JSON.decode(UTF8.decode(manifestBytes));
-    String expectedKey = BASE64.encode(keyPair.publicKey.Q.getEncoded());
-    expect(decodedManifest != null, equals(true));
-    expect(decodedManifest['name'], equals(kManifest['name']));
-    expect(decodedManifest['version'], equals(kManifest['version']));
-    expect(decodedManifest['key'], equals(expectedKey));
-    expect(decodedManifest['content-hash'], equals(kTestHash));
-  });
-
-  test('signManifest and verifyManifestSignature work', () {
-    AsymmetricKeyPair keyPair = keyPairFromPrivateKeyBytes(kPrivateKeyDER);
-    Map<String, dynamic> manifest = JSON.decode(UTF8.decode(
-        serializeManifest(kManifest, keyPair.publicKey, kTestBytes)));
-    Uint8List signatureBytes = signManifest(kTestBytes, keyPair.privateKey);
-
-    bool verifies = verifyManifestSignature(manifest, kTestBytes, signatureBytes);
-    expect(verifies, equals(true));
-
-    // Ensure it fails with invalid signature or content.
-    Uint8List badBytes = new Uint8List.fromList(<int>[42]);
-    verifies = verifyManifestSignature(manifest, kTestBytes, badBytes);
-    expect(verifies, equals(false));
-    verifies = verifyManifestSignature(manifest, badBytes, signatureBytes);
-    expect(verifies, equals(false));
-  });
-
-  test('signing works with arbitrary key', () {
-    AsymmetricKeyPair keyPair = keyGenerator.generateKeyPair();
-    String failReason = 'offending private key: ${keyPair.privateKey.d}';
-    Map<String, dynamic> manifest = JSON.decode(UTF8.decode(
-        serializeManifest(kManifest, keyPair.publicKey, kTestBytes)));
-    Uint8List signatureBytes = signManifest(kTestBytes, keyPair.privateKey);
-
-    bool verifies = verifyManifestSignature(manifest, kTestBytes, signatureBytes);
-    expect(verifies, equals(true), reason: failReason);
-
-    // Ensure it fails with invalid signature or content.
-    Uint8List badBytes = new Uint8List.fromList(<int>[42]);
-    verifies = verifyManifestSignature(manifest, kTestBytes, badBytes);
-    expect(verifies, equals(false), reason: failReason);
-    verifies = verifyManifestSignature(manifest, badBytes, signatureBytes);
-    expect(verifies, equals(false), reason: failReason);
-  });
-
-  test('verifyContentHash works', () async {
-    Stream contentStream = new Stream.fromIterable(kTestBytesList);
-    bool verifies = await verifyContentHash(new BigInteger(kTestHash), contentStream);
-    expect(verifies, equals(true));
-
-    // Ensure it fails with invalid hash or content.
-    contentStream = new Stream.fromIterable(kTestBytesList);
-    verifies = await verifyContentHash(new BigInteger(0xdeadbeef), contentStream);
-    expect(verifies, equals(false));
-
-    Stream badContentStream =
-        new Stream.fromIterable([new Uint8List.fromList(<int>[42])]);
-    verifies = await verifyContentHash(new BigInteger(kTestHash), badContentStream);
-    expect(verifies, equals(false));
-  });
-}
diff --git a/sky/unit/test/gestures/arena_test.dart b/sky/unit/test/gestures/arena_test.dart
deleted file mode 100644
index a5b59f7..0000000
--- a/sky/unit/test/gestures/arena_test.dart
+++ /dev/null
@@ -1,163 +0,0 @@
-import 'package:flutter/gestures.dart';
-import 'package:test/test.dart';
-
-typedef void GestureArenaCallback(Object key);
-
-const int primaryKey = 4;
-
-class TestGestureArenaMember extends GestureArenaMember {
-  bool acceptRan = false;
-  void acceptGesture(Object key) {
-    expect(key, equals(primaryKey));
-    acceptRan = true;
-  }
-  bool rejectRan = false;
-  void rejectGesture(Object key) {
-    expect(key, equals(primaryKey));
-    rejectRan = true;
-  }
-}
-
-class GestureTester {
-  GestureArena arena = new GestureArena();
-  TestGestureArenaMember first = new TestGestureArenaMember();
-  TestGestureArenaMember second = new TestGestureArenaMember();
-
-  GestureArenaEntry firstEntry;
-  void addFirst() {
-    firstEntry = arena.add(primaryKey, first);
-  }
-
-  GestureArenaEntry secondEntry;
-  void addSecond() {
-    secondEntry = arena.add(primaryKey, second);
-  }
-
-  void expectNothing() {
-    expect(first.acceptRan, isFalse);
-    expect(first.rejectRan, isFalse);
-    expect(second.acceptRan, isFalse);
-    expect(second.rejectRan, isFalse);
-  }
-
-  void expectFirstWin() {
-    expect(first.acceptRan, isTrue);
-    expect(first.rejectRan, isFalse);
-    expect(second.acceptRan, isFalse);
-    expect(second.rejectRan, isTrue);
-  }
-
-  void expectSecondWin() {
-    expect(first.acceptRan, isFalse);
-    expect(first.rejectRan, isTrue);
-    expect(second.acceptRan, isTrue);
-    expect(second.rejectRan, isFalse);
-  }
-}
-
-void main() {
-  test('Should win by accepting', () {
-    GestureTester tester = new GestureTester();
-    tester.addFirst();
-    tester.addSecond();
-    tester.arena.close(primaryKey);
-    tester.expectNothing();
-    tester.firstEntry.resolve(GestureDisposition.accepted);
-    tester.expectFirstWin();
-  });
-
-  test('Should win by sweep', () {
-    GestureTester tester = new GestureTester();
-    tester.addFirst();
-    tester.addSecond();
-    tester.arena.close(primaryKey);
-    tester.expectNothing();
-    tester.arena.sweep(primaryKey);
-    tester.expectFirstWin();
-  });
-
-  test('Should win on release after hold sweep release', () {
-    GestureTester tester = new GestureTester();
-    tester.addFirst();
-    tester.addSecond();
-    tester.arena.close(primaryKey);
-    tester.expectNothing();
-    tester.arena.hold(primaryKey);
-    tester.expectNothing();
-    tester.arena.sweep(primaryKey);
-    tester.expectNothing();
-    tester.arena.release(primaryKey);
-    tester.expectFirstWin();
-  });
-
-  test('Should win on sweep after hold release sweep', () {
-    GestureTester tester = new GestureTester();
-    tester.addFirst();
-    tester.addSecond();
-    tester.arena.close(primaryKey);
-    tester.expectNothing();
-    tester.arena.hold(primaryKey);
-    tester.expectNothing();
-    tester.arena.release(primaryKey);
-    tester.expectNothing();
-    tester.arena.sweep(primaryKey);
-    tester.expectFirstWin();
-  });
-
-  test('Only first winner should win', () {
-    GestureTester tester = new GestureTester();
-    tester.addFirst();
-    tester.addSecond();
-    tester.arena.close(primaryKey);
-    tester.expectNothing();
-    tester.firstEntry.resolve(GestureDisposition.accepted);
-    tester.secondEntry.resolve(GestureDisposition.accepted);
-    tester.expectFirstWin();
-  });
-
-  test('Only first winner should win, regardless of order', () {
-    GestureTester tester = new GestureTester();
-    tester.addFirst();
-    tester.addSecond();
-    tester.arena.close(primaryKey);
-    tester.expectNothing();
-    tester.secondEntry.resolve(GestureDisposition.accepted);
-    tester.firstEntry.resolve(GestureDisposition.accepted);
-    tester.expectSecondWin();
-  });
-
-  test('Win before close is delayed to close', () {
-    GestureTester tester = new GestureTester();
-    tester.addFirst();
-    tester.addSecond();
-    tester.expectNothing();
-    tester.firstEntry.resolve(GestureDisposition.accepted);
-    tester.expectNothing();
-    tester.arena.close(primaryKey);
-    tester.expectFirstWin();
-  });
-
-  test('Win before close is delayed to close, and only first winner should win', () {
-    GestureTester tester = new GestureTester();
-    tester.addFirst();
-    tester.addSecond();
-    tester.expectNothing();
-    tester.firstEntry.resolve(GestureDisposition.accepted);
-    tester.secondEntry.resolve(GestureDisposition.accepted);
-    tester.expectNothing();
-    tester.arena.close(primaryKey);
-    tester.expectFirstWin();
-  });
-
-  test('Win before close is delayed to close, and only first winner should win, regardless of order', () {
-    GestureTester tester = new GestureTester();
-    tester.addFirst();
-    tester.addSecond();
-    tester.expectNothing();
-    tester.secondEntry.resolve(GestureDisposition.accepted);
-    tester.firstEntry.resolve(GestureDisposition.accepted);
-    tester.expectNothing();
-    tester.arena.close(primaryKey);
-    tester.expectSecondWin();
-  });
-}
diff --git a/sky/unit/test/gestures/double_tap_test.dart b/sky/unit/test/gestures/double_tap_test.dart
deleted file mode 100644
index ea8758b..0000000
--- a/sky/unit/test/gestures/double_tap_test.dart
+++ /dev/null
@@ -1,557 +0,0 @@
-import 'package:flutter/gestures.dart';
-import 'package:quiver/testing/async.dart';
-import 'package:test/test.dart';
-
-class TestGestureArenaMember extends GestureArenaMember {
-  void acceptGesture(Object key) {
-    accepted = true;
-  }
-  void rejectGesture(Object key) {
-    rejected = true;
-  }
-  bool accepted = false;
-  bool rejected = false;
-}
-
-void main() {
-
-  // Down/up pair 1: normal tap sequence
-  final PointerInputEvent down1 = new PointerInputEvent(
-    pointer: 1,
-    type: 'pointerdown',
-    x: 10.0,
-    y: 10.0
-  );
-
-  final PointerInputEvent up1 = new PointerInputEvent(
-    pointer: 1,
-    type: 'pointerup',
-    x: 11.0,
-    y: 9.0
-  );
-
-  // Down/up pair 2: normal tap sequence close to pair 1
-  final PointerInputEvent down2 = new PointerInputEvent(
-    pointer: 2,
-    type: 'pointerdown',
-    x: 12.0,
-    y: 12.0
-  );
-
-  final PointerInputEvent up2 = new PointerInputEvent(
-    pointer: 2,
-    type: 'pointerup',
-    x: 13.0,
-    y: 11.0
-  );
-
-  // Down/up pair 3: normal tap sequence far away from pair 1
-  final PointerInputEvent down3 = new PointerInputEvent(
-    pointer: 3,
-    type: 'pointerdown',
-    x: 130.0,
-    y: 130.0
-  );
-
-  final PointerInputEvent up3 = new PointerInputEvent(
-    pointer: 3,
-    type: 'pointerup',
-    x: 131.0,
-    y: 129.0
-  );
-
-  // Down/move/up sequence 4: intervening motion
-  final PointerInputEvent down4 = new PointerInputEvent(
-    pointer: 4,
-    type: 'pointerdown',
-    x: 10.0,
-    y: 10.0
-  );
-
-  final PointerInputEvent move4 = new PointerInputEvent(
-    pointer: 4,
-    type: 'pointermove',
-    x: 25.0,
-    y: 25.0
-  );
-
-  final PointerInputEvent up4 = new PointerInputEvent(
-    pointer: 4,
-    type: 'pointerup',
-    x: 25.0,
-    y: 25.0
-  );
-
-  // Down/up pair 5: normal tap sequence identical to pair 1 with different pointer
-  final PointerInputEvent down5 = new PointerInputEvent(
-    pointer: 5,
-    type: 'pointerdown',
-    x: 10.0,
-    y: 10.0
-  );
-
-  final PointerInputEvent up5 = new PointerInputEvent(
-    pointer: 5,
-    type: 'pointerup',
-    x: 11.0,
-    y: 9.0
-  );
-
-  test('Should recognize double tap', () {
-    PointerRouter router = new PointerRouter();
-    DoubleTapGestureRecognizer tap = new DoubleTapGestureRecognizer(router: router);
-
-    bool doubleTapRecognized = false;
-    tap.onDoubleTap = () {
-      doubleTapRecognized = true;
-    };
-
-    tap.addPointer(down1);
-    GestureArena.instance.close(1);
-    expect(doubleTapRecognized, isFalse);
-    router.route(down1);
-    expect(doubleTapRecognized, isFalse);
-
-    router.route(up1);
-    expect(doubleTapRecognized, isFalse);
-    GestureArena.instance.sweep(1);
-    expect(doubleTapRecognized, isFalse);
-
-    tap.addPointer(down2);
-    GestureArena.instance.close(2);
-    expect(doubleTapRecognized, isFalse);
-    router.route(down2);
-    expect(doubleTapRecognized, isFalse);
-
-    router.route(up2);
-    expect(doubleTapRecognized, isTrue);
-    GestureArena.instance.sweep(2);
-    expect(doubleTapRecognized, isTrue);
-
-    tap.dispose();
-  });
-
-  test('Inter-tap distance cancels double tap', () {
-    PointerRouter router = new PointerRouter();
-    DoubleTapGestureRecognizer tap = new DoubleTapGestureRecognizer(router: router);
-
-    bool doubleTapRecognized = false;
-    tap.onDoubleTap = () {
-      doubleTapRecognized = true;
-    };
-
-    tap.addPointer(down1);
-    GestureArena.instance.close(1);
-    expect(doubleTapRecognized, isFalse);
-    router.route(down1);
-    expect(doubleTapRecognized, isFalse);
-
-    router.route(up1);
-    expect(doubleTapRecognized, isFalse);
-    GestureArena.instance.sweep(1);
-    expect(doubleTapRecognized, isFalse);
-
-    tap.addPointer(down3);
-    GestureArena.instance.close(3);
-    expect(doubleTapRecognized, isFalse);
-    router.route(down3);
-    expect(doubleTapRecognized, isFalse);
-
-    router.route(up3);
-    expect(doubleTapRecognized, isFalse);
-    GestureArena.instance.sweep(3);
-    expect(doubleTapRecognized, isFalse);
-
-    tap.dispose();
-  });
-
-  test('Intra-tap distance cancels double tap', () {
-    PointerRouter router = new PointerRouter();
-    DoubleTapGestureRecognizer tap = new DoubleTapGestureRecognizer(router: router);
-
-    bool doubleTapRecognized = false;
-    tap.onDoubleTap = () {
-      doubleTapRecognized = true;
-    };
-
-    tap.addPointer(down4);
-    GestureArena.instance.close(4);
-    expect(doubleTapRecognized, isFalse);
-    router.route(down4);
-    expect(doubleTapRecognized, isFalse);
-
-    router.route(move4);
-    expect(doubleTapRecognized, isFalse);
-    router.route(up4);
-    expect(doubleTapRecognized, isFalse);
-    GestureArena.instance.sweep(4);
-    expect(doubleTapRecognized, isFalse);
-
-    tap.addPointer(down1);
-    GestureArena.instance.close(1);
-    expect(doubleTapRecognized, isFalse);
-    router.route(down2);
-    expect(doubleTapRecognized, isFalse);
-
-    router.route(up1);
-    expect(doubleTapRecognized, isFalse);
-    GestureArena.instance.sweep(1);
-    expect(doubleTapRecognized, isFalse);
-
-    tap.dispose();
-  });
-
-  test('Inter-tap delay cancels double tap', () {
-    PointerRouter router = new PointerRouter();
-    DoubleTapGestureRecognizer tap = new DoubleTapGestureRecognizer(router: router);
-
-    bool doubleTapRecognized = false;
-    tap.onDoubleTap = () {
-      doubleTapRecognized = true;
-    };
-
-    new FakeAsync().run((FakeAsync async) {
-      tap.addPointer(down1);
-      GestureArena.instance.close(1);
-      expect(doubleTapRecognized, isFalse);
-      router.route(down1);
-      expect(doubleTapRecognized, isFalse);
-
-      router.route(up1);
-      expect(doubleTapRecognized, isFalse);
-      GestureArena.instance.sweep(1);
-      expect(doubleTapRecognized, isFalse);
-
-      async.elapse(new Duration(milliseconds: 5000));
-      tap.addPointer(down2);
-      GestureArena.instance.close(2);
-      expect(doubleTapRecognized, isFalse);
-      router.route(down2);
-      expect(doubleTapRecognized, isFalse);
-
-      router.route(up2);
-      expect(doubleTapRecognized, isFalse);
-      GestureArena.instance.sweep(2);
-      expect(doubleTapRecognized, isFalse);
-    });
-
-    tap.dispose();
-  });
-
-  test('Inter-tap delay resets double tap, allowing third tap to be a double-tap', () {
-    PointerRouter router = new PointerRouter();
-    DoubleTapGestureRecognizer tap = new DoubleTapGestureRecognizer(router: router);
-
-    bool doubleTapRecognized = false;
-    tap.onDoubleTap = () {
-      doubleTapRecognized = true;
-    };
-
-    new FakeAsync().run((FakeAsync async) {
-      tap.addPointer(down1);
-      GestureArena.instance.close(1);
-      expect(doubleTapRecognized, isFalse);
-      router.route(down1);
-      expect(doubleTapRecognized, isFalse);
-
-      router.route(up1);
-      expect(doubleTapRecognized, isFalse);
-      GestureArena.instance.sweep(1);
-      expect(doubleTapRecognized, isFalse);
-
-      async.elapse(new Duration(milliseconds: 5000));
-      tap.addPointer(down2);
-      GestureArena.instance.close(2);
-      expect(doubleTapRecognized, isFalse);
-      router.route(down2);
-      expect(doubleTapRecognized, isFalse);
-
-      router.route(up2);
-      expect(doubleTapRecognized, isFalse);
-      GestureArena.instance.sweep(2);
-      expect(doubleTapRecognized, isFalse);
-
-      async.elapse(new Duration(milliseconds: 100));
-      tap.addPointer(down5);
-      GestureArena.instance.close(5);
-      expect(doubleTapRecognized, isFalse);
-      router.route(down5);
-      expect(doubleTapRecognized, isFalse);
-
-      router.route(up5);
-      expect(doubleTapRecognized, isTrue);
-      GestureArena.instance.sweep(5);
-      expect(doubleTapRecognized, isTrue);
-    });
-
-    tap.dispose();
-  });
-
-  test('Intra-tap delay does not cancel double tap', () {
-    PointerRouter router = new PointerRouter();
-    DoubleTapGestureRecognizer tap = new DoubleTapGestureRecognizer(router: router);
-
-    bool doubleTapRecognized = false;
-    tap.onDoubleTap = () {
-      doubleTapRecognized = true;
-    };
-
-    new FakeAsync().run((FakeAsync async) {
-      tap.addPointer(down1);
-      GestureArena.instance.close(1);
-      expect(doubleTapRecognized, isFalse);
-      router.route(down1);
-      expect(doubleTapRecognized, isFalse);
-
-      async.elapse(new Duration(milliseconds: 1000));
-      router.route(up1);
-      expect(doubleTapRecognized, isFalse);
-      GestureArena.instance.sweep(1);
-      expect(doubleTapRecognized, isFalse);
-
-      tap.addPointer(down2);
-      GestureArena.instance.close(2);
-      expect(doubleTapRecognized, isFalse);
-      router.route(down2);
-      expect(doubleTapRecognized, isFalse);
-
-      router.route(up2);
-      expect(doubleTapRecognized, isTrue);
-      GestureArena.instance.sweep(2);
-      expect(doubleTapRecognized, isTrue);
-    });
-
-    tap.dispose();
-  });
-
-  test('Should not recognize two overlapping taps', () {
-    PointerRouter router = new PointerRouter();
-    DoubleTapGestureRecognizer tap = new DoubleTapGestureRecognizer(router: router);
-
-    bool doubleTapRecognized = false;
-    tap.onDoubleTap = () {
-      doubleTapRecognized = true;
-    };
-
-    tap.addPointer(down1);
-    GestureArena.instance.close(1);
-    expect(doubleTapRecognized, isFalse);
-    router.route(down1);
-    expect(doubleTapRecognized, isFalse);
-
-    tap.addPointer(down2);
-    GestureArena.instance.close(2);
-    expect(doubleTapRecognized, isFalse);
-    router.route(down1);
-    expect(doubleTapRecognized, isFalse);
-
-    router.route(up1);
-    expect(doubleTapRecognized, isFalse);
-    GestureArena.instance.sweep(1);
-    expect(doubleTapRecognized, isFalse);
-
-    router.route(up2);
-    expect(doubleTapRecognized, isFalse);
-    GestureArena.instance.sweep(2);
-    expect(doubleTapRecognized, isFalse);
-
-    tap.dispose();
-  });
-
-  test('Should recognize one tap of group followed by second tap', () {
-    PointerRouter router = new PointerRouter();
-    DoubleTapGestureRecognizer tap = new DoubleTapGestureRecognizer(router: router);
-
-    bool doubleTapRecognized = false;
-    tap.onDoubleTap = () {
-      doubleTapRecognized = true;
-    };
-
-    tap.addPointer(down1);
-    GestureArena.instance.close(1);
-    expect(doubleTapRecognized, isFalse);
-    router.route(down1);
-    expect(doubleTapRecognized, isFalse);
-
-    tap.addPointer(down2);
-    GestureArena.instance.close(2);
-    expect(doubleTapRecognized, isFalse);
-    router.route(down1);
-    expect(doubleTapRecognized, isFalse);
-
-    router.route(up1);
-    expect(doubleTapRecognized, isFalse);
-    GestureArena.instance.sweep(1);
-    expect(doubleTapRecognized, isFalse);
-
-    router.route(up2);
-    expect(doubleTapRecognized, isFalse);
-    GestureArena.instance.sweep(2);
-    expect(doubleTapRecognized, isFalse);
-
-    tap.addPointer(down1);
-    GestureArena.instance.close(1);
-    expect(doubleTapRecognized, isFalse);
-    router.route(down1);
-    expect(doubleTapRecognized, isFalse);
-
-    router.route(up1);
-    expect(doubleTapRecognized, isTrue);
-    GestureArena.instance.sweep(1);
-    expect(doubleTapRecognized, isTrue);
-
-    tap.dispose();
-
-  });
-
-  test('Should cancel on arena reject during first tap', () {
-    PointerRouter router = new PointerRouter();
-    DoubleTapGestureRecognizer tap = new DoubleTapGestureRecognizer(router: router);
-
-    bool doubleTapRecognized = false;
-    tap.onDoubleTap = () {
-      doubleTapRecognized = true;
-    };
-
-    tap.addPointer(down1);
-    TestGestureArenaMember member = new TestGestureArenaMember();
-    GestureArenaEntry entry = GestureArena.instance.add(1, member);
-    GestureArena.instance.close(1);
-    expect(doubleTapRecognized, isFalse);
-    router.route(down1);
-    expect(doubleTapRecognized, isFalse);
-
-    router.route(up1);
-    expect(doubleTapRecognized, isFalse);
-    entry.resolve(GestureDisposition.accepted);
-    expect(member.accepted, isTrue);
-    expect(doubleTapRecognized, isFalse);
-    GestureArena.instance.sweep(1);
-    expect(doubleTapRecognized, isFalse);
-
-    tap.addPointer(down2);
-    GestureArena.instance.close(2);
-    expect(doubleTapRecognized, isFalse);
-    router.route(down2);
-    expect(doubleTapRecognized, isFalse);
-
-    router.route(up2);
-    expect(doubleTapRecognized, isFalse);
-    GestureArena.instance.sweep(2);
-    expect(doubleTapRecognized, isFalse);
-
-    tap.dispose();
-  });
-
-  test('Should cancel on arena reject between taps', () {
-    PointerRouter router = new PointerRouter();
-    DoubleTapGestureRecognizer tap = new DoubleTapGestureRecognizer(router: router);
-
-    bool doubleTapRecognized = false;
-    tap.onDoubleTap = () {
-      doubleTapRecognized = true;
-    };
-
-    tap.addPointer(down1);
-    TestGestureArenaMember member = new TestGestureArenaMember();
-    GestureArenaEntry entry = GestureArena.instance.add(1, member);
-    GestureArena.instance.close(1);
-    expect(doubleTapRecognized, isFalse);
-    router.route(down1);
-    expect(doubleTapRecognized, isFalse);
-
-    router.route(up1);
-    expect(doubleTapRecognized, isFalse);
-    GestureArena.instance.sweep(1);
-    expect(doubleTapRecognized, isFalse);
-
-    entry.resolve(GestureDisposition.accepted);
-    expect(member.accepted, isTrue);
-
-    tap.addPointer(down2);
-    GestureArena.instance.close(2);
-    expect(doubleTapRecognized, isFalse);
-    router.route(down2);
-    expect(doubleTapRecognized, isFalse);
-
-    router.route(up2);
-    expect(doubleTapRecognized, isFalse);
-    GestureArena.instance.sweep(2);
-    expect(doubleTapRecognized, isFalse);
-
-    tap.dispose();
-  });
-
-  test('Should cancel on arena reject during last tap', () {
-    PointerRouter router = new PointerRouter();
-    DoubleTapGestureRecognizer tap = new DoubleTapGestureRecognizer(router: router);
-
-    bool doubleTapRecognized = false;
-    tap.onDoubleTap = () {
-      doubleTapRecognized = true;
-    };
-
-    tap.addPointer(down1);
-    TestGestureArenaMember member = new TestGestureArenaMember();
-    GestureArenaEntry entry = GestureArena.instance.add(1, member);
-    GestureArena.instance.close(1);
-    expect(doubleTapRecognized, isFalse);
-    router.route(down1);
-    expect(doubleTapRecognized, isFalse);
-
-    router.route(up1);
-    expect(doubleTapRecognized, isFalse);
-    GestureArena.instance.sweep(1);
-    expect(doubleTapRecognized, isFalse);
-
-    tap.addPointer(down2);
-    GestureArena.instance.close(2);
-    expect(doubleTapRecognized, isFalse);
-    router.route(down2);
-    expect(doubleTapRecognized, isFalse);
-
-    entry.resolve(GestureDisposition.accepted);
-    expect(member.accepted, isTrue);
-
-    router.route(up2);
-    expect(doubleTapRecognized, isFalse);
-    GestureArena.instance.sweep(2);
-    expect(doubleTapRecognized, isFalse);
-
-    tap.dispose();
-  });
-
-  test('Passive gesture should trigger on double tap cancel', () {
-    PointerRouter router = new PointerRouter();
-    DoubleTapGestureRecognizer tap = new DoubleTapGestureRecognizer(router: router);
-
-    bool doubleTapRecognized = false;
-    tap.onDoubleTap = () {
-      doubleTapRecognized = true;
-    };
-
-    new FakeAsync().run((FakeAsync async) {
-      tap.addPointer(down1);
-      TestGestureArenaMember member = new TestGestureArenaMember();
-      GestureArena.instance.add(1, member);
-      GestureArena.instance.close(1);
-      expect(doubleTapRecognized, isFalse);
-      router.route(down1);
-      expect(doubleTapRecognized, isFalse);
-
-      router.route(up1);
-      expect(doubleTapRecognized, isFalse);
-      GestureArena.instance.sweep(1);
-      expect(doubleTapRecognized, isFalse);
-
-      expect(member.accepted, isFalse);
-
-      async.elapse(new Duration(milliseconds: 5000));
-
-      expect(member.accepted, isTrue);
-    });
-
-    tap.dispose();
-  });
-
-}
diff --git a/sky/unit/test/gestures/long_press_test.dart b/sky/unit/test/gestures/long_press_test.dart
deleted file mode 100644
index 1871112..0000000
--- a/sky/unit/test/gestures/long_press_test.dart
+++ /dev/null
@@ -1,105 +0,0 @@
-import 'package:quiver/testing/async.dart';
-import 'package:flutter/gestures.dart';
-import 'package:test/test.dart';
-
-final PointerInputEvent down = new PointerInputEvent(
-  pointer: 5,
-  type: 'pointerdown',
-  x: 10.0,
-  y: 10.0
-);
-
-final PointerInputEvent up = new PointerInputEvent(
-  pointer: 5,
-  type: 'pointerup',
-  x: 11.0,
-  y: 9.0
-);
-
-void main() {
-  test('Should recognize long press', () {
-    PointerRouter router = new PointerRouter();
-    LongPressGestureRecognizer longPress = new LongPressGestureRecognizer(router: router);
-
-    bool longPressRecognized = false;
-    longPress.onLongPress = () {
-      longPressRecognized = true;
-    };
-
-    new FakeAsync().run((FakeAsync async) {
-      longPress.addPointer(down);
-      GestureArena.instance.close(5);
-      expect(longPressRecognized, isFalse);
-      router.route(down);
-      expect(longPressRecognized, isFalse);
-      async.elapse(new Duration(milliseconds: 300));
-      expect(longPressRecognized, isFalse);
-      async.elapse(new Duration(milliseconds: 700));
-      expect(longPressRecognized, isTrue);
-    });
-
-    longPress.dispose();
-  });
-
-  test('Up cancels long press', () {
-    PointerRouter router = new PointerRouter();
-    LongPressGestureRecognizer longPress = new LongPressGestureRecognizer(router: router);
-
-    bool longPressRecognized = false;
-    longPress.onLongPress = () {
-      longPressRecognized = true;
-    };
-
-    new FakeAsync().run((FakeAsync async) {
-      longPress.addPointer(down);
-      GestureArena.instance.close(5);
-      expect(longPressRecognized, isFalse);
-      router.route(down);
-      expect(longPressRecognized, isFalse);
-      async.elapse(new Duration(milliseconds: 300));
-      expect(longPressRecognized, isFalse);
-      router.route(up);
-      expect(longPressRecognized, isFalse);
-      async.elapse(new Duration(seconds: 1));
-      expect(longPressRecognized, isFalse);
-    });
-
-    longPress.dispose();
-  });
-
-  test('Should recognize both tap down and long press', () {
-    PointerRouter router = new PointerRouter();
-    TapGestureRecognizer tap = new TapGestureRecognizer(router: router);
-    LongPressGestureRecognizer longPress = new LongPressGestureRecognizer(router: router);
-
-    bool tapDownRecognized = false;
-    tap.onTapDown = (_) {
-      tapDownRecognized = true;
-    };
-
-    bool longPressRecognized = false;
-    longPress.onLongPress = () {
-      longPressRecognized = true;
-    };
-
-    new FakeAsync().run((FakeAsync async) {
-      tap.addPointer(down);
-      longPress.addPointer(down);
-      GestureArena.instance.close(5);
-      expect(tapDownRecognized, isFalse);
-      expect(longPressRecognized, isFalse);
-      router.route(down);
-      expect(tapDownRecognized, isFalse);
-      expect(longPressRecognized, isFalse);
-      async.elapse(new Duration(milliseconds: 300));
-      expect(tapDownRecognized, isTrue);
-      expect(longPressRecognized, isFalse);
-      async.elapse(new Duration(milliseconds: 700));
-      expect(tapDownRecognized, isTrue);
-      expect(longPressRecognized, isTrue);
-    });
-
-    tap.dispose();
-    longPress.dispose();
-  });
-}
diff --git a/sky/unit/test/gestures/lsq_solver_test.dart b/sky/unit/test/gestures/lsq_solver_test.dart
deleted file mode 100644
index c322cf1..0000000
--- a/sky/unit/test/gestures/lsq_solver_test.dart
+++ /dev/null
@@ -1,69 +0,0 @@
-import 'package:flutter/gestures.dart';
-import 'package:test/test.dart';
-
-
-void main() {
-  approx(double value, double expectation) {
-    const double eps = 1e-6;
-    return (value - expectation).abs() < eps;
-  }
-
-  test('Least-squares fit: linear polynomial to line', () {
-    List<double> x = [0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0];
-    List<double> y = [1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0];
-    List<double> w = [1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0];
-
-    LeastSquaresSolver solver = new LeastSquaresSolver(x, y, w);
-    PolynomialFit fit = solver.solve(1);
-
-    expect(fit.coefficients.length, 2);
-    expect(approx(fit.coefficients[0], 1.0), isTrue);
-    expect(approx(fit.coefficients[1], 0.0), isTrue);
-    expect(approx(fit.confidence, 1.0), isTrue);
-  });
-
-  test('Least-squares fit: linear polynomial to sloped line', () {
-    List<double> x = [0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0];
-    List<double> y = [1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0];
-    List<double> w = [1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0];
-
-    LeastSquaresSolver solver = new LeastSquaresSolver(x, y, w);
-    PolynomialFit fit = solver.solve(1);
-
-    expect(fit.coefficients.length, 2);
-    expect(approx(fit.coefficients[0], 1.0), isTrue);
-    expect(approx(fit.coefficients[1], 1.0), isTrue);
-    expect(approx(fit.confidence, 1.0), isTrue);
-  });
-
-  test('Least-squares fit: quadratic polynomial to line', () {
-    List<double> x = [0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0];
-    List<double> y = [1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0];
-    List<double> w = [1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0];
-
-    LeastSquaresSolver solver = new LeastSquaresSolver(x, y, w);
-    PolynomialFit fit = solver.solve(2);
-
-    expect(fit.coefficients.length, 3);
-    expect(approx(fit.coefficients[0], 1.0), isTrue);
-    expect(approx(fit.coefficients[1], 0.0), isTrue);
-    expect(approx(fit.coefficients[2], 0.0), isTrue);
-    expect(approx(fit.confidence, 1.0), isTrue);
-  });
-
-  test('Least-squares fit: quadratic polynomial to sloped line', () {
-    List<double> x = [0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0];
-    List<double> y = [1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0];
-    List<double> w = [1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0];
-
-    LeastSquaresSolver solver = new LeastSquaresSolver(x, y, w);
-    PolynomialFit fit = solver.solve(2);
-
-    expect(fit.coefficients.length, 3);
-    expect(approx(fit.coefficients[0], 1.0), isTrue);
-    expect(approx(fit.coefficients[1], 1.0), isTrue);
-    expect(approx(fit.coefficients[2], 0.0), isTrue);
-    expect(approx(fit.confidence, 1.0), isTrue);
-  });
-
-}
diff --git a/sky/unit/test/gestures/pointer_router_test.dart b/sky/unit/test/gestures/pointer_router_test.dart
deleted file mode 100644
index ba3efb9..0000000
--- a/sky/unit/test/gestures/pointer_router_test.dart
+++ /dev/null
@@ -1,27 +0,0 @@
-import 'package:flutter/gestures.dart';
-import 'package:test/test.dart';
-
-import '../engine/mock_events.dart';
-
-void main() {
-  test('Should route pointers', () {
-    bool callbackRan = false;
-    void callback(PointerInputEvent event) {
-      callbackRan = true;
-    }
-
-    TestPointer pointer2 = new TestPointer(2);
-    TestPointer pointer3 = new TestPointer(3);
-
-    PointerRouter router = new PointerRouter();
-    router.addRoute(3, callback);
-    router.route(pointer2.down());
-    expect(callbackRan, isFalse);
-    router.route(pointer3.down());
-    expect(callbackRan, isTrue);
-    callbackRan = false;
-    router.removeRoute(3, callback);
-    router.route(pointer3.up());
-    expect(callbackRan, isFalse);
-  });
-}
diff --git a/sky/unit/test/gestures/scale_test.dart b/sky/unit/test/gestures/scale_test.dart
deleted file mode 100644
index 149d14b..0000000
--- a/sky/unit/test/gestures/scale_test.dart
+++ /dev/null
@@ -1,184 +0,0 @@
-import 'dart:ui' as ui;
-
-import 'package:flutter/gestures.dart';
-import 'package:test/test.dart';
-
-import '../engine/mock_events.dart';
-
-void main() {
-  test('Should recognize scale gestures', () {
-    PointerRouter router = new PointerRouter();
-    ScaleGestureRecognizer scale = new ScaleGestureRecognizer(router: router);
-    TapGestureRecognizer tap = new TapGestureRecognizer(router: router);
-
-    bool didStartScale = false;
-    ui.Point updatedFocalPoint;
-    scale.onStart = (ui.Point focalPoint) {
-      didStartScale = true;
-      updatedFocalPoint = focalPoint;
-    };
-
-    double updatedScale;
-    scale.onUpdate = (double scale, ui.Point focalPoint) {
-      updatedScale = scale;
-      updatedFocalPoint = focalPoint;
-    };
-
-    bool didEndScale = false;
-    scale.onEnd = () {
-      didEndScale = true;
-    };
-
-    bool didTap = false;
-    tap.onTap = () {
-      didTap = true;
-    };
-
-    TestPointer pointer1 = new TestPointer(1);
-
-    PointerInputEvent down = pointer1.down(new Point(10.0, 10.0));
-    scale.addPointer(down);
-    tap.addPointer(down);
-
-    GestureArena.instance.close(1);
-    expect(didStartScale, isFalse);
-    expect(updatedScale, isNull);
-    expect(updatedFocalPoint, isNull);
-    expect(didEndScale, isFalse);
-    expect(didTap, isFalse);
-
-    // One-finger panning
-    router.route(down);
-    expect(didStartScale, isFalse);
-    expect(updatedScale, isNull);
-    expect(updatedFocalPoint, isNull);
-    expect(didEndScale, isFalse);
-    expect(didTap, isFalse);
-
-    router.route(pointer1.move(new Point(20.0, 30.0)));
-    expect(didStartScale, isTrue);
-    didStartScale = false;
-    expect(updatedFocalPoint, new ui.Point(20.0, 30.0));
-    updatedFocalPoint = null;
-    expect(updatedScale, 1.0);
-    updatedScale = null;
-    expect(didEndScale, isFalse);
-    expect(didTap, isFalse);
-
-    // Two-finger scaling
-    TestPointer pointer2 = new TestPointer(2);
-    PointerInputEvent down2 = pointer2.down(new Point(10.0, 20.0));
-    scale.addPointer(down2);
-    tap.addPointer(down2);
-    GestureArena.instance.close(2);
-    router.route(down2);
-
-    expect(didEndScale, isTrue);
-    didEndScale = false;
-    expect(updatedScale, isNull);
-    expect(updatedFocalPoint, isNull);
-    expect(didStartScale, isFalse);
-
-    // Zoom in
-    router.route(pointer2.move(new Point(0.0, 10.0)));
-    expect(didStartScale, isTrue);
-    didStartScale = false;
-    expect(updatedFocalPoint, new ui.Point(10.0, 20.0));
-    updatedFocalPoint = null;
-    expect(updatedScale, 2.0);
-    updatedScale = null;
-    expect(didEndScale, isFalse);
-    expect(didTap, isFalse);
-
-    // Zoom out
-    router.route(pointer2.move(new Point(15.0, 25.0)));
-    expect(updatedFocalPoint, new ui.Point(17.5, 27.5));
-    updatedFocalPoint = null;
-    expect(updatedScale, 0.5);
-    updatedScale = null;
-    expect(didTap, isFalse);
-
-    // Three-finger scaling
-    TestPointer pointer3 = new TestPointer(3);
-    PointerInputEvent down3 = pointer3.down(new Point(25.0, 35.0));
-    scale.addPointer(down3);
-    tap.addPointer(down3);
-    GestureArena.instance.close(3);
-    router.route(down3);
-
-    expect(didEndScale, isTrue);
-    didEndScale = false;
-    expect(updatedScale, isNull);
-    expect(updatedFocalPoint, isNull);
-    expect(didStartScale, isFalse);
-
-    // Zoom in
-    router.route(pointer3.move(new Point(55.0, 65.0)));
-    expect(didStartScale, isTrue);
-    didStartScale = false;
-    expect(updatedFocalPoint, new ui.Point(30.0, 40.0));
-    updatedFocalPoint = null;
-    expect(updatedScale, 5.0);
-    updatedScale = null;
-    expect(didEndScale, isFalse);
-    expect(didTap, isFalse);
-
-    // Return to original positions but with different fingers
-    router.route(pointer1.move(new Point(25.0, 35.0)));
-    router.route(pointer2.move(new Point(20.0, 30.0)));
-    router.route(pointer3.move(new Point(15.0, 25.0)));
-    expect(didStartScale, isFalse);
-    expect(updatedFocalPoint, new ui.Point(20.0, 30.0));
-    updatedFocalPoint = null;
-    expect(updatedScale, 1.0);
-    updatedScale = null;
-    expect(didEndScale, isFalse);
-    expect(didTap, isFalse);
-
-    router.route(pointer1.up());
-    expect(didStartScale, isFalse);
-    expect(updatedFocalPoint, isNull);
-    expect(updatedScale, isNull);
-    expect(didEndScale, isTrue);
-    didEndScale = false;
-    expect(didTap, isFalse);
-
-    // Continue scaling with two fingers
-    router.route(pointer3.move(new Point(10.0, 20.0)));
-    expect(didStartScale, isTrue);
-    didStartScale = false;
-    expect(updatedFocalPoint, new ui.Point(15.0, 25.0));
-    updatedFocalPoint = null;
-    expect(updatedScale, 2.0);
-    updatedScale = null;
-
-    router.route(pointer2.up());
-    expect(didStartScale, isFalse);
-    expect(updatedFocalPoint, isNull);
-    expect(updatedScale, isNull);
-    expect(didEndScale, isTrue);
-    didEndScale = false;
-    expect(didTap, isFalse);
-
-    // Continue panning with one finger
-    router.route(pointer3.move(new Point(0.0, 0.0)));
-    expect(didStartScale, isTrue);
-    didStartScale = false;
-    expect(updatedFocalPoint, new ui.Point(0.0, 0.0));
-    updatedFocalPoint = null;
-    expect(updatedScale, 1.0);
-    updatedScale = null;
-
-    // We are done
-    router.route(pointer3.up());
-    expect(didStartScale, isFalse);
-    expect(updatedFocalPoint, isNull);
-    expect(updatedScale, isNull);
-    expect(didEndScale, isTrue);
-    didEndScale = false;
-    expect(didTap, isFalse);
-
-    scale.dispose();
-    tap.dispose();
-  });
-}
diff --git a/sky/unit/test/gestures/scroll_test.dart b/sky/unit/test/gestures/scroll_test.dart
deleted file mode 100644
index 9c1c049..0000000
--- a/sky/unit/test/gestures/scroll_test.dart
+++ /dev/null
@@ -1,75 +0,0 @@
-import 'dart:ui' as ui;
-
-import 'package:flutter/gestures.dart';
-import 'package:test/test.dart';
-
-import '../engine/mock_events.dart';
-
-void main() {
-  test('Should recognize pan', () {
-    PointerRouter router = new PointerRouter();
-    PanGestureRecognizer pan = new PanGestureRecognizer(router: router);
-    TapGestureRecognizer tap = new TapGestureRecognizer(router: router);
-
-    bool didStartPan = false;
-    pan.onStart = (_) {
-      didStartPan = true;
-    };
-
-    ui.Offset updatedScrollDelta;
-    pan.onUpdate = (ui.Offset offset) {
-      updatedScrollDelta = offset;
-    };
-
-    bool didEndPan = false;
-    pan.onEnd = (ui.Offset velocity) {
-      didEndPan = true;
-    };
-
-    bool didTap = false;
-    tap.onTap = () {
-      didTap = true;
-    };
-
-    TestPointer pointer = new TestPointer(5);
-    PointerInputEvent down = pointer.down(new Point(10.0, 10.0));
-    pan.addPointer(down);
-    tap.addPointer(down);
-    GestureArena.instance.close(5);
-    expect(didStartPan, isFalse);
-    expect(updatedScrollDelta, isNull);
-    expect(didEndPan, isFalse);
-    expect(didTap, isFalse);
-
-    router.route(down);
-    expect(didStartPan, isFalse);
-    expect(updatedScrollDelta, isNull);
-    expect(didEndPan, isFalse);
-    expect(didTap, isFalse);
-
-    router.route(pointer.move(new Point(20.0, 20.0)));
-    expect(didStartPan, isTrue);
-    didStartPan = false;
-    expect(updatedScrollDelta, new ui.Offset(10.0, 10.0));
-    updatedScrollDelta = null;
-    expect(didEndPan, isFalse);
-    expect(didTap, isFalse);
-
-    router.route(pointer.move(new Point(20.0, 25.0)));
-    expect(didStartPan, isFalse);
-    expect(updatedScrollDelta, new ui.Offset(0.0, 5.0));
-    updatedScrollDelta = null;
-    expect(didEndPan, isFalse);
-    expect(didTap, isFalse);
-
-    router.route(pointer.up());
-    expect(didStartPan, isFalse);
-    expect(updatedScrollDelta, isNull);
-    expect(didEndPan, isTrue);
-    didEndPan = false;
-    expect(didTap, isFalse);
-
-    pan.dispose();
-    tap.dispose();
-  });
-}
diff --git a/sky/unit/test/gestures/tap_test.dart b/sky/unit/test/gestures/tap_test.dart
deleted file mode 100644
index 4ddabff..0000000
--- a/sky/unit/test/gestures/tap_test.dart
+++ /dev/null
@@ -1,266 +0,0 @@
-import 'package:flutter/gestures.dart';
-import 'package:quiver/testing/async.dart';
-import 'package:test/test.dart';
-
-class TestGestureArenaMember extends GestureArenaMember {
-  void acceptGesture(Object key) {}
-  void rejectGesture(Object key) {}
-}
-
-void main() {
-
-  // Down/up pair 1: normal tap sequence
-  final PointerInputEvent down1 = new PointerInputEvent(
-    pointer: 1,
-    type: 'pointerdown',
-    x: 10.0,
-    y: 10.0
-  );
-
-  final PointerInputEvent up1 = new PointerInputEvent(
-    pointer: 1,
-    type: 'pointerup',
-    x: 11.0,
-    y: 9.0
-  );
-
-  // Down/up pair 2: normal tap sequence far away from pair 1
-  final PointerInputEvent down2 = new PointerInputEvent(
-    pointer: 2,
-    type: 'pointerdown',
-    x: 30.0,
-    y: 30.0
-  );
-
-  final PointerInputEvent up2 = new PointerInputEvent(
-    pointer: 2,
-    type: 'pointerup',
-    x: 31.0,
-    y: 29.0
-  );
-
-  // Down/move/up sequence 3: intervening motion
-  final PointerInputEvent down3 = new PointerInputEvent(
-    pointer: 3,
-    type: 'pointerdown',
-    x: 10.0,
-    y: 10.0
-  );
-
-  final PointerInputEvent move3 = new PointerInputEvent(
-    pointer: 3,
-    type: 'pointermove',
-    x: 25.0,
-    y: 25.0
-  );
-
-  final PointerInputEvent up3 = new PointerInputEvent(
-    pointer: 3,
-    type: 'pointerup',
-    x: 25.0,
-    y: 25.0
-  );
-
-  test('Should recognize tap', () {
-    PointerRouter router = new PointerRouter();
-    TapGestureRecognizer tap = new TapGestureRecognizer(router: router);
-
-    bool tapRecognized = false;
-    tap.onTap = () {
-      tapRecognized = true;
-    };
-
-    tap.addPointer(down1);
-    GestureArena.instance.close(1);
-    expect(tapRecognized, isFalse);
-    router.route(down1);
-    expect(tapRecognized, isFalse);
-
-    router.route(up1);
-    expect(tapRecognized, isTrue);
-    GestureArena.instance.sweep(1);
-    expect(tapRecognized, isTrue);
-
-    tap.dispose();
-  });
-
-  test('No duplicate tap events', () {
-    PointerRouter router = new PointerRouter();
-    TapGestureRecognizer tap = new TapGestureRecognizer(router: router);
-
-    int tapsRecognized = 0;
-    tap.onTap = () {
-      tapsRecognized++;
-    };
-
-    tap.addPointer(down1);
-    GestureArena.instance.close(1);
-    expect(tapsRecognized, 0);
-    router.route(down1);
-    expect(tapsRecognized, 0);
-
-    router.route(up1);
-    expect(tapsRecognized, 1);
-    GestureArena.instance.sweep(1);
-    expect(tapsRecognized, 1);
-
-    tap.addPointer(down1);
-    GestureArena.instance.close(1);
-    expect(tapsRecognized, 1);
-    router.route(down1);
-    expect(tapsRecognized, 1);
-
-    router.route(up1);
-    expect(tapsRecognized, 2);
-    GestureArena.instance.sweep(1);
-    expect(tapsRecognized, 2);
-
-    tap.dispose();
-  });
-
-  test('Should not recognize two overlapping taps', () {
-    PointerRouter router = new PointerRouter();
-    TapGestureRecognizer tap = new TapGestureRecognizer(router: router);
-
-    int tapsRecognized = 0;
-    tap.onTap = () {
-      tapsRecognized++;
-    };
-
-    tap.addPointer(down1);
-    GestureArena.instance.close(1);
-    expect(tapsRecognized, 0);
-    router.route(down1);
-    expect(tapsRecognized, 0);
-
-    tap.addPointer(down2);
-    GestureArena.instance.close(2);
-    expect(tapsRecognized, 0);
-    router.route(down1);
-    expect(tapsRecognized, 0);
-
-
-    router.route(up1);
-    expect(tapsRecognized, 1);
-    GestureArena.instance.sweep(1);
-    expect(tapsRecognized, 1);
-
-    router.route(up2);
-    expect(tapsRecognized, 1);
-    GestureArena.instance.sweep(2);
-    expect(tapsRecognized, 1);
-
-    tap.dispose();
-  });
-
-  test('Distance cancels tap', () {
-    PointerRouter router = new PointerRouter();
-    TapGestureRecognizer tap = new TapGestureRecognizer(router: router);
-
-    bool tapRecognized = false;
-    tap.onTap = () {
-      tapRecognized = true;
-    };
-
-    tap.addPointer(down3);
-    GestureArena.instance.close(3);
-    expect(tapRecognized, isFalse);
-    router.route(down3);
-    expect(tapRecognized, isFalse);
-
-    router.route(move3);
-    expect(tapRecognized, isFalse);
-    router.route(up3);
-    expect(tapRecognized, isFalse);
-    GestureArena.instance.sweep(3);
-    expect(tapRecognized, isFalse);
-
-    tap.dispose();
-  });
-
-  test('Timeout does not cancel tap', () {
-    PointerRouter router = new PointerRouter();
-    TapGestureRecognizer tap = new TapGestureRecognizer(router: router);
-
-    bool tapRecognized = false;
-    tap.onTap = () {
-      tapRecognized = true;
-    };
-
-    new FakeAsync().run((FakeAsync async) {
-      tap.addPointer(down1);
-      GestureArena.instance.close(1);
-      expect(tapRecognized, isFalse);
-      router.route(down1);
-      expect(tapRecognized, isFalse);
-
-      async.elapse(new Duration(milliseconds: 500));
-      expect(tapRecognized, isFalse);
-      router.route(up1);
-      expect(tapRecognized, isTrue);
-      GestureArena.instance.sweep(1);
-      expect(tapRecognized, isTrue);
-    });
-
-    tap.dispose();
-  });
-
-  test('Should yield to other arena members', () {
-    PointerRouter router = new PointerRouter();
-    TapGestureRecognizer tap = new TapGestureRecognizer(router: router);
-
-    bool tapRecognized = false;
-    tap.onTap = () {
-      tapRecognized = true;
-    };
-
-    tap.addPointer(down1);
-    TestGestureArenaMember member = new TestGestureArenaMember();
-    GestureArenaEntry entry = GestureArena.instance.add(1, member);
-    GestureArena.instance.hold(1);
-    GestureArena.instance.close(1);
-    expect(tapRecognized, isFalse);
-    router.route(down1);
-    expect(tapRecognized, isFalse);
-
-    router.route(up1);
-    expect(tapRecognized, isFalse);
-    GestureArena.instance.sweep(1);
-    expect(tapRecognized, isFalse);
-
-    entry.resolve(GestureDisposition.accepted);
-    expect(tapRecognized, isFalse);
-
-    tap.dispose();
-  });
-
-  test('Should trigger on release of held arena', () {
-    PointerRouter router = new PointerRouter();
-    TapGestureRecognizer tap = new TapGestureRecognizer(router: router);
-
-    bool tapRecognized = false;
-    tap.onTap = () {
-      tapRecognized = true;
-    };
-
-    tap.addPointer(down1);
-    TestGestureArenaMember member = new TestGestureArenaMember();
-    GestureArenaEntry entry = GestureArena.instance.add(1, member);
-    GestureArena.instance.hold(1);
-    GestureArena.instance.close(1);
-    expect(tapRecognized, isFalse);
-    router.route(down1);
-    expect(tapRecognized, isFalse);
-
-    router.route(up1);
-    expect(tapRecognized, isFalse);
-    GestureArena.instance.sweep(1);
-    expect(tapRecognized, isFalse);
-
-    entry.resolve(GestureDisposition.rejected);
-    expect(tapRecognized, isTrue);
-
-    tap.dispose();
-  });
-
-}
diff --git a/sky/unit/test/gestures/velocity_tracker_data.dart b/sky/unit/test/gestures/velocity_tracker_data.dart
deleted file mode 100644
index baa6c14..0000000
--- a/sky/unit/test/gestures/velocity_tracker_data.dart
+++ /dev/null
@@ -1,2144 +0,0 @@
-final List<Map> velocityEventData = [
-  {
-    "type":"pointerdown",
-    "timeStamp":216690896.0,
-    "pointer":1,
-    "x":270.0,
-    "y":538.2857055664062
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216690906.0,
-    "pointer":1,
-    "x":270.0,
-    "y":538.2857055664062
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216690951.0,
-    "pointer":1,
-    "x":270.0,
-    "y":530.8571166992188
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216690959.0,
-    "pointer":1,
-    "x":270.0,
-    "y":526.8571166992188
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216690967.0,
-    "pointer":1,
-    "x":270.0,
-    "y":521.4285888671875
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216690975.0,
-    "pointer":1,
-    "x":270.0,
-    "y":515.4285888671875
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216690983.0,
-    "pointer":1,
-    "x":270.0,
-    "y":506.8571472167969
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216690991.0,
-    "pointer":1,
-    "x":268.8571472167969,
-    "y":496.0
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216690998.0,
-    "pointer":1,
-    "x":267.4285583496094,
-    "y":483.1428527832031
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216691006.0,
-    "pointer":1,
-    "x":266.28570556640625,
-    "y":469.71429443359375
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216691014.0,
-    "pointer":1,
-    "x":265.4285583496094,
-    "y":456.8571472167969
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216691021.0,
-    "pointer":1,
-    "x":264.28570556640625,
-    "y":443.71429443359375
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216691029.0,
-    "pointer":1,
-    "x":264.0,
-    "y":431.71429443359375
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216691036.0,
-    "pointer":1,
-    "x":263.4285583496094,
-    "y":421.1428527832031
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216691044.0,
-    "pointer":1,
-    "x":263.4285583496094,
-    "y":412.5714416503906
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216691052.0,
-    "pointer":1,
-    "x":263.4285583496094,
-    "y":404.5714416503906
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216691060.0,
-    "pointer":1,
-    "x":263.4285583496094,
-    "y":396.5714416503906
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216691068.0,
-    "pointer":1,
-    "x":264.5714416503906,
-    "y":390.0
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216691075.0,
-    "pointer":1,
-    "x":265.1428527832031,
-    "y":384.8571472167969
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216691083.0,
-    "pointer":1,
-    "x":266.0,
-    "y":380.28570556640625
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216691091.0,
-    "pointer":1,
-    "x":266.5714416503906,
-    "y":376.28570556640625
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216691098.0,
-    "pointer":1,
-    "x":267.1428527832031,
-    "y":373.1428527832031
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216691106.0,
-    "pointer":1,
-    "x":267.71429443359375,
-    "y":370.28570556640625
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216691114.0,
-    "pointer":1,
-    "x":268.28570556640625,
-    "y":367.71429443359375
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216691121.0,
-    "pointer":1,
-    "x":268.5714416503906,
-    "y":366.0
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216691130.0,
-    "pointer":1,
-    "x":268.8571472167969,
-    "y":364.5714416503906
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216691137.0,
-    "pointer":1,
-    "x":269.1428527832031,
-    "y":363.71429443359375
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216691145.0,
-    "pointer":1,
-    "x":269.1428527832031,
-    "y":362.8571472167969
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216691153.0,
-    "pointer":1,
-    "x":269.4285583496094,
-    "y":362.8571472167969
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216691168.0,
-    "pointer":1,
-    "x":268.5714416503906,
-    "y":365.4285583496094
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216691176.0,
-    "pointer":1,
-    "x":267.1428527832031,
-    "y":370.28570556640625
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216691183.0,
-    "pointer":1,
-    "x":265.4285583496094,
-    "y":376.8571472167969
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216691191.0,
-    "pointer":1,
-    "x":263.1428527832031,
-    "y":385.71429443359375
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216691199.0,
-    "pointer":1,
-    "x":261.4285583496094,
-    "y":396.5714416503906
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216691207.0,
-    "pointer":1,
-    "x":259.71429443359375,
-    "y":408.5714416503906
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216691215.0,
-    "pointer":1,
-    "x":258.28570556640625,
-    "y":419.4285583496094
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216691222.0,
-    "pointer":1,
-    "x":257.4285583496094,
-    "y":428.5714416503906
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216691230.0,
-    "pointer":1,
-    "x":256.28570556640625,
-    "y":436.0
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216691238.0,
-    "pointer":1,
-    "x":255.7142791748047,
-    "y":442.0
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216691245.0,
-    "pointer":1,
-    "x":255.14285278320312,
-    "y":447.71429443359375
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216691253.0,
-    "pointer":1,
-    "x":254.85714721679688,
-    "y":453.1428527832031
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216691261.0,
-    "pointer":1,
-    "x":254.57142639160156,
-    "y":458.5714416503906
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216691268.0,
-    "pointer":1,
-    "x":254.2857208251953,
-    "y":463.71429443359375
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216691276.0,
-    "pointer":1,
-    "x":254.2857208251953,
-    "y":470.28570556640625
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216691284.0,
-    "pointer":1,
-    "x":254.2857208251953,
-    "y":477.71429443359375
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216691292.0,
-    "pointer":1,
-    "x":255.7142791748047,
-    "y":487.1428527832031
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216691300.0,
-    "pointer":1,
-    "x":256.8571472167969,
-    "y":498.5714416503906
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216691307.0,
-    "pointer":1,
-    "x":258.28570556640625,
-    "y":507.71429443359375
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216691315.0,
-    "pointer":1,
-    "x":259.4285583496094,
-    "y":516.0
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216691323.0,
-    "pointer":1,
-    "x":260.28570556640625,
-    "y":521.7142944335938
-  },
-  {
-    "type":"pointerup",
-    "timeStamp":216691338.0,
-    "pointer":1,
-    "x":260.28570556640625,
-    "y":521.7142944335938
-  },
-  {
-    "type":"pointerdown",
-    "timeStamp":216691573.0,
-    "pointer":2,
-    "x":266.0,
-    "y":327.4285583496094
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216691588.0,
-    "pointer":2,
-    "x":266.0,
-    "y":327.4285583496094
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216691626.0,
-    "pointer":2,
-    "x":261.1428527832031,
-    "y":337.1428527832031
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216691634.0,
-    "pointer":2,
-    "x":258.28570556640625,
-    "y":343.1428527832031
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216691642.0,
-    "pointer":2,
-    "x":254.57142639160156,
-    "y":354.0
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216691650.0,
-    "pointer":2,
-    "x":250.2857208251953,
-    "y":368.28570556640625
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216691657.0,
-    "pointer":2,
-    "x":247.42857360839844,
-    "y":382.8571472167969
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216691665.0,
-    "pointer":2,
-    "x":245.14285278320312,
-    "y":397.4285583496094
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216691673.0,
-    "pointer":2,
-    "x":243.14285278320312,
-    "y":411.71429443359375
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216691680.0,
-    "pointer":2,
-    "x":242.2857208251953,
-    "y":426.28570556640625
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216691688.0,
-    "pointer":2,
-    "x":241.7142791748047,
-    "y":440.5714416503906
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216691696.0,
-    "pointer":2,
-    "x":241.7142791748047,
-    "y":454.5714416503906
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216691703.0,
-    "pointer":2,
-    "x":242.57142639160156,
-    "y":467.71429443359375
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216691712.0,
-    "pointer":2,
-    "x":243.42857360839844,
-    "y":477.4285583496094
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216691720.0,
-    "pointer":2,
-    "x":244.85714721679688,
-    "y":485.71429443359375
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216691727.0,
-    "pointer":2,
-    "x":246.2857208251953,
-    "y":493.1428527832031
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216691735.0,
-    "pointer":2,
-    "x":248.0,
-    "y":499.71429443359375
-  },
-  {
-    "type":"pointerup",
-    "timeStamp":216691750.0,
-    "pointer":2,
-    "x":248.0,
-    "y":499.71429443359375
-  },
-  {
-    "type":"pointerdown",
-    "timeStamp":216692255.0,
-    "pointer":3,
-    "x":249.42857360839844,
-    "y":351.4285583496094
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216692270.0,
-    "pointer":3,
-    "x":249.42857360839844,
-    "y":351.4285583496094
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216692309.0,
-    "pointer":3,
-    "x":246.2857208251953,
-    "y":361.71429443359375
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216692317.0,
-    "pointer":3,
-    "x":244.0,
-    "y":368.5714416503906
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216692325.0,
-    "pointer":3,
-    "x":241.42857360839844,
-    "y":377.71429443359375
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216692333.0,
-    "pointer":3,
-    "x":237.7142791748047,
-    "y":391.71429443359375
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216692340.0,
-    "pointer":3,
-    "x":235.14285278320312,
-    "y":406.5714416503906
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216692348.0,
-    "pointer":3,
-    "x":232.57142639160156,
-    "y":421.4285583496094
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216692356.0,
-    "pointer":3,
-    "x":230.2857208251953,
-    "y":436.5714416503906
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216692363.0,
-    "pointer":3,
-    "x":228.2857208251953,
-    "y":451.71429443359375
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216692371.0,
-    "pointer":3,
-    "x":227.42857360839844,
-    "y":466.0
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216692378.0,
-    "pointer":3,
-    "x":226.2857208251953,
-    "y":479.71429443359375
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216692387.0,
-    "pointer":3,
-    "x":225.7142791748047,
-    "y":491.71429443359375
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216692395.0,
-    "pointer":3,
-    "x":225.14285278320312,
-    "y":501.71429443359375
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216692402.0,
-    "pointer":3,
-    "x":224.85714721679688,
-    "y":509.1428527832031
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216692410.0,
-    "pointer":3,
-    "x":224.57142639160156,
-    "y":514.8571166992188
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216692418.0,
-    "pointer":3,
-    "x":224.2857208251953,
-    "y":519.4285888671875
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216692425.0,
-    "pointer":3,
-    "x":224.0,
-    "y":523.4285888671875
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216692433.0,
-    "pointer":3,
-    "x":224.0,
-    "y":527.1428833007812
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216692441.0,
-    "pointer":3,
-    "x":224.0,
-    "y":530.5714111328125
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216692448.0,
-    "pointer":3,
-    "x":224.0,
-    "y":533.1428833007812
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216692456.0,
-    "pointer":3,
-    "x":224.0,
-    "y":535.4285888671875
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216692464.0,
-    "pointer":3,
-    "x":223.7142791748047,
-    "y":536.8571166992188
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216692472.0,
-    "pointer":3,
-    "x":223.7142791748047,
-    "y":538.2857055664062
-  },
-  {
-    "type":"pointerup",
-    "timeStamp":216692487.0,
-    "pointer":3,
-    "x":223.7142791748047,
-    "y":538.2857055664062
-  },
-  {
-    "type":"pointerdown",
-    "timeStamp":216692678.0,
-    "pointer":4,
-    "x":221.42857360839844,
-    "y":526.2857055664062
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216692701.0,
-    "pointer":4,
-    "x":220.57142639160156,
-    "y":514.8571166992188
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216692708.0,
-    "pointer":4,
-    "x":220.2857208251953,
-    "y":508.0
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216692716.0,
-    "pointer":4,
-    "x":220.2857208251953,
-    "y":498.0
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216692724.0,
-    "pointer":4,
-    "x":221.14285278320312,
-    "y":484.28570556640625
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216692732.0,
-    "pointer":4,
-    "x":221.7142791748047,
-    "y":469.4285583496094
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216692740.0,
-    "pointer":4,
-    "x":223.42857360839844,
-    "y":453.1428527832031
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216692748.0,
-    "pointer":4,
-    "x":225.7142791748047,
-    "y":436.28570556640625
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216692755.0,
-    "pointer":4,
-    "x":229.14285278320312,
-    "y":418.28570556640625
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216692763.0,
-    "pointer":4,
-    "x":232.85714721679688,
-    "y":400.28570556640625
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216692770.0,
-    "pointer":4,
-    "x":236.85714721679688,
-    "y":382.5714416503906
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216692778.0,
-    "pointer":4,
-    "x":241.14285278320312,
-    "y":366.0
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216692786.0,
-    "pointer":4,
-    "x":244.85714721679688,
-    "y":350.28570556640625
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216692793.0,
-    "pointer":4,
-    "x":249.14285278320312,
-    "y":335.4285583496094
-  },
-  {
-    "type":"pointerup",
-    "timeStamp":216692809.0,
-    "pointer":4,
-    "x":249.14285278320312,
-    "y":335.4285583496094
-  },
-  {
-    "type":"pointerdown",
-    "timeStamp":216693222.0,
-    "pointer":5,
-    "x":224.0,
-    "y":545.4285888671875
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216693245.0,
-    "pointer":5,
-    "x":224.0,
-    "y":545.4285888671875
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216693275.0,
-    "pointer":5,
-    "x":222.85714721679688,
-    "y":535.1428833007812
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216693284.0,
-    "pointer":5,
-    "x":222.85714721679688,
-    "y":528.8571166992188
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216693291.0,
-    "pointer":5,
-    "x":222.2857208251953,
-    "y":518.5714111328125
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216693299.0,
-    "pointer":5,
-    "x":222.0,
-    "y":503.4285583496094
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216693307.0,
-    "pointer":5,
-    "x":222.0,
-    "y":485.4285583496094
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216693314.0,
-    "pointer":5,
-    "x":221.7142791748047,
-    "y":464.0
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216693322.0,
-    "pointer":5,
-    "x":222.2857208251953,
-    "y":440.28570556640625
-  },
-  {
-    "type":"pointerup",
-    "timeStamp":216693337.0,
-    "pointer":5,
-    "x":222.2857208251953,
-    "y":440.28570556640625
-  },
-  {
-    "type":"pointerdown",
-    "timeStamp":216693985.0,
-    "pointer":6,
-    "x":208.0,
-    "y":544.0
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216694047.0,
-    "pointer":6,
-    "x":208.57142639160156,
-    "y":532.2857055664062
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216694054.0,
-    "pointer":6,
-    "x":208.85714721679688,
-    "y":525.7142944335938
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216694062.0,
-    "pointer":6,
-    "x":208.85714721679688,
-    "y":515.1428833007812
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216694070.0,
-    "pointer":6,
-    "x":208.0,
-    "y":501.4285583496094
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216694077.0,
-    "pointer":6,
-    "x":207.42857360839844,
-    "y":487.1428527832031
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216694085.0,
-    "pointer":6,
-    "x":206.57142639160156,
-    "y":472.8571472167969
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216694092.0,
-    "pointer":6,
-    "x":206.57142639160156,
-    "y":458.8571472167969
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216694100.0,
-    "pointer":6,
-    "x":206.57142639160156,
-    "y":446.0
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216694108.0,
-    "pointer":6,
-    "x":206.57142639160156,
-    "y":434.28570556640625
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216694116.0,
-    "pointer":6,
-    "x":207.14285278320312,
-    "y":423.71429443359375
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216694124.0,
-    "pointer":6,
-    "x":208.57142639160156,
-    "y":412.8571472167969
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216694131.0,
-    "pointer":6,
-    "x":209.7142791748047,
-    "y":402.28570556640625
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216694139.0,
-    "pointer":6,
-    "x":211.7142791748047,
-    "y":393.1428527832031
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216694147.0,
-    "pointer":6,
-    "x":213.42857360839844,
-    "y":385.1428527832031
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216694154.0,
-    "pointer":6,
-    "x":215.42857360839844,
-    "y":378.28570556640625
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216694162.0,
-    "pointer":6,
-    "x":217.42857360839844,
-    "y":371.71429443359375
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216694169.0,
-    "pointer":6,
-    "x":219.42857360839844,
-    "y":366.0
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216694177.0,
-    "pointer":6,
-    "x":221.42857360839844,
-    "y":360.8571472167969
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216694185.0,
-    "pointer":6,
-    "x":223.42857360839844,
-    "y":356.5714416503906
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216694193.0,
-    "pointer":6,
-    "x":225.14285278320312,
-    "y":352.28570556640625
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216694201.0,
-    "pointer":6,
-    "x":226.85714721679688,
-    "y":348.5714416503906
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216694209.0,
-    "pointer":6,
-    "x":228.2857208251953,
-    "y":346.0
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216694216.0,
-    "pointer":6,
-    "x":229.14285278320312,
-    "y":343.71429443359375
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216694224.0,
-    "pointer":6,
-    "x":230.0,
-    "y":342.0
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216694232.0,
-    "pointer":6,
-    "x":230.57142639160156,
-    "y":340.5714416503906
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216694239.0,
-    "pointer":6,
-    "x":230.85714721679688,
-    "y":339.71429443359375
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216694247.0,
-    "pointer":6,
-    "x":230.85714721679688,
-    "y":339.4285583496094
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216694262.0,
-    "pointer":6,
-    "x":230.2857208251953,
-    "y":342.0
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216694270.0,
-    "pointer":6,
-    "x":228.85714721679688,
-    "y":346.28570556640625
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216694278.0,
-    "pointer":6,
-    "x":227.14285278320312,
-    "y":352.5714416503906
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216694286.0,
-    "pointer":6,
-    "x":225.42857360839844,
-    "y":359.4285583496094
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216694294.0,
-    "pointer":6,
-    "x":223.7142791748047,
-    "y":367.71429443359375
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216694301.0,
-    "pointer":6,
-    "x":222.57142639160156,
-    "y":376.0
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216694309.0,
-    "pointer":6,
-    "x":221.42857360839844,
-    "y":384.28570556640625
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216694317.0,
-    "pointer":6,
-    "x":220.85714721679688,
-    "y":392.28570556640625
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216694324.0,
-    "pointer":6,
-    "x":220.0,
-    "y":400.5714416503906
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216694332.0,
-    "pointer":6,
-    "x":219.14285278320312,
-    "y":409.71429443359375
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216694339.0,
-    "pointer":6,
-    "x":218.85714721679688,
-    "y":419.1428527832031
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216694348.0,
-    "pointer":6,
-    "x":218.2857208251953,
-    "y":428.8571472167969
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216694356.0,
-    "pointer":6,
-    "x":218.2857208251953,
-    "y":438.8571472167969
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216694363.0,
-    "pointer":6,
-    "x":218.2857208251953,
-    "y":447.71429443359375
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216694371.0,
-    "pointer":6,
-    "x":218.2857208251953,
-    "y":455.71429443359375
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216694379.0,
-    "pointer":6,
-    "x":219.14285278320312,
-    "y":462.8571472167969
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216694386.0,
-    "pointer":6,
-    "x":220.0,
-    "y":469.4285583496094
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216694394.0,
-    "pointer":6,
-    "x":221.14285278320312,
-    "y":475.4285583496094
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216694401.0,
-    "pointer":6,
-    "x":222.0,
-    "y":480.5714416503906
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216694409.0,
-    "pointer":6,
-    "x":222.85714721679688,
-    "y":485.4285583496094
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216694417.0,
-    "pointer":6,
-    "x":224.0,
-    "y":489.71429443359375
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216694425.0,
-    "pointer":6,
-    "x":224.85714721679688,
-    "y":492.8571472167969
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216694433.0,
-    "pointer":6,
-    "x":225.42857360839844,
-    "y":495.4285583496094
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216694440.0,
-    "pointer":6,
-    "x":226.0,
-    "y":497.1428527832031
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216694448.0,
-    "pointer":6,
-    "x":226.2857208251953,
-    "y":498.28570556640625
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216694456.0,
-    "pointer":6,
-    "x":226.2857208251953,
-    "y":498.8571472167969
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216694471.0,
-    "pointer":6,
-    "x":226.2857208251953,
-    "y":498.28570556640625
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216694479.0,
-    "pointer":6,
-    "x":226.2857208251953,
-    "y":496.5714416503906
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216694486.0,
-    "pointer":6,
-    "x":226.2857208251953,
-    "y":493.71429443359375
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216694494.0,
-    "pointer":6,
-    "x":226.2857208251953,
-    "y":490.0
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216694502.0,
-    "pointer":6,
-    "x":226.2857208251953,
-    "y":486.0
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216694510.0,
-    "pointer":6,
-    "x":226.2857208251953,
-    "y":480.5714416503906
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216694518.0,
-    "pointer":6,
-    "x":226.2857208251953,
-    "y":475.71429443359375
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216694525.0,
-    "pointer":6,
-    "x":226.2857208251953,
-    "y":468.8571472167969
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216694533.0,
-    "pointer":6,
-    "x":226.2857208251953,
-    "y":461.4285583496094
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216694541.0,
-    "pointer":6,
-    "x":226.2857208251953,
-    "y":452.5714416503906
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216694548.0,
-    "pointer":6,
-    "x":226.57142639160156,
-    "y":442.28570556640625
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216694556.0,
-    "pointer":6,
-    "x":226.57142639160156,
-    "y":432.28570556640625
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216694564.0,
-    "pointer":6,
-    "x":226.85714721679688,
-    "y":423.4285583496094
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216694571.0,
-    "pointer":6,
-    "x":227.42857360839844,
-    "y":416.0
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216694580.0,
-    "pointer":6,
-    "x":227.7142791748047,
-    "y":410.0
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216694587.0,
-    "pointer":6,
-    "x":228.2857208251953,
-    "y":404.28570556640625
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216694595.0,
-    "pointer":6,
-    "x":228.85714721679688,
-    "y":399.71429443359375
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216694603.0,
-    "pointer":6,
-    "x":229.14285278320312,
-    "y":395.4285583496094
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216694610.0,
-    "pointer":6,
-    "x":229.42857360839844,
-    "y":392.28570556640625
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216694618.0,
-    "pointer":6,
-    "x":229.7142791748047,
-    "y":390.0
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216694625.0,
-    "pointer":6,
-    "x":229.7142791748047,
-    "y":388.0
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216694633.0,
-    "pointer":6,
-    "x":229.7142791748047,
-    "y":386.8571472167969
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216694641.0,
-    "pointer":6,
-    "x":229.7142791748047,
-    "y":386.28570556640625
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216694648.0,
-    "pointer":6,
-    "x":229.7142791748047,
-    "y":386.0
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216694657.0,
-    "pointer":6,
-    "x":228.85714721679688,
-    "y":386.0
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216694665.0,
-    "pointer":6,
-    "x":228.0,
-    "y":388.0
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216694672.0,
-    "pointer":6,
-    "x":226.0,
-    "y":392.5714416503906
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216694680.0,
-    "pointer":6,
-    "x":224.0,
-    "y":397.71429443359375
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216694688.0,
-    "pointer":6,
-    "x":222.0,
-    "y":404.28570556640625
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216694695.0,
-    "pointer":6,
-    "x":219.7142791748047,
-    "y":411.1428527832031
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216694703.0,
-    "pointer":6,
-    "x":218.2857208251953,
-    "y":418.0
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216694710.0,
-    "pointer":6,
-    "x":217.14285278320312,
-    "y":425.4285583496094
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216694718.0,
-    "pointer":6,
-    "x":215.7142791748047,
-    "y":433.4285583496094
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216694726.0,
-    "pointer":6,
-    "x":214.85714721679688,
-    "y":442.28570556640625
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216694734.0,
-    "pointer":6,
-    "x":214.0,
-    "y":454.0
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216694742.0,
-    "pointer":6,
-    "x":214.0,
-    "y":469.4285583496094
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216694749.0,
-    "pointer":6,
-    "x":215.42857360839844,
-    "y":485.4285583496094
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216694757.0,
-    "pointer":6,
-    "x":217.7142791748047,
-    "y":502.8571472167969
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216694765.0,
-    "pointer":6,
-    "x":221.14285278320312,
-    "y":521.4285888671875
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216694772.0,
-    "pointer":6,
-    "x":224.57142639160156,
-    "y":541.1428833007812
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216694780.0,
-    "pointer":6,
-    "x":229.14285278320312,
-    "y":561.1428833007812
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216694788.0,
-    "pointer":6,
-    "x":233.42857360839844,
-    "y":578.8571166992188
-  },
-  {
-    "type":"pointerup",
-    "timeStamp":216694802.0,
-    "pointer":6,
-    "x":233.42857360839844,
-    "y":578.8571166992188
-  },
-  {
-    "type":"pointerdown",
-    "timeStamp":216695344.0,
-    "pointer":7,
-    "x":253.42857360839844,
-    "y":310.5714416503906
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216695352.0,
-    "pointer":7,
-    "x":253.42857360839844,
-    "y":310.5714416503906
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216695359.0,
-    "pointer":7,
-    "x":252.85714721679688,
-    "y":318.0
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216695367.0,
-    "pointer":7,
-    "x":251.14285278320312,
-    "y":322.0
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216695375.0,
-    "pointer":7,
-    "x":248.85714721679688,
-    "y":327.1428527832031
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216695382.0,
-    "pointer":7,
-    "x":246.0,
-    "y":334.8571472167969
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216695390.0,
-    "pointer":7,
-    "x":242.57142639160156,
-    "y":344.5714416503906
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216695397.0,
-    "pointer":7,
-    "x":238.85714721679688,
-    "y":357.4285583496094
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216695406.0,
-    "pointer":7,
-    "x":235.7142791748047,
-    "y":371.71429443359375
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216695414.0,
-    "pointer":7,
-    "x":232.2857208251953,
-    "y":386.8571472167969
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216695421.0,
-    "pointer":7,
-    "x":229.42857360839844,
-    "y":402.0
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216695429.0,
-    "pointer":7,
-    "x":227.42857360839844,
-    "y":416.8571472167969
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216695437.0,
-    "pointer":7,
-    "x":226.2857208251953,
-    "y":431.4285583496094
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216695444.0,
-    "pointer":7,
-    "x":226.2857208251953,
-    "y":446.0
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216695452.0,
-    "pointer":7,
-    "x":227.7142791748047,
-    "y":460.28570556640625
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216695459.0,
-    "pointer":7,
-    "x":230.0,
-    "y":475.1428527832031
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216695467.0,
-    "pointer":7,
-    "x":232.2857208251953,
-    "y":489.71429443359375
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216695475.0,
-    "pointer":7,
-    "x":235.7142791748047,
-    "y":504.0
-  },
-  {
-    "type":"pointerup",
-    "timeStamp":216695490.0,
-    "pointer":7,
-    "x":235.7142791748047,
-    "y":504.0
-  },
-  {
-    "type":"pointerdown",
-    "timeStamp":216695885.0,
-    "pointer":8,
-    "x":238.85714721679688,
-    "y":524.0
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216695908.0,
-    "pointer":8,
-    "x":236.2857208251953,
-    "y":515.7142944335938
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216695916.0,
-    "pointer":8,
-    "x":234.85714721679688,
-    "y":509.1428527832031
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216695924.0,
-    "pointer":8,
-    "x":232.57142639160156,
-    "y":498.5714416503906
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216695931.0,
-    "pointer":8,
-    "x":230.57142639160156,
-    "y":483.71429443359375
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216695939.0,
-    "pointer":8,
-    "x":229.14285278320312,
-    "y":466.5714416503906
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216695947.0,
-    "pointer":8,
-    "x":229.14285278320312,
-    "y":446.5714416503906
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216695955.0,
-    "pointer":8,
-    "x":230.57142639160156,
-    "y":424.8571472167969
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216695963.0,
-    "pointer":8,
-    "x":232.57142639160156,
-    "y":402.28570556640625
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216695970.0,
-    "pointer":8,
-    "x":235.14285278320312,
-    "y":380.0
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216695978.0,
-    "pointer":8,
-    "x":238.57142639160156,
-    "y":359.4285583496094
-  },
-  {
-    "type":"pointerup",
-    "timeStamp":216695993.0,
-    "pointer":8,
-    "x":238.57142639160156,
-    "y":359.4285583496094
-  },
-  {
-    "type":"pointerdown",
-    "timeStamp":216696429.0,
-    "pointer":9,
-    "x":238.2857208251953,
-    "y":568.5714111328125
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216696459.0,
-    "pointer":9,
-    "x":234.0,
-    "y":560.0
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216696467.0,
-    "pointer":9,
-    "x":231.42857360839844,
-    "y":553.1428833007812
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216696475.0,
-    "pointer":9,
-    "x":228.2857208251953,
-    "y":543.1428833007812
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216696483.0,
-    "pointer":9,
-    "x":225.42857360839844,
-    "y":528.8571166992188
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216696491.0,
-    "pointer":9,
-    "x":223.14285278320312,
-    "y":512.2857055664062
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216696498.0,
-    "pointer":9,
-    "x":222.0,
-    "y":495.4285583496094
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216696506.0,
-    "pointer":9,
-    "x":221.7142791748047,
-    "y":477.4285583496094
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216696514.0,
-    "pointer":9,
-    "x":221.7142791748047,
-    "y":458.28570556640625
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216696521.0,
-    "pointer":9,
-    "x":223.14285278320312,
-    "y":438.0
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216696529.0,
-    "pointer":9,
-    "x":224.2857208251953,
-    "y":416.28570556640625
-  },
-  {
-    "type":"pointerup",
-    "timeStamp":216696544.0,
-    "pointer":9,
-    "x":224.2857208251953,
-    "y":416.28570556640625
-  },
-  {
-    "type":"pointerdown",
-    "timeStamp":216696974.0,
-    "pointer":10,
-    "x":218.57142639160156,
-    "y":530.5714111328125
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216697012.0,
-    "pointer":10,
-    "x":220.2857208251953,
-    "y":522.0
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216697020.0,
-    "pointer":10,
-    "x":221.14285278320312,
-    "y":517.7142944335938
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216697028.0,
-    "pointer":10,
-    "x":222.2857208251953,
-    "y":511.71429443359375
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216697036.0,
-    "pointer":10,
-    "x":224.0,
-    "y":504.28570556640625
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216697044.0,
-    "pointer":10,
-    "x":227.14285278320312,
-    "y":490.5714416503906
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216697052.0,
-    "pointer":10,
-    "x":229.42857360839844,
-    "y":474.0
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216697059.0,
-    "pointer":10,
-    "x":231.42857360839844,
-    "y":454.5714416503906
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216697067.0,
-    "pointer":10,
-    "x":233.7142791748047,
-    "y":431.1428527832031
-  },
-  {
-    "type":"pointerup",
-    "timeStamp":216697082.0,
-    "pointer":10,
-    "x":233.7142791748047,
-    "y":431.1428527832031
-  },
-  {
-    "type":"pointerdown",
-    "timeStamp":216697435.0,
-    "pointer":11,
-    "x":257.1428527832031,
-    "y":285.1428527832031
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216697465.0,
-    "pointer":11,
-    "x":251.7142791748047,
-    "y":296.8571472167969
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216697473.0,
-    "pointer":11,
-    "x":248.2857208251953,
-    "y":304.0
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216697481.0,
-    "pointer":11,
-    "x":244.57142639160156,
-    "y":314.8571472167969
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216697489.0,
-    "pointer":11,
-    "x":240.2857208251953,
-    "y":329.1428527832031
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216697497.0,
-    "pointer":11,
-    "x":236.85714721679688,
-    "y":345.1428527832031
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216697505.0,
-    "pointer":11,
-    "x":233.7142791748047,
-    "y":361.4285583496094
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216697512.0,
-    "pointer":11,
-    "x":231.14285278320312,
-    "y":378.28570556640625
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216697520.0,
-    "pointer":11,
-    "x":229.42857360839844,
-    "y":395.4285583496094
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216697528.0,
-    "pointer":11,
-    "x":229.42857360839844,
-    "y":412.8571472167969
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216697535.0,
-    "pointer":11,
-    "x":230.85714721679688,
-    "y":430.8571472167969
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216697543.0,
-    "pointer":11,
-    "x":233.42857360839844,
-    "y":449.71429443359375
-  },
-  {
-    "type":"pointerup",
-    "timeStamp":216697558.0,
-    "pointer":11,
-    "x":233.42857360839844,
-    "y":449.71429443359375
-  },
-  {
-    "type":"pointerdown",
-    "timeStamp":216697749.0,
-    "pointer":12,
-    "x":246.0,
-    "y":311.4285583496094
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216697780.0,
-    "pointer":12,
-    "x":244.57142639160156,
-    "y":318.28570556640625
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216697787.0,
-    "pointer":12,
-    "x":243.14285278320312,
-    "y":325.4285583496094
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216697795.0,
-    "pointer":12,
-    "x":241.42857360839844,
-    "y":336.0
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216697803.0,
-    "pointer":12,
-    "x":239.7142791748047,
-    "y":351.1428527832031
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216697811.0,
-    "pointer":12,
-    "x":238.2857208251953,
-    "y":368.5714416503906
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216697819.0,
-    "pointer":12,
-    "x":238.0,
-    "y":389.4285583496094
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216697826.0,
-    "pointer":12,
-    "x":239.14285278320312,
-    "y":412.0
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216697834.0,
-    "pointer":12,
-    "x":242.2857208251953,
-    "y":438.0
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216697842.0,
-    "pointer":12,
-    "x":247.42857360839844,
-    "y":466.8571472167969
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216697849.0,
-    "pointer":12,
-    "x":254.2857208251953,
-    "y":497.71429443359375
-  },
-  {
-    "type":"pointerup",
-    "timeStamp":216697864.0,
-    "pointer":12,
-    "x":254.2857208251953,
-    "y":497.71429443359375
-  },
-  {
-    "type":"pointerdown",
-    "timeStamp":216698321.0,
-    "pointer":13,
-    "x":250.0,
-    "y":306.0
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216698328.0,
-    "pointer":13,
-    "x":250.0,
-    "y":306.0
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216698344.0,
-    "pointer":13,
-    "x":249.14285278320312,
-    "y":314.0
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216698351.0,
-    "pointer":13,
-    "x":247.42857360839844,
-    "y":319.4285583496094
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216698359.0,
-    "pointer":13,
-    "x":245.14285278320312,
-    "y":326.8571472167969
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216698366.0,
-    "pointer":13,
-    "x":241.7142791748047,
-    "y":339.4285583496094
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216698374.0,
-    "pointer":13,
-    "x":238.57142639160156,
-    "y":355.71429443359375
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216698382.0,
-    "pointer":13,
-    "x":236.2857208251953,
-    "y":374.28570556640625
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216698390.0,
-    "pointer":13,
-    "x":235.14285278320312,
-    "y":396.5714416503906
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216698398.0,
-    "pointer":13,
-    "x":236.57142639160156,
-    "y":421.4285583496094
-  },
-  {
-    "type":"pointermove",
-    "timeStamp":216698406.0,
-    "pointer":13,
-    "x":241.14285278320312,
-    "y":451.4285583496094
-  },
-  {
-    "type":"pointerup",
-    "timeStamp":216698421.0,
-    "pointer":13,
-    "x":241.14285278320312,
-    "y":451.4285583496094
-  }
-];
diff --git a/sky/unit/test/gestures/velocity_tracker_test.dart b/sky/unit/test/gestures/velocity_tracker_test.dart
deleted file mode 100644
index 0c6a1f1..0000000
--- a/sky/unit/test/gestures/velocity_tracker_test.dart
+++ /dev/null
@@ -1,64 +0,0 @@
-import 'package:flutter/gestures.dart';
-import 'package:test/test.dart';
-import 'velocity_tracker_data.dart';
-
-bool _withinTolerance(double actual, double expected) {
-  const double kTolerance = 0.001; // Within .1% of expected value
-  double diff = (actual - expected)/expected;
-  return diff.abs() < kTolerance;
-}
-
-bool _checkVelocity(GestureVelocity actual, GestureVelocity expected) {
-  return (actual.isValid == expected.isValid) &&
-    _withinTolerance(actual.x, expected.x) &&
-    _withinTolerance(actual.y, expected.y);
-}
-
-List<PointerInputEvent> _eventFromMap(List<Map> intermediate) {
-  List<PointerInputEvent> events = new List<PointerInputEvent>();
-  for (Map entry in intermediate)
-    events.add(_eventFor(entry));
-  return events;
-}
-
-PointerInputEvent _eventFor(Map entry) {
-  PointerInputEvent result = new PointerInputEvent(
-    type: entry['type'],
-    timeStamp: entry['timeStamp'],
-    pointer: entry['pointer'],
-    x: entry['x'],
-    y: entry['y']
-  );
-  return result;
-}
-
-void main() {
-  List<PointerInputEvent> events = _eventFromMap(velocityEventData);
-
-  List<GestureVelocity> expected = new List<GestureVelocity>(13);
-  expected[0] = new GestureVelocity(isValid: true, x: 219.5762939453125, y: 1304.6705322265625);
-  expected[1] = new GestureVelocity(isValid: true, x: 355.6900939941406, y: 967.1700439453125);
-  expected[2] = new GestureVelocity(isValid: true, x: 12.651158332824707, y: -36.9227180480957);
-  expected[3] = new GestureVelocity(isValid: true, x: 714.1383056640625, y: -2561.540283203125);
-  expected[4] = new GestureVelocity(isValid: true, x: -19.658065795898438, y: -2910.080322265625);
-  expected[5] = new GestureVelocity(isValid: true, x: 646.8700561523438, y: 2976.982421875);
-  expected[6] = new GestureVelocity(isValid: true, x: 396.6878967285156, y: 2106.204833984375);
-  expected[7] = new GestureVelocity(isValid: true, x: 298.3150634765625, y: -3660.821044921875);
-  expected[8] = new GestureVelocity(isValid: true, x: -1.7460877895355225, y: -3288.16162109375);
-  expected[9] = new GestureVelocity(isValid: true, x: 384.6415710449219, y: -2645.6484375);
-  expected[10] = new GestureVelocity(isValid: true, x: 176.3752899169922, y: 2711.24609375);
-  expected[11] = new GestureVelocity(isValid: true, x: 396.9254455566406, y: 4280.640625);
-  expected[12] = new GestureVelocity(isValid: true, x: -71.51288604736328, y: 3716.74560546875);
-
-  test('Velocity tracker gives expected results', () {
-    VelocityTracker tracker = new VelocityTracker();
-    int i = 0;
-    for (PointerInputEvent event in events) {
-      if (event.type == 'pointerdown' || event.type == 'pointermove')
-        tracker.addPosition(event.timeStamp, event.x, event.y);
-      if (event.type == 'pointerup') {
-        _checkVelocity(tracker.getVelocity(), expected[i++]);
-      }
-    }
-  });
-}
diff --git a/sky/unit/test/harness/trivial_test.dart b/sky/unit/test/harness/trivial_test.dart
deleted file mode 100644
index bbca5f2..0000000
--- a/sky/unit/test/harness/trivial_test.dart
+++ /dev/null
@@ -1,7 +0,0 @@
-import 'package:test/test.dart';
-
-void main() {
-  test("should pass", () {
-    expect(1 + 1, equals(2));
-  });
-}
diff --git a/sky/unit/test/painting/edge_dims_test.dart b/sky/unit/test/painting/edge_dims_test.dart
deleted file mode 100644
index 5dbc3b8..0000000
--- a/sky/unit/test/painting/edge_dims_test.dart
+++ /dev/null
@@ -1,14 +0,0 @@
-import 'package:flutter/painting.dart';
-
-import 'package:test/test.dart';
-
-void main() {
-  test("EdgeDims.lerp()", () {
-    EdgeDims a = new EdgeDims.all(10.0);
-    EdgeDims b = new EdgeDims.all(20.0);
-    expect(EdgeDims.lerp(a, b, 0.25), equals(a * 1.25));
-    expect(EdgeDims.lerp(a, b, 0.25), equals(b * 0.625));
-    expect(EdgeDims.lerp(a, b, 0.25), equals(a + const EdgeDims.all(2.5)));
-    expect(EdgeDims.lerp(a, b, 0.25), equals(b - const EdgeDims.all(7.5)));
-  });
-}
diff --git a/sky/unit/test/rendering/box_test.dart b/sky/unit/test/rendering/box_test.dart
deleted file mode 100644
index cac8d1d..0000000
--- a/sky/unit/test/rendering/box_test.dart
+++ /dev/null
@@ -1,97 +0,0 @@
-import 'package:flutter/material.dart';
-import 'package:flutter/rendering.dart';
-import 'package:test/test.dart';
-
-import 'rendering_tester.dart';
-
-void main() {
-  test("should size to render view", () {
-    RenderBox root = new RenderDecoratedBox(
-      decoration: new BoxDecoration(
-        backgroundColor: const Color(0xFF00FF00),
-        gradient: new RadialGradient(
-          center: Point.origin, radius: 500.0,
-          colors: <Color>[Colors.yellow[500], Colors.blue[500]]),
-        boxShadow: shadows[3])
-    );
-    layout(root);
-    expect(root.size.width, equals(800.0));
-    expect(root.size.height, equals(600.0));
-  });
-
-  test('Flex and padding', () {
-    RenderBox size = new RenderConstrainedBox(
-      additionalConstraints: new BoxConstraints().tightenHeight(100.0)
-    );
-    RenderBox inner = new RenderDecoratedBox(
-      decoration: new BoxDecoration(
-        backgroundColor: const Color(0xFF00FF00)
-      ),
-      child: size
-    );
-    RenderBox padding = new RenderPadding(
-      padding: new EdgeDims.all(50.0),
-      child: inner
-    );
-    RenderBox flex = new RenderFlex(
-      children: <RenderBox>[padding],
-      direction: FlexDirection.vertical,
-      alignItems: FlexAlignItems.stretch
-    );
-    RenderBox outer = new RenderDecoratedBox(
-      decoration: new BoxDecoration(
-        backgroundColor: const Color(0xFF0000FF)
-      ),
-      child: flex
-    );
-
-    layout(outer);
-
-    expect(size.size.width, equals(700.0));
-    expect(size.size.height, equals(100.0));
-    expect(inner.size.width, equals(700.0));
-    expect(inner.size.height, equals(100.0));
-    expect(padding.size.width, equals(800.0));
-    expect(padding.size.height, equals(200.0));
-    expect(flex.size.width, equals(800.0));
-    expect(flex.size.height, equals(600.0));
-    expect(outer.size.width, equals(800.0));
-    expect(outer.size.height, equals(600.0));
-  });
-
-  test("should not have a 0 sized colored Box", () {
-    var coloredBox = new RenderDecoratedBox(
-      decoration: new BoxDecoration()
-    );
-    var paddingBox = new RenderPadding(padding: const EdgeDims.all(10.0),
-        child: coloredBox);
-    RenderBox root = new RenderDecoratedBox(
-      decoration: new BoxDecoration(),
-      child: paddingBox
-    );
-    layout(root);
-    expect(coloredBox.size.width, equals(780.0));
-    expect(coloredBox.size.height, equals(580.0));
-  });
-
-  test("reparenting should clear position", () {
-    RenderDecoratedBox coloredBox = new RenderDecoratedBox(
-      decoration: new BoxDecoration());
-    RenderPadding paddedBox = new RenderPadding(
-      child: coloredBox, padding: const EdgeDims.all(10.0));
-
-    layout(paddedBox);
-
-    BoxParentData parentData = coloredBox.parentData;
-    expect(parentData.position.x, isNot(equals(0.0)));
-
-    paddedBox.child = null;
-    RenderConstrainedBox constraintedBox = new RenderConstrainedBox(
-      child: coloredBox, additionalConstraints: const BoxConstraints());
-
-    layout(constraintedBox);
-
-    parentData = coloredBox.parentData;
-    expect(parentData.position.x, equals(0.0));
-  });
-}
diff --git a/sky/unit/test/rendering/flex_test.dart b/sky/unit/test/rendering/flex_test.dart
deleted file mode 100644
index 0d223c9..0000000
--- a/sky/unit/test/rendering/flex_test.dart
+++ /dev/null
@@ -1,76 +0,0 @@
-import 'package:flutter/rendering.dart';
-import 'package:test/test.dart';
-
-import 'rendering_tester.dart';
-
-void main() {
-  test('Overconstrained flex', () {
-    RenderDecoratedBox box = new RenderDecoratedBox(decoration: new BoxDecoration());
-    RenderFlex flex = new RenderFlex(children: <RenderBox>[box]);
-    layout(flex, constraints: const BoxConstraints(
-      minWidth: 200.0, maxWidth: 100.0, minHeight: 200.0, maxHeight: 100.0)
-    );
-
-    expect(flex.size.width, equals(200.0), reason: "flex width");
-    expect(flex.size.height, equals(200.0), reason: "flex height");
-  });
-
-  test('Defaults', () {
-    RenderFlex flex = new RenderFlex();
-    expect(flex.alignItems, equals(FlexAlignItems.center));
-    expect(flex.direction, equals(FlexDirection.horizontal));
-  });
-
-  test('Parent data', () {
-    RenderDecoratedBox box1 = new RenderDecoratedBox(decoration: new BoxDecoration());
-    RenderDecoratedBox box2 = new RenderDecoratedBox(decoration: new BoxDecoration());
-    RenderFlex flex = new RenderFlex(children: <RenderBox>[box1, box2]);
-    layout(flex, constraints: const BoxConstraints(
-      minWidth: 0.0, maxWidth: 100.0, minHeight: 0.0, maxHeight: 100.0)
-    );
-    expect(box1.size.width, equals(0.0));
-    expect(box1.size.height, equals(0.0));
-    expect(box2.size.width, equals(0.0));
-    expect(box2.size.height, equals(0.0));
-
-    final FlexParentData box2ParentData = box2.parentData;
-    box2ParentData.flex = 1;
-    flex.markNeedsLayout();
-    pumpFrame();
-    expect(box1.size.width, equals(0.0));
-    expect(box1.size.height, equals(0.0));
-    expect(box2.size.width, equals(100.0));
-    expect(box2.size.height, equals(0.0));
-  });
-
-  test('Stretch', () {
-    RenderDecoratedBox box1 = new RenderDecoratedBox(decoration: new BoxDecoration());
-    RenderDecoratedBox box2 = new RenderDecoratedBox(decoration: new BoxDecoration());
-    RenderFlex flex = new RenderFlex();
-    flex.setupParentData(box2);
-    final FlexParentData box2ParentData = box2.parentData;
-    box2ParentData.flex = 2;
-    flex.addAll(<RenderBox>[box1, box2]);
-    layout(flex, constraints: const BoxConstraints(
-      minWidth: 0.0, maxWidth: 100.0, minHeight: 0.0, maxHeight: 100.0)
-    );
-    expect(box1.size.width, equals(0.0));
-    expect(box1.size.height, equals(0.0));
-    expect(box2.size.width, equals(100.0));
-    expect(box2.size.height, equals(0.0));
-
-    flex.alignItems = FlexAlignItems.stretch;
-    pumpFrame();
-    expect(box1.size.width, equals(0.0));
-    expect(box1.size.height, equals(100.0));
-    expect(box2.size.width, equals(100.0));
-    expect(box2.size.height, equals(100.0));
-
-    flex.direction = FlexDirection.vertical;
-    pumpFrame();
-    expect(box1.size.width, equals(100.0));
-    expect(box1.size.height, equals(0.0));
-    expect(box2.size.width, equals(100.0));
-    expect(box2.size.height, equals(100.0));
-  });
-}
diff --git a/sky/unit/test/rendering/grid_test.dart b/sky/unit/test/rendering/grid_test.dart
deleted file mode 100644
index 8646ba3..0000000
--- a/sky/unit/test/rendering/grid_test.dart
+++ /dev/null
@@ -1,40 +0,0 @@
-import 'package:flutter/rendering.dart';
-import 'package:test/test.dart';
-
-import 'rendering_tester.dart';
-
-void main() {
-  test('Basic grid layout test', () {
-    List<RenderBox> children = <RenderBox>[
-      new RenderDecoratedBox(decoration: new BoxDecoration()),
-      new RenderDecoratedBox(decoration: new BoxDecoration()),
-      new RenderDecoratedBox(decoration: new BoxDecoration()),
-      new RenderDecoratedBox(decoration: new BoxDecoration())
-    ];
-
-    RenderGrid grid = new RenderGrid(children: children, maxChildExtent: 100.0);
-    layout(grid, constraints: const BoxConstraints(maxWidth: 200.0));
-
-    children.forEach((RenderBox child) {
-      expect(child.size.width, equals(100.0), reason: "child width");
-      expect(child.size.height, equals(100.0), reason: "child height");
-    });
-
-    expect(grid.size.width, equals(200.0), reason: "grid width");
-    expect(grid.size.height, equals(200.0), reason: "grid height");
-
-    expect(grid.needsLayout, equals(false));
-    grid.maxChildExtent = 60.0;
-    expect(grid.needsLayout, equals(true));
-
-    pumpFrame();
-
-    children.forEach((RenderBox child) {
-      expect(child.size.width, equals(50.0), reason: "child width");
-      expect(child.size.height, equals(50.0), reason: "child height");
-    });
-
-    expect(grid.size.width, equals(200.0), reason: "grid width");
-    expect(grid.size.height, equals(50.0), reason: "grid height");
-  });
-}
diff --git a/sky/unit/test/rendering/image_test.dart b/sky/unit/test/rendering/image_test.dart
deleted file mode 100644
index b794f84..0000000
--- a/sky/unit/test/rendering/image_test.dart
+++ /dev/null
@@ -1,161 +0,0 @@
-import 'dart:ui' as ui;
-
-import 'package:flutter/rendering.dart';
-import 'package:test/test.dart';
-
-import 'rendering_tester.dart';
-
-class SquareImage implements ui.Image {
-  int get width => 10;
-  int get height => 10;
-}
-
-class WideImage implements ui.Image {
-  int get width => 20;
-  int get height => 10;
-}
-
-class TallImage implements ui.Image {
-  int get width => 10;
-  int get height => 20;
-}
-
-void main() {
-  test('Image sizing', () {
-    RenderImage image;
-
-    image = new RenderImage(image: new SquareImage());
-    layout(image,
-          constraints: new BoxConstraints(
-              minWidth: 25.0,
-              minHeight: 25.0,
-              maxWidth: 100.0,
-              maxHeight: 100.0));
-    expect(image.size.width, equals(25.0));
-    expect(image.size.height, equals(25.0));
-
-    image = new RenderImage(image: new WideImage());
-    layout(image,
-           constraints: new BoxConstraints(
-              minWidth: 5.0,
-              minHeight: 30.0,
-              maxWidth: 100.0,
-              maxHeight: 100.0));
-    expect(image.size.width, equals(60.0));
-    expect(image.size.height, equals(30.0));
-
-    image = new RenderImage(image: new TallImage());
-    layout(image,
-           constraints: new BoxConstraints(
-              minWidth: 50.0,
-              minHeight: 5.0,
-              maxWidth: 75.0,
-              maxHeight: 75.0));
-    expect(image.size.width, equals(50.0));
-    expect(image.size.height, equals(75.0));
-
-    image = new RenderImage(image: new WideImage());
-    layout(image,
-           constraints: new BoxConstraints(
-              minWidth: 5.0,
-              minHeight: 5.0,
-              maxWidth: 100.0,
-              maxHeight: 100.0));
-    expect(image.size.width, equals(20.0));
-    expect(image.size.height, equals(10.0));
-
-    image = new RenderImage(image: new WideImage());
-    layout(image,
-           constraints: new BoxConstraints(
-              minWidth: 5.0,
-              minHeight: 5.0,
-              maxWidth: 16.0,
-              maxHeight: 16.0));
-    expect(image.size.width, equals(16.0));
-    expect(image.size.height, equals(8.0));
-
-    image = new RenderImage(image: new TallImage());
-    layout(image,
-           constraints: new BoxConstraints(
-              minWidth: 5.0,
-              minHeight: 5.0,
-              maxWidth: 16.0,
-              maxHeight: 16.0));
-    expect(image.size.width, equals(8.0));
-    expect(image.size.height, equals(16.0));
-
-    image = new RenderImage(image: new SquareImage());
-    layout(image,
-           constraints: new BoxConstraints(
-              minWidth: 4.0,
-              minHeight: 4.0,
-              maxWidth: 8.0,
-              maxHeight: 8.0));
-    expect(image.size.width, equals(8.0));
-    expect(image.size.height, equals(8.0));
-
-    image = new RenderImage(image: new WideImage());
-    layout(image,
-           constraints: new BoxConstraints(
-              minWidth: 20.0,
-              minHeight: 20.0,
-              maxWidth: 30.0,
-              maxHeight: 30.0));
-    expect(image.size.width, equals(30.0));
-    expect(image.size.height, equals(20.0));
-
-    image = new RenderImage(image: new TallImage());
-    layout(image,
-           constraints: new BoxConstraints(
-              minWidth: 20.0,
-              minHeight: 20.0,
-              maxWidth: 30.0,
-              maxHeight: 30.0));
-    expect(image.size.width, equals(20.0));
-    expect(image.size.height, equals(30.0));
-  });
-
-  test('Null image sizing', () {
-    RenderImage image;
-
-    image = new RenderImage();
-    layout(image,
-           constraints: new BoxConstraints(
-             minWidth: 25.0,
-             minHeight: 25.0,
-             maxWidth: 100.0,
-             maxHeight: 100.0));
-    expect(image.size.width, equals(25.0));
-    expect(image.size.height, equals(25.0));
-
-    image = new RenderImage(width: 50.0);
-    layout(image,
-           constraints: new BoxConstraints(
-             minWidth: 25.0,
-             minHeight: 25.0,
-             maxWidth: 100.0,
-             maxHeight: 100.0));
-    expect(image.size.width, equals(50.0));
-    expect(image.size.height, equals(25.0));
-
-    image = new RenderImage(height: 50.0);
-    layout(image,
-           constraints: new BoxConstraints(
-             minWidth: 25.0,
-             minHeight: 25.0,
-             maxWidth: 100.0,
-             maxHeight: 100.0));
-    expect(image.size.width, equals(25.0));
-    expect(image.size.height, equals(50.0));
-
-    image = new RenderImage(width: 100.0, height: 100.0);
-    layout(image,
-           constraints: new BoxConstraints(
-             minWidth: 25.0,
-             minHeight: 25.0,
-             maxWidth: 75.0,
-             maxHeight: 75.0));
-    expect(image.size.width, equals(75.0));
-    expect(image.size.height, equals(75.0));
-  });
-}
diff --git a/sky/unit/test/rendering/intrinsic_width_test.dart b/sky/unit/test/rendering/intrinsic_width_test.dart
deleted file mode 100644
index de28dba..0000000
--- a/sky/unit/test/rendering/intrinsic_width_test.dart
+++ /dev/null
@@ -1,62 +0,0 @@
-import 'package:flutter/rendering.dart';
-import 'package:test/test.dart';
-
-import 'rendering_tester.dart';
-
-class RenderTestBox extends RenderBox {
-  RenderTestBox(this._intrinsicDimensions);
-
-  final BoxConstraints _intrinsicDimensions;
-
-  double getMinIntrinsicWidth(BoxConstraints constraints) {
-    return constraints.constrainWidth(_intrinsicDimensions.minWidth);
-  }
-
-  double getMaxIntrinsicWidth(BoxConstraints constraints) {
-    return constraints.constrainWidth(_intrinsicDimensions.maxWidth);
-  }
-
-  double getMinIntrinsicHeight(BoxConstraints constraints) {
-    return constraints.constrainHeight(_intrinsicDimensions.minHeight);
-  }
-
-  double getMaxIntrinsicHeight(BoxConstraints constraints) {
-    return constraints.constrainHeight(_intrinsicDimensions.maxHeight);
-  }
-
-  bool get sizedByParent => true;
-  void performResize() {
-    size = constraints.constrain(new Size(_intrinsicDimensions.minWidth + (_intrinsicDimensions.maxWidth-_intrinsicDimensions.minWidth) / 2.0,
-                                          _intrinsicDimensions.minHeight + (_intrinsicDimensions.maxHeight-_intrinsicDimensions.minHeight) / 2.0));
-  }
-}
-
-void main() {
-  test('Shrink-wrapping width', () {
-    RenderBox child = new RenderTestBox(new BoxConstraints(minWidth: 10.0, maxWidth: 100.0, minHeight: 20.0, maxHeight: 200.0));
-
-    RenderBox parent = new RenderIntrinsicWidth(child: child);
-    layout(parent,
-          constraints: new BoxConstraints(
-              minWidth: 5.0,
-              minHeight: 8.0,
-              maxWidth: 500.0,
-              maxHeight: 800.0));
-    expect(parent.size.width, equals(100.0));
-    expect(parent.size.height, equals(110.0));
-  });
-
-  test('Shrink-wrapping height', () {
-    RenderBox child = new RenderTestBox(new BoxConstraints(minWidth: 10.0, maxWidth: 100.0, minHeight: 20.0, maxHeight: 200.0));
-
-    RenderBox parent = new RenderIntrinsicHeight(child: child);
-    layout(parent,
-          constraints: new BoxConstraints(
-              minWidth: 5.0,
-              minHeight: 8.0,
-              maxWidth: 500.0,
-              maxHeight: 800.0));
-    expect(parent.size.width, equals(55.0));
-    expect(parent.size.height, equals(200.0));
-  });
-}
diff --git a/sky/unit/test/rendering/offstage_test.dart b/sky/unit/test/rendering/offstage_test.dart
deleted file mode 100644
index 76b16f9..0000000
--- a/sky/unit/test/rendering/offstage_test.dart
+++ /dev/null
@@ -1,32 +0,0 @@
-import 'package:flutter/material.dart';
-import 'package:flutter/rendering.dart';
-import 'package:test/test.dart';
-
-import 'rendering_tester.dart';
-
-void main() {
-  test("offstage", () {
-    RenderBox child;
-    bool painted = false;
-    // viewport incoming constraints are tight 800x600
-    // viewport is vertical by default
-    RenderBox root = new RenderViewport(
-      child: new RenderOffStage(
-        child: new RenderCustomPaint(
-          child: child = new RenderConstrainedBox(
-            additionalConstraints: new BoxConstraints.tightFor(height: 10.0, width: 10.0)
-          ),
-          onPaint: (PaintingCanvas canvas, Size size) {
-            painted = true;
-          }
-        )
-      )
-    );
-    expect(child.hasSize, isFalse);
-    expect(painted, isFalse);
-    layout(root, phase: EnginePhase.paint);
-    expect(child.hasSize, isTrue);
-    expect(painted, isFalse);
-    expect(child.size, equals(const Size(800.0, 10.0)));
-  });
-}
diff --git a/sky/unit/test/rendering/overflow_test.dart b/sky/unit/test/rendering/overflow_test.dart
deleted file mode 100644
index 2528f58..0000000
--- a/sky/unit/test/rendering/overflow_test.dart
+++ /dev/null
@@ -1,42 +0,0 @@
-import 'package:flutter/material.dart';
-import 'package:flutter/rendering.dart';
-import 'package:test/test.dart';
-
-import 'rendering_tester.dart';
-
-void main() {
-  test("overflow should not affect baseline", () {
-    RenderBox root, child, text;
-    double baseline1, baseline2, height1, height2;
-
-    root = new RenderPositionedBox(
-      child: new RenderCustomPaint(
-        child: child = text = new RenderParagraph(new PlainTextSpan('Hello World')),
-        onPaint: (PaintingCanvas canvas, Size size) {
-          baseline1 = child.getDistanceToBaseline(TextBaseline.alphabetic);
-          height1 = text.size.height;
-        }
-      )
-    );
-    layout(root, phase: EnginePhase.paint);
-
-    root = new RenderPositionedBox(
-      child: new RenderCustomPaint(
-        child: child = new RenderOverflowBox(
-          child: text = new RenderParagraph(new PlainTextSpan('Hello World')),
-          maxHeight: height1 / 2.0
-        ),
-        onPaint: (PaintingCanvas canvas, Size size) {
-          baseline2 = child.getDistanceToBaseline(TextBaseline.alphabetic);
-          height2 = text.size.height;
-        }
-      )
-    );
-    layout(root, phase: EnginePhase.paint);
-
-    expect(baseline1, lessThan(height1));
-    expect(height2, equals(height1 / 2.0));
-    expect(baseline2, equals(baseline1));
-    expect(baseline2, greaterThan(height2));
-  });
-}
diff --git a/sky/unit/test/rendering/positioned_box_test.dart b/sky/unit/test/rendering/positioned_box_test.dart
deleted file mode 100644
index 3b71b91..0000000
--- a/sky/unit/test/rendering/positioned_box_test.dart
+++ /dev/null
@@ -1,69 +0,0 @@
-import 'package:flutter/rendering.dart';
-import 'package:test/test.dart';
-
-import 'rendering_tester.dart';
-
-void main() {
-  test('RenderPositionedBox expands', () {
-    RenderConstrainedBox sizer = new RenderConstrainedBox(
-      additionalConstraints: new BoxConstraints.tight(new Size(100.0, 100.0)),
-      child: new RenderDecoratedBox(decoration: new BoxDecoration())
-    );
-    RenderPositionedBox positioner = new RenderPositionedBox(child: sizer);
-    layout(positioner, constraints: new BoxConstraints.loose(new Size(200.0, 200.0)));
-
-    expect(positioner.size.width, equals(200.0), reason: "positioner width");
-    expect(positioner.size.height, equals(200.0), reason: "positioner height");
-  });
-
-  test('RenderPositionedBox shrink wraps', () {
-    RenderConstrainedBox sizer = new RenderConstrainedBox(
-      additionalConstraints: new BoxConstraints.tight(new Size(100.0, 100.0)),
-      child: new RenderDecoratedBox(decoration: new BoxDecoration())
-    );
-    RenderPositionedBox positioner = new RenderPositionedBox(child: sizer, widthFactor: 1.0);
-    layout(positioner, constraints: new BoxConstraints.loose(new Size(200.0, 200.0)));
-
-    expect(positioner.size.width, equals(100.0), reason: "positioner width");
-    expect(positioner.size.height, equals(200.0), reason: "positioner height");
-
-    positioner.widthFactor = null;
-    positioner.heightFactor = 1.0;
-    pumpFrame();
-
-    expect(positioner.size.width, equals(200.0), reason: "positioner width");
-    expect(positioner.size.height, equals(100.0), reason: "positioner height");
-
-    positioner.widthFactor = 1.0;
-    pumpFrame();
-
-    expect(positioner.size.width, equals(100.0), reason: "positioner width");
-    expect(positioner.size.height, equals(100.0), reason: "positioner height");
-  });
-
-  test('RenderPositionedBox width and height factors', () {
-    RenderConstrainedBox sizer = new RenderConstrainedBox(
-      additionalConstraints: new BoxConstraints.tight(new Size(100.0, 100.0)),
-      child: new RenderDecoratedBox(decoration: new BoxDecoration())
-    );
-    RenderPositionedBox positioner = new RenderPositionedBox(child: sizer, widthFactor: 1.0, heightFactor: 0.0);
-    layout(positioner, constraints: new BoxConstraints.loose(new Size(200.0, 200.0)));
-
-    expect(positioner.size.width, equals(100.0));
-    expect(positioner.size.height, equals(0.0));
-
-    positioner.widthFactor = 0.5;
-    positioner.heightFactor = 0.5;
-    pumpFrame();
-
-    expect(positioner.size.width, equals(50.0));
-    expect(positioner.size.height, equals(50.0));
-
-    positioner.widthFactor = null;
-    positioner.heightFactor = null;
-    pumpFrame();
-
-    expect(positioner.size.width, equals(200.0));
-    expect(positioner.size.height, equals(200.0));
-  });
-}
diff --git a/sky/unit/test/rendering/rendering_tester.dart b/sky/unit/test/rendering/rendering_tester.dart
deleted file mode 100644
index 10e596d..0000000
--- a/sky/unit/test/rendering/rendering_tester.dart
+++ /dev/null
@@ -1,55 +0,0 @@
-import 'package:flutter/rendering.dart';
-
-const Size _kTestViewSize = const Size(800.0, 600.0);
-
-class TestRenderView extends RenderView {
-  TestRenderView() {
-    attach();
-    rootConstraints = new ViewConstraints(size: _kTestViewSize);
-    scheduleInitialLayout();
-    scheduleInitialPaint(new TransformLayer(transform: new Matrix4.identity()));
-  }
-}
-
-enum EnginePhase {
-  layout,
-  paint,
-  composite
-}
-
-RenderView _renderView;
-RenderView get renderView => _renderView;
-
-void layout(RenderBox box, { BoxConstraints constraints, EnginePhase phase: EnginePhase.layout }) {
-  assert(box != null); // if you want to just repump the last box, call pumpFrame().
-
-  if (renderView == null)
-    _renderView = new TestRenderView();
-
-  if (renderView.child != null)
-    renderView.child = null;
-
-  if (constraints != null) {
-    box = new RenderPositionedBox(
-      child: new RenderConstrainedBox(
-        additionalConstraints: constraints,
-        child: box
-      )
-    );
-  }
-
-  renderView.child = box;
-
-  pumpFrame(phase: phase);
-}
-
-void pumpFrame({ EnginePhase phase: EnginePhase.layout }) {
-  RenderObject.flushLayout();
-  if (phase == EnginePhase.layout)
-    return;
-  renderView.updateCompositingBits();
-  RenderObject.flushPaint();
-  if (phase == EnginePhase.paint)
-    return;
-  renderView.compositeFrame();
-}
diff --git a/sky/unit/test/rendering/size_test.dart b/sky/unit/test/rendering/size_test.dart
deleted file mode 100644
index 8d76727..0000000
--- a/sky/unit/test/rendering/size_test.dart
+++ /dev/null
@@ -1,18 +0,0 @@
-import 'package:flutter/rendering.dart';
-import 'package:test/test.dart';
-
-import 'rendering_tester.dart';
-
-void main() {
-  test('Stack can layout with top, right, bottom, left 0.0', () {
-    RenderBox box = new RenderConstrainedBox(
-      additionalConstraints: new BoxConstraints.tight(const Size(100.0, 100.0)));
-
-    layout(box, constraints: const BoxConstraints());
-
-    expect(box.size.width, equals(100.0));
-    expect(box.size.height, equals(100.0));
-    expect(box.size, equals(const Size(100.0, 100.0)));
-    expect(box.size.runtimeType.toString(), equals('_DebugSize'));
-  });
-}
diff --git a/sky/unit/test/rendering/stack_test.dart b/sky/unit/test/rendering/stack_test.dart
deleted file mode 100644
index 8fc40a5..0000000
--- a/sky/unit/test/rendering/stack_test.dart
+++ /dev/null
@@ -1,40 +0,0 @@
-import 'package:flutter/rendering.dart';
-import 'package:test/test.dart';
-
-import 'rendering_tester.dart';
-
-void main() {
-  test('Stack can layout with top, right, bottom, left 0.0', () {
-    RenderBox size = new RenderConstrainedBox(
-      additionalConstraints: new BoxConstraints.tight(const Size(100.0, 100.0)));
-
-    RenderBox red = new RenderDecoratedBox(
-      decoration: new BoxDecoration(
-        backgroundColor: const Color(0xFFFF0000)
-      ),
-      child: size);
-
-    RenderBox green = new RenderDecoratedBox(
-      decoration: new BoxDecoration(
-        backgroundColor: const Color(0xFFFF0000)
-      ));
-
-    RenderBox stack = new RenderStack(children: <RenderBox>[red, green]);
-    (green.parentData as StackParentData)
-      ..top = 0.0
-      ..right = 0.0
-      ..bottom = 0.0
-      ..left = 0.0;
-
-    layout(stack, constraints: const BoxConstraints());
-
-    expect(stack.size.width, equals(100.0));
-    expect(stack.size.height, equals(100.0));
-
-    expect(red.size.width, equals(100.0));
-    expect(red.size.height, equals(100.0));
-
-    expect(green.size.width, equals(100.0));
-    expect(green.size.height, equals(100.0));
-  });
-}
diff --git a/sky/unit/test/rendering/viewport_test.dart b/sky/unit/test/rendering/viewport_test.dart
deleted file mode 100644
index af1cf16..0000000
--- a/sky/unit/test/rendering/viewport_test.dart
+++ /dev/null
@@ -1,36 +0,0 @@
-import 'package:flutter/rendering.dart';
-import 'package:test/test.dart';
-
-import 'rendering_tester.dart';
-
-void main() {
-  test('Should be able to hit with negative scroll offset', () {
-    RenderBox green = new RenderDecoratedBox(
-      decoration: new BoxDecoration(
-        backgroundColor: const Color(0xFF00FF00)
-      ));
-
-    RenderBox size = new RenderConstrainedBox(
-      additionalConstraints: new BoxConstraints.tight(const Size(100.0, 100.0)),
-      child: green);
-
-    RenderBox red = new RenderDecoratedBox(
-      decoration: new BoxDecoration(
-        backgroundColor: const Color(0xFFFF0000)
-      ),
-      child: size);
-
-    RenderViewport viewport = new RenderViewport(child: red, scrollOffset: new Offset(0.0, -10.0));
-    layout(viewport);
-
-    HitTestResult result;
-
-    result = new HitTestResult();
-    renderView.hitTest(result, position: new Point(15.0, 0.0));
-    expect(result.path.first.target.runtimeType, equals(TestRenderView));
-
-    result = new HitTestResult();
-    renderView.hitTest(result, position: new Point(15.0, 15.0));
-    expect(result.path.first.target, equals(green));
-  });
-}
diff --git a/sky/unit/test/services/mock_services.dart b/sky/unit/test/services/mock_services.dart
deleted file mode 100644
index 6953778..0000000
--- a/sky/unit/test/services/mock_services.dart
+++ /dev/null
@@ -1,31 +0,0 @@
-import 'package:flutter/src/services/shell.dart' as shell;
-
-// Tests can use ServiceMocker to register replacement implementations
-// of Mojo services.
-class _ServiceMocker {
-  _ServiceMocker() {
-    shell.overrideConnectToService = _connectToService;
-  }
-
-  // Map of interface names to mock implementations.
-  Map<String, Object> _interfaceMock = new Map<String, Object>();
-
-  bool _connectToService(String url, dynamic proxy) {
-    Object mock = _interfaceMock[proxy.impl.name];
-    if (mock != null) {
-      // Replace the proxy's implementation of the service interface with the
-      // mock.
-      proxy.ptr = mock;
-      return true;
-    } else {
-      return false;
-    }
-  }
-
-  // Provide a mock implementation for a Mojo interface.
-  void registerMockService(String interfaceName, Object mock) {
-    _interfaceMock[interfaceName] = mock;
-  }
-}
-
-final _ServiceMocker serviceMocker = new _ServiceMocker();
diff --git a/sky/unit/test/widget/align_test.dart b/sky/unit/test/widget/align_test.dart
deleted file mode 100644
index 6d3d05f..0000000
--- a/sky/unit/test/widget/align_test.dart
+++ /dev/null
@@ -1,47 +0,0 @@
-import 'package:flutter/rendering.dart';
-import 'package:flutter/widgets.dart';
-import 'package:test/test.dart';
-
-import 'widget_tester.dart';
-
-void main() {
-  test('Align smoke test', () {
-    testWidgets((WidgetTester tester) {
-      tester.pumpWidget(
-        new Align(
-          child: new Container(),
-          alignment: const FractionalOffset(0.75, 0.75)
-        )
-      );
-
-      tester.pumpWidget(
-        new Align(
-          child: new Container(),
-          alignment: const FractionalOffset(0.5, 0.5)
-        )
-      );
-    });
-  });
-
-  test('Shrink wraps in finite space', () {
-    testWidgets((WidgetTester tester) {
-      GlobalKey alignKey = new GlobalKey();
-      tester.pumpWidget(
-        new ScrollableViewport(
-          child: new Align(
-            key: alignKey,
-            child: new Container(
-              width: 10.0,
-              height: 10.0
-            ),
-            alignment: const FractionalOffset(0.50, 0.50)
-          )
-        )
-      );
-
-      RenderBox box = alignKey.currentContext.findRenderObject();
-      expect(box.size.width, equals(800.0));
-      expect(box.size.height, equals(10.0));
-    });
-  });
-}
diff --git a/sky/unit/test/widget/animated_container_test.dart b/sky/unit/test/widget/animated_container_test.dart
deleted file mode 100644
index 653f20f..0000000
--- a/sky/unit/test/widget/animated_container_test.dart
+++ /dev/null
@@ -1,96 +0,0 @@
-import 'package:flutter/animation.dart';
-import 'package:flutter/rendering.dart';
-import 'package:flutter/widgets.dart';
-import 'package:test/test.dart';
-
-import 'widget_tester.dart';
-
-void main() {
-  test('AnimatedContainer control test', () {
-    testWidgets((WidgetTester tester) {
-      GlobalKey key = new GlobalKey();
-
-      BoxDecoration decorationA = new BoxDecoration(
-        backgroundColor: new Color(0xFF00FF00)
-      );
-
-      BoxDecoration decorationB = new BoxDecoration(
-        backgroundColor: new Color(0xFF0000FF)
-      );
-
-      tester.pumpWidget(
-        new AnimatedContainer(
-          key: key,
-          duration: const Duration(milliseconds: 200),
-          decoration: decorationA
-        )
-      );
-
-      RenderDecoratedBox box = key.currentState.context.findRenderObject();
-      expect(box.decoration.backgroundColor, equals(decorationA.backgroundColor));
-
-      tester.pumpWidget(
-        new AnimatedContainer(
-          key: key,
-          duration: const Duration(milliseconds: 200),
-          decoration: decorationB
-        )
-      );
-
-      expect(key.currentState.context.findRenderObject(), equals(box));
-      expect(box.decoration.backgroundColor, equals(decorationA.backgroundColor));
-
-      tester.pump(const Duration(seconds: 1));
-
-      expect(box.decoration.backgroundColor, equals(decorationB.backgroundColor));
-
-    });
-  });
-
-  test('AnimatedContainer overanimate test', () {
-    testWidgets((WidgetTester tester) {
-      tester.pumpWidget(
-        new AnimatedContainer(
-          duration: const Duration(milliseconds: 200),
-          decoration: new BoxDecoration(
-            backgroundColor: new Color(0xFF00FF00)
-          )
-        )
-      );
-      expect(scheduler.transientCallbackCount, 0);
-      tester.pump(new Duration(seconds: 1));
-      expect(scheduler.transientCallbackCount, 0);
-      tester.pumpWidget(
-        new AnimatedContainer(
-          duration: const Duration(milliseconds: 200),
-          decoration: new BoxDecoration(
-            backgroundColor: new Color(0xFF00FF00)
-          )
-        )
-      );
-      expect(scheduler.transientCallbackCount, 0);
-      tester.pump(new Duration(seconds: 1));
-      expect(scheduler.transientCallbackCount, 0);
-      tester.pumpWidget(
-        new AnimatedContainer(
-          duration: const Duration(milliseconds: 200),
-          decoration: new BoxDecoration(
-            backgroundColor: new Color(0xFF0000FF)
-          )
-        )
-      );
-      expect(scheduler.transientCallbackCount, 1); // this is the only time an animation should have started!
-      tester.pump(new Duration(seconds: 1));
-      expect(scheduler.transientCallbackCount, 0);
-      tester.pumpWidget(
-        new AnimatedContainer(
-          duration: const Duration(milliseconds: 200),
-          decoration: new BoxDecoration(
-            backgroundColor: new Color(0xFF0000FF)
-          )
-        )
-      );
-      expect(scheduler.transientCallbackCount, 0);
-    });
-  });
-}
diff --git a/sky/unit/test/widget/block_test.dart b/sky/unit/test/widget/block_test.dart
deleted file mode 100644
index b0722d9..0000000
--- a/sky/unit/test/widget/block_test.dart
+++ /dev/null
@@ -1,63 +0,0 @@
-import 'package:flutter/widgets.dart';
-import 'package:test/test.dart';
-
-import '../engine/mock_events.dart';
-import 'widget_tester.dart';
-
-final Key blockKey = new Key('test');
-
-void main() {
-  test('Cannot scroll a non-overflowing block', () {
-    testWidgets((WidgetTester tester) {
-      tester.pumpWidget(
-        new Block(<Widget>[
-          new Container(
-            height: 200.0, // less than 600, the height of the test area
-            child: new Text('Hello')
-          )
-        ],
-        key: blockKey)
-      );
-      tester.pump(); // for SizeObservers
-
-      Point middleOfContainer = tester.getCenter(tester.findText('Hello'));
-      Point target = tester.getCenter(tester.findElementByKey(blockKey));
-      TestPointer pointer = new TestPointer();
-      tester.dispatchEvent(pointer.down(target), target);
-      tester.dispatchEvent(pointer.move(target + const Offset(0.0, -10.0)), target);
-
-      tester.pump(const Duration(milliseconds: 1));
-
-      expect(tester.getCenter(tester.findText('Hello')) == middleOfContainer, isTrue);
-
-      tester.dispatchEvent(pointer.up(), target);
-    });
-  });
-
-  test('Can scroll an overflowing block', () {
-    testWidgets((WidgetTester tester) {
-      tester.pumpWidget(
-        new Block(<Widget>[
-          new Container(
-            height: 2000.0, // more than 600, the height of the test area
-            child: new Text('Hello')
-          )
-        ],
-        key: blockKey)
-      );
-      tester.pump(); // for SizeObservers
-
-      Point middleOfContainer = tester.getCenter(tester.findText('Hello'));
-      Point target = tester.getCenter(tester.findElementByKey(blockKey));
-      TestPointer pointer = new TestPointer();
-      tester.dispatchEvent(pointer.down(target), target);
-      tester.dispatchEvent(pointer.move(target + const Offset(0.0, -10.0)), target);
-
-      tester.pump(const Duration(milliseconds: 1));
-
-      expect(tester.getCenter(tester.findText('Hello')) == middleOfContainer, isFalse);
-
-      tester.dispatchEvent(pointer.up(), target);
-    });
-  });
-}
diff --git a/sky/unit/test/widget/bottom_sheet_test.dart b/sky/unit/test/widget/bottom_sheet_test.dart
deleted file mode 100644
index 39f308d..0000000
--- a/sky/unit/test/widget/bottom_sheet_test.dart
+++ /dev/null
@@ -1,47 +0,0 @@
-import 'package:flutter/material.dart';
-import 'package:flutter/widgets.dart';
-import 'package:test/test.dart';
-
-import 'widget_tester.dart';
-
-void main() {
-  test('Verify that a tap dismisses the BottomSheet', () {
-    testWidgets((WidgetTester tester) {
-      BuildContext context;
-      tester.pumpWidget(new MaterialApp(
-          routes: <String, RouteBuilder>{
-            '/': (RouteArguments args) {
-              context = args.context;
-              return new Container();
-            }
-          }
-      ));
-
-      tester.pump();
-      expect(tester.findText('BottomSheet'), isNull);
-
-      showModalBottomSheet(context: context, child: new Text('BottomSheet'));
-      tester.pump(); // bottom sheet show animation starts
-      tester.pump(new Duration(seconds: 1)); // animation done
-      expect(tester.findText('BottomSheet'), isNotNull);
-
-      // Tap on the the bottom sheet itself to dismiss it
-      tester.tap(tester.findText('BottomSheet'));
-      tester.pump(); // bottom sheet dismiss animation starts
-      tester.pump(new Duration(seconds: 1)); // animation done
-      expect(tester.findText('BottomSheet'), isNull);
-
-      showModalBottomSheet(context: context, child: new Text('BottomSheet'));
-      tester.pump(); // bottom sheet show animation starts
-      tester.pump(new Duration(seconds: 1)); // animation done
-      expect(tester.findText('BottomSheet'), isNotNull);
-
-      // Tap above the the bottom sheet to dismiss it
-      tester.tapAt(new Point(20.0, 20.0));
-      tester.pump(); // bottom sheet dismiss animation starts
-      tester.pump(new Duration(seconds: 1)); // animation done
-      expect(tester.findText('BottomSheet'), isNull);
-    });
-  });
-
-}
diff --git a/sky/unit/test/widget/box_decoration_test.dart b/sky/unit/test/widget/box_decoration_test.dart
deleted file mode 100644
index 57bdcd4..0000000
--- a/sky/unit/test/widget/box_decoration_test.dart
+++ /dev/null
@@ -1,22 +0,0 @@
-import 'package:flutter/material.dart';
-import 'package:flutter/widgets.dart';
-import 'package:test/test.dart';
-
-import 'widget_tester.dart';
-
-void main() {
-  test('Circles can have uniform borders', () {
-    testWidgets((WidgetTester tester) {
-      tester.pumpWidget(
-        new Container(
-          padding: new EdgeDims.all(50.0),
-          decoration: new BoxDecoration(
-            shape: Shape.circle,
-            border: new Border.all(width: 10.0, color: const Color(0x80FF00FF)),
-            backgroundColor: Colors.teal[600]
-          )
-        )
-      );
-    });
-  });
-}
diff --git a/sky/unit/test/widget/build_scope_test.dart b/sky/unit/test/widget/build_scope_test.dart
deleted file mode 100644
index ccb8788..0000000
--- a/sky/unit/test/widget/build_scope_test.dart
+++ /dev/null
@@ -1,133 +0,0 @@
-import 'package:flutter/animation.dart';
-import 'package:flutter/widgets.dart';
-import 'package:test/test.dart';
-
-import 'widget_tester.dart';
-import 'test_widgets.dart';
-
-class ProbeWidget extends StatefulComponent {
-  ProbeWidgetState createState() => new ProbeWidgetState();
-}
-
-class ProbeWidgetState extends State<ProbeWidget> {
-  static int buildCount = 0;
-
-  void initState() {
-    super.initState();
-    setState(() {});
-  }
-
-  void didUpdateConfig(ProbeWidget oldConfig) {
-    setState(() {});
-  }
-
-  Widget build(BuildContext context) {
-    setState(() {});
-    buildCount++;
-    return new Container();
-  }
-}
-
-class BadWidget extends StatelessComponent {
-  BadWidget(this.parentState);
-
-  final State parentState;
-
-  Widget build(BuildContext context) {
-    parentState.setState(() {});
-    return new Container();
-  }
-}
-
-class BadWidgetParent extends StatefulComponent {
-  BadWidgetParentState createState() => new BadWidgetParentState();
-}
-
-class BadWidgetParentState extends State<BadWidgetParent> {
-  Widget build(BuildContext context) {
-    return new BadWidget(this);
-  }
-}
-
-class BadDisposeWidget extends StatefulComponent {
-  BadDisposeWidgetState createState() => new BadDisposeWidgetState();
-}
-
-class BadDisposeWidgetState extends State<BadDisposeWidget> {
-  Widget build(BuildContext context) {
-    return new Container();
-  }
-
-  void dispose() {
-    setState(() {});
-    super.dispose();
-  }
-}
-
-void main() {
-  dynamic cachedException;
-
-  // ** WARNING **
-  // THIS TEST OVERRIDES THE NORMAL EXCEPTION HANDLING
-  // AND DOES NOT REPORT EXCEPTIONS FROM THE FRAMEWORK
-
-  setUp(() {
-    assert(cachedException == null);
-    debugWidgetsExceptionHandler = (String context, dynamic exception, StackTrace stack) {
-      cachedException = exception;
-    };
-    debugSchedulerExceptionHandler = (dynamic exception, StackTrace stack) { throw exception; };
-  });
-
-  tearDown(() {
-    assert(cachedException == null);
-    cachedException = null;
-    debugWidgetsExceptionHandler = null;
-    debugSchedulerExceptionHandler = null;
-  });
-
-  test('Legal times for setState', () {
-    testWidgets((WidgetTester tester) {
-      GlobalKey flipKey = new GlobalKey();
-      expect(ProbeWidgetState.buildCount, equals(0));
-      tester.pumpWidget(new ProbeWidget());
-      expect(ProbeWidgetState.buildCount, equals(1));
-      tester.pumpWidget(new ProbeWidget());
-      expect(ProbeWidgetState.buildCount, equals(2));
-      tester.pumpWidget(new FlipComponent(
-        key: flipKey,
-        left: new Container(),
-        right: new ProbeWidget()
-      ));
-      expect(ProbeWidgetState.buildCount, equals(2));
-      (flipKey.currentState as FlipComponentState).flip();
-      tester.pump();
-      expect(ProbeWidgetState.buildCount, equals(3));
-      (flipKey.currentState as FlipComponentState).flip();
-      tester.pump();
-      expect(ProbeWidgetState.buildCount, equals(3));
-      tester.pumpWidget(new Container());
-      expect(ProbeWidgetState.buildCount, equals(3));
-    });
-  });
-
-  test('Setting parent state during build is forbidden', () {
-    testWidgets((WidgetTester tester) {
-      expect(cachedException, isNull);
-      tester.pumpWidget(new BadWidgetParent());
-      expect(cachedException, isNotNull);
-      cachedException = null;
-      tester.pumpWidget(new Container());
-      expect(cachedException, isNull);
-    });
-  });
-
-  test('Setting state during dispose is forbidden', () {
-    testWidgets((WidgetTester tester) {
-      tester.pumpWidget(new BadDisposeWidget());
-      expect(() {
-        tester.pumpWidget(new Container());
-      }, throws);
-    });
-  });
-}
diff --git a/sky/unit/test/widget/center_test.dart b/sky/unit/test/widget/center_test.dart
deleted file mode 100644
index ee21e6b..0000000
--- a/sky/unit/test/widget/center_test.dart
+++ /dev/null
@@ -1,12 +0,0 @@
-import 'package:flutter/widgets.dart';
-import 'package:test/test.dart';
-
-import 'widget_tester.dart';
-
-void main() {
-  test('Can be placed in an infinte box', () {
-    testWidgets((WidgetTester tester) {
-      tester.pumpWidget(new Block(<Widget>[new Center()]));
-    });
-  });
-}
diff --git a/sky/unit/test/widget/coordinates_test.dart b/sky/unit/test/widget/coordinates_test.dart
deleted file mode 100644
index 3bd3808..0000000
--- a/sky/unit/test/widget/coordinates_test.dart
+++ /dev/null
@@ -1,46 +0,0 @@
-import 'package:flutter/rendering.dart';
-import 'package:flutter/widgets.dart';
-import 'package:test/test.dart';
-
-import 'widget_tester.dart';
-
-void main() {
-  test('Comparing coordinates', () {
-    testWidgets((WidgetTester tester) {
-      Key keyA = new GlobalKey();
-      Key keyB = new GlobalKey();
-
-      tester.pumpWidget(
-        new Stack(<Widget>[
-          new Positioned(
-            top: 100.0,
-            left: 100.0,
-            child: new SizedBox(
-              key: keyA,
-              width: 10.0,
-              height: 10.0
-            )
-          ),
-          new Positioned(
-            left: 100.0,
-            top: 200.0,
-            child: new SizedBox(
-              key: keyB,
-              width: 20.0,
-              height: 10.0
-            )
-          ),
-        ])
-      );
-
-      expect((tester.findElementByKey(keyA).renderObject as RenderBox).localToGlobal(const Point(0.0, 0.0)),
-             equals(const Point(100.0, 100.0)));
-
-      expect((tester.findElementByKey(keyB).renderObject as RenderBox).localToGlobal(const Point(0.0, 0.0)),
-             equals(const Point(100.0, 200.0)));
-
-      expect((tester.findElementByKey(keyB).renderObject as RenderBox).globalToLocal(const Point(110.0, 205.0)),
-             equals(const Point(10.0, 5.0)));
-    });
-  });
-}
diff --git a/sky/unit/test/widget/custom_multi_child_layout_test.dart b/sky/unit/test/widget/custom_multi_child_layout_test.dart
deleted file mode 100644
index 3a4cb19..0000000
--- a/sky/unit/test/widget/custom_multi_child_layout_test.dart
+++ /dev/null
@@ -1,61 +0,0 @@
-import 'package:flutter/rendering.dart';
-import 'package:flutter/widgets.dart';
-import 'package:test/test.dart';
-
-import 'widget_tester.dart';
-
-class TestMultiChildLayoutDelegate extends MultiChildLayoutDelegate {
-  BoxConstraints getSizeConstraints;
-
-  Size getSize(BoxConstraints constraints) {
-    getSizeConstraints = constraints;
-    return new Size(200.0, 300.0);
-  }
-
-  Size performLayoutSize;
-  BoxConstraints performLayoutConstraints;
-  Size performLayoutSize0;
-  Size performLayoutSize1;
-  bool performLayoutIsChild;
-
-  void performLayout(Size size, BoxConstraints constraints) {
-    performLayoutSize = size;
-    performLayoutConstraints = constraints;
-    performLayoutSize0 = layoutChild(0, constraints);
-    performLayoutSize1 = layoutChild(1, constraints);
-    performLayoutIsChild = isChild('fred');
-  }
-}
-
-void main() {
-  test('Control test for CustomMultiChildLayout', () {
-    testWidgets((WidgetTester tester) {
-      TestMultiChildLayoutDelegate delegate = new TestMultiChildLayoutDelegate();
-      tester.pumpWidget(new Center(
-        child: new CustomMultiChildLayout([
-          new LayoutId(id: 0, child: new Container(width: 150.0, height: 100.0)),
-          new LayoutId(id: 1, child: new Container(width: 100.0, height: 200.0))
-        ],
-          delegate: delegate
-        )
-      ));
-
-      expect(delegate.getSizeConstraints.minWidth, 0.0);
-      expect(delegate.getSizeConstraints.maxWidth, 800.0);
-      expect(delegate.getSizeConstraints.minHeight, 0.0);
-      expect(delegate.getSizeConstraints.maxHeight, 600.0);
-
-      expect(delegate.performLayoutSize.width, 200.0);
-      expect(delegate.performLayoutSize.height, 300.0);
-      expect(delegate.performLayoutConstraints.minWidth, 0.0);
-      expect(delegate.performLayoutConstraints.maxWidth, 800.0);
-      expect(delegate.performLayoutConstraints.minHeight, 0.0);
-      expect(delegate.performLayoutConstraints.maxHeight, 600.0);
-      expect(delegate.performLayoutSize0.width, 150.0);
-      expect(delegate.performLayoutSize0.height, 100.0);
-      expect(delegate.performLayoutSize1.width, 100.0);
-      expect(delegate.performLayoutSize1.height, 200.0);
-      expect(delegate.performLayoutIsChild, false);
-    });
-  });
-}
diff --git a/sky/unit/test/widget/custom_one_child_layout_test.dart b/sky/unit/test/widget/custom_one_child_layout_test.dart
deleted file mode 100644
index 6010414..0000000
--- a/sky/unit/test/widget/custom_one_child_layout_test.dart
+++ /dev/null
@@ -1,59 +0,0 @@
-import 'package:flutter/widgets.dart';
-import 'package:test/test.dart';
-
-import 'widget_tester.dart';
-
-class TestOneChildLayoutDelegate extends OneChildLayoutDelegate {
-  BoxConstraints constraintsFromGetSize;
-  BoxConstraints constraintsFromGetConstraintsForChild;
-  Size sizeFromGetPositionForChild;
-  Size childSizeFromGetPositionForChild;
-
-  Size getSize(BoxConstraints constraints) {
-    constraintsFromGetSize = constraints;
-    return new Size(200.0, 300.0);
-  }
-
-  BoxConstraints getConstraintsForChild(BoxConstraints constraints) {
-    constraintsFromGetConstraintsForChild = constraints;
-    return new BoxConstraints(
-      minWidth: 100.0,
-      maxWidth: 150.0,
-      minHeight: 200.0,
-      maxHeight: 400.0
-    );
-  }
-
-  Point getPositionForChild(Size size, Size childSize) {
-    sizeFromGetPositionForChild = size;
-    childSizeFromGetPositionForChild = childSize;
-    return Point.origin;
-  }
-}
-
-void main() {
-  test('Control test for CustomOneChildLayout', () {
-    testWidgets((WidgetTester tester) {
-      TestOneChildLayoutDelegate delegate = new TestOneChildLayoutDelegate();
-      tester.pumpWidget(new Center(
-        child: new CustomOneChildLayout(delegate: delegate, child: new Container())
-      ));
-
-      expect(delegate.constraintsFromGetSize.minWidth, 0.0);
-      expect(delegate.constraintsFromGetSize.maxWidth, 800.0);
-      expect(delegate.constraintsFromGetSize.minHeight, 0.0);
-      expect(delegate.constraintsFromGetSize.maxHeight, 600.0);
-
-      expect(delegate.constraintsFromGetConstraintsForChild.minWidth, 0.0);
-      expect(delegate.constraintsFromGetConstraintsForChild.maxWidth, 800.0);
-      expect(delegate.constraintsFromGetConstraintsForChild.minHeight, 0.0);
-      expect(delegate.constraintsFromGetConstraintsForChild.maxHeight, 600.0);
-
-      expect(delegate.sizeFromGetPositionForChild.width, 200.0);
-      expect(delegate.sizeFromGetPositionForChild.height, 300.0);
-
-      expect(delegate.childSizeFromGetPositionForChild.width, 150.0);
-      expect(delegate.childSizeFromGetPositionForChild.height, 400.0);
-    });
-  });
-}
diff --git a/sky/unit/test/widget/date_picker_test.dart b/sky/unit/test/widget/date_picker_test.dart
deleted file mode 100644
index 0fdbdc4..0000000
--- a/sky/unit/test/widget/date_picker_test.dart
+++ /dev/null
@@ -1,34 +0,0 @@
-import 'package:flutter/material.dart';
-import 'package:test/test.dart';
-
-import 'widget_tester.dart';
-
-void main() {
-  test('Can select a day', () {
-    testWidgets((WidgetTester tester) {
-      DateTime currentValue;
-
-      Widget widget = new Block(<Widget>[
-        new DatePicker(
-          selectedDate: new DateTime.utc(2015, 6, 9, 7, 12),
-          firstDate: new DateTime.utc(2013),
-          lastDate: new DateTime.utc(2018),
-          onChanged: (DateTime dateTime) {
-            currentValue = dateTime;
-          }
-        )
-      ]);
-
-      tester.pumpWidget(widget);
-
-      expect(currentValue, isNull);
-      tester.tap(tester.findText('2015'));
-      tester.pumpWidget(widget);
-      tester.tap(tester.findText('2014'));
-      tester.pumpWidget(widget);
-      expect(currentValue, equals(new DateTime(2014, 6, 9)));
-      tester.tap(tester.findText('30'));
-      expect(currentValue, equals(new DateTime(2013, 1, 30)));
-    });
-  });
-}
diff --git a/sky/unit/test/widget/dismissable_test.dart b/sky/unit/test/widget/dismissable_test.dart
deleted file mode 100644
index 3c717f2..0000000
--- a/sky/unit/test/widget/dismissable_test.dart
+++ /dev/null
@@ -1,282 +0,0 @@
-import 'package:flutter/rendering.dart';
-import 'package:flutter/widgets.dart';
-import 'package:test/test.dart';
-
-import '../engine/mock_events.dart';
-import 'widget_tester.dart';
-
-const double itemExtent = 100.0;
-ScrollDirection scrollDirection = ScrollDirection.vertical;
-DismissDirection dismissDirection = DismissDirection.horizontal;
-List<int> dismissedItems = <int>[];
-
-void handleOnResized(item) {
-  expect(dismissedItems.contains(item), isFalse);
-}
-
-void handleOnDismissed(item) {
-  expect(dismissedItems.contains(item), isFalse);
-  dismissedItems.add(item);
-}
-
-Widget buildDismissableItem(BuildContext context, int item) {
-  return new Dismissable(
-    key: new ValueKey<int>(item),
-    direction: dismissDirection,
-    onDismissed: () { handleOnDismissed(item); },
-    onResized: () { handleOnResized(item); },
-    child: new Container(
-      width: itemExtent,
-      height: itemExtent,
-      child: new Text(item.toString())
-    )
-  );
-}
-
-Widget widgetBuilder() {
-  return new Container(
-    padding: const EdgeDims.all(10.0),
-    child: new ScrollableList<int>(
-      items: [0, 1, 2, 3, 4].where((int i) => !dismissedItems.contains(i)).toList(),
-      itemBuilder: buildDismissableItem,
-      scrollDirection: scrollDirection,
-      itemExtent: itemExtent
-    )
-  );
-}
-
-void dismissElement(WidgetTester tester, Element itemElement, { DismissDirection gestureDirection }) {
-  assert(itemElement != null);
-  assert(gestureDirection != DismissDirection.horizontal);
-  assert(gestureDirection != DismissDirection.vertical);
-
-  Point downLocation;
-  Point upLocation;
-  switch(gestureDirection) {
-    case DismissDirection.left:
-      // Note: getTopRight() returns a point that's just beyond
-      // itemWidget's right edge and outside the Dismissable event
-      // listener's bounds.
-      downLocation = tester.getTopRight(itemElement) + const Offset(-0.1, 0.0);
-      upLocation = tester.getTopLeft(itemElement);
-      break;
-    case DismissDirection.right:
-      downLocation = tester.getTopLeft(itemElement);
-      upLocation = tester.getTopRight(itemElement);
-      break;
-    case DismissDirection.up:
-      // Note: getBottomLeft() returns a point that's just below
-      // itemWidget's bottom edge and outside the Dismissable event
-      // listener's bounds.
-      downLocation = tester.getBottomLeft(itemElement) + const Offset(0.0, -0.1);
-      upLocation = tester.getTopLeft(itemElement);
-      break;
-    case DismissDirection.down:
-      downLocation = tester.getTopLeft(itemElement);
-      upLocation = tester.getBottomLeft(itemElement);
-      break;
-    default:
-      fail("unsupported gestureDirection");
-  }
-
-  TestPointer pointer = new TestPointer(5);
-  tester.dispatchEvent(pointer.down(downLocation), downLocation);
-  tester.dispatchEvent(pointer.move(upLocation), downLocation);
-  tester.dispatchEvent(pointer.up(), downLocation);
-}
-
-void dismissItem(WidgetTester tester, int item, { DismissDirection gestureDirection }) {
-  assert(gestureDirection != DismissDirection.horizontal);
-  assert(gestureDirection != DismissDirection.vertical);
-
-  Element itemElement = tester.findText(item.toString());
-  expect(itemElement, isNotNull);
-
-  dismissElement(tester, itemElement, gestureDirection: gestureDirection);
-
-  tester.pumpWidget(widgetBuilder()); // start the resize animation
-  tester.pumpWidget(widgetBuilder(), const Duration(seconds: 1)); // finish the resize animation
-  tester.pumpWidget(widgetBuilder(), const Duration(seconds: 1)); // dismiss
-}
-
-class Test1215DismissableComponent extends StatelessComponent {
-  Test1215DismissableComponent(this.text);
-  final String text;
-  Widget build(BuildContext context) {
-    return new Dismissable(
-      child: new AspectRatio(
-        aspectRatio: 1.0,
-        child: new Text(this.text)
-      )
-    );
-  }
-}
-
-void main() {
-  test('Horizontal drag triggers dismiss scrollDirection=vertical', () {
-    testWidgets((WidgetTester tester) {
-      scrollDirection = ScrollDirection.vertical;
-      dismissDirection = DismissDirection.horizontal;
-      dismissedItems = <int>[];
-
-      tester.pumpWidget(widgetBuilder());
-      expect(dismissedItems, isEmpty);
-
-      dismissItem(tester, 0, gestureDirection: DismissDirection.right);
-      expect(tester.findText('0'), isNull);
-      expect(dismissedItems, equals([0]));
-
-      dismissItem(tester, 1, gestureDirection: DismissDirection.left);
-      expect(tester.findText('1'), isNull);
-      expect(dismissedItems, equals([0, 1]));
-    });
-  });
-
-  test('Vertical drag triggers dismiss scrollDirection=horizontal', () {
-    testWidgets((WidgetTester tester) {
-      scrollDirection = ScrollDirection.horizontal;
-      dismissDirection = DismissDirection.vertical;
-      dismissedItems = <int>[];
-
-      tester.pumpWidget(widgetBuilder());
-      expect(dismissedItems, isEmpty);
-
-      dismissItem(tester, 0, gestureDirection: DismissDirection.up);
-      expect(tester.findText('0'), isNull);
-      expect(dismissedItems, equals([0]));
-
-      dismissItem(tester, 1, gestureDirection: DismissDirection.down);
-      expect(tester.findText('1'), isNull);
-      expect(dismissedItems, equals([0, 1]));
-    });
-  });
-
-  test('drag-left with DismissDirection.left triggers dismiss', () {
-    testWidgets((WidgetTester tester) {
-      scrollDirection = ScrollDirection.vertical;
-      dismissDirection = DismissDirection.left;
-      dismissedItems = <int>[];
-
-      tester.pumpWidget(widgetBuilder());
-      expect(dismissedItems, isEmpty);
-
-      dismissItem(tester, 0, gestureDirection: DismissDirection.right);
-      expect(tester.findText('0'), isNotNull);
-      expect(dismissedItems, isEmpty);
-
-      dismissItem(tester, 0, gestureDirection: DismissDirection.left);
-      expect(tester.findText('0'), isNull);
-      expect(dismissedItems, equals([0]));
-    });
-  });
-
-  test('drag-right with DismissDirection.right triggers dismiss', () {
-    testWidgets((WidgetTester tester) {
-      scrollDirection = ScrollDirection.vertical;
-      dismissDirection = DismissDirection.right;
-      dismissedItems = <int>[];
-
-      tester.pumpWidget(widgetBuilder());
-      expect(dismissedItems, isEmpty);
-
-      dismissItem(tester, 0, gestureDirection: DismissDirection.left);
-      expect(tester.findText('0'), isNotNull);
-      expect(dismissedItems, isEmpty);
-
-      dismissItem(tester, 0, gestureDirection: DismissDirection.right);
-      expect(tester.findText('0'), isNull);
-      expect(dismissedItems, equals([0]));
-    });
-  });
-
-  test('drag-up with DismissDirection.up triggers dismiss', () {
-    testWidgets((WidgetTester tester) {
-      scrollDirection = ScrollDirection.horizontal;
-      dismissDirection = DismissDirection.up;
-      dismissedItems = <int>[];
-
-      tester.pumpWidget(widgetBuilder());
-      expect(dismissedItems, isEmpty);
-
-      dismissItem(tester, 0, gestureDirection: DismissDirection.down);
-      expect(tester.findText('0'), isNotNull);
-      expect(dismissedItems, isEmpty);
-
-      dismissItem(tester, 0, gestureDirection: DismissDirection.up);
-      expect(tester.findText('0'), isNull);
-      expect(dismissedItems, equals([0]));
-    });
-  });
-
-  test('drag-down with DismissDirection.down triggers dismiss', () {
-    testWidgets((WidgetTester tester) {
-      scrollDirection = ScrollDirection.horizontal;
-      dismissDirection = DismissDirection.down;
-      dismissedItems = <int>[];
-
-      tester.pumpWidget(widgetBuilder());
-      expect(dismissedItems, isEmpty);
-
-      dismissItem(tester, 0, gestureDirection: DismissDirection.up);
-      expect(tester.findText('0'), isNotNull);
-      expect(dismissedItems, isEmpty);
-
-      dismissItem(tester, 0, gestureDirection: DismissDirection.down);
-      expect(tester.findText('0'), isNull);
-      expect(dismissedItems, equals([0]));
-    });
-  });
-
-  // This is a regression test for
-  // https://github.com/domokit/sky_engine/issues/1068
-  test('Verify that drag-move events do not assert', () {
-    testWidgets((WidgetTester tester) {
-      scrollDirection = ScrollDirection.horizontal;
-      dismissDirection = DismissDirection.down;
-      dismissedItems = <int>[];
-
-      tester.pumpWidget(widgetBuilder());
-      Element itemElement = tester.findText('0');
-
-      TestPointer pointer = new TestPointer(5);
-      Point location = tester.getTopLeft(itemElement);
-      Offset offset = new Offset(0.0, 5.0);
-      tester.dispatchEvent(pointer.down(location), location);
-      tester.dispatchEvent(pointer.move(location + offset), location);
-      tester.pumpWidget(widgetBuilder());
-      tester.dispatchEvent(pointer.move(location + (offset * 2.0)), location);
-      tester.pumpWidget(widgetBuilder());
-      tester.dispatchEvent(pointer.move(location + (offset * 3.0)), location);
-      tester.pumpWidget(widgetBuilder());
-      tester.dispatchEvent(pointer.move(location + (offset * 4.0)), location);
-      tester.pumpWidget(widgetBuilder());
-    });
-  });
-
-  // This one is for
-  // https://github.com/flutter/engine/issues/1215
-  test('dismissing bottom then top (smoketest)', () {
-    testWidgets((WidgetTester tester) {
-      tester.pumpWidget(new Center(
-        child: new Container(
-          width: 100.0,
-          height: 1000.0,
-          child: new Column(<Widget>[
-            new Test1215DismissableComponent('1'),
-            new Test1215DismissableComponent('2')
-          ])
-        )
-      ));
-      expect(tester.findText('1'), isNotNull);
-      expect(tester.findText('2'), isNotNull);
-      dismissElement(tester, tester.findText('2'), gestureDirection: DismissDirection.right);
-      tester.pump(new Duration(seconds: 1));
-      expect(tester.findText('1'), isNotNull);
-      expect(tester.findText('2'), isNull);
-      dismissElement(tester, tester.findText('1'), gestureDirection: DismissDirection.right);
-      tester.pump(new Duration(seconds: 1));
-      expect(tester.findText('1'), isNull);
-      expect(tester.findText('2'), isNull);
-    });
-  });
-}
diff --git a/sky/unit/test/widget/draggable_test.dart b/sky/unit/test/widget/draggable_test.dart
deleted file mode 100644
index 38d8994..0000000
--- a/sky/unit/test/widget/draggable_test.dart
+++ /dev/null
@@ -1,70 +0,0 @@
-import 'package:flutter/material.dart';
-import 'package:test/test.dart';
-
-import '../engine/mock_events.dart';
-import 'widget_tester.dart';
-
-void main() {
-  test('Drag and drop - control test', () {
-    testWidgets((WidgetTester tester) {
-      TestPointer pointer = new TestPointer(7);
-
-      List accepted = [];
-
-      tester.pumpWidget(new MaterialApp(
-        routes: <String, RouteBuilder>{
-          '/': (RouteArguments args) { return new Column(<Widget>[
-              new Draggable(
-                data: 1,
-                child: new Text('Source'),
-                feedback: new Text('Dragging')
-              ),
-              new DragTarget(
-                builder: (context, data, rejects) {
-                  return new Container(
-                    height: 100.0,
-                    child: new Text('Target')
-                  );
-                },
-                onAccept: (data) {
-                  accepted.add(data);
-                }
-              ),
-            ]);
-          },
-        }
-      ));
-
-      expect(accepted, isEmpty);
-      expect(tester.findText('Source'), isNotNull);
-      expect(tester.findText('Dragging'), isNull);
-      expect(tester.findText('Target'), isNotNull);
-
-      Point firstLocation = tester.getCenter(tester.findText('Source'));
-      tester.dispatchEvent(pointer.down(firstLocation), firstLocation);
-      tester.pump();
-
-      expect(accepted, isEmpty);
-      expect(tester.findText('Source'), isNotNull);
-      expect(tester.findText('Dragging'), isNotNull);
-      expect(tester.findText('Target'), isNotNull);
-
-      Point secondLocation = tester.getCenter(tester.findText('Target'));
-      tester.dispatchEvent(pointer.move(secondLocation), firstLocation);
-      tester.pump();
-
-      expect(accepted, isEmpty);
-      expect(tester.findText('Source'), isNotNull);
-      expect(tester.findText('Dragging'), isNotNull);
-      expect(tester.findText('Target'), isNotNull);
-
-      tester.dispatchEvent(pointer.up(), firstLocation);
-      tester.pump();
-
-      expect(accepted, equals([1]));
-      expect(tester.findText('Source'), isNotNull);
-      expect(tester.findText('Dragging'), isNull);
-      expect(tester.findText('Target'), isNotNull);
-    });
-  });
-}
diff --git a/sky/unit/test/widget/drawer_test.dart b/sky/unit/test/widget/drawer_test.dart
deleted file mode 100644
index 0d47078..0000000
--- a/sky/unit/test/widget/drawer_test.dart
+++ /dev/null
@@ -1,71 +0,0 @@
-import 'package:flutter/material.dart';
-import 'package:flutter/widgets.dart';
-import 'package:test/test.dart';
-
-import 'widget_tester.dart';
-
-void main() {
-
-  test('Drawer control test', () {
-    testWidgets((WidgetTester tester) {
-      BuildContext context;
-      tester.pumpWidget(
-        new MaterialApp(
-          routes: <String, RouteBuilder>{
-            '/': (RouteArguments args) {
-              context = args.context;
-              return new Container();
-            }
-          }
-        )
-      );
-      tester.pump(); // no effect
-      expect(tester.findText('drawer'), isNull);
-      showDrawer(context: context, child: new Text('drawer'));
-      tester.pump(); // drawer should be starting to animate in
-      expect(tester.findText('drawer'), isNotNull);
-      tester.pump(new Duration(seconds: 1)); // animation done
-      expect(tester.findText('drawer'), isNotNull);
-      Navigator.of(context).pop();
-      tester.pump(); // drawer should be starting to animate away
-      expect(tester.findText('drawer'), isNotNull);
-      tester.pump(new Duration(seconds: 1)); // animation done
-      expect(tester.findText('drawer'), isNull);
-    });
-  });
-
-  test('Drawer tap test', () {
-    testWidgets((WidgetTester tester) {
-      BuildContext context;
-      tester.pumpWidget(new Container()); // throw away the old App and its Navigator
-      tester.pumpWidget(
-        new MaterialApp(
-          routes: <String, RouteBuilder>{
-            '/': (RouteArguments args) {
-              context = args.context;
-              return new Container();
-            }
-          }
-        )
-      );
-      tester.pump(); // no effect
-      expect(tester.findText('drawer'), isNull);
-      showDrawer(context: context, child: new Text('drawer'));
-      tester.pump(); // drawer should be starting to animate in
-      expect(tester.findText('drawer'), isNotNull);
-      tester.pump(new Duration(seconds: 1)); // animation done
-      expect(tester.findText('drawer'), isNotNull);
-      tester.tap(tester.findText('drawer'));
-      tester.pump(); // nothing should have happened
-      expect(tester.findText('drawer'), isNotNull);
-      tester.pump(new Duration(seconds: 1)); // ditto
-      expect(tester.findText('drawer'), isNotNull);
-      tester.tapAt(const Point(750.0, 100.0)); // on the mask
-      tester.pump(); // drawer should be starting to animate away
-      expect(tester.findText('drawer'), isNotNull);
-      tester.pump(new Duration(seconds: 1)); // animation done
-      expect(tester.findText('drawer'), isNull);
-    });
-  });
-
-}
diff --git a/sky/unit/test/widget/duplicate_key_test.dart b/sky/unit/test/widget/duplicate_key_test.dart
deleted file mode 100644
index 9040b6a..0000000
--- a/sky/unit/test/widget/duplicate_key_test.dart
+++ /dev/null
@@ -1,56 +0,0 @@
-import 'package:flutter/widgets.dart';
-import 'package:test/test.dart';
-
-import 'widget_tester.dart';
-
-class Item {
-  GlobalKey key1 = new GlobalKey();
-  GlobalKey key2 = new GlobalKey();
-  String toString() => "Item($key1, $key2)";
-}
-List<Item> items = <Item>[new Item(), new Item()];
-
-class StatefulLeaf extends StatefulComponent {
-  StatefulLeaf({ GlobalKey key }) : super(key: key);
-  StatefulLeafState createState() => new StatefulLeafState();
-}
-
-class StatefulLeafState extends State<StatefulLeaf> {
-  void test() { setState(() { }); }
-  Widget build(BuildContext context) => new Text('leaf');
-}
-
-class KeyedWrapper extends StatelessComponent {
-  KeyedWrapper(this.key1, this.key2);
-  Key key1, key2;
-  Widget build(BuildContext context) {
-    return new Container(
-      key: key1,
-      child: new StatefulLeaf(
-        key: key2
-      )
-    );
-  }
-}
-
-Widget builder() {
-  return new Column(<Widget>[
-    new KeyedWrapper(items[1].key1, items[1].key2),
-    new KeyedWrapper(items[0].key1, items[0].key2)
-  ]);
-}
-
-void main() {
-  test('duplicate key smoke test', () {
-    testWidgets((WidgetTester tester) {
-      tester.pumpWidget(builder());
-      StatefulLeafState leaf = tester.findStateOfType(StatefulLeafState);
-      leaf.test();
-      tester.pump();
-      Item lastItem = items[1];
-      items.remove(lastItem);
-      items.insert(0, lastItem);
-      tester.pumpWidget(builder()); // this marks the app dirty and rebuilds it
-    });
-  });
-}
diff --git a/sky/unit/test/widget/flex_test.dart b/sky/unit/test/widget/flex_test.dart
deleted file mode 100644
index 34a2710..0000000
--- a/sky/unit/test/widget/flex_test.dart
+++ /dev/null
@@ -1,108 +0,0 @@
-import 'package:flutter/rendering.dart';
-import 'package:flutter/widgets.dart';
-import 'package:test/test.dart';
-
-import 'widget_tester.dart';
-
-void main() {
-  test('Can hit test flex children of stacks', () {
-    testWidgets((WidgetTester tester) {
-      bool didReceiveTap = false;
-      tester.pumpWidget(
-        new Container(
-          decoration: const BoxDecoration(
-            backgroundColor: const Color(0xFF00FF00)
-          ),
-          child: new Stack(<Widget>[
-            new Positioned(
-              top: 10.0,
-              left: 10.0,
-              child: new Column(<Widget>[
-                new GestureDetector(
-                  onTap: () {
-                    didReceiveTap = true;
-                  },
-                  child: new Container(
-                    decoration: const BoxDecoration(
-                      backgroundColor: const Color(0xFF0000FF)
-                    ),
-                    width: 100.0,
-                    height: 100.0,
-                    child: new Center(
-                      child: new Text('X')
-                    )
-                  )
-                )
-              ])
-            )
-          ])
-        )
-      );
-
-      tester.tap(tester.findText('X'));
-      expect(didReceiveTap, isTrue);
-    });
-  });
-
-  test('Row, Column and FlexJustifyContent.collapse', () {
-    final Key flexKey = new Key('flexKey');
-
-    // Row without justifyContent: FlexJustifyContent.collapse
-    testWidgets((WidgetTester tester) {
-      tester.pumpWidget(new Center(
-        child: new Row([
-          new Container(width: 10.0, height: 100.0),
-          new Container(width: 30.0, height: 100.0)
-        ],
-          key: flexKey
-        )
-      ));
-      RenderBox renderBox = tester.findElementByKey(flexKey).renderObject;
-      expect(renderBox.size.width, equals(800.0));
-      expect(renderBox.size.height, equals(100.0));
-
-      // Row with justifyContent: FlexJustifyContent.collapse
-      tester.pumpWidget(new Center(
-        child: new Row([
-          new Container(width: 10.0, height: 100.0),
-          new Container(width: 30.0, height: 100.0)
-        ],
-          key: flexKey,
-          justifyContent: FlexJustifyContent.collapse
-        )
-      ));
-      renderBox = tester.findElementByKey(flexKey).renderObject;
-      expect(renderBox.size.width, equals(40.0));
-      expect(renderBox.size.height, equals(100.0));
-    });
-
-    // Column without justifyContent: FlexJustifyContent.collapse
-    testWidgets((WidgetTester tester) {
-      tester.pumpWidget(new Center(
-        child: new Column([
-          new Container(width: 100.0, height: 100.0),
-          new Container(width: 100.0, height: 150.0)
-        ],
-          key: flexKey
-        )
-      ));
-      RenderBox renderBox = tester.findElementByKey(flexKey).renderObject;
-      expect(renderBox.size.width, equals(100.0));
-      expect(renderBox.size.height, equals(600.0));
-
-      // Column with justifyContent: FlexJustifyContent.collapse
-      tester.pumpWidget(new Center(
-        child: new Column([
-          new Container(width: 100.0, height: 100.0),
-          new Container(width: 100.0, height: 150.0)
-        ],
-          key: flexKey,
-          justifyContent: FlexJustifyContent.collapse
-        )
-      ));
-      renderBox = tester.findElementByKey(flexKey).renderObject;
-      expect(renderBox.size.width, equals(100.0));
-      expect(renderBox.size.height, equals(250.0));
-    });
-  });
-}
diff --git a/sky/unit/test/widget/focus_test.dart b/sky/unit/test/widget/focus_test.dart
deleted file mode 100644
index d270564..0000000
--- a/sky/unit/test/widget/focus_test.dart
+++ /dev/null
@@ -1,63 +0,0 @@
-import 'package:flutter/widgets.dart';
-import 'package:test/test.dart';
-
-import 'widget_tester.dart';
-
-class TestFocusable extends StatelessComponent {
-  TestFocusable(this.no, this.yes, GlobalKey key) : super(key: key);
-  final String no;
-  final String yes;
-  Widget build(BuildContext context) {
-    bool focused = Focus.at(context, this);
-    return new GestureDetector(
-      onTap: () { Focus.moveTo(context, this); },
-      child: new Text(focused ? yes : no)
-    );
-  }
-}
-
-void main() {
-  test('Can have multiple focused children and they update accordingly', () {
-    testWidgets((WidgetTester tester) {
-      GlobalKey keyA = new GlobalKey();
-      GlobalKey keyB = new GlobalKey();
-      tester.pumpWidget(
-        new Focus(
-          child: new Column(<Widget>[
-            // reverse these when you fix https://github.com/flutter/engine/issues/1495
-            new TestFocusable('b', 'B FOCUSED', keyB),
-            new TestFocusable('a', 'A FOCUSED', keyA),
-          ])
-        )
-      );
-      expect(tester.findText('a'),         isNull);
-      expect(tester.findText('A FOCUSED'), isNotNull);
-      expect(tester.findText('b'),         isNotNull);
-      expect(tester.findText('B FOCUSED'), isNull);
-      tester.tap(tester.findText('A FOCUSED'));
-      tester.pump();
-      expect(tester.findText('a'),         isNull);
-      expect(tester.findText('A FOCUSED'), isNotNull);
-      expect(tester.findText('b'),         isNotNull);
-      expect(tester.findText('B FOCUSED'), isNull);
-      tester.tap(tester.findText('A FOCUSED'));
-      tester.pump();
-      expect(tester.findText('a'),         isNull);
-      expect(tester.findText('A FOCUSED'), isNotNull);
-      expect(tester.findText('b'),         isNotNull);
-      expect(tester.findText('B FOCUSED'), isNull);
-      tester.tap(tester.findText('b'));
-      tester.pump();
-      expect(tester.findText('a'),         isNotNull);
-      expect(tester.findText('A FOCUSED'), isNull);
-      expect(tester.findText('b'),         isNull);
-      expect(tester.findText('B FOCUSED'), isNotNull);
-      tester.tap(tester.findText('a'));
-      tester.pump();
-      expect(tester.findText('a'),         isNull);
-      expect(tester.findText('A FOCUSED'), isNotNull);
-      expect(tester.findText('b'),         isNotNull);
-      expect(tester.findText('B FOCUSED'), isNull);
-    });
-  });
-}
diff --git a/sky/unit/test/widget/fractionally_sized_box_test.dart b/sky/unit/test/widget/fractionally_sized_box_test.dart
deleted file mode 100644
index 148486b..0000000
--- a/sky/unit/test/widget/fractionally_sized_box_test.dart
+++ /dev/null
@@ -1,37 +0,0 @@
-import 'package:flutter/rendering.dart';
-import 'package:flutter/widgets.dart';
-import 'package:test/test.dart';
-
-import 'widget_tester.dart';
-
-void main() {
-  test('FractionallySizedBox', () {
-    testWidgets((WidgetTester tester) {
-      Size detectedSize;
-      GlobalKey inner = new GlobalKey();
-      tester.pumpWidget(new OverflowBox(
-        minWidth: 0.0,
-        maxWidth: 100.0,
-        minHeight: 0.0,
-        maxHeight: 100.0,
-        child: new Center(
-          child: new FractionallySizedBox(
-            width: 0.5,
-            height: 0.25,
-            child: new SizeObserver(
-              onSizeChanged: (Size size) {
-                detectedSize = size;
-              },
-              child: new Container(
-                key: inner
-              )
-            )
-          )
-        )
-      ));
-      expect(detectedSize, equals(const Size(50.0, 25.0)));
-      RenderBox box = inner.currentContext.findRenderObject();
-      expect(box.localToGlobal(Point.origin), equals(const Point(25.0, 37.5)));
-    });
-  });
-}
diff --git a/sky/unit/test/widget/gesture_detector_test.dart b/sky/unit/test/widget/gesture_detector_test.dart
deleted file mode 100644
index 030af3c..0000000
--- a/sky/unit/test/widget/gesture_detector_test.dart
+++ /dev/null
@@ -1,202 +0,0 @@
-import 'package:flutter/widgets.dart';
-import 'package:test/test.dart';
-
-import '../engine/mock_events.dart';
-import 'widget_tester.dart';
-
-void main() {
-  test('Uncontested scrolls start immediately', () {
-    testWidgets((WidgetTester tester) {
-      TestPointer pointer = new TestPointer(7);
-
-      bool didStartDrag = false;
-      double updatedDragDelta;
-      bool didEndDrag = false;
-
-      Widget widget = new GestureDetector(
-        onVerticalDragStart: (_) {
-          didStartDrag = true;
-        },
-        onVerticalDragUpdate: (double scrollDelta) {
-          updatedDragDelta = scrollDelta;
-        },
-        onVerticalDragEnd: (Offset velocity) {
-          didEndDrag = true;
-        },
-        child: new Container(
-          decoration: const BoxDecoration(
-            backgroundColor: const Color(0xFF00FF00)
-          )
-        )
-      );
-
-      tester.pumpWidget(widget);
-      expect(didStartDrag, isFalse);
-      expect(updatedDragDelta, isNull);
-      expect(didEndDrag, isFalse);
-
-      Point firstLocation = new Point(10.0, 10.0);
-      tester.dispatchEvent(pointer.down(firstLocation), firstLocation);
-      expect(didStartDrag, isTrue);
-      didStartDrag = false;
-      expect(updatedDragDelta, isNull);
-      expect(didEndDrag, isFalse);
-
-      Point secondLocation = new Point(10.0, 9.0);
-      tester.dispatchEvent(pointer.move(secondLocation), firstLocation);
-      expect(didStartDrag, isFalse);
-      expect(updatedDragDelta, -1.0);
-      updatedDragDelta = null;
-      expect(didEndDrag, isFalse);
-
-      tester.dispatchEvent(pointer.up(), firstLocation);
-      expect(didStartDrag, isFalse);
-      expect(updatedDragDelta, isNull);
-      expect(didEndDrag, isTrue);
-      didEndDrag = false;
-
-      tester.pumpWidget(new Container());
-    });
-  });
-
-  test('Match two scroll gestures in succession', () {
-    testWidgets((WidgetTester tester) {
-      TestPointer pointer = new TestPointer(7);
-
-      int gestureCount = 0;
-      double dragDistance = 0.0;
-
-      Point downLocation = new Point(10.0, 10.0);
-      Point upLocation = new Point(10.0, 20.0);
-
-      Widget widget = new GestureDetector(
-        onVerticalDragUpdate: (double delta) { dragDistance += delta; },
-        onVerticalDragEnd: (Offset velocity) { gestureCount += 1; },
-        onHorizontalDragUpdate: (_) { fail("gesture should not match"); },
-        onHorizontalDragEnd: (Offset velocity) { fail("gesture should not match"); },
-        child: new Container(
-          decoration: const BoxDecoration(
-            backgroundColor: const Color(0xFF00FF00)
-          )
-        )
-      );
-      tester.pumpWidget(widget);
-
-      tester.dispatchEvent(pointer.down(downLocation), downLocation);
-      tester.dispatchEvent(pointer.move(upLocation), downLocation);
-      tester.dispatchEvent(pointer.up(), downLocation);
-
-      tester.dispatchEvent(pointer.down(downLocation), downLocation);
-      tester.dispatchEvent(pointer.move(upLocation), downLocation);
-      tester.dispatchEvent(pointer.up(), downLocation);
-
-      expect(gestureCount, 2);
-      expect(dragDistance, 20.0);
-
-      tester.pumpWidget(new Container());
-    });
-  });
-
-  test('Pan doesn\'t crash', () {
-    testWidgets((WidgetTester tester) {
-      bool didStartPan = false;
-      Offset panDelta;
-      bool didEndPan = false;
-
-      tester.pumpWidget(
-        new GestureDetector(
-          onPanStart: (_) {
-            didStartPan = true;
-          },
-          onPanUpdate: (Offset delta) {
-            panDelta = delta;
-          },
-          onPanEnd: (_) {
-            didEndPan = true;
-          },
-          child: new Container(
-            decoration: const BoxDecoration(
-              backgroundColor: const Color(0xFF00FF00)
-            )
-          )
-        )
-      );
-
-      expect(didStartPan, isFalse);
-      expect(panDelta, isNull);
-      expect(didEndPan, isFalse);
-
-      tester.scrollAt(new Point(10.0, 10.0), new Offset(20.0, 30.0));
-
-      expect(didStartPan, isTrue);
-      expect(panDelta.dx, 20.0);
-      expect(panDelta.dy, 30.0);
-      expect(didEndPan, isTrue);
-    });
-  });
-
-  test('Translucent', () {
-    testWidgets((WidgetTester tester) {
-      bool didReceivePointerDown;
-      bool didTap;
-
-      void pumpWidgetTree(HitTestBehavior behavior) {
-        tester.pumpWidget(
-          new Stack([
-            new Listener(
-              onPointerDown: (_) {
-                didReceivePointerDown = true;
-              },
-              child: new Container(
-                width: 100.0,
-                height: 100.0,
-                decoration: const BoxDecoration(
-                  backgroundColor: const Color(0xFF00FF00)
-                )
-              )
-            ),
-            new Container(
-              width: 100.0,
-              height: 100.0,
-              child: new GestureDetector(
-                onTap: () {
-                  didTap = true;
-                },
-                behavior: behavior
-              )
-            )
-          ])
-        );
-      }
-
-      didReceivePointerDown = false;
-      didTap = false;
-      pumpWidgetTree(null);
-      tester.tapAt(new Point(10.0, 10.0));
-      expect(didReceivePointerDown, isTrue);
-      expect(didTap, isTrue);
-
-      didReceivePointerDown = false;
-      didTap = false;
-      pumpWidgetTree(HitTestBehavior.deferToChild);
-      tester.tapAt(new Point(10.0, 10.0));
-      expect(didReceivePointerDown, isTrue);
-      expect(didTap, isFalse);
-
-      didReceivePointerDown = false;
-      didTap = false;
-      pumpWidgetTree(HitTestBehavior.opaque);
-      tester.tapAt(new Point(10.0, 10.0));
-      expect(didReceivePointerDown, isFalse);
-      expect(didTap, isTrue);
-
-      didReceivePointerDown = false;
-      didTap = false;
-      pumpWidgetTree(HitTestBehavior.translucent);
-      tester.tapAt(new Point(10.0, 10.0));
-      expect(didReceivePointerDown, isTrue);
-      expect(didTap, isTrue);
-
-    });
-  });
-}
diff --git a/sky/unit/test/widget/heroes_test.dart b/sky/unit/test/widget/heroes_test.dart
deleted file mode 100644
index 92aa348..0000000
--- a/sky/unit/test/widget/heroes_test.dart
+++ /dev/null
@@ -1,118 +0,0 @@
-import 'package:flutter/material.dart';
-import 'package:test/test.dart';
-
-import 'widget_tester.dart';
-
-class TestOverlayRoute extends OverlayRoute {
-  List<WidgetBuilder> get builders => <WidgetBuilder>[ _build ];
-  Widget _build(BuildContext context) => new Text('Overlay');
-}
-
-bool _isOnStage(Element element) {
-  expect(element, isNotNull);
-  bool result = true;
-  element.visitAncestorElements((Element ancestor) {
-    if (ancestor.widget is OffStage) {
-      result = false;
-      return false;
-    }
-    return true;
-  });
-  return result;
-}
-
-class _IsOnStage extends Matcher {
-  const _IsOnStage();
-  bool matches(item, Map matchState) => _isOnStage(item);
-  Description describe(Description description) => description.add('onstage');
-}
-
-class _IsOffStage extends Matcher {
-  const _IsOffStage();
-  bool matches(item, Map matchState) => !_isOnStage(item);
-  Description describe(Description description) => description.add('offstage');
-}
-
-const Matcher isOnStage = const _IsOnStage();
-const Matcher isOffStage = const _IsOffStage();
-
-void main() {
-  test('Can pop ephemeral route without black flash', () {
-    testWidgets((WidgetTester tester) {
-      GlobalKey containerKey = new GlobalKey();
-      final Map<String, RouteBuilder> routes = <String, RouteBuilder>{
-        '/': (_) => new Container(key: containerKey, child: new Text('Home')),
-        '/settings': (_) => new Container(child: new Text('Settings')),
-      };
-
-      tester.pumpWidget(new MaterialApp(routes: routes));
-
-      expect(tester.findText('Home'), isOnStage);
-      expect(tester.findText('Settings'), isNull);
-      expect(tester.findText('Overlay'), isNull);
-
-      NavigatorState navigator = Navigator.of(containerKey.currentContext);
-
-      navigator.pushNamed('/settings');
-
-      tester.pump();
-
-      expect(tester.findText('Home'), isOnStage);
-      expect(tester.findText('Settings'), isOffStage);
-      expect(tester.findText('Overlay'), isNull);
-
-      tester.pump(const Duration(milliseconds: 16));
-
-      expect(tester.findText('Home'), isOnStage);
-      expect(tester.findText('Settings'), isOnStage);
-      expect(tester.findText('Overlay'), isNull);
-
-      tester.pump(const Duration(seconds: 1));
-
-      expect(tester.findText('Home'), isNull);
-      expect(tester.findText('Settings'), isOnStage);
-      expect(tester.findText('Overlay'), isNull);
-
-      navigator.push(new TestOverlayRoute());
-
-      tester.pump();
-
-      expect(tester.findText('Home'), isNull);
-      expect(tester.findText('Settings'), isOnStage);
-      expect(tester.findText('Overlay'), isOnStage);
-
-      tester.pump(const Duration(seconds: 1));
-
-      expect(tester.findText('Home'), isNull);
-      expect(tester.findText('Settings'), isOnStage);
-      expect(tester.findText('Overlay'), isOnStage);
-
-      navigator.pop();
-      tester.pump();
-
-      expect(tester.findText('Home'), isNull);
-      expect(tester.findText('Settings'), isOnStage);
-      expect(tester.findText('Overlay'), isNull);
-
-      tester.pump(const Duration(seconds: 1));
-
-      expect(tester.findText('Home'), isNull);
-      expect(tester.findText('Settings'), isOnStage);
-      expect(tester.findText('Overlay'), isNull);
-
-      navigator.pop();
-      tester.pump();
-
-      expect(tester.findText('Home'), isOnStage);
-      expect(tester.findText('Settings'), isOnStage);
-      expect(tester.findText('Overlay'), isNull);
-
-      tester.pump(const Duration(seconds: 1));
-
-      expect(tester.findText('Home'), isOnStage);
-      expect(tester.findText('Settings'), isNull);
-      expect(tester.findText('Overlay'), isNull);
-
-    });
-  });
-}
diff --git a/sky/unit/test/widget/homogeneous_viewport_test.dart b/sky/unit/test/widget/homogeneous_viewport_test.dart
deleted file mode 100644
index 3f96271..0000000
--- a/sky/unit/test/widget/homogeneous_viewport_test.dart
+++ /dev/null
@@ -1,164 +0,0 @@
-import 'package:flutter/widgets.dart';
-import 'package:test/test.dart';
-
-import 'widget_tester.dart';
-import 'test_widgets.dart';
-
-void main() {
-  test('HomogeneousViewport mount/dismount smoke test', () {
-    testWidgets((WidgetTester tester) {
-      List<int> callbackTracker = <int>[];
-
-      // the root view is 800x600 in the test environment
-      // so if our widget is 100 pixels tall, it should fit exactly 6 times.
-
-      Widget builder() {
-        return new FlipComponent(
-          left: new HomogeneousViewport(
-            builder: (BuildContext context, int start, int count) {
-              List<Widget> result = <Widget>[];
-              for (int index = start; index < start + count; index += 1) {
-                callbackTracker.add(index);
-                result.add(new Container(
-                  key: new ValueKey<int>(index),
-                  height: 100.0,
-                  child: new Text("$index")
-                ));
-              }
-              return result;
-            },
-            startOffset: 0.0,
-            itemExtent: 100.0
-          ),
-          right: new Text('Not Today')
-        );
-      }
-
-      tester.pumpWidget(builder());
-
-      StatefulComponentElement element = tester.findElement((Element element) => element.widget is FlipComponent);
-      FlipComponentState testComponent = element.state;
-
-      expect(callbackTracker, equals([0, 1, 2, 3, 4, 5]));
-
-      callbackTracker.clear();
-      testComponent.flip();
-      tester.pump();
-
-      expect(callbackTracker, equals([]));
-
-      callbackTracker.clear();
-      testComponent.flip();
-      tester.pump();
-
-      expect(callbackTracker, equals([0, 1, 2, 3, 4, 5]));
-    });
-  });
-
-  test('HomogeneousViewport vertical', () {
-    testWidgets((WidgetTester tester) {
-      List<int> callbackTracker = <int>[];
-
-      // the root view is 800x600 in the test environment
-      // so if our widget is 200 pixels tall, it should fit exactly 3 times.
-      // but if we are offset by 300 pixels, there will be 4, numbered 1-4.
-
-      double offset = 300.0;
-
-      ListBuilder itemBuilder = (BuildContext context, int start, int count) {
-        List<Widget> result = <Widget>[];
-        for (int index = start; index < start + count; index += 1) {
-          callbackTracker.add(index);
-          result.add(new Container(
-            key: new ValueKey<int>(index),
-            width: 500.0, // this should be ignored
-            height: 400.0, // should be overridden by itemExtent
-            child: new Text("$index")
-          ));
-        }
-        return result;
-      };
-
-      FlipComponent testComponent;
-      Widget builder() {
-        testComponent = new FlipComponent(
-          left: new HomogeneousViewport(
-            builder: itemBuilder,
-            startOffset: offset,
-            itemExtent: 200.0
-          ),
-          right: new Text('Not Today')
-        );
-        return testComponent;
-      }
-
-      tester.pumpWidget(builder());
-
-      expect(callbackTracker, equals([1, 2, 3, 4]));
-
-      callbackTracker.clear();
-
-      offset = 400.0; // now only 3 should fit, numbered 2-4.
-
-      tester.pumpWidget(builder());
-
-      expect(callbackTracker, equals([2, 3, 4]));
-
-      callbackTracker.clear();
-    });
-  });
-
-  test('HomogeneousViewport horizontal', () {
-    testWidgets((WidgetTester tester) {
-      List<int> callbackTracker = <int>[];
-
-      // the root view is 800x600 in the test environment
-      // so if our widget is 200 pixels wide, it should fit exactly 4 times.
-      // but if we are offset by 300 pixels, there will be 5, numbered 1-5.
-
-      double offset = 300.0;
-
-      ListBuilder itemBuilder = (BuildContext context, int start, int count) {
-        List<Widget> result = <Widget>[];
-        for (int index = start; index < start + count; index += 1) {
-          callbackTracker.add(index);
-          result.add(new Container(
-            key: new ValueKey<int>(index),
-            width: 400.0, // this should be overridden by itemExtent
-            height: 500.0, // this should be ignored
-            child: new Text("$index")
-          ));
-        }
-        return result;
-      };
-
-      FlipComponent testComponent;
-      Widget builder() {
-        testComponent = new FlipComponent(
-          left: new HomogeneousViewport(
-            builder: itemBuilder,
-            startOffset: offset,
-            itemExtent: 200.0,
-            direction: ScrollDirection.horizontal
-          ),
-          right: new Text('Not Today')
-        );
-        return testComponent;
-      }
-
-      tester.pumpWidget(builder());
-
-      expect(callbackTracker, equals([1, 2, 3, 4, 5]));
-
-      callbackTracker.clear();
-
-      offset = 400.0; // now only 4 should fit, numbered 2-5.
-
-      tester.pumpWidget(builder());
-
-      expect(callbackTracker, equals([2, 3, 4, 5]));
-
-      callbackTracker.clear();
-    });
-  });
-}
diff --git a/sky/unit/test/widget/init_state_test.dart b/sky/unit/test/widget/init_state_test.dart
deleted file mode 100644
index f21fb85..0000000
--- a/sky/unit/test/widget/init_state_test.dart
+++ /dev/null
@@ -1,35 +0,0 @@
-// Copyright 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:flutter/widgets.dart';
-import 'package:test/test.dart';
-
-import 'widget_tester.dart';
-
-List<String> ancestors = <String>[];
-
-class TestComponent extends StatefulComponent {
-  TestComponentState createState() => new TestComponentState();
-}
-
-class TestComponentState extends State<TestComponent> {
-  void initState() {
-    super.initState();
-    context.visitAncestorElements((Element element) {
-      ancestors.add(element.widget.runtimeType.toString());
-      return true;
-    });
-  }
-
-  Widget build(BuildContext context) => new Container();
-}
-
-void main() {
-  test('initState() is called when we are in the tree', () {
-    testWidgets((WidgetTester tester) {
-      tester.pumpWidget(new Container(child: new TestComponent()));
-      expect(ancestors, equals(<String>['Container', 'RenderObjectToWidgetAdapter<RenderBox>']));
-    });
-  });
-}
diff --git a/sky/unit/test/widget/input_test.dart b/sky/unit/test/widget/input_test.dart
deleted file mode 100644
index f175e2b..0000000
--- a/sky/unit/test/widget/input_test.dart
+++ /dev/null
@@ -1,137 +0,0 @@
-import 'package:mojo_services/keyboard/keyboard.mojom.dart';
-import 'package:flutter/rendering.dart';
-import 'package:flutter/services.dart';
-import 'package:flutter/material.dart';
-import 'package:test/test.dart';
-
-import 'widget_tester.dart';
-import '../services/mock_services.dart';
-
-class MockKeyboard implements KeyboardService {
-  KeyboardClient client;
-
-  void show(KeyboardClientStub client, KeyboardType type) {
-    this.client = client.impl;
-  }
-
-  void showByRequest() {}
-
-  void hide() {}
-
-  void setText(String text) {}
-
-  void setSelection(int start, int end) {}
-}
-
-void main() {
-  MockKeyboard mockKeyboard = new MockKeyboard();
-  serviceMocker.registerMockService(KeyboardServiceName, mockKeyboard);
-
-  test('Editable text has consistent width', () {
-    testWidgets((WidgetTester tester) {
-      GlobalKey inputKey = new GlobalKey();
-      String inputValue;
-
-      Widget builder() {
-        return new Center(
-          child: new Input(
-            key: inputKey,
-            placeholder: 'Placeholder',
-            onChanged: (String value) { inputValue = value; }
-          )
-        );
-      }
-
-      tester.pumpWidget(builder());
-
-      Element input = tester.findElementByKey(inputKey);
-      Size emptyInputSize = (input.renderObject as RenderBox).size;
-
-      // Simulate entry of text through the keyboard.
-      expect(mockKeyboard.client, isNotNull);
-      const String testValue = 'Test';
-      mockKeyboard.client.setComposingText(testValue, testValue.length);
-
-      // Check that the onChanged event handler fired.
-      expect(inputValue, equals(testValue));
-
-      tester.pumpWidget(builder());
-
-      // Check that the Input with text has the same size as the empty Input.
-      expect((input.renderObject as RenderBox).size, equals(emptyInputSize));
-    });
-  });
-
-  test('Cursor blinks', () {
-    testWidgets((WidgetTester tester) {
-      GlobalKey inputKey = new GlobalKey();
-
-      Widget builder() {
-        return new Center(
-          child: new Input(
-            key: inputKey,
-            placeholder: 'Placeholder'
-          )
-        );
-      }
-
-      tester.pumpWidget(builder());
-
-      EditableTextState editableText = tester.findStateOfType(EditableTextState);
-
-      // Check that the cursor visibility toggles after each blink interval.
-      void checkCursorToggle() {
-        bool initialShowCursor = editableText.cursorCurrentlyVisible;
-        tester.async.elapse(editableText.cursorBlinkInterval);
-        expect(editableText.cursorCurrentlyVisible, equals(!initialShowCursor));
-        tester.async.elapse(editableText.cursorBlinkInterval);
-        expect(editableText.cursorCurrentlyVisible, equals(initialShowCursor));
-        tester.async.elapse(editableText.cursorBlinkInterval ~/ 10);
-        expect(editableText.cursorCurrentlyVisible, equals(initialShowCursor));
-        tester.async.elapse(editableText.cursorBlinkInterval);
-        expect(editableText.cursorCurrentlyVisible, equals(!initialShowCursor));
-        tester.async.elapse(editableText.cursorBlinkInterval);
-        expect(editableText.cursorCurrentlyVisible, equals(initialShowCursor));
-      }
-
-      checkCursorToggle();
-
-      // Try the test again with a nonempty EditableText.
-      mockKeyboard.client.setComposingText('X', 1);
-      checkCursorToggle();
-    });
-  });
-
-  test('Selection remains valid', () {
-    testWidgets((WidgetTester tester) {
-      GlobalKey inputKey = new GlobalKey();
-
-      Widget builder() {
-        return new Center(
-          child: new Input(
-            key: inputKey,
-            placeholder: 'Placeholder'
-          )
-        );
-      }
-
-      tester.pumpWidget(builder());
-
-      const String testValue = 'ABC';
-      mockKeyboard.client.commitText(testValue, testValue.length);
-      InputState input = tester.findStateOfType(InputState);
-
-      // Delete characters and verify that the selection follows the length
-      // of the text.
-      for (int i = 0; i < testValue.length; i++) {
-        mockKeyboard.client.deleteSurroundingText(1, 0);
-        expect(input.editableValue.selection.start, equals(testValue.length - i - 1));
-      }
-
-      // Delete a characters when the text is empty.  The selection should
-      // remain at zero.
-      mockKeyboard.client.deleteSurroundingText(1, 0);
-      expect(input.editableValue.selection.start, equals(0));
-    });
-  });
-}
diff --git a/sky/unit/test/widget/listener_test.dart b/sky/unit/test/widget/listener_test.dart
deleted file mode 100644
index 804494b..0000000
--- a/sky/unit/test/widget/listener_test.dart
+++ /dev/null
@@ -1,42 +0,0 @@
-import 'package:flutter/widgets.dart';
-import 'package:test/test.dart';
-
-import 'widget_tester.dart';
-
-void main() {
-  test('Events bubble up the tree', () {
-    testWidgets((WidgetTester tester) {
-      List<String> log = new List<String>();
-
-      tester.pumpWidget(
-        new Listener(
-          onPointerDown: (_) {
-            log.add('top');
-          },
-          child: new Listener(
-            onPointerDown: (_) {
-              log.add('middle');
-            },
-            child: new DecoratedBox(
-              decoration: const BoxDecoration(),
-              child: new Listener(
-                onPointerDown: (_) {
-                  log.add('bottom');
-                },
-                child: new Text('X')
-              )
-            )
-          )
-        )
-      );
-
-      tester.tap(tester.findText('X'));
-
-      expect(log, equals([
-        'bottom',
-        'middle',
-        'top',
-      ]));
-    });
-  });
-}
diff --git a/sky/unit/test/widget/mixed_viewport_test.dart b/sky/unit/test/widget/mixed_viewport_test.dart
deleted file mode 100644
index f5532a8..0000000
--- a/sky/unit/test/widget/mixed_viewport_test.dart
+++ /dev/null
@@ -1,149 +0,0 @@
-import 'package:flutter/widgets.dart';
-import 'package:test/test.dart';
-
-import 'widget_tester.dart';
-import 'test_widgets.dart';
-
-void main() {
-  test('MixedViewport mount/dismount smoke test', () {
-    testWidgets((WidgetTester tester) {
-      List<int> callbackTracker = <int>[];
-
-      // the root view is 800x600 in the test environment
-      // so if our widget is 100 pixels tall, it should fit exactly 6 times.
-
-      Widget builder() {
-        return new FlipComponent(
-          left: new MixedViewport(
-            builder: (BuildContext context, int i) {
-              callbackTracker.add(i);
-              return new Container(
-                key: new ValueKey<int>(i),
-                height: 100.0,
-                child: new Text("$i")
-              );
-            },
-            startOffset: 0.0
-          ),
-          right: new Text('Not Today')
-        );
-      }
-
-      tester.pumpWidget(builder());
-
-      StatefulComponentElement element = tester.findElement((Element element) => element.widget is FlipComponent);
-      FlipComponentState testComponent = element.state;
-
-      expect(callbackTracker, equals([0, 1, 2, 3, 4, 5]));
-
-      callbackTracker.clear();
-      testComponent.flip();
-      tester.pump();
-
-      expect(callbackTracker, equals([]));
-
-      callbackTracker.clear();
-      testComponent.flip();
-      tester.pump();
-
-      expect(callbackTracker, equals([0, 1, 2, 3, 4, 5]));
-    });
-  });
-
-  test('MixedViewport vertical', () {
-    testWidgets((WidgetTester tester) {
-      List<int> callbackTracker = <int>[];
-
-      // the root view is 800x600 in the test environment
-      // so if our widget is 200 pixels tall, it should fit exactly 3 times.
-      // but if we are offset by 300 pixels, there will be 4, numbered 1-4.
-
-      double offset = 300.0;
-
-      IndexedBuilder itemBuilder = (BuildContext context, int i) {
-        callbackTracker.add(i);
-        return new Container(
-          key: new ValueKey<int>(i),
-          width: 500.0, // this should be ignored
-          height: 200.0,
-          child: new Text("$i")
-        );
-      };
-
-      Widget builder() {
-        return new FlipComponent(
-          left: new MixedViewport(
-            builder: itemBuilder,
-            startOffset: offset
-          ),
-          right: new Text('Not Today')
-        );
-      }
-
-      tester.pumpWidget(builder());
-
-      // 0 is built to find its width
-      expect(callbackTracker, equals([0, 1, 2, 3, 4]));
-
-      callbackTracker.clear();
-
-      offset = 400.0; // now only 3 should fit, numbered 2-4.
-
-      tester.pumpWidget(builder());
-
-      // 0 and 1 aren't built, we know their size and nothing else changed
-      expect(callbackTracker, equals([2, 3, 4]));
-
-      callbackTracker.clear();
-    });
-  });
-
-  test('MixedViewport horizontal', () {
-    testWidgets((WidgetTester tester) {
-      List<int> callbackTracker = <int>[];
-
-      // the root view is 800x600 in the test environment
-      // so if our widget is 200 pixels wide, it should fit exactly 4 times.
-      // but if we are offset by 300 pixels, there will be 5, numbered 1-5.
-
-      double offset = 300.0;
-
-      IndexedBuilder itemBuilder = (BuildContext context, int i) {
-        callbackTracker.add(i);
-        return new Container(
-          key: new ValueKey<int>(i),
-          height: 500.0, // this should be ignored
-          width: 200.0,
-          child: new Text("$i")
-        );
-      };
-
-      Widget builder() {
-        return new FlipComponent(
-          left: new MixedViewport(
-            builder: itemBuilder,
-            startOffset: offset,
-            direction: ScrollDirection.horizontal
-          ),
-          right: new Text('Not Today')
-        );
-      }
-
-      tester.pumpWidget(builder());
-
-      // 0 is built to find its width
-      expect(callbackTracker, equals([0, 1, 2, 3, 4, 5]));
-
-      callbackTracker.clear();
-
-      offset = 400.0; // now only 4 should fit, numbered 2-5.
-
-      tester.pumpWidget(builder());
-
-      // 0 and 1 aren't built, we know their size and nothing else changed
-      expect(callbackTracker, equals([2, 3, 4, 5]));
-
-      callbackTracker.clear();
-    });
-  });
-}
diff --git a/sky/unit/test/widget/multichild_test.dart b/sky/unit/test/widget/multichild_test.dart
deleted file mode 100644
index e2f7b34..0000000
--- a/sky/unit/test/widget/multichild_test.dart
+++ /dev/null
@@ -1,293 +0,0 @@
-import 'package:flutter/rendering.dart';
-import 'package:flutter/widgets.dart';
-import 'package:test/test.dart';
-
-import 'test_widgets.dart';
-import 'widget_tester.dart';
-
-void checkTree(WidgetTester tester, List<BoxDecoration> expectedDecorations) {
-  MultiChildRenderObjectElement element =
-      tester.findElement((Element element) => element is MultiChildRenderObjectElement);
-  expect(element, isNotNull);
-  expect(element.renderObject is RenderStack, isTrue);
-  RenderStack renderObject = element.renderObject;
-  try {
-    RenderObject child = renderObject.firstChild;
-    for (BoxDecoration decoration in expectedDecorations) {
-      expect(child is RenderDecoratedBox, isTrue);
-      RenderDecoratedBox decoratedBox = child;
-      expect(decoratedBox.decoration, equals(decoration));
-      final StackParentData decoratedBoxParentData = decoratedBox.parentData;
-      child = decoratedBoxParentData.nextSibling;
-    }
-    expect(child, isNull);
-  } catch (e) {
-    print(renderObject.toStringDeep());
-    rethrow;
-  }
-}
-
-void main() {
-  test('MultiChildRenderObjectElement control test', () {
-    testWidgets((WidgetTester tester) {
-
-      tester.pumpWidget(
-        new Stack(<Widget>[
-          new DecoratedBox(decoration: kBoxDecorationA),
-          new DecoratedBox(decoration: kBoxDecorationB),
-          new DecoratedBox(decoration: kBoxDecorationC),
-        ])
-      );
-
-      checkTree(tester, <BoxDecoration>[kBoxDecorationA, kBoxDecorationB, kBoxDecorationC]);
-
-      tester.pumpWidget(
-        new Stack(<Widget>[
-          new DecoratedBox(decoration: kBoxDecorationA),
-          new DecoratedBox(decoration: kBoxDecorationC),
-        ])
-      );
-
-      checkTree(tester, <BoxDecoration>[kBoxDecorationA, kBoxDecorationC]);
-
-      tester.pumpWidget(
-        new Stack(<Widget>[
-          new DecoratedBox(decoration: kBoxDecorationA),
-          new DecoratedBox(key: new Key('b'), decoration: kBoxDecorationB),
-          new DecoratedBox(decoration: kBoxDecorationC),
-        ])
-      );
-
-      checkTree(tester, <BoxDecoration>[kBoxDecorationA, kBoxDecorationB, kBoxDecorationC]);
-
-      tester.pumpWidget(
-        new Stack(<Widget>[
-          new DecoratedBox(key: new Key('b'), decoration: kBoxDecorationB),
-          new DecoratedBox(decoration: kBoxDecorationC),
-          new DecoratedBox(key: new Key('a'), decoration: kBoxDecorationA),
-        ])
-      );
-
-      checkTree(tester, <BoxDecoration>[kBoxDecorationB, kBoxDecorationC, kBoxDecorationA]);
-
-      tester.pumpWidget(
-        new Stack(<Widget>[
-          new DecoratedBox(key: new Key('a'), decoration: kBoxDecorationA),
-          new DecoratedBox(decoration: kBoxDecorationC),
-          new DecoratedBox(key: new Key('b'), decoration: kBoxDecorationB),
-        ])
-      );
-
-      checkTree(tester, <BoxDecoration>[kBoxDecorationA, kBoxDecorationC, kBoxDecorationB]);
-
-      tester.pumpWidget(
-        new Stack(<Widget>[
-          new DecoratedBox(decoration: kBoxDecorationC),
-        ])
-      );
-
-      checkTree(tester, <BoxDecoration>[kBoxDecorationC]);
-
-      tester.pumpWidget(
-        new Stack(<Widget>[])
-      );
-
-      checkTree(tester, <BoxDecoration>[]);
-
-    });
-  });
-
-  test('MultiChildRenderObjectElement with stateless components', () {
-    testWidgets((WidgetTester tester) {
-
-      tester.pumpWidget(
-        new Stack(<Widget>[
-          new DecoratedBox(decoration: kBoxDecorationA),
-          new DecoratedBox(decoration: kBoxDecorationB),
-          new DecoratedBox(decoration: kBoxDecorationC),
-        ])
-      );
-
-      checkTree(tester, <BoxDecoration>[kBoxDecorationA, kBoxDecorationB, kBoxDecorationC]);
-
-      tester.pumpWidget(
-        new Stack(<Widget>[
-          new DecoratedBox(decoration: kBoxDecorationA),
-          new Container(
-            child: new DecoratedBox(decoration: kBoxDecorationB)
-          ),
-          new DecoratedBox(decoration: kBoxDecorationC),
-        ])
-      );
-
-      checkTree(tester, <BoxDecoration>[kBoxDecorationA, kBoxDecorationB, kBoxDecorationC]);
-
-      tester.pumpWidget(
-        new Stack(<Widget>[
-          new DecoratedBox(decoration: kBoxDecorationA),
-          new Container(
-            child: new Container(
-              child: new DecoratedBox(decoration: kBoxDecorationB)
-            )
-          ),
-          new DecoratedBox(decoration: kBoxDecorationC),
-        ])
-      );
-
-      checkTree(tester, <BoxDecoration>[kBoxDecorationA, kBoxDecorationB, kBoxDecorationC]);
-
-      tester.pumpWidget(
-        new Stack(<Widget>[
-          new Container(
-            child: new Container(
-              child: new DecoratedBox(decoration: kBoxDecorationB)
-            )
-          ),
-          new Container(
-            child: new DecoratedBox(decoration: kBoxDecorationA)
-          ),
-          new DecoratedBox(decoration: kBoxDecorationC),
-        ])
-      );
-
-      checkTree(tester, <BoxDecoration>[kBoxDecorationB, kBoxDecorationA, kBoxDecorationC]);
-
-      tester.pumpWidget(
-        new Stack(<Widget>[
-          new Container(
-            child: new DecoratedBox(decoration: kBoxDecorationB)
-          ),
-          new Container(
-            child: new DecoratedBox(decoration: kBoxDecorationA)
-          ),
-          new DecoratedBox(decoration: kBoxDecorationC),
-        ])
-      );
-
-      checkTree(tester, <BoxDecoration>[kBoxDecorationB, kBoxDecorationA, kBoxDecorationC]);
-
-      tester.pumpWidget(
-        new Stack(<Widget>[
-          new Container(
-            key: new Key('b'),
-            child: new DecoratedBox(decoration: kBoxDecorationB)
-          ),
-          new Container(
-            key: new Key('a'),
-            child: new DecoratedBox(decoration: kBoxDecorationA)
-          ),
-        ])
-      );
-
-      checkTree(tester, <BoxDecoration>[kBoxDecorationB, kBoxDecorationA]);
-
-      tester.pumpWidget(
-        new Stack(<Widget>[
-          new Container(
-            key: new Key('a'),
-            child: new DecoratedBox(decoration: kBoxDecorationA)
-          ),
-          new Container(
-            key: new Key('b'),
-            child: new DecoratedBox(decoration: kBoxDecorationB)
-          ),
-        ])
-      );
-
-      checkTree(tester, <BoxDecoration>[kBoxDecorationA, kBoxDecorationB]);
-
-      tester.pumpWidget(
-        new Stack(<Widget>[])
-      );
-
-      checkTree(tester, <BoxDecoration>[]);
-    });
-  });
-
-  test('MultiChildRenderObjectElement with stateful components', () {
-    testWidgets((WidgetTester tester) {
-      tester.pumpWidget(
-        new Stack(<Widget>[
-          new DecoratedBox(decoration: kBoxDecorationA),
-          new DecoratedBox(decoration: kBoxDecorationB),
-        ])
-      );
-
-      checkTree(tester, <BoxDecoration>[kBoxDecorationA, kBoxDecorationB]);
-
-      tester.pumpWidget(
-        new Stack(<Widget>[
-          new FlipComponent(
-            left: new DecoratedBox(decoration: kBoxDecorationA),
-            right: new DecoratedBox(decoration: kBoxDecorationB)
-          ),
-          new DecoratedBox(decoration: kBoxDecorationC),
-        ])
-      );
-
-      checkTree(tester, <BoxDecoration>[kBoxDecorationA, kBoxDecorationC]);
-
-      flipStatefulComponent(tester);
-      tester.pump();
-
-      checkTree(tester, <BoxDecoration>[kBoxDecorationB, kBoxDecorationC]);
-
-      tester.pumpWidget(
-        new Stack(<Widget>[
-          new FlipComponent(
-            left: new DecoratedBox(decoration: kBoxDecorationA),
-            right: new DecoratedBox(decoration: kBoxDecorationB)
-          ),
-        ])
-      );
-
-      checkTree(tester, <BoxDecoration>[kBoxDecorationB]);
-
-      flipStatefulComponent(tester);
-      tester.pump();
-
-      checkTree(tester, <BoxDecoration>[kBoxDecorationA]);
-
-      tester.pumpWidget(
-        new Stack(<Widget>[
-          new FlipComponent(
-            key: new Key('flip'),
-            left: new DecoratedBox(decoration: kBoxDecorationA),
-            right: new DecoratedBox(decoration: kBoxDecorationB)
-          ),
-        ])
-      );
-
-      tester.pumpWidget(
-        new Stack(<Widget>[
-          new DecoratedBox(key: new Key('c'), decoration: kBoxDecorationC),
-          new FlipComponent(
-            key: new Key('flip'),
-            left: new DecoratedBox(decoration: kBoxDecorationA),
-            right: new DecoratedBox(decoration: kBoxDecorationB)
-          ),
-        ])
-      );
-
-      checkTree(tester, <BoxDecoration>[kBoxDecorationC, kBoxDecorationA]);
-
-      flipStatefulComponent(tester);
-      tester.pump();
-
-      checkTree(tester, <BoxDecoration>[kBoxDecorationC, kBoxDecorationB]);
-
-      tester.pumpWidget(
-        new Stack(<Widget>[
-          new FlipComponent(
-            key: new Key('flip'),
-            left: new DecoratedBox(decoration: kBoxDecorationA),
-            right: new DecoratedBox(decoration: kBoxDecorationB)
-          ),
-          new DecoratedBox(key: new Key('c'), decoration: kBoxDecorationC),
-        ])
-      );
-
-      checkTree(tester, <BoxDecoration>[kBoxDecorationB, kBoxDecorationC]);
-    });
-  });
-}
diff --git a/sky/unit/test/widget/navigator_test.dart b/sky/unit/test/widget/navigator_test.dart
deleted file mode 100644
index 88dd13b..0000000
--- a/sky/unit/test/widget/navigator_test.dart
+++ /dev/null
@@ -1,73 +0,0 @@
-import 'package:flutter/material.dart';
-import 'package:test/test.dart';
-
-import 'widget_tester.dart';
-
-class FirstComponent extends StatelessComponent {
-  Widget build(BuildContext context) {
-    return new GestureDetector(
-      onTap: () {
-        Navigator.of(context).pushNamed('/second');
-      },
-      child: new Container(
-        decoration: new BoxDecoration(
-          backgroundColor: new Color(0xFFFFFF00)
-        ),
-        child: new Text('X')
-      )
-    );
-  }
-}
-
-class SecondComponent extends StatefulComponent {
-  SecondComponentState createState() => new SecondComponentState();
-}
-
-class SecondComponentState extends State<SecondComponent> {
-  Widget build(BuildContext context) {
-    return new GestureDetector(
-      onTap: Navigator.of(context).pop,
-      child: new Container(
-        decoration: new BoxDecoration(
-          backgroundColor: new Color(0xFFFF00FF)
-        ),
-        child: new Text('Y')
-      )
-    );
-  }
-}
-
-void main() {
-  test('Can navigator navigate to and from a stateful component', () {
-    testWidgets((WidgetTester tester) {
-      final Map<String, RouteBuilder> routes = <String, RouteBuilder>{
-        '/': (RouteArguments args) => new FirstComponent(),
-        '/second': (RouteArguments args) => new SecondComponent(),
-      };
-
-      tester.pumpWidget(new MaterialApp(routes: routes));
-
-      expect(tester.findText('X'), isNotNull);
-      expect(tester.findText('Y'), isNull);
-
-      tester.tap(tester.findText('X'));
-      tester.pump(const Duration(milliseconds: 10));
-
-      expect(tester.findText('X'), isNotNull);
-      expect(tester.findText('Y'), isNotNull);
-
-      tester.pump(const Duration(milliseconds: 10));
-      tester.pump(const Duration(milliseconds: 10));
-      tester.pump(const Duration(seconds: 1));
-
-      tester.tap(tester.findText('Y'));
-      tester.pump(const Duration(milliseconds: 10));
-      tester.pump(const Duration(milliseconds: 10));
-      tester.pump(const Duration(milliseconds: 10));
-      tester.pump(const Duration(seconds: 1));
-
-      expect(tester.findText('X'), isNotNull);
-      expect(tester.findText('Y'), isNull);
-    });
-  });
-}
diff --git a/sky/unit/test/widget/pageable_list_test.dart b/sky/unit/test/widget/pageable_list_test.dart
deleted file mode 100644
index fe40653..0000000
--- a/sky/unit/test/widget/pageable_list_test.dart
+++ /dev/null
@@ -1,114 +0,0 @@
-import 'package:flutter/widgets.dart';
-import 'package:test/test.dart';
-
-import 'widget_tester.dart';
-
-const Size pageSize = const Size(800.0, 600.0);
-const List<int> pages = const <int>[0, 1, 2, 3, 4, 5];
-int currentPage = null;
-bool itemsWrap = false;
-
-Widget buildPage(BuildContext context, int page) {
-  return new Container(
-    key: new ValueKey<int>(page),
-    width: pageSize.width,
-    height: pageSize.height,
-    child: new Text(page.toString())
-  );
-}
-
-Widget buildFrame() {
-  // The test framework forces the frame (and so the PageableList)
-  // to be 800x600. The pageSize constant reflects this.
-  return new PageableList<int>(
-    items: pages,
-    itemBuilder: buildPage,
-    itemsWrap: itemsWrap,
-    itemExtent: pageSize.width,
-    scrollDirection: ScrollDirection.horizontal,
-    onPageChanged: (int page) { currentPage = page; }
-  );
-}
-
-void page(WidgetTester tester, Offset offset) {
-  String itemText = currentPage != null ? currentPage.toString() : '0';
-  tester.scroll(tester.findText(itemText), offset);
-  // One frame to start the animation, a second to complete it.
-  tester.pump();
-  tester.pump(const Duration(seconds: 1));
-}
-
-void pageLeft(WidgetTester tester) {
-  page(tester, new Offset(-pageSize.width, 0.0));
-}
-
-void pageRight(WidgetTester tester) {
-  page(tester, new Offset(pageSize.width, 0.0));
-}
-
-void main() {
-  // PageableList with itemsWrap: false
-
-  test('Scroll left from page 0 to page 1', () {
-    testWidgets((WidgetTester tester) {
-      currentPage = null;
-      itemsWrap = false;
-      tester.pumpWidget(buildFrame());
-      expect(currentPage, isNull);
-      pageLeft(tester);
-      expect(currentPage, equals(1));
-    });
-  });
-
-  test('Scroll right from page 1 to page 0', () {
-    testWidgets((WidgetTester tester) {
-      itemsWrap = false;
-      tester.pumpWidget(buildFrame());
-      expect(currentPage, equals(1));
-      pageRight(tester);
-      expect(currentPage, equals(0));
-    });
-  });
-
-  test('Scroll right from page 0 does nothing (underscroll)', () {
-    testWidgets((WidgetTester tester) {
-      itemsWrap = false;
-      tester.pumpWidget(buildFrame());
-      expect(currentPage, equals(0));
-      pageRight(tester);
-      expect(currentPage, equals(0));
-    });
-  });
-
-  // PageableList with itemsWrap: true
-
-  test('Scroll left page 0 to page 1, itemsWrap: true', () {
-    testWidgets((WidgetTester tester) {
-      tester.pumpWidget(new Container());
-      currentPage = null;
-      itemsWrap = true;
-      tester.pumpWidget(buildFrame());
-      expect(currentPage, isNull);
-      pageLeft(tester);
-      expect(currentPage, equals(1));
-    });
-  });
-
-  test('Scroll right from page 1 to page 0, itemsWrap: true', () {
-    testWidgets((WidgetTester tester) {
-      tester.pumpWidget(buildFrame());
-      expect(currentPage, equals(1));
-      pageRight(tester);
-      expect(currentPage, equals(0));
-    });
-  });
-
-  test('Scroll right from page 0 to page 5, itemsWrap: true (underscroll)', () {
-    testWidgets((WidgetTester tester) {
-      tester.pumpWidget(buildFrame());
-      expect(currentPage, equals(0));
-      pageRight(tester);
-      expect(currentPage, equals(5));
-    });
-  });
-}
diff --git a/sky/unit/test/widget/parent_data_test.dart b/sky/unit/test/widget/parent_data_test.dart
deleted file mode 100644
index bc5eb2e..0000000
--- a/sky/unit/test/widget/parent_data_test.dart
+++ /dev/null
@@ -1,287 +0,0 @@
-import 'package:flutter/rendering.dart';
-import 'package:flutter/widgets.dart';
-import 'package:test/test.dart';
-
-import 'test_widgets.dart';
-import 'widget_tester.dart';
-
-class TestParentData {
-  TestParentData({ this.top, this.right, this.bottom, this.left });
-
-  final double top;
-  final double right;
-  final double bottom;
-  final double left;
-}
-
-void checkTree(WidgetTester tester, List<TestParentData> expectedParentData) {
-  MultiChildRenderObjectElement element =
-      tester.findElement((Element element) => element is MultiChildRenderObjectElement);
-  expect(element, isNotNull);
-  expect(element.renderObject is RenderStack, isTrue);
-  RenderStack renderObject = element.renderObject;
-  try {
-    RenderObject child = renderObject.firstChild;
-    for (TestParentData expected in expectedParentData) {
-      expect(child is RenderDecoratedBox, isTrue);
-      RenderDecoratedBox decoratedBox = child;
-      expect(decoratedBox.parentData is StackParentData, isTrue);
-      StackParentData parentData = decoratedBox.parentData;
-      expect(parentData.top, equals(expected.top));
-      expect(parentData.right, equals(expected.right));
-      expect(parentData.bottom, equals(expected.bottom));
-      expect(parentData.left, equals(expected.left));
-      child = (decoratedBox.parentData as StackParentData).nextSibling;
-    }
-    expect(child, isNull);
-  } catch (e) {
-    print(renderObject.toStringDeep());
-    rethrow;
-  }
-}
-
-final TestParentData kNonPositioned = new TestParentData();
-
-void main() {
-  dynamic cachedException;
-
-  setUp(() {
-    assert(cachedException == null);
-    debugWidgetsExceptionHandler = (String context, dynamic exception, StackTrace stack) {
-      cachedException = exception;
-    };
-  });
-
-  tearDown(() {
-    cachedException = null;
-    debugWidgetsExceptionHandler = null;
-  });
-
-  test('ParentDataWidget control test', () {
-    testWidgets((WidgetTester tester) {
-
-      tester.pumpWidget(
-        new Stack(<Widget>[
-          new DecoratedBox(decoration: kBoxDecorationA),
-          new Positioned(
-            top: 10.0,
-            left: 10.0,
-            child: new DecoratedBox(decoration: kBoxDecorationB)
-          ),
-          new DecoratedBox(decoration: kBoxDecorationC),
-        ])
-      );
-
-      checkTree(tester, <TestParentData>[
-        kNonPositioned,
-        new TestParentData(top: 10.0, left: 10.0),
-        kNonPositioned,
-      ]);
-
-      tester.pumpWidget(
-        new Stack(<Widget>[
-          new Positioned(
-            bottom: 5.0,
-            right: 7.0,
-            child: new DecoratedBox(decoration: kBoxDecorationA)
-          ),
-          new Positioned(
-            top: 10.0,
-            left: 10.0,
-            child: new DecoratedBox(decoration: kBoxDecorationB)
-          ),
-          new DecoratedBox(decoration: kBoxDecorationC),
-        ])
-      );
-
-      checkTree(tester, <TestParentData>[
-        new TestParentData(bottom: 5.0, right: 7.0),
-        new TestParentData(top: 10.0, left: 10.0),
-        kNonPositioned,
-      ]);
-
-      DecoratedBox kDecoratedBoxA = new DecoratedBox(decoration: kBoxDecorationA);
-      DecoratedBox kDecoratedBoxB = new DecoratedBox(decoration: kBoxDecorationB);
-      DecoratedBox kDecoratedBoxC = new DecoratedBox(decoration: kBoxDecorationC);
-
-      tester.pumpWidget(
-        new Stack(<Widget>[
-          new Positioned(
-            bottom: 5.0,
-            right: 7.0,
-            child: kDecoratedBoxA
-          ),
-          new Positioned(
-            top: 10.0,
-            left: 10.0,
-            child: kDecoratedBoxB
-          ),
-          kDecoratedBoxC,
-        ])
-      );
-
-      checkTree(tester, <TestParentData>[
-        new TestParentData(bottom: 5.0, right: 7.0),
-        new TestParentData(top: 10.0, left: 10.0),
-        kNonPositioned,
-      ]);
-
-      tester.pumpWidget(
-        new Stack(<Widget>[
-          new Positioned(
-            bottom: 6.0,
-            right: 8.0,
-            child: kDecoratedBoxA
-          ),
-          new Positioned(
-            left: 10.0,
-            right: 10.0,
-            child: kDecoratedBoxB
-          ),
-          kDecoratedBoxC,
-        ])
-      );
-
-      checkTree(tester, <TestParentData>[
-        new TestParentData(bottom: 6.0, right: 8.0),
-        new TestParentData(left: 10.0, right: 10.0),
-        kNonPositioned,
-      ]);
-
-      tester.pumpWidget(
-        new Stack(<Widget>[
-          kDecoratedBoxA,
-          new Positioned(
-            left: 11.0,
-            right: 12.0,
-            child: new Container(child: kDecoratedBoxB)
-          ),
-          kDecoratedBoxC,
-        ])
-      );
-
-      checkTree(tester, <TestParentData>[
-        kNonPositioned,
-        new TestParentData(left: 11.0, right: 12.0),
-        kNonPositioned,
-      ]);
-
-      tester.pumpWidget(
-        new Stack(<Widget>[
-          kDecoratedBoxA,
-          new Positioned(
-            right: 10.0,
-            child: new Container(child: kDecoratedBoxB)
-          ),
-          new Container(
-            child: new Positioned(
-              top: 8.0,
-              child: kDecoratedBoxC
-            )
-          )
-        ])
-      );
-
-      checkTree(tester, <TestParentData>[
-        kNonPositioned,
-        new TestParentData(right: 10.0),
-        new TestParentData(top: 8.0),
-      ]);
-
-      tester.pumpWidget(
-        new Stack(<Widget>[
-          new Positioned(
-            right: 10.0,
-            child: new FlipComponent(left: kDecoratedBoxA, right: kDecoratedBoxB)
-          ),
-        ])
-      );
-
-      checkTree(tester, <TestParentData>[
-        new TestParentData(right: 10.0),
-      ]);
-
-      flipStatefulComponent(tester);
-      tester.pump();
-
-      checkTree(tester, <TestParentData>[
-        new TestParentData(right: 10.0),
-      ]);
-
-      tester.pumpWidget(
-        new Stack(<Widget>[
-          new Positioned(
-            top: 7.0,
-            child: new FlipComponent(left: kDecoratedBoxA, right: kDecoratedBoxB)
-          ),
-        ])
-      );
-
-      checkTree(tester, <TestParentData>[
-        new TestParentData(top: 7.0),
-      ]);
-
-      flipStatefulComponent(tester);
-      tester.pump();
-
-      checkTree(tester, <TestParentData>[
-        new TestParentData(top: 7.0),
-      ]);
-
-      tester.pumpWidget(
-        new Stack(<Widget>[])
-      );
-
-      checkTree(tester, <TestParentData>[]);
-    });
-  });
-
-  test('ParentDataWidget conflicting data', () {
-    testWidgets((WidgetTester tester) {
-      expect(cachedException, isNull);
-
-      tester.pumpWidget(
-        new Stack(<Widget>[
-          new Positioned(
-            top: 5.0,
-            bottom: 8.0,
-            child: new Positioned(
-              top: 6.0,
-              left: 7.0,
-              child: new DecoratedBox(decoration: kBoxDecorationB)
-            )
-          )
-        ])
-      );
-
-      expect(cachedException, isNotNull);
-      cachedException = null;
-
-      tester.pumpWidget(new Stack(<Widget>[]));
-
-      checkTree(tester, <TestParentData>[]);
-      expect(cachedException, isNull);
-
-      tester.pumpWidget(
-        new Container(
-          child: new Flex(<Widget>[
-            new Positioned(
-              top: 6.0,
-              left: 7.0,
-              child: new DecoratedBox(decoration: kBoxDecorationB)
-            )
-          ])
-        )
-      );
-
-      expect(cachedException, isNotNull);
-      cachedException = null;
-
-      tester.pumpWidget(
-        new Stack(<Widget>[])
-      );
-
-      checkTree(tester, <TestParentData>[]);
-    });
-  });
-}
diff --git a/sky/unit/test/widget/positioned_test.dart b/sky/unit/test/widget/positioned_test.dart
deleted file mode 100644
index d6bcb0e..0000000
--- a/sky/unit/test/widget/positioned_test.dart
+++ /dev/null
@@ -1,74 +0,0 @@
-import 'package:flutter/animation.dart';
-import 'package:flutter/rendering.dart';
-import 'package:flutter/widgets.dart';
-import 'package:test/test.dart';
-
-import 'widget_tester.dart';
-
-void main() {
-
-  test('Can animate position data', () {
-    testWidgets((WidgetTester tester) {
-
-      final AnimatedRelativeRectValue rect = new AnimatedRelativeRectValue(
-        new RelativeRect.fromRect(
-          new Rect.fromLTRB(10.0, 20.0, 20.0, 30.0),
-          new Rect.fromLTRB(0.0, 10.0, 100.0, 110.0)
-        ),
-        end: new RelativeRect.fromRect(
-          new Rect.fromLTRB(80.0, 90.0, 90.0, 100.0),
-          new Rect.fromLTRB(0.0, 10.0, 100.0, 110.0)
-        ),
-        curve: Curves.linear
-      );
-      final Performance performance = new Performance(
-        duration: const Duration(seconds: 10)
-      );
-      final List<Size> sizes = <Size>[];
-      final List<Point> positions = <Point>[];
-      final GlobalKey key = new GlobalKey();
-
-      void recordMetrics() {
-        RenderBox box = key.currentContext.findRenderObject();
-        BoxParentData boxParentData = box.parentData;
-        sizes.add(box.size);
-        positions.add(boxParentData.position);
-      }
-
-      tester.pumpWidget(
-        new Center(
-          child: new Container(
-            height: 100.0,
-            width: 100.0,
-            child: new Stack(<Widget>[
-              new PositionedTransition(
-                rect: rect,
-                performance: performance,
-                child: new Container(
-                  key: key
-                )
-              )
-            ])
-          )
-        )
-      ); // t=0
-      recordMetrics();
-      performance.play();
-      tester.pump(); // t=0 again
-      recordMetrics();
-      tester.pump(const Duration(seconds: 1)); // t=1
-      recordMetrics();
-      tester.pump(const Duration(seconds: 1)); // t=2
-      recordMetrics();
-      tester.pump(const Duration(seconds: 3)); // t=5
-      recordMetrics();
-      tester.pump(const Duration(seconds: 5)); // t=10
-      recordMetrics();
-
-      expect(sizes, equals([const Size(10.0, 10.0), const Size(10.0, 10.0), const Size(10.0, 10.0), const Size(10.0, 10.0), const Size(10.0, 10.0), const Size(10.0, 10.0)]));
-      expect(positions, equals([const Point(10.0, 10.0), const Point(10.0, 10.0), const Point(17.0, 17.0), const Point(24.0, 24.0), const Point(45.0, 45.0), const Point(80.0, 80.0)]));
-
-    });
-  });
-
-}
diff --git a/sky/unit/test/widget/progress_indicator_test.dart b/sky/unit/test/widget/progress_indicator_test.dart
deleted file mode 100644
index 9a5c971..0000000
--- a/sky/unit/test/widget/progress_indicator_test.dart
+++ /dev/null
@@ -1,21 +0,0 @@
-
-import 'package:flutter/rendering.dart';
-import 'package:flutter/material.dart';
-import 'package:test/test.dart';
-
-import 'widget_tester.dart';
-
-void main() {
-  test('LinearProgressIndicator changes when its value changes', () {
-    testWidgets((WidgetTester tester) {
-      tester.pumpWidget(new Block(<Widget>[new LinearProgressIndicator(value: 0.0)]));
-
-      List<Layer> layers1 = tester.layers;
-
-      tester.pumpWidget(new Block(<Widget>[new LinearProgressIndicator(value: 0.5)]));
-
-      List<Layer> layers2 = tester.layers;
-      expect(layers1, isNot(equals(layers2)));
-    });
-  });
-}
diff --git a/sky/unit/test/widget/remember_scroll_position_test.dart b/sky/unit/test/widget/remember_scroll_position_test.dart
deleted file mode 100644
index 904ba71..0000000
--- a/sky/unit/test/widget/remember_scroll_position_test.dart
+++ /dev/null
@@ -1,114 +0,0 @@
-// Copyright 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:flutter/animation.dart';
-import 'package:flutter/widgets.dart';
-import 'package:test/test.dart';
-
-import 'widget_tester.dart';
-
-class ThePositiveNumbers extends ScrollableWidgetList {
-  ThePositiveNumbers() : super(itemExtent: 100.0);
-  ThePositiveNumbersState createState() => new ThePositiveNumbersState();
-}
-
-class ThePositiveNumbersState extends ScrollableWidgetListState<ThePositiveNumbers> {
-
-  ScrollBehavior createScrollBehavior() => new UnboundedBehavior();
-
-  int get itemCount => null;
-
-  List<Widget> buildItems(BuildContext context, int start, int count) {
-    List<Widget> result = new List<Widget>();
-    for (int index = start; index < start + count; index += 1)
-      result.add(new Text('$index', key: new ValueKey<int>(index)));
-    return result;
-  }
-}
-
-
-void main() {
-  test('whether we remember our scroll position', () {
-    testWidgets((WidgetTester tester) {
-      GlobalKey<NavigatorState> navigatorKey = new GlobalKey<NavigatorState>();
-      tester.pumpWidget(new Navigator(
-        key: navigatorKey,
-        onGenerateRoute: (NamedRouteSettings settings) {
-          if (settings.name == '/')
-            return new PageRoute(builder: (_) => new Container(child: new ThePositiveNumbers()));
-          else if (settings.name == '/second')
-            return new PageRoute(builder: (_) => new Container(child: new ThePositiveNumbers()));
-          return null;
-        }
-      ));
-
-      // we're 600 pixels high, each item is 100 pixels high, scroll position is
-      // zero, so we should have exactly 6 items, 0..5.
-      expect(tester.findText('0'), isNotNull);
-      expect(tester.findText('1'), isNotNull);
-      expect(tester.findText('2'), isNotNull);
-      expect(tester.findText('3'), isNotNull);
-      expect(tester.findText('4'), isNotNull);
-      expect(tester.findText('5'), isNotNull);
-      expect(tester.findText('6'), isNull);
-      expect(tester.findText('10'), isNull);
-      expect(tester.findText('100'), isNull);
-
-      StatefulComponentElement<ThePositiveNumbers, ThePositiveNumbersState> target =
-        tester.findElement((Element element) => element.widget is ThePositiveNumbers);
-      target.state.scrollTo(1000.0);
-      tester.pump(new Duration(seconds: 1));
-
-      // we're 600 pixels high, each item is 100 pixels high, scroll position is
-      // 1000, so we should have exactly 6 items, 10..15.
-
-      expect(tester.findText('0'), isNull);
-      expect(tester.findText('8'), isNull);
-      expect(tester.findText('9'), isNull);
-      expect(tester.findText('10'), isNotNull);
-      expect(tester.findText('11'), isNotNull);
-      expect(tester.findText('12'), isNotNull);
-      expect(tester.findText('13'), isNotNull);
-      expect(tester.findText('14'), isNotNull);
-      expect(tester.findText('15'), isNotNull);
-      expect(tester.findText('16'), isNull);
-      expect(tester.findText('100'), isNull);
-
-      navigatorKey.currentState.pushNamed('/second');
-      tester.pump(); // navigating always takes two frames
-      tester.pump(new Duration(seconds: 1));
-
-      // same as the first list again
-      expect(tester.findText('0'), isNotNull);
-      expect(tester.findText('1'), isNotNull);
-      expect(tester.findText('2'), isNotNull);
-      expect(tester.findText('3'), isNotNull);
-      expect(tester.findText('4'), isNotNull);
-      expect(tester.findText('5'), isNotNull);
-      expect(tester.findText('6'), isNull);
-      expect(tester.findText('10'), isNull);
-      expect(tester.findText('100'), isNull);
-
-      navigatorKey.currentState.pop();
-      tester.pump(); // navigating always takes two frames
-      tester.pump(new Duration(seconds: 1));
-
-      // we're 600 pixels high, each item is 100 pixels high, scroll position is
-      // 1000, so we should have exactly 6 items, 10..15.
-
-      expect(tester.findText('0'), isNull);
-      expect(tester.findText('8'), isNull);
-      expect(tester.findText('9'), isNull);
-      expect(tester.findText('10'), isNotNull);
-      expect(tester.findText('11'), isNotNull);
-      expect(tester.findText('12'), isNotNull);
-      expect(tester.findText('13'), isNotNull);
-      expect(tester.findText('14'), isNotNull);
-      expect(tester.findText('15'), isNotNull);
-      expect(tester.findText('16'), isNull);
-      expect(tester.findText('100'), isNull);
-
-    });
-  });
-}
diff --git a/sky/unit/test/widget/render_object_widget_test.dart b/sky/unit/test/widget/render_object_widget_test.dart
deleted file mode 100644
index 61e8944..0000000
--- a/sky/unit/test/widget/render_object_widget_test.dart
+++ /dev/null
@@ -1,168 +0,0 @@
-import 'package:flutter/rendering.dart';
-import 'package:flutter/widgets.dart';
-import 'package:test/test.dart';
-
-import 'widget_tester.dart';
-
-final BoxDecoration kBoxDecorationA = new BoxDecoration();
-final BoxDecoration kBoxDecorationB = new BoxDecoration();
-final BoxDecoration kBoxDecorationC = new BoxDecoration();
-
-class TestComponent extends StatelessComponent {
-  const TestComponent({ this.child });
-  final Widget child;
-  Widget build(BuildContext context) => child;
-}
-
-void main() {
-  test('RenderObjectWidget smoke test', () {
-    testWidgets((WidgetTester tester) {
-      tester.pumpWidget(new DecoratedBox(decoration: kBoxDecorationA));
-      OneChildRenderObjectElement element =
-          tester.findElement((Element element) => element is OneChildRenderObjectElement);
-      expect(element, isNotNull);
-      expect(element.renderObject is RenderDecoratedBox, isTrue);
-      RenderDecoratedBox renderObject = element.renderObject;
-      expect(renderObject.decoration, equals(kBoxDecorationA));
-      expect(renderObject.position, equals(BoxDecorationPosition.background));
-
-      tester.pumpWidget(new DecoratedBox(decoration: kBoxDecorationB));
-      element = tester.findElement((Element element) => element is OneChildRenderObjectElement);
-      expect(element, isNotNull);
-      expect(element.renderObject is RenderDecoratedBox, isTrue);
-      renderObject = element.renderObject;
-      expect(renderObject.decoration, equals(kBoxDecorationB));
-      expect(renderObject.position, equals(BoxDecorationPosition.background));
-    });
-  });
-
-  test('RenderObjectWidget can add and remove children', () {
-    testWidgets((WidgetTester tester) {
-
-      void checkFullTree() {
-        OneChildRenderObjectElement element =
-            tester.findElement((Element element) => element is OneChildRenderObjectElement);
-        expect(element, isNotNull);
-        expect(element.renderObject is RenderDecoratedBox, isTrue);
-        RenderDecoratedBox renderObject = element.renderObject;
-        expect(renderObject.decoration, equals(kBoxDecorationA));
-        expect(renderObject.position, equals(BoxDecorationPosition.background));
-        expect(renderObject.child, isNotNull);
-        expect(renderObject.child is RenderDecoratedBox, isTrue);
-        RenderDecoratedBox child = renderObject.child;
-        expect(child.decoration, equals(kBoxDecorationB));
-        expect(child.position, equals(BoxDecorationPosition.background));
-        expect(child.child, isNull);
-      }
-
-      void childBareTree() {
-        OneChildRenderObjectElement element =
-            tester.findElement((Element element) => element is OneChildRenderObjectElement);
-        expect(element, isNotNull);
-        expect(element.renderObject is RenderDecoratedBox, isTrue);
-        RenderDecoratedBox renderObject = element.renderObject;
-        expect(renderObject.decoration, equals(kBoxDecorationA));
-        expect(renderObject.position, equals(BoxDecorationPosition.background));
-        expect(renderObject.child, isNull);
-      }
-
-      tester.pumpWidget(new DecoratedBox(
-        decoration: kBoxDecorationA,
-        child: new DecoratedBox(
-          decoration: kBoxDecorationB
-        )
-      ));
-
-      checkFullTree();
-
-      tester.pumpWidget(new DecoratedBox(
-        decoration: kBoxDecorationA,
-        child: new TestComponent(
-          child: new DecoratedBox(
-            decoration: kBoxDecorationB
-          )
-        )
-      ));
-
-      checkFullTree();
-
-      tester.pumpWidget(new DecoratedBox(
-        decoration: kBoxDecorationA,
-        child: new DecoratedBox(
-          decoration: kBoxDecorationB
-        )
-      ));
-
-      checkFullTree();
-
-      tester.pumpWidget(new DecoratedBox(
-        decoration: kBoxDecorationA
-      ));
-
-      childBareTree();
-
-      tester.pumpWidget(new DecoratedBox(
-        decoration: kBoxDecorationA,
-        child: new TestComponent(
-          child: new TestComponent(
-            child: new DecoratedBox(
-              decoration: kBoxDecorationB
-            )
-          )
-        )
-      ));
-
-      checkFullTree();
-
-      tester.pumpWidget(new DecoratedBox(
-        decoration: kBoxDecorationA
-      ));
-
-      childBareTree();
-    });
-  });
-
-  test('Detached render tree is intact', () {
-    testWidgets((WidgetTester tester) {
-
-      tester.pumpWidget(new DecoratedBox(
-        decoration: kBoxDecorationA,
-        child: new DecoratedBox(
-          decoration: kBoxDecorationB,
-          child: new DecoratedBox(
-            decoration: kBoxDecorationC
-          )
-        )
-      ));
-
-      OneChildRenderObjectElement element =
-          tester.findElement((Element element) => element is OneChildRenderObjectElement);
-      expect(element.renderObject is RenderDecoratedBox, isTrue);
-      RenderDecoratedBox parent = element.renderObject;
-      expect(parent.child is RenderDecoratedBox, isTrue);
-      RenderDecoratedBox child = parent.child;
-      expect(child.decoration, equals(kBoxDecorationB));
-      expect(child.child is RenderDecoratedBox, isTrue);
-      RenderDecoratedBox grandChild = child.child;
-      expect(grandChild.decoration, equals(kBoxDecorationC));
-      expect(grandChild.child, isNull);
-
-      tester.pumpWidget(new DecoratedBox(
-        decoration: kBoxDecorationA
-      ));
-
-      element =
-          tester.findElement((Element element) => element is OneChildRenderObjectElement);
-      expect(element.renderObject is RenderDecoratedBox, isTrue);
-      expect(element.renderObject, equals(parent));
-      expect(parent.child, isNull);
-
-      expect(child.parent, isNull);
-      expect(child.decoration, equals(kBoxDecorationB));
-      expect(child.child, equals(grandChild));
-      expect(grandChild.parent, equals(child));
-      expect(grandChild.decoration, equals(kBoxDecorationC));
-      expect(grandChild.child, isNull);
-    });
-  });
-}
diff --git a/sky/unit/test/widget/reparent_state_test.dart b/sky/unit/test/widget/reparent_state_test.dart
deleted file mode 100644
index cf3cbc1..0000000
--- a/sky/unit/test/widget/reparent_state_test.dart
+++ /dev/null
@@ -1,122 +0,0 @@
-// Copyright 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:flutter/widgets.dart';
-import 'package:test/test.dart';
-
-import 'widget_tester.dart';
-
-class StateMarker extends StatefulComponent {
-  StateMarker({ Key key, this.child }) : super(key: key);
-
-  final Widget child;
-
-  StateMarkerState createState() => new StateMarkerState();
-}
-
-class StateMarkerState extends State<StateMarker> {
-  String marker;
-
-  Widget build(BuildContext context) {
-    if (config.child != null)
-      return config.child;
-    return new Container();
-  }
-}
-
-void main() {
-  test('can reparent state', () {
-    testWidgets((WidgetTester tester) {
-      GlobalKey left = new GlobalKey();
-      GlobalKey right = new GlobalKey();
-
-      StateMarker grandchild = new StateMarker();
-      tester.pumpWidget(
-        new Stack(<Widget>[
-          new Container(
-            child: new StateMarker(key: left)
-          ),
-          new Container(
-            child: new StateMarker(
-              key: right,
-              child: grandchild
-            )
-          ),
-        ])
-      );
-
-      (left.currentState as StateMarkerState).marker = "left";
-      (right.currentState as StateMarkerState).marker = "right";
-
-      StateMarkerState grandchildState = tester.findStateByConfig(grandchild);
-      expect(grandchildState, isNotNull);
-      grandchildState.marker = "grandchild";
-
-      StateMarker newGrandchild = new StateMarker();
-      tester.pumpWidget(
-        new Stack(<Widget>[
-          new Container(
-            child: new StateMarker(
-              key: right,
-              child: newGrandchild
-            )
-          ),
-          new Container(
-            child: new StateMarker(key: left)
-          ),
-        ])
-      );
-
-      expect((left.currentState as StateMarkerState).marker, equals("left"));
-      expect((right.currentState as StateMarkerState).marker, equals("right"));
-
-      StateMarkerState newGrandchildState = tester.findStateByConfig(newGrandchild);
-      expect(newGrandchildState, isNotNull);
-      expect(newGrandchildState, equals(grandchildState));
-      expect(newGrandchildState.marker, equals("grandchild"));
-
-      tester.pumpWidget(
-        new Center(
-          child: new Container(
-            child: new StateMarker(
-              key: left,
-              child: new Container()
-            )
-          )
-        )
-      );
-
-      expect((left.currentState as StateMarkerState).marker, equals("left"));
-      expect(right.currentState, isNull);
-    });
-  });
-
-  test('can with scrollable list', () {
-    testWidgets((WidgetTester tester) {
-      GlobalKey key = new GlobalKey();
-
-      tester.pumpWidget(new StateMarker(key: key));
-
-      (key.currentState as StateMarkerState).marker = "marked";
-
-      tester.pumpWidget(new ScrollableList<int>(
-        items: <int>[0],
-        itemExtent: 100.0,
-        itemBuilder: (BuildContext context, int item) {
-          return new Container(
-            key: new Key('container'),
-            height: 100.0,
-            child: new StateMarker(key: key)
-          );
-        }
-      ));
-
-      expect((key.currentState as StateMarkerState).marker, equals("marked"));
-
-      tester.pumpWidget(new StateMarker(key: key));
-
-      expect((key.currentState as StateMarkerState).marker, equals("marked"));
-    });
-  });
-}
diff --git a/sky/unit/test/widget/scrollable_list_hit_testing_test.dart b/sky/unit/test/widget/scrollable_list_hit_testing_test.dart
deleted file mode 100644
index 2a392d5..0000000
--- a/sky/unit/test/widget/scrollable_list_hit_testing_test.dart
+++ /dev/null
@@ -1,96 +0,0 @@
-import 'package:flutter/rendering.dart';
-import 'package:flutter/widgets.dart';
-import 'package:test/test.dart';
-
-import 'widget_tester.dart';
-
-const List<int> items = const <int>[0, 1, 2, 3, 4, 5];
-List<int> tapped = <int>[];
-
-void main() {
-  test('Tap item after scroll - horizontal', () {
-    testWidgets((WidgetTester tester) {
-      tester.pumpWidget(new Container());
-      tester.pumpWidget(new Center(
-        child: new Container(
-          height: 50.0,
-          child: new ScrollableList<int>(
-            key: new GlobalKey(),
-            items: items,
-            itemBuilder: (BuildContext context, int item) {
-              return new Container(
-                key: new ValueKey<int>(item),
-                child: new GestureDetector(
-                  onTap: () { tapped.add(item); },
-                  child: new Text('$item')
-                )
-              );
-            },
-            itemExtent: 290.0,
-            scrollDirection: ScrollDirection.horizontal
-          )
-        )
-      ));
-      tester.scroll(tester.findText('2'), const Offset(-280.0, 0.0));
-      tester.pump(const Duration(seconds: 1));
-      // screen is 800px wide, and has the following items:
-      //  -280..10  = 0
-      //    10..300 = 1
-      //   300..590 = 2
-      //   590..880 = 3
-      expect(tester.findText('0'), isNotNull);
-      expect(tester.findText('1'), isNotNull);
-      expect(tester.findText('2'), isNotNull);
-      expect(tester.findText('3'), isNotNull);
-      expect(tester.findText('4'), isNull);
-      expect(tester.findText('5'), isNull);
-      expect(tapped, equals([]));
-      tester.tap(tester.findText('2'));
-      expect(tapped, equals([2]));
-    });
-  });
-
-  test('Tap item after scroll - vertical', () {
-    testWidgets((WidgetTester tester) {
-      tester.pumpWidget(new Container());
-      tester.pumpWidget(new Center(
-        child: new Container(
-          width: 50.0,
-          child: new ScrollableList<int>(
-            key: new GlobalKey(),
-            items: items,
-            itemBuilder: (BuildContext context, int item) {
-              return new Container(
-                key: new ValueKey<int>(item),
-                child: new GestureDetector(
-                  onTap: () { tapped.add(item); },
-                  child: new Text('$item')
-                )
-              );
-            },
-            itemExtent: 290.0,
-            scrollDirection: ScrollDirection.vertical
-          )
-        )
-      ));
-      tester.scroll(tester.findText('1'), const Offset(0.0, -280.0));
-      tester.pump(const Duration(seconds: 1));
-      // screen is 600px tall, and has the following items:
-      //  -280..10  = 0
-      //    10..300 = 1
-      //   300..590 = 2
-      //   590..880 = 3
-      expect(tester.findText('0'), isNotNull);
-      expect(tester.findText('1'), isNotNull);
-      expect(tester.findText('2'), isNotNull);
-      expect(tester.findText('3'), isNotNull);
-      expect(tester.findText('4'), isNull);
-      expect(tester.findText('5'), isNull);
-      expect(tapped, equals([2]));
-      tester.tap(tester.findText('1'));
-      expect(tapped, equals([2, 1]));
-      tester.tap(tester.findText('3'));
-      expect(tapped, equals([2, 1])); // the center of the third item is off-screen so it shouldn't get hit
-    });
-  });
-}
diff --git a/sky/unit/test/widget/scrollable_list_horizontal_test.dart b/sky/unit/test/widget/scrollable_list_horizontal_test.dart
deleted file mode 100644
index 94cdd51..0000000
--- a/sky/unit/test/widget/scrollable_list_horizontal_test.dart
+++ /dev/null
@@ -1,149 +0,0 @@
-import 'package:flutter/rendering.dart';
-import 'package:flutter/widgets.dart';
-import 'package:test/test.dart';
-
-import 'widget_tester.dart';
-
-const List<int> items = const <int>[0, 1, 2, 3, 4, 5];
-
-Widget buildFrame() {
-  return new Center(
-    child: new Container(
-      height: 50.0,
-      child: new ScrollableList<int>(
-        items: items,
-        itemBuilder: (BuildContext context, int item) {
-          return new Container(
-            key: new ValueKey<int>(item),
-            child: new Text('$item')
-          );
-        },
-        itemExtent: 290.0,
-        scrollDirection: ScrollDirection.horizontal
-      )
-    )
-  );
-}
-
-void main() {
-  test('Drag horizontally', () {
-    testWidgets((WidgetTester tester) {
-      tester.pumpWidget(buildFrame());
-
-      tester.pump(const Duration(seconds: 1));
-      tester.scroll(tester.findText('1'), const Offset(-300.0, 0.0));
-      tester.pump(const Duration(seconds: 1));
-      // screen is 800px wide, and has the following items:
-      //   -10..280 = 1
-      //   280..570 = 2
-      //   570..860 = 3
-      expect(tester.findText('0'), isNull);
-      expect(tester.findText('1'), isNotNull);
-      expect(tester.findText('2'), isNotNull);
-      expect(tester.findText('3'), isNotNull);
-      expect(tester.findText('4'), isNull);
-      expect(tester.findText('5'), isNull);
-
-      // the center of item 3 is visible, so this works;
-      // if item 3 was a bit wider, such that it's center was past the 800px mark, this would fail,
-      // because it wouldn't be hit tested when scrolling from its center, as scroll() does.
-      tester.pump(const Duration(seconds: 1));
-      tester.scroll(tester.findText('3'), const Offset(-290.0, 0.0));
-      tester.pump(const Duration(seconds: 1));
-      // screen is 800px wide, and has the following items:
-      //   -10..280 = 2
-      //   280..570 = 3
-      //   570..860 = 4
-      expect(tester.findText('0'), isNull);
-      expect(tester.findText('1'), isNull);
-      expect(tester.findText('2'), isNotNull);
-      expect(tester.findText('3'), isNotNull);
-      expect(tester.findText('4'), isNotNull);
-      expect(tester.findText('5'), isNull);
-
-      tester.pump(const Duration(seconds: 1));
-      tester.scroll(tester.findText('3'), const Offset(0.0, -290.0));
-      tester.pump(const Duration(seconds: 1));
-      // unchanged
-      expect(tester.findText('0'), isNull);
-      expect(tester.findText('1'), isNull);
-      expect(tester.findText('2'), isNotNull);
-      expect(tester.findText('3'), isNotNull);
-      expect(tester.findText('4'), isNotNull);
-      expect(tester.findText('5'), isNull);
-
-      tester.pump(const Duration(seconds: 1));
-      tester.scroll(tester.findText('3'), const Offset(-290.0, 0.0));
-      tester.pump(const Duration(seconds: 1));
-      // screen is 800px wide, and has the following items:
-      //   -10..280 = 3
-      //   280..570 = 4
-      //   570..860 = 5
-      expect(tester.findText('0'), isNull);
-      expect(tester.findText('1'), isNull);
-      expect(tester.findText('2'), isNull);
-      expect(tester.findText('3'), isNotNull);
-      expect(tester.findText('4'), isNotNull);
-      expect(tester.findText('5'), isNotNull);
-
-      tester.pump(const Duration(seconds: 1));
-      // at this point we can drag 60 pixels further before we hit the friction zone
-      // then, every pixel we drag is equivalent to half a pixel of movement
-      // to move item 3 entirely off screen therefore takes:
-      //  60 + (290-60)*2 = 520 pixels
-      // plus a couple more to be sure
-      tester.scroll(tester.findText('3'), const Offset(-522.0, 0.0));
-      tester.pump(); // just after release
-      // screen is 800px wide, and has the following items:
-      //   -11..279 = 4
-      //   279..569 = 5
-      expect(tester.findText('0'), isNull);
-      expect(tester.findText('1'), isNull);
-      expect(tester.findText('2'), isNull);
-      expect(tester.findText('3'), isNull);
-      expect(tester.findText('4'), isNotNull);
-      expect(tester.findText('5'), isNotNull);
-      tester.pump(const Duration(seconds: 1)); // a second after release
-      // screen is 800px wide, and has the following items:
-      //   -70..220 = 3
-      //   220..510 = 4
-      //   510..800 = 5
-      expect(tester.findText('0'), isNull);
-      expect(tester.findText('1'), isNull);
-      expect(tester.findText('2'), isNull);
-      expect(tester.findText('3'), isNotNull);
-      expect(tester.findText('4'), isNotNull);
-      expect(tester.findText('5'), isNotNull);
-
-      tester.pumpWidget(new Container());
-      tester.pumpWidget(buildFrame(), const Duration(seconds: 1));
-      tester.scroll(tester.findText('2'), const Offset(-280.0, 0.0));
-      tester.pump(const Duration(seconds: 1));
-      // screen is 800px wide, and has the following items:
-      //  -280..10  = 0
-      //    10..300 = 1
-      //   300..590 = 2
-      //   590..880 = 3
-      expect(tester.findText('0'), isNotNull);
-      expect(tester.findText('1'), isNotNull);
-      expect(tester.findText('2'), isNotNull);
-      expect(tester.findText('3'), isNotNull);
-      expect(tester.findText('4'), isNull);
-      expect(tester.findText('5'), isNull);
-      tester.pump(const Duration(seconds: 1));
-      tester.scroll(tester.findText('2'), const Offset(-290.0, 0.0));
-      tester.pump(const Duration(seconds: 1));
-      // screen is 800px wide, and has the following items:
-      //  -280..10  = 1
-      //    10..300 = 2
-      //   300..590 = 3
-      //   590..880 = 4
-      expect(tester.findText('0'), isNull);
-      expect(tester.findText('1'), isNotNull);
-      expect(tester.findText('2'), isNotNull);
-      expect(tester.findText('3'), isNotNull);
-      expect(tester.findText('4'), isNotNull);
-      expect(tester.findText('5'), isNull);
-    });
-  });
-}
diff --git a/sky/unit/test/widget/scrollable_list_vertical_test.dart b/sky/unit/test/widget/scrollable_list_vertical_test.dart
deleted file mode 100644
index 3998cef..0000000
--- a/sky/unit/test/widget/scrollable_list_vertical_test.dart
+++ /dev/null
@@ -1,67 +0,0 @@
-import 'package:flutter/widgets.dart';
-import 'package:test/test.dart';
-
-import 'widget_tester.dart';
-
-const List<int> items = const <int>[0, 1, 2, 3, 4, 5];
-
-Widget buildFrame() {
-  return new ScrollableList<int>(
-    items: items,
-    itemBuilder: (BuildContext context, int item) {
-      return new Container(
-        key: new ValueKey<int>(item),
-        child: new Text('$item')
-      );
-    },
-    itemExtent: 290.0,
-    scrollDirection: ScrollDirection.vertical
-  );
-}
-
-void main() {
-  test('Drag vertically', () {
-    testWidgets((WidgetTester tester) {
-      tester.pumpWidget(buildFrame());
-
-      tester.pump();
-      tester.scroll(tester.findText('1'), const Offset(0.0, -300.0));
-      tester.pump();
-      // screen is 600px high, and has the following items:
-      //   -10..280 = 1
-      //   280..570 = 2
-      //   570..860 = 3
-      expect(tester.findText('0'), isNull);
-      expect(tester.findText('1'), isNotNull);
-      expect(tester.findText('2'), isNotNull);
-      expect(tester.findText('3'), isNotNull);
-      expect(tester.findText('4'), isNull);
-      expect(tester.findText('5'), isNull);
-
-      tester.pump();
-      tester.scroll(tester.findText('2'), const Offset(0.0, -290.0));
-      tester.pump();
-      // screen is 600px high, and has the following items:
-      //   -10..280 = 2
-      //   280..570 = 3
-      //   570..860 = 4
-      expect(tester.findText('0'), isNull);
-      expect(tester.findText('1'), isNull);
-      expect(tester.findText('2'), isNotNull);
-      expect(tester.findText('3'), isNotNull);
-      expect(tester.findText('4'), isNotNull);
-      expect(tester.findText('5'), isNull);
-
-      tester.pump();
-      tester.scroll(tester.findText('3'), const Offset(-300.0, 0.0));
-      tester.pump();
-      // nothing should have changed
-      expect(tester.findText('0'), isNull);
-      expect(tester.findText('1'), isNull);
-      expect(tester.findText('2'), isNotNull);
-      expect(tester.findText('3'), isNotNull);
-      expect(tester.findText('4'), isNotNull);
-      expect(tester.findText('5'), isNull);
-    });
-  });
-}
diff --git a/sky/unit/test/widget/scrollable_list_with_inherited_test.dart b/sky/unit/test/widget/scrollable_list_with_inherited_test.dart
deleted file mode 100644
index 53d7c71..0000000
--- a/sky/unit/test/widget/scrollable_list_with_inherited_test.dart
+++ /dev/null
@@ -1,47 +0,0 @@
-import 'package:flutter/widgets.dart';
-import 'package:test/test.dart';
-
-import 'widget_tester.dart';
-
-List<int> items = <int>[0, 1, 2, 3, 4, 5];
-
-Widget buildCard(BuildContext context, int index) {
-  if (index >= items.length)
-    return null;
-  return new Container(
-    key: new ValueKey<int>(items[index]),
-    height: 100.0,
-    child: new DefaultTextStyle(
-      style: new TextStyle(fontSize: 2.0 + items.length.toDouble()),
-      child: new Text('${items[index]}')
-    )
-  );
-}
-
-InvalidatorCallback invalidator;
-
-Widget buildFrame() {
-  return new ScrollableMixedWidgetList(
-    builder: buildCard,
-    token: items.length,
-    onInvalidatorAvailable: (InvalidatorCallback callback) { invalidator = callback; }
-  );
-}
-
-void main() {
-  test('MixedViewport is a build function (smoketest)', () {
-    testWidgets((WidgetTester tester) {
-      tester.pumpWidget(buildFrame());
-      expect(tester.findText('0'), isNotNull);
-      expect(tester.findText('1'), isNotNull);
-      expect(tester.findText('2'), isNotNull);
-      expect(tester.findText('3'), isNotNull);
-      items.removeAt(2);
-      tester.pumpWidget(buildFrame());
-      expect(tester.findText('0'), isNotNull);
-      expect(tester.findText('1'), isNotNull);
-      expect(tester.findText('2'), isNull);
-      expect(tester.findText('3'), isNotNull);
-    });
-  });
-}
diff --git a/sky/unit/test/widget/set_state_3_test.dart b/sky/unit/test/widget/set_state_3_test.dart
deleted file mode 100644
index fcf2372..0000000
--- a/sky/unit/test/widget/set_state_3_test.dart
+++ /dev/null
@@ -1,58 +0,0 @@
-// Copyright 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:flutter/widgets.dart';
-import 'package:test/test.dart';
-
-import 'widget_tester.dart';
-
-ChangerState changer;
-
-class Changer extends StatefulComponent {
-  Changer(this.child);
-
-  final Widget child;
-
-  ChangerState createState() => new ChangerState();
-}
-
-class ChangerState extends State<Changer> {
-  bool _state = false;
-
-  void initState() {
-    super.initState();
-    changer = this;
-  }
-
-  void test() { setState(() { _state = true; }); }
-
-  Widget build(BuildContext context) => _state ? new Wrapper(config.child) : config.child;
-}
-
-class Wrapper extends StatelessComponent {
-  Wrapper(this.child);
-
-  final Widget child;
-
-  Widget build(BuildContext context) => child;
-}
-
-class Leaf extends StatefulComponent {
-  LeafState createState() => new LeafState();
-}
-
-class LeafState extends State<Leaf> {
-  Widget build(BuildContext context) => new Text("leaf");
-}
-
-void main() {
-  test('three-way setState() smoke test', () {
-    testWidgets((WidgetTester tester) {
-      tester.pumpWidget(new Changer(new Wrapper(new Leaf())));
-      tester.pumpWidget(new Changer(new Wrapper(new Leaf())));
-      changer.test();
-      tester.pump();
-    });
-  });
-}
diff --git a/sky/unit/test/widget/set_state_test.dart b/sky/unit/test/widget/set_state_test.dart
deleted file mode 100644
index f396a07..0000000
--- a/sky/unit/test/widget/set_state_test.dart
+++ /dev/null
@@ -1,67 +0,0 @@
-import 'package:flutter/widgets.dart';
-import 'package:test/test.dart';
-
-import '../engine/mock_events.dart';
-import 'widget_tester.dart';
-
-class Inside extends StatefulComponent {
-  InsideState createState() => new InsideState();
-}
-
-class InsideState extends State<Inside> {
-  Widget build(BuildContext context) {
-    return new Listener(
-      onPointerDown: _handlePointerDown,
-      child: new Text('INSIDE')
-    );
-  }
-
-  void _handlePointerDown(_) {
-    setState(() { });
-  }
-}
-
-class Middle extends StatefulComponent {
-  Middle({ this.child });
-
-  final Inside child;
-
-  MiddleState createState() => new MiddleState();
-}
-
-class MiddleState extends State<Middle> {
-  Widget build(BuildContext context) {
-    return new Listener(
-      onPointerDown: _handlePointerDown,
-      child: config.child
-    );
-  }
-
-  void _handlePointerDown(_) {
-    setState(() { });
-  }
-}
-
-class Outside extends StatefulComponent {
-  OutsideState createState() => new OutsideState();
-}
-
-class OutsideState extends State<Outside> {
-  Widget build(BuildContext context) {
-    return new Middle(child: new Inside());
-  }
-}
-
-void main() {
-  test('setState() smoke test', () {
-    testWidgets((WidgetTester tester) {
-      tester.pumpWidget(new Outside());
-      TestPointer pointer = new TestPointer(1);
-      Point location = tester.getCenter(tester.findText('INSIDE'));
-      tester.dispatchEvent(pointer.down(location), location);
-      tester.pump();
-      tester.dispatchEvent(pointer.up(), location);
-      tester.pump();
-    });
-  });
-}
diff --git a/sky/unit/test/widget/shader_mask_test.dart b/sky/unit/test/widget/shader_mask_test.dart
deleted file mode 100644
index 22c0360..0000000
--- a/sky/unit/test/widget/shader_mask_test.dart
+++ /dev/null
@@ -1,27 +0,0 @@
-import 'dart:ui' as ui;
-
-import 'package:flutter/painting.dart';
-import 'package:flutter/widgets.dart';
-import 'package:test/test.dart';
-
-import 'widget_tester.dart';
-
-ui.Shader createShader(Rect bounds) {
-  return new LinearGradient(
-      begin: Point.origin,
-      end: new Point(0.0, bounds.height),
-      colors: <Color>[const Color(0x00FFFFFF), const Color(0xFFFFFFFF)],
-      stops: <double>[0.1, 0.35]
-  )
-  .createShader();
-}
-
-
-void main() {
-  test('Can be constructed', () {
-    testWidgets((WidgetTester tester) {
-      Widget child = new Container(width: 100.0, height: 100.0);
-      tester.pumpWidget(new ShaderMask(child: child, shaderCallback: createShader));
-    });
-  });
-}
diff --git a/sky/unit/test/widget/size_observer_test.dart b/sky/unit/test/widget/size_observer_test.dart
deleted file mode 100644
index 1ebb816..0000000
--- a/sky/unit/test/widget/size_observer_test.dart
+++ /dev/null
@@ -1,48 +0,0 @@
-
-import 'package:flutter/rendering.dart';
-import 'package:flutter/widgets.dart';
-import 'package:test/test.dart';
-
-import 'widget_tester.dart';
-
-void main() {
-  test('SizeObserver notices zero size', () {
-    testWidgets((WidgetTester tester) {
-      List<Size> results = <Size>[];
-      tester.pumpWidget(new Center(
-        child: new SizeObserver(
-          onSizeChanged: (Size size) { results.add(size); },
-          child: new Container(width:0.0, height:0.0)
-        )
-      ));
-      expect(results, equals([Size.zero]));
-      tester.pump();
-      expect(results, equals([Size.zero]));
-      tester.pumpWidget(new Center(
-        child: new SizeObserver(
-          onSizeChanged: (Size size) { results.add(size); },
-          child: new Container(width:100.0, height:0.0)
-        )
-      ));
-      expect(results, equals([Size.zero, const Size(100.0, 0.0)]));
-      tester.pump();
-      expect(results, equals([Size.zero, const Size(100.0, 0.0)]));
-      tester.pumpWidget(new Center(
-        child: new SizeObserver(
-          onSizeChanged: (Size size) { results.add(size); },
-          child: new Container(width:0.0, height:0.0)
-        )
-      ));
-      expect(results, equals([Size.zero, const Size(100.0, 0.0), Size.zero]));
-      tester.pump();
-      expect(results, equals([Size.zero, const Size(100.0, 0.0), Size.zero]));
-      tester.pumpWidget(new Center(
-        child: new SizeObserver(
-          onSizeChanged: (Size size) { results.add(size); },
-          child: new Container(width:0.0, height:0.0)
-        )
-      ));
-      expect(results, equals([Size.zero, const Size(100.0, 0.0), Size.zero]));
-    });
-  });
-}
diff --git a/sky/unit/test/widget/snack_bar_test.dart b/sky/unit/test/widget/snack_bar_test.dart
deleted file mode 100644
index f79ef54..0000000
--- a/sky/unit/test/widget/snack_bar_test.dart
+++ /dev/null
@@ -1,45 +0,0 @@
-import 'package:flutter/material.dart';
-import 'package:test/test.dart';
-
-import 'widget_tester.dart';
-
-void main() {
-  test('SnackBar control test', () {
-    testWidgets((WidgetTester tester) {
-      String helloSnackBar = 'Hello SnackBar';
-      GlobalKey<PlaceholderState> placeholderKey = new GlobalKey<PlaceholderState>();
-      Key tapTarget = new Key('tap-target');
-
-      tester.pumpWidget(new MaterialApp(
-        routes: <String, RouteBuilder>{
-          '/': (RouteArguments args) {
-            return new GestureDetector(
-              onTap: () {
-                showSnackBar(
-                  context: args.context,
-                  placeholderKey: placeholderKey,
-                  content: new Text(helloSnackBar)
-                );
-              },
-              child: new Container(
-                decoration: const BoxDecoration(
-                  backgroundColor: const Color(0xFF00FF00)
-                ),
-                child: new Center(
-                  key: tapTarget,
-                  child: new Placeholder(key: placeholderKey)
-                )
-              )
-            );
-          }
-        }
-      ));
-
-      tester.tap(tester.findElementByKey(tapTarget));
-
-      expect(tester.findText(helloSnackBar), isNull);
-      tester.pump();
-      expect(tester.findText(helloSnackBar), isNotNull);
-    });
-  });
-}
diff --git a/sky/unit/test/widget/snap_scrolling_test.dart b/sky/unit/test/widget/snap_scrolling_test.dart
deleted file mode 100644
index b55bfe4..0000000
--- a/sky/unit/test/widget/snap_scrolling_test.dart
+++ /dev/null
@@ -1,117 +0,0 @@
-// Copyright 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 'dart:async';
-
-import 'package:flutter/widgets.dart';
-import 'package:test/test.dart';
-
-import 'widget_tester.dart';
-
-const double itemExtent = 200.0;
-ScrollDirection scrollDirection = ScrollDirection.vertical;
-GlobalKey scrollableListKey;
-
-Widget buildItem(BuildContext context, int item) {
-  return new Container(
-    key: new ValueKey<int>(item),
-    width: itemExtent,
-    height: itemExtent,
-    child: new Text(item.toString())
-  );
-}
-
-double snapOffsetCallback(double offset) {
-  return (offset / itemExtent).floor() * itemExtent;
-}
-
-Widget buildFrame() {
-  scrollableListKey = new GlobalKey();
-  return new Center(
-    child: new Container(
-      height: itemExtent * 2.0,
-      child: new ScrollableList<int>(
-        key: scrollableListKey,
-        snapOffsetCallback: snapOffsetCallback,
-        scrollDirection: scrollDirection,
-        items: <int>[0, 1, 2, 3, 4, 5, 7, 8, 9],
-        itemBuilder: buildItem,
-        itemExtent: itemExtent
-      )
-    )
-  );
-}
-
-ScrollableState get scrollableState => scrollableListKey.currentState;
-
-double get scrollOffset =>  scrollableState.scrollOffset;
-void set scrollOffset(double value) {
-  scrollableState.scrollTo(value);
-}
-
-Future fling(double velocity) {
-  Offset velocityOffset = scrollDirection == ScrollDirection.vertical
-    ? new Offset(0.0, velocity)
-    : new Offset(velocity, 0.0);
-  return scrollableState.fling(velocityOffset);
-}
-
-void main() {
-  test('ScrollableList snap scrolling, fling(-800)', () {
-    testWidgets((WidgetTester tester) {
-      tester.pumpWidget(buildFrame());
-
-      scrollOffset = 0.0;
-      tester.pump();
-      expect(scrollOffset, 0.0);
-
-      Duration dt = const Duration(seconds: 2);
-
-      fling(-800.0);
-      tester.pump(); // Start the scheduler at 0.0
-      tester.pump(dt);
-      expect(scrollOffset, closeTo(200.0, 1.0));
-
-      scrollOffset = 0.0;
-      tester.pump();
-      expect(scrollOffset, 0.0);
-
-      fling(-2000.0);
-      tester.pump();
-      tester.pump(dt);
-      expect(scrollOffset, closeTo(400.0, 1.0));
-
-      scrollOffset = 400.0;
-      tester.pump();
-      expect(scrollOffset, 400.0);
-
-      fling(800.0);
-      tester.pump();
-      tester.pump(dt);
-      expect(scrollOffset, closeTo(0.0, 1.0));
-
-      scrollOffset = 800.0;
-      tester.pump();
-      expect(scrollOffset, 800.0);
-
-      fling(2000.0);
-      tester.pump();
-      tester.pump(dt);
-      expect(scrollOffset, closeTo(200.0, 1.0));
-
-      scrollOffset = 800.0;
-      tester.pump();
-      expect(scrollOffset, 800.0);
-
-      bool completed = false;
-      fling(2000.0).then((_) {
-        completed = true;
-        expect(scrollOffset, closeTo(200.0, 1.0));
-      });
-      tester.pump();
-      tester.pump(dt);
-      expect(completed, true);
-    });
-  });
-}
diff --git a/sky/unit/test/widget/stack_test.dart b/sky/unit/test/widget/stack_test.dart
deleted file mode 100644
index 7f6dc31..0000000
--- a/sky/unit/test/widget/stack_test.dart
+++ /dev/null
@@ -1,186 +0,0 @@
-import 'package:flutter/rendering.dart';
-import 'package:flutter/widgets.dart';
-import 'package:test/test.dart';
-
-import 'widget_tester.dart';
-
-void main() {
-  test('Can construct an empty Stack', () {
-    testWidgets((WidgetTester tester) {
-      tester.pumpWidget(new Stack(<Widget>[]));
-    });
-  });
-
-  test('Can construct an empty Centered Stack', () {
-    testWidgets((WidgetTester tester) {
-      tester.pumpWidget(new Center(child: new Stack(<Widget>[])));
-    });
-  });
-
-  test('Can change position data', () {
-    testWidgets((WidgetTester tester) {
-      Key key = new Key('container');
-
-      tester.pumpWidget(
-        new Stack(<Widget>[
-          new Positioned(
-            left: 10.0,
-            child: new Container(
-              key: key,
-              width: 10.0,
-              height: 10.0
-            )
-          )
-        ])
-      );
-
-      Element container;
-      StackParentData parentData;
-
-      container = tester.findElementByKey(key);
-      parentData = container.renderObject.parentData;
-      expect(parentData.top, isNull);
-      expect(parentData.right, isNull);
-      expect(parentData.bottom, isNull);
-      expect(parentData.left, equals(10.0));
-
-      tester.pumpWidget(
-        new Stack(<Widget>[
-          new Positioned(
-            right: 10.0,
-            child: new Container(
-              key: key,
-              width: 10.0,
-              height: 10.0
-            )
-          )
-        ])
-      );
-
-      container = tester.findElementByKey(key);
-      parentData = container.renderObject.parentData;
-      expect(parentData.top, isNull);
-      expect(parentData.right, equals(10.0));
-      expect(parentData.bottom, isNull);
-      expect(parentData.left, isNull);
-    });
-  });
-
-  test('Can remove parent data', () {
-    testWidgets((WidgetTester tester) {
-      Key key = new Key('container');
-      Container container = new Container(key: key, width: 10.0, height: 10.0);
-
-      tester.pumpWidget(new Stack(<Widget>[ new Positioned(left: 10.0, child: container) ]));
-      Element containerElement = tester.findElementByKey(key);
-
-      StackParentData parentData;
-      parentData = containerElement.renderObject.parentData;
-      expect(parentData.top, isNull);
-      expect(parentData.right, isNull);
-      expect(parentData.bottom, isNull);
-      expect(parentData.left, equals(10.0));
-
-      tester.pumpWidget(new Stack(<Widget>[ container ]));
-      containerElement = tester.findElementByKey(key);
-
-      parentData = containerElement.renderObject.parentData;
-      expect(parentData.top, isNull);
-      expect(parentData.right, isNull);
-      expect(parentData.bottom, isNull);
-      expect(parentData.left, isNull);
-    });
-  });
-
-  test('Can align non-positioned children', () {
-    testWidgets((WidgetTester tester) {
-      Key child0Key = new Key('child0');
-      Key child1Key = new Key('child1');
-
-      tester.pumpWidget(
-        new Center(
-          child: new Stack(<Widget>[
-              new Container(key: child0Key, width: 20.0, height: 20.0),
-              new Container(key: child1Key, width: 10.0, height: 10.0)
-            ],
-            alignment: const FractionalOffset(0.5, 0.5)
-          )
-        )
-      );
-
-      Element child0 = tester.findElementByKey(child0Key);
-      final StackParentData child0RenderObjectParentData = child0.renderObject.parentData;
-      expect(child0RenderObjectParentData.position, equals(const Point(0.0, 0.0)));
-
-      Element child1 = tester.findElementByKey(child1Key);
-      final StackParentData child1RenderObjectParentData = child1.renderObject.parentData;
-      expect(child1RenderObjectParentData.position, equals(const Point(5.0, 5.0)));
-    });
-  });
-
-  test('Can construct an empty IndexedStack', () {
-    testWidgets((WidgetTester tester) {
-      tester.pumpWidget(new IndexedStack(<Widget>[]));
-    });
-  });
-
-  test('Can construct an empty Centered IndexedStack', () {
-    testWidgets((WidgetTester tester) {
-      tester.pumpWidget(new Center(child: new IndexedStack(<Widget>[])));
-    });
-  });
-
-  test('Can construct an IndexedStack', () {
-    testWidgets((WidgetTester tester) {
-      int itemCount = 3;
-      List<int> itemsPainted;
-
-      Widget buildFrame(int index) {
-        itemsPainted = <int>[];
-        List<Widget> items = new List<Widget>.generate(itemCount, (i) {
-          return new CustomPaint(child: new Text('$i'), onPaint: (_, __) { itemsPainted.add(i); });
-        });
-        return new Center(child: new IndexedStack(items, index: index));
-      }
-
-      tester.pumpWidget(buildFrame(0));
-      expect(tester.findText('0'), isNotNull);
-      expect(tester.findText('1'), isNotNull);
-      expect(tester.findText('2'), isNotNull);
-      expect(itemsPainted, equals([0]));
-
-      tester.pumpWidget(buildFrame(1));
-      expect(itemsPainted, equals([1]));
-
-      tester.pumpWidget(buildFrame(2));
-      expect(itemsPainted, equals([2]));
-    });
-  });
-
-  test('Can hit test an IndexedStack', () {
-    testWidgets((WidgetTester tester) {
-      Key key = new Key('indexedStack');
-      int itemCount = 3;
-      List<int> itemsTapped;
-
-      Widget buildFrame(int index) {
-        itemsTapped = <int>[];
-        List<Widget> items = new List<Widget>.generate(itemCount, (i) {
-          return new GestureDetector(child: new Text('$i'), onTap: () { itemsTapped.add(i); });
-        });
-        return new Center(child: new IndexedStack(items, key: key, index: index));
-      }
-
-      tester.pumpWidget(buildFrame(0));
-      expect(itemsTapped, isEmpty);
-      tester.tap(tester.findElementByKey(key));
-      expect(itemsTapped, [0]);
-
-      tester.pumpWidget(buildFrame(2));
-      expect(itemsTapped, isEmpty);
-      tester.tap(tester.findElementByKey(key));
-      expect(itemsTapped, [2]);
-    });
-  });
-
-}
diff --git a/sky/unit/test/widget/stateful_component_test.dart b/sky/unit/test/widget/stateful_component_test.dart
deleted file mode 100644
index c545744..0000000
--- a/sky/unit/test/widget/stateful_component_test.dart
+++ /dev/null
@@ -1,75 +0,0 @@
-import 'package:flutter/rendering.dart';
-import 'package:flutter/widgets.dart';
-import 'package:test/test.dart';
-
-import 'widget_tester.dart';
-import 'test_widgets.dart';
-
-void main() {
-  test('Stateful component smoke test', () {
-    testWidgets((WidgetTester tester) {
-
-      void checkTree(BoxDecoration expectedDecoration) {
-        OneChildRenderObjectElement element =
-            tester.findElement((Element element) => element is OneChildRenderObjectElement);
-        expect(element, isNotNull);
-        expect(element.renderObject is RenderDecoratedBox, isTrue);
-        RenderDecoratedBox renderObject = element.renderObject;
-        expect(renderObject.decoration, equals(expectedDecoration));
-      }
-
-      tester.pumpWidget(
-        new FlipComponent(
-          left: new DecoratedBox(decoration: kBoxDecorationA),
-          right: new DecoratedBox(decoration: kBoxDecorationB)
-        )
-      );
-
-      checkTree(kBoxDecorationA);
-
-      tester.pumpWidget(
-        new FlipComponent(
-          left: new DecoratedBox(decoration: kBoxDecorationB),
-          right: new DecoratedBox(decoration: kBoxDecorationA)
-        )
-      );
-
-      checkTree(kBoxDecorationB);
-
-      flipStatefulComponent(tester);
-
-      tester.pump();
-
-      checkTree(kBoxDecorationA);
-
-      tester.pumpWidget(
-        new FlipComponent(
-          left: new DecoratedBox(decoration: kBoxDecorationA),
-          right: new DecoratedBox(decoration: kBoxDecorationB)
-        )
-      );
-
-      checkTree(kBoxDecorationB);
-    });
-  });
-
-  test('Don\'t rebuild subcomponents', () {
-    testWidgets((WidgetTester tester) {
-      tester.pumpWidget(
-        new FlipComponent(
-          key: new Key('rebuild test'), // this is so we don't get the state from the TestComponentConfig in the last test, but instead instantiate a new element with a new state.
-          left: new TestBuildCounter(),
-          right: new DecoratedBox(decoration: kBoxDecorationB)
-        )
-      );
-
-      expect(TestBuildCounter.buildCount, equals(1));
-
-      flipStatefulComponent(tester);
-
-      tester.pump();
-
-      expect(TestBuildCounter.buildCount, equals(1));
-    });
-  });
-}
diff --git a/sky/unit/test/widget/stateful_components_test.dart b/sky/unit/test/widget/stateful_components_test.dart
deleted file mode 100644
index 828611e..0000000
--- a/sky/unit/test/widget/stateful_components_test.dart
+++ /dev/null
@@ -1,80 +0,0 @@
-import 'package:flutter/widgets.dart';
-import 'package:test/test.dart';
-
-import 'widget_tester.dart';
-
-class InnerComponent extends StatefulComponent {
-  InnerComponent({ Key key }) : super(key: key);
-  InnerComponentState createState() => new InnerComponentState();
-}
-
-class InnerComponentState extends State<InnerComponent> {
-  bool _didInitState = false;
-
-  void initState() {
-    super.initState();
-    _didInitState = true;
-  }
-
-  Widget build(BuildContext context) {
-    return new Container();
-  }
-}
-
-class OuterContainer extends StatefulComponent {
-  OuterContainer({ Key key, this.child }) : super(key: key);
-
-  final InnerComponent child;
-
-  OuterContainerState createState() => new OuterContainerState();
-}
-
-class OuterContainerState extends State<OuterContainer> {
-  Widget build(BuildContext context) {
-    return config.child;
-  }
-}
-
-void main() {
-  test('resync stateful widget', () {
-    testWidgets((WidgetTester tester) {
-      Key innerKey = new Key('inner');
-      Key outerKey = new Key('outer');
-
-      InnerComponent inner1 = new InnerComponent(key: innerKey);
-      InnerComponent inner2;
-      OuterContainer outer1 = new OuterContainer(key: outerKey, child: inner1);
-      OuterContainer outer2;
-
-      tester.pumpWidget(outer1);
-
-      StatefulComponentElement innerElement = tester.findElementByKey(innerKey);
-      InnerComponentState innerElementState = innerElement.state;
-      expect(innerElementState.config, equals(inner1));
-      expect(innerElementState._didInitState, isTrue);
-      expect(innerElement.renderObject.attached, isTrue);
-
-      inner2 = new InnerComponent(key: innerKey);
-      outer2 = new OuterContainer(key: outerKey, child: inner2);
-
-      tester.pumpWidget(outer2);
-
-      expect(tester.findElementByKey(innerKey), equals(innerElement));
-      expect(innerElement.state, equals(innerElementState));
-
-      expect(innerElementState.config, equals(inner2));
-      expect(innerElementState._didInitState, isTrue);
-      expect(innerElement.renderObject.attached, isTrue);
-
-      StatefulComponentElement outerElement = tester.findElementByKey(outerKey);
-      expect(outerElement.state.config, equals(outer2));
-      outerElement.state.setState(() {});
-      tester.pump();
-
-      expect(tester.findElementByKey(innerKey), equals(innerElement));
-      expect(innerElement.state, equals(innerElementState));
-      expect(innerElementState.config, equals(inner2));
-      expect(innerElement.renderObject.attached, isTrue);
-    });
-  });
-}
diff --git a/sky/unit/test/widget/syncing_test.dart b/sky/unit/test/widget/syncing_test.dart
deleted file mode 100644
index 77afd31..0000000
--- a/sky/unit/test/widget/syncing_test.dart
+++ /dev/null
@@ -1,196 +0,0 @@
-import 'package:flutter/widgets.dart';
-import 'package:test/test.dart';
-
-import 'widget_tester.dart';
-
-class TestWidget extends StatefulComponent {
-  TestWidget({ this.child, this.persistentState, this.syncedState });
-
-  final Widget child;
-  final int persistentState;
-  final int syncedState;
-
-  TestWidgetState createState() => new TestWidgetState();
-}
-
-class TestWidgetState extends State<TestWidget> {
-  int persistentState;
-  int syncedState;
-  int updates = 0;
-
-  void initState() {
-    super.initState();
-    persistentState = config.persistentState;
-    syncedState = config.syncedState;
-  }
-
-  void didUpdateConfig(TestWidget oldConfig) {
-    syncedState = config.syncedState;
-    // we explicitly do NOT sync the persistentState from the new instance
-    // because we're using that to track whether we got recreated
-    updates += 1;
-  }
-
-  Widget build(BuildContext context) => config.child;
-}
-
-void main() {
-
-  test('no change', () {
-    testWidgets((WidgetTester tester) {
-      tester.pumpWidget(
-        new Container(
-          child: new Container(
-            child: new TestWidget(
-              persistentState: 1,
-              child: new Container()
-            )
-          )
-        )
-      );
-
-      TestWidgetState state = tester.findStateOfType(TestWidgetState);
-
-      expect(state.persistentState, equals(1));
-      expect(state.updates, equals(0));
-
-      tester.pumpWidget(
-        new Container(
-          child: new Container(
-            child: new TestWidget(
-              persistentState: 2,
-              child: new Container()
-            )
-          )
-        )
-      );
-
-      expect(state.persistentState, equals(1));
-      expect(state.updates, equals(1));
-
-      tester.pumpWidget(new Container());
-    });
-  });
-
-  test('remove one', () {
-    testWidgets((WidgetTester tester) {
-      tester.pumpWidget(
-        new Container(
-          child: new Container(
-            child: new TestWidget(
-              persistentState: 10,
-              child: new Container()
-            )
-          )
-        )
-      );
-
-      TestWidgetState state = tester.findStateOfType(TestWidgetState);
-
-      expect(state.persistentState, equals(10));
-      expect(state.updates, equals(0));
-
-      tester.pumpWidget(
-        new Container(
-          child: new TestWidget(
-            persistentState: 11,
-            child: new Container()
-          )
-        )
-      );
-
-      state = tester.findStateOfType(TestWidgetState);
-
-      expect(state.persistentState, equals(11));
-      expect(state.updates, equals(0));
-
-      tester.pumpWidget(new Container());
-    });
-  });
-
-  test('swap instances around', () {
-    testWidgets((WidgetTester tester) {
-      Widget a = new TestWidget(persistentState: 0x61, syncedState: 0x41, child: new Text('apple'));
-      Widget b = new TestWidget(persistentState: 0x62, syncedState: 0x42, child: new Text('banana'));
-      tester.pumpWidget(new Column(<Widget>[]));
-
-      GlobalKey keyA = new GlobalKey();
-      GlobalKey keyB = new GlobalKey();
-
-      tester.pumpWidget(
-        new Column(<Widget>[
-          new Container(
-            key: keyA,
-            child: a
-          ),
-          new Container(
-            key: keyB,
-            child: b
-          )
-        ])
-      );
-
-      TestWidgetState first, second;
-
-      first = tester.findStateByConfig(a);
-      second = tester.findStateByConfig(b);
-
-      expect(first.config, equals(a));
-      expect(first.persistentState, equals(0x61));
-      expect(first.syncedState, equals(0x41));
-      expect(second.config, equals(b));
-      expect(second.persistentState, equals(0x62));
-      expect(second.syncedState, equals(0x42));
-
-      tester.pumpWidget(
-        new Column(<Widget>[
-          new Container(
-            key: keyA,
-            child: a
-          ),
-          new Container(
-            key: keyB,
-            child: b
-          )
-        ])
-      );
-
-      first = tester.findStateByConfig(a);
-      second = tester.findStateByConfig(b);
-
-      // same as before
-      expect(first.config, equals(a));
-      expect(first.persistentState, equals(0x61));
-      expect(first.syncedState, equals(0x41));
-      expect(second.config, equals(b));
-      expect(second.persistentState, equals(0x62));
-      expect(second.syncedState, equals(0x42));
-
-      // now we swap the nodes over
-      // since they are both "old" nodes, they shouldn't sync with each other even though they look alike
-
-      tester.pumpWidget(
-        new Column(<Widget>[
-          new Container(
-            key: keyA,
-            child: b
-          ),
-          new Container(
-            key: keyB,
-            child: a
-          )
-        ])
-      );
-
-      first = tester.findStateByConfig(b);
-      second = tester.findStateByConfig(a);
-
-      expect(first.config, equals(b));
-      expect(first.persistentState, equals(0x61));
-      expect(first.syncedState, equals(0x42));
-      expect(second.config, equals(a));
-      expect(second.persistentState, equals(0x62));
-      expect(second.syncedState, equals(0x41));
-    });
-  });
-}
diff --git a/sky/unit/test/widget/tabs_test.dart b/sky/unit/test/widget/tabs_test.dart
deleted file mode 100644
index 188bfad..0000000
--- a/sky/unit/test/widget/tabs_test.dart
+++ /dev/null
@@ -1,76 +0,0 @@
-import 'package:flutter/material.dart';
-import 'package:flutter/widgets.dart';
-import 'package:test/test.dart';
-
-import 'widget_tester.dart';
-
-int selectedIndex = 2;
-
-Widget buildFrame({ List<String> tabs, bool isScrollable: false }) {
-  return new TabBar(
-    labels: tabs.map((String tab) => new TabLabel(text: tab)).toList(),
-    selectedIndex: selectedIndex,
-    isScrollable: isScrollable,
-    onChanged: (int tabIndex) {
-      selectedIndex = tabIndex;
-    }
-  );
-}
-
-void main() {
-  test('TabBar tap selects tab', () {
-    testWidgets((WidgetTester tester) {
-      List<String> tabs = <String>['A', 'B', 'C'];
-      selectedIndex = 2;
-
-      tester.pumpWidget(buildFrame(tabs: tabs, isScrollable: false));
-      expect(tester.findText('A'), isNotNull);
-      expect(tester.findText('B'), isNotNull);
-      expect(tester.findText('C'), isNotNull);
-      expect(selectedIndex, equals(2));
-
-      tester.pumpWidget(buildFrame(tabs: tabs, isScrollable: false));
-      tester.tap(tester.findText('B'));
-      tester.pump();
-      expect(selectedIndex, equals(1));
-
-      tester.pumpWidget(buildFrame(tabs: tabs, isScrollable: false));
-      tester.tap(tester.findText('C'));
-      tester.pump();
-      expect(selectedIndex, equals(2));
-
-      tester.pumpWidget(buildFrame(tabs: tabs, isScrollable: false));
-      tester.tap(tester.findText('A'));
-      tester.pump();
-      expect(selectedIndex, equals(0));
-    });
-  });
-
-  test('Scrollable TabBar tap selects tab', () {
-    testWidgets((WidgetTester tester) {
-      List<String> tabs = <String>['A', 'B', 'C'];
-      selectedIndex = 2;
-
-      tester.pumpWidget(buildFrame(tabs: tabs, isScrollable: true));
-      expect(tester.findText('A'), isNotNull);
-      expect(tester.findText('B'), isNotNull);
-      expect(tester.findText('C'), isNotNull);
-      expect(selectedIndex, equals(2));
-
-      tester.pumpWidget(buildFrame(tabs: tabs, isScrollable: true));
-      tester.tap(tester.findText('B'));
-      tester.pump();
-      expect(selectedIndex, equals(1));
-
-      tester.pumpWidget(buildFrame(tabs: tabs, isScrollable: true));
-      tester.tap(tester.findText('C'));
-      tester.pump();
-      expect(selectedIndex, equals(2));
-
-      tester.pumpWidget(buildFrame(tabs: tabs, isScrollable: true));
-      tester.tap(tester.findText('A'));
-      tester.pump();
-      expect(selectedIndex, equals(0));
-    });
-  });
-}
diff --git a/sky/unit/test/widget/test_widgets.dart b/sky/unit/test/widget/test_widgets.dart
deleted file mode 100644
index 06caf1b..0000000
--- a/sky/unit/test/widget/test_widgets.dart
+++ /dev/null
@@ -1,58 +0,0 @@
-import 'package:flutter/widgets.dart';
-import 'package:test/test.dart';
-
-import 'widget_tester.dart';
-
-final BoxDecoration kBoxDecorationA = new BoxDecoration(
-  backgroundColor: const Color(0xFFFF0000)
-);
-
-final BoxDecoration kBoxDecorationB = new BoxDecoration(
-  backgroundColor: const Color(0xFF00FF00)
-);
-
-final BoxDecoration kBoxDecorationC = new BoxDecoration(
-  backgroundColor: const Color(0xFF0000FF)
-);
-
-class TestBuildCounter extends StatelessComponent {
-  static int buildCount = 0;
-
-  Widget build(BuildContext context) {
-    ++buildCount;
-    return new DecoratedBox(decoration: kBoxDecorationA);
-  }
-}
-
-
-class FlipComponent extends StatefulComponent {
-  FlipComponent({ Key key, this.left, this.right }) : super(key: key);
-
-  final Widget left;
-  final Widget right;
-
-  FlipComponentState createState() => new FlipComponentState();
-}
-
-class FlipComponentState extends State<FlipComponent> {
-  bool _showLeft = true;
-
-  void flip() {
-    setState(() {
-      _showLeft = !_showLeft;
-    });
-  }
-
-  Widget build(BuildContext context) {
-    return _showLeft ? config.left : config.right;
-  }
-}
-
-void flipStatefulComponent(WidgetTester tester) {
-  StatefulComponentElement stateElement =
-      tester.findElement((Element element) => element is StatefulComponentElement);
-  expect(stateElement, isNotNull);
-  expect(stateElement.state is FlipComponentState, isTrue);
-  FlipComponentState state = stateElement.state;
-  state.flip();
-}
diff --git a/sky/unit/test/widget/transform_test.dart b/sky/unit/test/widget/transform_test.dart
deleted file mode 100644
index b1e9afd..0000000
--- a/sky/unit/test/widget/transform_test.dart
+++ /dev/null
@@ -1,154 +0,0 @@
-import 'package:flutter/widgets.dart';
-import 'package:test/test.dart';
-
-import 'widget_tester.dart';
-
-void main() {
-  test('Transform origin', () {
-    testWidgets((WidgetTester tester) {
-      bool didReceiveTap = false;
-      tester.pumpWidget(
-        new Stack(<Widget>[
-          new Positioned(
-            top: 100.0,
-            left: 100.0,
-            child: new Container(
-              width: 100.0,
-              height: 100.0,
-              decoration: new BoxDecoration(
-                backgroundColor: new Color(0xFF0000FF)
-              )
-            )
-          ),
-          new Positioned(
-            top: 100.0,
-            left: 100.0,
-            child: new Container(
-              width: 100.0,
-              height: 100.0,
-              child: new Transform(
-                transform: new Matrix4.identity().scale(0.5, 0.5),
-                origin: new Offset(100.0, 50.0),
-                child: new GestureDetector(
-                  onTap: () {
-                    didReceiveTap = true;
-                  },
-                  child: new Container(
-                    decoration: new BoxDecoration(
-                      backgroundColor: new Color(0xFF00FFFF)
-                    )
-                  )
-                )
-              )
-            )
-          )
-        ])
-      );
-
-      expect(didReceiveTap, isFalse);
-      tester.tapAt(new Point(110.0, 110.0));
-      expect(didReceiveTap, isFalse);
-      tester.tapAt(new Point(190.0, 150.0));
-      expect(didReceiveTap, isTrue);
-    });
-  });
-
-  test('Transform alignment', () {
-    testWidgets((WidgetTester tester) {
-      bool didReceiveTap = false;
-      tester.pumpWidget(
-        new Stack(<Widget>[
-          new Positioned(
-            top: 100.0,
-            left: 100.0,
-            child: new Container(
-              width: 100.0,
-              height: 100.0,
-              decoration: new BoxDecoration(
-                backgroundColor: new Color(0xFF0000FF)
-              )
-            )
-          ),
-          new Positioned(
-            top: 100.0,
-            left: 100.0,
-            child: new Container(
-              width: 100.0,
-              height: 100.0,
-              child: new Transform(
-                transform: new Matrix4.identity().scale(0.5, 0.5),
-                alignment: new FractionalOffset(1.0, 0.5),
-                child: new GestureDetector(
-                  onTap: () {
-                    didReceiveTap = true;
-                  },
-                  child: new Container(
-                    decoration: new BoxDecoration(
-                      backgroundColor: new Color(0xFF00FFFF)
-                    )
-                  )
-                )
-              )
-            )
-          )
-        ])
-      );
-
-      expect(didReceiveTap, isFalse);
-      tester.tapAt(new Point(110.0, 110.0));
-      expect(didReceiveTap, isFalse);
-      tester.tapAt(new Point(190.0, 150.0));
-      expect(didReceiveTap, isTrue);
-    });
-  });
-
-  test('Transform offset + alignment', () {
-    testWidgets((WidgetTester tester) {
-      bool didReceiveTap = false;
-      tester.pumpWidget(
-        new Stack(<Widget>[
-          new Positioned(
-            top: 100.0,
-            left: 100.0,
-            child: new Container(
-              width: 100.0,
-              height: 100.0,
-              decoration: new BoxDecoration(
-                backgroundColor: new Color(0xFF0000FF)
-              )
-            )
-          ),
-          new Positioned(
-            top: 100.0,
-            left: 100.0,
-            child: new Container(
-              width: 100.0,
-              height: 100.0,
-              child: new Transform(
-                transform: new Matrix4.identity().scale(0.5, 0.5),
-                origin: new Offset(100.0, 0.0),
-                alignment: new FractionalOffset(0.0, 0.5),
-                child: new GestureDetector(
-                  onTap: () {
-                    didReceiveTap = true;
-                  },
-                  child: new Container(
-                    decoration: new BoxDecoration(
-                      backgroundColor: new Color(0xFF00FFFF)
-                    )
-                  )
-                )
-              )
-            )
-          )
-        ])
-      );
-
-      expect(didReceiveTap, isFalse);
-      tester.tapAt(new Point(110.0, 110.0));
-      expect(didReceiveTap, isFalse);
-      tester.tapAt(new Point(190.0, 150.0));
-      expect(didReceiveTap, isTrue);
-    });
-  });
-}
diff --git a/sky/unit/test/widget/widget_tester.dart b/sky/unit/test/widget/widget_tester.dart
deleted file mode 100644
index ac0a965..0000000
--- a/sky/unit/test/widget/widget_tester.dart
+++ /dev/null
@@ -1,178 +0,0 @@
-import 'package:flutter/animation.dart';
-import 'package:flutter/gestures.dart';
-import 'package:flutter/rendering.dart';
-import 'package:flutter/widgets.dart';
-import 'package:quiver/testing/async.dart';
-import 'package:quiver/time.dart';
-
-import '../engine/mock_events.dart';
-
-class RootComponent extends StatefulComponent {
-  RootComponentState createState() => new RootComponentState();
-}
-
-class RootComponentState extends State<RootComponent> {
-  Widget _child = new DecoratedBox(decoration: new BoxDecoration());
-  Widget get child => _child;
-  void set child(Widget value) {
-    if (value != _child) {
-      setState(() {
-        _child = value;
-      });
-    }
-  }
-  Widget build(BuildContext context) => child;
-}
-
-typedef Point SizeToPointFunction(Size size);
-
-class WidgetTester {
-  WidgetTester._(FakeAsync async)
-    : async = async,
-      clock = async.getClock(new DateTime.utc(2015, 1, 1));
-
-  final FakeAsync async;
-  final Clock clock;
-
-  void pumpWidget(Widget widget, [ Duration duration ]) {
-    runApp(widget);
-    pump(duration);
-  }
-
-  void pump([ Duration duration ]) {
-    if (duration != null)
-      async.elapse(duration);
-    scheduler.beginFrame(new Duration(milliseconds: clock.now().millisecondsSinceEpoch));
-    async.flushMicrotasks();
-  }
-
-  List<Layer> _layers(Layer layer) {
-    List<Layer> result = <Layer>[layer];
-    if (layer is ContainerLayer) {
-      ContainerLayer root = layer;
-      Layer child = root.firstChild;
-      while(child != null) {
-        result.addAll(_layers(child));
-        child = child.nextSibling;
-      }
-    }
-    return result;
-  }
-  List<Layer> get layers => _layers(FlutterBinding.instance.renderView.layer);
-
-
-  void walkElements(ElementVisitor visitor) {
-    void walk(Element element) {
-      visitor(element);
-      element.visitChildren(walk);
-    }
-    WidgetFlutterBinding.instance.renderViewElement.visitChildren(walk);
-  }
-
-  Element findElement(bool predicate(Element element)) {
-    try {
-      walkElements((Element element) {
-        if (predicate(element))
-          throw element;
-      });
-    } on Element catch (e) {
-      return e;
-    }
-    return null;
-  }
-
-  Element findElementByKey(Key key) {
-    return findElement((Element element) => element.widget.key == key);
-  }
-
-  Element findText(String text) {
-    return findElement((Element element) {
-      return element.widget is Text && element.widget.data == text;
-    });
-  }
-
-  State findStateOfType(Type type) {
-    StatefulComponentElement element = findElement((Element element) {
-      return element is StatefulComponentElement && element.state.runtimeType == type;
-    });
-    return element?.state;
-  }
-
-  State findStateByConfig(Widget config) {
-    StatefulComponentElement element = findElement((Element element) {
-      return element is StatefulComponentElement && element.state.config == config;
-    });
-    return element?.state;
-  }
-
-  Point getCenter(Element element) {
-    return _getElementPoint(element, (Size size) => size.center(Point.origin));
-  }
-
-  Point getTopLeft(Element element) {
-    return _getElementPoint(element, (_) => Point.origin);
-  }
-
-  Point getTopRight(Element element) {
-    return _getElementPoint(element, (Size size) => size.topRight(Point.origin));
-  }
-
-  Point getBottomLeft(Element element) {
-    return _getElementPoint(element, (Size size) => size.bottomLeft(Point.origin));
-  }
-
-  Point getBottomRight(Element element) {
-    return _getElementPoint(element, (Size size) => size.bottomRight(Point.origin));
-  }
-
-  Point _getElementPoint(Element element, SizeToPointFunction sizeToPoint) {
-    assert(element != null);
-    RenderBox box = element.renderObject as RenderBox;
-    assert(box != null);
-    return box.localToGlobal(sizeToPoint(box.size));
-  }
-
-
-  void tap(Element element, { int pointer: 1 }) {
-    tapAt(getCenter(element), pointer: pointer);
-  }
-
-  void tapAt(Point location, { int pointer: 1 }) {
-    HitTestResult result = _hitTest(location);
-    TestPointer p = new TestPointer(pointer);
-    _dispatchEvent(p.down(location), result);
-    _dispatchEvent(p.up(), result);
-  }
-
-  void scroll(Element element, Offset offset, { int pointer: 1 }) {
-    scrollAt(getCenter(element), offset, pointer: pointer);
-  }
-
-  void scrollAt(Point startLocation, Offset offset, { int pointer: 1 }) {
-    Point endLocation = startLocation + offset;
-    TestPointer p = new TestPointer(pointer);
-    // Events for the entire press-drag-release gesture are dispatched
-    // to the widgets "hit" by the pointer down event.
-    HitTestResult result = _hitTest(startLocation);
-    _dispatchEvent(p.down(startLocation), result);
-    _dispatchEvent(p.move(endLocation), result);
-    _dispatchEvent(p.up(), result);
-  }
-
-  void dispatchEvent(InputEvent event, Point location) {
-    _dispatchEvent(event, _hitTest(location));
-  }
-
-  HitTestResult _hitTest(Point location) => WidgetFlutterBinding.instance.hitTest(location);
-
-  void _dispatchEvent(InputEvent event, HitTestResult result) {
-    WidgetFlutterBinding.instance.dispatchEvent(event, result);
-  }
-
-}
-
-void testWidgets(callback(WidgetTester tester)) {
-  new FakeAsync().run((FakeAsync async) {
-    callback(new WidgetTester._(async));
-  });
-}
diff --git a/skysprites/.gitignore b/skysprites/.gitignore
deleted file mode 100644
index 1687d39..0000000
--- a/skysprites/.gitignore
+++ /dev/null
@@ -1,7 +0,0 @@
-.DS_Store
-.idea
-.packages
-.pub/
-build/
-packages
-pubspec.lock
diff --git a/skysprites/LICENSE b/skysprites/LICENSE
deleted file mode 100644
index 972bb2e..0000000
--- a/skysprites/LICENSE
+++ /dev/null
@@ -1,27 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//    * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//    * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//    * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/skysprites/README.md b/skysprites/README.md
deleted file mode 100644
index a7ebb81..0000000
--- a/skysprites/README.md
+++ /dev/null
@@ -1,8 +0,0 @@
-# Flutter Sprites
-
-A sprite toolkit built on top of Flutter.
-
-## Getting Started
-
-For help getting started with Flutter, view our online
-[documentation](http://flutter.io).
diff --git a/skysprites/lib/flutter_sprites.dart b/skysprites/lib/flutter_sprites.dart
deleted file mode 100644
index 41f6830..0000000
--- a/skysprites/lib/flutter_sprites.dart
+++ /dev/null
@@ -1,52 +0,0 @@
-// Copyright 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.
-
-library flutter_sprites;
-
-import 'dart:async';
-import 'dart:convert';
-import 'dart:math' as math;
-import 'dart:typed_data';
-import 'dart:ui' as ui;
-
-import 'package:box2d/box2d.dart' as box2d;
-import 'package:mojo/core.dart';
-import 'package:sky_services/media/media.mojom.dart';
-import 'package:flutter/animation.dart';
-import 'package:flutter/gestures.dart';
-import 'package:flutter/painting.dart';
-import 'package:flutter/rendering.dart';
-import 'package:flutter/services.dart';
-import 'package:flutter/widgets.dart';
-import 'package:vector_math/vector_math_64.dart';
-
-part 'src/action.dart';
-part 'src/action_spline.dart';
-part 'src/color_secuence.dart';
-part 'src/constraint.dart';
-part 'src/effect_line.dart';
-part 'src/image_map.dart';
-part 'src/label.dart';
-part 'src/layer.dart';
-part 'src/node.dart';
-part 'src/node3d.dart';
-part 'src/node_with_size.dart';
-part 'src/particle_system.dart';
-part 'src/physics_body.dart';
-part 'src/physics_collision_groups.dart';
-part 'src/physics_debug.dart';
-part 'src/physics_group.dart';
-part 'src/physics_joint.dart';
-part 'src/physics_shape.dart';
-part 'src/physics_world.dart';
-part 'src/sound.dart';
-part 'src/sound_manager.dart';
-part 'src/sprite.dart';
-part 'src/spritesheet.dart';
-part 'src/sprite_box.dart';
-part 'src/sprite_widget.dart';
-part 'src/texture.dart';
-part 'src/textured_line.dart';
-part 'src/util.dart';
-part 'src/virtual_joystick.dart';
diff --git a/skysprites/lib/src/action.dart b/skysprites/lib/src/action.dart
deleted file mode 100644
index cd6915b..0000000
--- a/skysprites/lib/src/action.dart
+++ /dev/null
@@ -1,557 +0,0 @@
-part of flutter_sprites;
-
-typedef void ActionCallback();
-
-/// Actions are used to animate properties of nodes or any other type of
-/// objects. The actions are powered by an [ActionController], typically
-/// associated with a [Node]. The most commonly used action is the
-/// [ActionTween] which interpolates a property between two values over time.
-///
-/// Actions can be nested in different ways; played in sequence using the
-/// [ActionSequence], or looped using the [ActionRepeat].
-///
-/// You should typically not override this class directly, instead override
-/// [ActionInterval] or [ActionInstant] if you need to create a new action
-/// class.
-abstract class Action {
-  Object _tag;
-  bool _finished = false;
-  bool _added = false;
-
-  /// Moves to the next time step in an action, [dt] is the delta time since
-  /// the last time step in seconds. Typically this method is called from the
-  /// [ActionController].
-  void step(double dt);
-
-  /// Sets the action to a specific point in time. The [t] value that is passed
-  /// in is a normalized value 0.0 to 1.0 of the duration of the action. Every
-  /// action will always recieve a callback with the end time point (1.0),
-  /// unless it is cancelled.
-  void update(double t) {
-  }
-
-  void _reset() {
-    _finished = false;
-  }
-
-  double get duration => 0.0;
-}
-
-typedef void SetterCallback(dynamic value);
-
-/// The abstract class for an action that changes properties over a time
-/// interval, optionally using an easing curve.
-abstract class ActionInterval extends Action {
-  double _duration;
-
-  bool _firstTick = true;
-  double _elapsed = 0.0;
-
-  /// The duration, in seconds, of the action.
-  ///
-  ///     double myTime = myAction.duration;
-  double get duration => _duration;
-
-  /// The animation curve used to ease the animation.
-  ///
-  ///     myAction.curve = bounceOut;
-  Curve curve;
-
-  ActionInterval([this._duration = 0.0, this.curve]);
-
-  void step(double dt) {
-    if (_firstTick) {
-      _firstTick = false;
-    } else {
-      _elapsed += dt;
-    }
-
-    double t;
-    if (this._duration == 0.0) {
-      t = 1.0;
-    } else {
-      t = (_elapsed / _duration).clamp(0.0, 1.0);
-    }
-
-    if (curve == null) {
-      update(t);
-    } else {
-      update(curve.transform(t));
-    }
-
-    if (t >= 1.0) _finished = true;
-  }
-}
-
-/// An action that repeats an action a fixed number of times.
-class ActionRepeat extends ActionInterval {
-  final int numRepeats;
-  final ActionInterval action;
-  int _lastFinishedRepeat = -1;
-
-  /// Creates a new action that is repeats the passed in action a fixed number
-  /// of times.
-  ///
-  ///     var myLoop = new ActionRepeat(myAction);
-  ActionRepeat(this.action, this.numRepeats) {
-    _duration = action.duration * numRepeats;
-  }
-
-  void update(double t) {
-    int currentRepeat = math.min((t * numRepeats.toDouble()).toInt(), numRepeats - 1);
-    for (int i = math.max(_lastFinishedRepeat, 0); i < currentRepeat; i++) {
-      if (!action._finished) action.update(1.0);
-      action._reset();
-    }
-    _lastFinishedRepeat = currentRepeat;
-
-    double ta = (t * numRepeats.toDouble()) % 1.0;
-    action.update(ta);
-
-    if (t >= 1.0) {
-      action.update(1.0);
-      action._finished = true;
-    }
-  }
-}
-
-/// An action that repeats an action an indefinite number of times.
-class ActionRepeatForever extends Action {
-  final ActionInterval action;
-  double _elapsedInAction = 0.0;
-
-  /// Creates a new action with the action that is passed in.
-  ///
-  ///     var myInifiniteLoop = new ActionRepeatForever(myAction);
-  ActionRepeatForever(this.action);
-
-  step(double dt) {
-    _elapsedInAction += dt;
-    while (_elapsedInAction > action.duration) {
-      _elapsedInAction -= action.duration;
-      if (!action._finished) action.update(1.0);
-      action._reset();
-    }
-    _elapsedInAction = math.max(_elapsedInAction, 0.0);
-
-    double t;
-    if (action._duration == 0.0) {
-      t = 1.0;
-    } else {
-      t = (_elapsedInAction / action._duration).clamp(0.0, 1.0);
-    }
-
-    action.update(t);
-  }
-}
-
-/// An action that plays a number of supplied actions in sequence. The duration
-/// of the [ActionSequence] with be the sum of the durations of the actions
-/// passed in to the constructor.
-class ActionSequence extends ActionInterval {
-  Action _a;
-  Action _b;
-  double _split;
-
-  /// Creates a new action with the list of actions passed in.
-  ///
-  ///     var mySequence = new ActionSequence([myAction0, myAction1, myAction2]);
-  ActionSequence(List<Action> actions) {
-    assert(actions.length >= 2);
-
-    if (actions.length == 2) {
-      // Base case
-      _a = actions[0];
-      _b = actions[1];
-    } else {
-      _a = actions[0];
-      _b = new ActionSequence(actions.sublist(1));
-    }
-
-    // Calculate split and duration
-    _duration = _a.duration + _b.duration;
-    if (_duration > 0) {
-      _split = _a.duration / _duration;
-    } else {
-      _split = 1.0;
-    }
-  }
-
-  void update(double t) {
-    if (t < _split) {
-      // Play first action
-      double ta;
-      if (_split > 0.0) {
-        ta = (t / _split).clamp(0.0, 1.0);
-      } else {
-        ta = 1.0;
-      }
-      _updateWithCurve(_a, ta);
-    } else if (t >= 1.0) {
-      // Make sure everything is finished
-      if (!_a._finished) _finish(_a);
-      if (!_b._finished) _finish(_b);
-    } else {
-      // Play second action, but first make sure the first has finished
-      if (!_a._finished) _finish(_a);
-      double tb;
-      if (_split < 1.0) {
-        tb = (1.0 - (1.0 - t) / (1.0 - _split)).clamp(0.0, 1.0);
-      } else {
-        tb = 1.0;
-      }
-      _updateWithCurve(_b, tb);
-    }
-  }
-
-  void _updateWithCurve(Action action, double t) {
-    if (action is ActionInterval) {
-      ActionInterval actionInterval = action;
-      if (actionInterval.curve == null) {
-        action.update(t);
-      } else {
-        action.update(actionInterval.curve.transform(t));
-      }
-    } else {
-      action.update(t);
-    }
-
-    if (t >= 1.0) {
-      action._finished = true;
-    }
-  }
-
-  void _finish(Action action) {
-    action.update(1.0);
-    action._finished = true;
-  }
-
-  void _reset() {
-    super._reset();
-    _a._reset();
-    _b._reset();
-  }
-}
-
-/// An action that plays the supplied actions in parallell. The duration of the
-/// [ActionGroup] will be the maximum of the durations of the actions used to
-/// compose this action.
-class ActionGroup extends ActionInterval {
-  List<Action> _actions;
-
-  /// Creates a new action with the list of actions passed in.
-  ///
-  ///     var myGroup = new ActionGroup([myAction0, myAction1, myAction2]);
-  ActionGroup(this._actions) {
-    for (Action action in _actions) {
-      if (action.duration > _duration) {
-        _duration = action.duration;
-      }
-    }
-  }
-
-  void update(double t) {
-    if (t >= 1.0) {
-      // Finish all unfinished actions
-      for (Action action in _actions) {
-        if (!action._finished) {
-          action.update(1.0);
-          action._finished = true;
-        }
-      }
-    } else {
-      for (Action action in _actions) {
-        if (action.duration == 0.0) {
-          // Fire all instant actions immediately
-          if (!action._finished) {
-            action.update(1.0);
-            action._finished = true;
-          }
-        } else {
-          // Update child actions
-          double ta = (t / (action.duration / duration)).clamp(0.0, 1.0);
-          if (ta < 1.0) {
-            if (action is ActionInterval) {
-              ActionInterval actionInterval = action;
-              if (actionInterval.curve == null) {
-                action.update(ta);
-              } else {
-                action.update(actionInterval.curve.transform(ta));
-              }
-            } else {
-              action.update(ta);
-            }
-          } else if (!action._finished){
-            action.update(1.0);
-            action._finished = true;
-          }
-        }
-      }
-    }
-  }
-
-  void _reset() {
-    for (Action action in _actions) {
-      action._reset();
-    }
-  }
-}
-
-/// An action that doesn't perform any other task than taking time. This action
-/// is typically used in a sequence to space out other events.
-class ActionDelay extends ActionInterval {
-  /// Creates a new action with the specified [delay]
-  ActionDelay(double delay) : super(delay);
-}
-
-/// An action that doesn't have a duration. If this class is overridden to
-/// create custom instant actions, only the [fire] method should be overriden.
-abstract class ActionInstant extends Action {
-
-  void step(double dt) {
-  }
-
-  void update(double t) {
-    fire();
-    _finished = true;
-  }
-
-  void fire();
-}
-
-/// An action that calls a custom function when it is fired.
-class ActionCallFunction extends ActionInstant {
-  ActionCallback _function;
-
-  /// Creates a new callback action with the supplied callback.
-  ///
-  ///     var myAction = new ActionCallFunction(() { print("Hello!";) });
-  ActionCallFunction(this._function);
-
-  void fire() {
-    _function();
-  }
-}
-
-/// An action that removes the supplied node from its parent when it's fired.
-class ActionRemoveNode extends ActionInstant {
-  Node _node;
-
-  /// Creates a new action with the node to remove as its argument.
-  ///
-  ///     var myAction = new ActionRemoveNode(myNode);
-  ActionRemoveNode(this._node);
-
-  void fire() {
-    _node.removeFromParent();
-  }
-}
-
-/// An action that tweens a property between two values, optionally using an
-/// animation curve. This is one of the most common building blocks when
-/// creating actions. The tween class can be used to animate properties of the
-/// type [Point], [Size], [Rect], [double], or [Color].
-class ActionTween extends ActionInterval {
-
-  /// Creates a new tween action. The [setter] will be called to update the
-  /// animated property from [startVal] to [endVal] over the [duration] time in
-  /// seconds. Optionally an animation [curve] can be passed in for easing the
-  /// animation.
-  ///
-  ///     // Animate myNode from its current position to 100.0, 100.0 during
-  ///     // 1.0 second and a bounceOut easing
-  ///     var myTween = new ActionTween(
-  ///       (a) => myNode.position = a,
-  ///       myNode.position,
-  ///       new Point(100.0, 100.0,
-  ///       1.0,
-  ///       bounceOut
-  ///     );
-  ///     myNode.actions.run(myTween);
-  ActionTween(this.setter, this.startVal, this.endVal, double duration, [Curve curve]) : super(duration, curve) {
-    _computeDelta();
-  }
-
-  /// The setter method used to set the property being animated.
-  final SetterCallback setter;
-
-  /// The start value of the animation.
-  final dynamic startVal;
-
-  /// The end value of the animation.
-  final dynamic endVal;
-
-  dynamic _delta;
-
-  void _computeDelta() {
-    if (startVal is Point) {
-      // Point
-      double xStart = startVal.x;
-      double yStart = startVal.y;
-      double xEnd = endVal.x;
-      double yEnd = endVal.y;
-      _delta = new Point(xEnd - xStart, yEnd - yStart);
-    } else if (startVal is Size) {
-      // Size
-      double wStart = startVal.width;
-      double hStart = startVal.height;
-      double wEnd = endVal.width;
-      double hEnd = endVal.height;
-      _delta = new Size(wEnd - wStart, hEnd - hStart);
-    } else if (startVal is Rect) {
-      // Rect
-      double lStart = startVal.left;
-      double tStart = startVal.top;
-      double rStart = startVal.right;
-      double bStart = startVal.bottom;
-      double lEnd = endVal.left;
-      double tEnd = endVal.top;
-      double rEnd = endVal.right;
-      double bEnd = endVal.bottom;
-      _delta = new Rect.fromLTRB(lEnd - lStart, tEnd - tStart, rEnd - rStart, bEnd - bStart);
-    } else if (startVal is double) {
-      // Double
-      _delta = endVal - startVal;
-    } else if (startVal is Color) {
-      // Color
-      int aDelta = endVal.alpha - startVal.alpha;
-      int rDelta = endVal.red - startVal.red;
-      int gDelta = endVal.green - startVal.green;
-      int bDelta = endVal.blue - startVal.blue;
-      _delta = new _ColorDiff(aDelta, rDelta, gDelta, bDelta);
-    } else {
-      assert(false);
-    }
-  }
-
-  void update(double t) {
-    var newVal;
-
-    if (startVal is Point) {
-      // Point
-      double xStart = startVal.x;
-      double yStart = startVal.y;
-      double xDelta = _delta.x;
-      double yDelta = _delta.y;
-      newVal = new Point(xStart + xDelta * t, yStart + yDelta * t);
-    } else if (startVal is Size) {
-      // Size
-      double wStart = startVal.width;
-      double hStart = startVal.height;
-      double wDelta = _delta.width;
-      double hDelta = _delta.height;
-      newVal = new Size(wStart + wDelta * t, hStart + hDelta * t);
-    } else if (startVal is Rect) {
-      // Rect
-      double lStart = startVal.left;
-      double tStart = startVal.top;
-      double rStart = startVal.right;
-      double bStart = startVal.bottom;
-      double lDelta = _delta.left;
-      double tDelta = _delta.top;
-      double rDelta = _delta.right;
-      double bDelta = _delta.bottom;
-      newVal = new Rect.fromLTRB(lStart + lDelta * t, tStart + tDelta * t, rStart + rDelta * t, bStart + bDelta * t);
-    } else if (startVal is double) {
-      // Doubles
-      newVal = startVal + _delta * t;
-    } else if (startVal is Color) {
-      // Colors
-      int aNew = (startVal.alpha + (_delta.alpha * t).toInt()).clamp(0, 255);
-      int rNew = (startVal.red + (_delta.red * t).toInt()).clamp(0, 255);
-      int gNew = (startVal.green + (_delta.green * t).toInt()).clamp(0, 255);
-      int bNew = (startVal.blue + (_delta.blue * t).toInt()).clamp(0, 255);
-      newVal = new Color.fromARGB(aNew, rNew, gNew, bNew);
-    } else {
-      // Oopses
-      assert(false);
-    }
-
-    setter(newVal);
-  }
-}
-
-/// A class the controls the playback of actions. To play back an action it is
-/// passed to the [ActionController]'s [run] method. The [ActionController]
-/// itself is typically a property of a [Node] and powered by the [SpriteBox].
-class ActionController {
-
-  List<Action> _actions = <Action>[];
-
-  /// Creates a new [ActionController]. However, for most uses a reference to
-  /// an [ActionController] is acquired through the [Node.actions] property.
-  ActionController();
-
-  /// Runs an [action], can optionally be passed a [tag]. The [tag] can be used
-  /// to reference the action or a set of actions with the same tag.
-  ///
-  ///     myNode.actions.run(myAction, "myActionGroup");
-  void run(Action action, [Object tag]) {
-    assert(!action._added);
-
-    action._tag = tag;
-    action._added = true;
-    action.update(0.0);
-    _actions.add(action);
-  }
-
-  /// Stops an [action] and removes it from the controller.
-  ///
-  ///     myNode.actions.stop(myAction);
-  void stop(Action action) {
-    if (_actions.remove(action)) {
-      action._added = false;
-      action._reset();
-    }
-  }
-
-  void _stopAtIndex(int i) {
-    Action action = _actions[i];
-    action._added = false;
-    action._reset();
-    _actions.removeAt(i);
-  }
-
-  /// Stops all actions with the specified tag and removes them from the
-  /// controller.
-  ///
-  ///     myNode.actions.stopWithTag("myActionGroup");
-  void stopWithTag(Object tag) {
-    for (int i = _actions.length - 1; i >= 0; i--) {
-      Action action = _actions[i];
-      if (action._tag == tag) {
-        _stopAtIndex(i);
-      }
-    }
-  }
-
-  /// Stops all actions currently being run by the controller and removes them.
-  ///
-  ///     myNode.actions.stopAll();
-  void stopAll() {
-    for (int i = _actions.length - 1; i >= 0; i--) {
-      _stopAtIndex(i);
-    }
-  }
-
-  void step(double dt) {
-    for (int i = _actions.length - 1; i >= 0; i--) {
-      Action action = _actions[i];
-      action.step(dt);
-
-      if (action._finished) {
-        action._added = false;
-        _actions.removeAt(i);
-      }
-    }
-  }
-}
-
-class _ColorDiff {
-  final int alpha;
-  final int red;
-  final int green;
-  final int blue;
-
-  _ColorDiff(this.alpha, this.red, this.green, this.blue);
-}
diff --git a/skysprites/lib/src/action_spline.dart b/skysprites/lib/src/action_spline.dart
deleted file mode 100644
index beef314..0000000
--- a/skysprites/lib/src/action_spline.dart
+++ /dev/null
@@ -1,69 +0,0 @@
-part of flutter_sprites;
-
-Point _cardinalSplineAt(Point p0, Point p1, Point p2, Point p3, double tension, double t) {
-  double t2 = t * t;
-  double t3 = t2 * t;
-
-  double s = (1.0 - tension) / 2.0;
-
-  double b1 = s * ((-t3 + (2.0 * t2)) - t);
-	double b2 = s * (-t3 + t2) + (2.0 * t3 - 3.0 * t2 + 1.0);
-	double b3 = s * (t3 - 2.0 * t2 + t) + (-2.0 * t3 + 3.0 * t2);
-	double b4 = s * (t3 - t2);
-
-  double x = p0.x * b1 + p1.x * b2 + p2.x * b3 + p3.x * b4;
-	double y = p0.y * b1 + p1.y * b2 + p2.y * b3 + p3.y * b4;
-
-  return new Point(x, y);
-}
-
-typedef void PointSetterCallback(Point value);
-
-/// The spline action is used to animate a point along a spline definied by
-/// a set of points.
-class ActionSpline extends ActionInterval {
-
-  /// Creates a new spline action with a set of points. The [setter] is a
-  /// callback for setting the positions, [points] define the spline, and
-  /// [duration] is the time for the action to complete. Optionally a [curve]
-  /// can be used for easing.
-  ActionSpline(this.setter, this.points, double duration, [Curve curve]) : super(duration, curve) {
-    _dt = 1.0 / (points.length - 1.0);
-  }
-
-  /// The callback used to update a point when the action is run.
-  final PointSetterCallback setter;
-
-  /// A list of points that define the spline.
-  final List<Point> points;
-
-  /// The tension of the spline, defines the roundness of the curve.
-  double tension = 0.5;
-
-  double _dt;
-
-  void update(double t) {
-
-    int p;
-    double lt;
-
-    if (t < 0.0) t = 0.0;
-
-    if (t >= 1.0) {
-      p = points.length - 1;
-      lt = 1.0;
-    } else {
-      p = (t / _dt).floor();
-      lt = (t - _dt * p) / _dt;
-    }
-
-    Point p0 = points[(p - 1).clamp(0, points.length - 1)];
-    Point p1 = points[(p + 0).clamp(0, points.length - 1)];
-    Point p2 = points[(p + 1).clamp(0, points.length - 1)];
-    Point p3 = points[(p + 2).clamp(0, points.length - 1)];
-
-    Point newPos = _cardinalSplineAt(p0, p1, p2, p3, tension, lt);
-
-    setter(newPos);
-  }
-}
diff --git a/skysprites/lib/src/color_secuence.dart b/skysprites/lib/src/color_secuence.dart
deleted file mode 100644
index 0b84a20..0000000
--- a/skysprites/lib/src/color_secuence.dart
+++ /dev/null
@@ -1,77 +0,0 @@
-part of flutter_sprites;
-
-/// A sequence of colors representing a gradient or a color transition over
-/// time. The sequence is represented by a list of [colors] and a list of
-/// [colorStops], the stops are normalized values (0.0 to 1.0) and ordered in
-/// the list. Both lists have the same number of elements.
-class ColorSequence {
-  /// List of colors.
-  List<Color> colors;
-
-  /// List of color stops, normalized values (0.0 to 1.0) and ordered.
-  List<double> colorStops;
-
-  /// Creates a new color sequence from a list of [colors] and a list of
-  /// [colorStops].
-  ColorSequence(this.colors, this.colorStops) {
-    assert(colors != null);
-    assert(colorStops != null);
-    assert(colors.length == colorStops.length);
-  }
-
-  /// Creates a new color sequence from a start and an end color.
-  ColorSequence.fromStartAndEndColor(Color start, Color end) {
-    colors = <Color>[start, end];
-    colorStops = <double>[0.0, 1.0];
-  }
-
-  /// Creates a new color sequence by copying an existing sequence.
-  ColorSequence.copy(ColorSequence sequence) {
-    colors = new List<Color>.from(sequence.colors);
-    colorStops = new List<double>.from(sequence.colorStops);
-  }
-
-  /// Returns the color at a normalized (0.0 to 1.0) position in the color
-  /// sequence. If a color stop isn't hit, the returned color will be an
-  /// interpolation of a color between two color stops.
-  Color colorAtPosition(double pos) {
-    assert(pos >= 0.0 && pos <= 1.0);
-
-    if (pos == 0.0) return colors[0];
-
-    double lastStop = colorStops[0];
-    Color lastColor = colors[0];
-
-    for (int i = 0; i < colors.length; i++) {
-      double currentStop = colorStops[i];
-      Color currentColor = colors[i];
-
-      if (pos <= currentStop) {
-        double blend = (pos - lastStop) / (currentStop - lastStop);
-        return _interpolateColor(lastColor, currentColor, blend);
-      }
-      lastStop = currentStop;
-      lastColor = currentColor;
-    }
-    return colors[colors.length-1];
-  }
-}
-
-Color _interpolateColor(Color a, Color b, double blend) {
-  double aa = a.alpha.toDouble();
-  double ar = a.red.toDouble();
-  double ag = a.green.toDouble();
-  double ab = a.blue.toDouble();
-
-  double ba = b.alpha.toDouble();
-  double br = b.red.toDouble();
-  double bg = b.green.toDouble();
-  double bb = b.blue.toDouble();
-
-  int na = (aa * (1.0 - blend) + ba * blend).toInt();
-  int nr = (ar * (1.0 - blend) + br * blend).toInt();
-  int ng = (ag * (1.0 - blend) + bg * blend).toInt();
-  int nb = (ab * (1.0 - blend) + bb * blend).toInt();
-
-  return new Color.fromARGB(na, nr, ng, nb);
-}
diff --git a/skysprites/lib/src/constraint.dart b/skysprites/lib/src/constraint.dart
deleted file mode 100644
index 99296cf..0000000
--- a/skysprites/lib/src/constraint.dart
+++ /dev/null
@@ -1,142 +0,0 @@
-part of flutter_sprites;
-
-/// A constraint limits or otherwise controls a [Node]'s properties, such as
-/// position or rotation. Add a list of constraints by setting the [Node]'s
-/// constraints property.
-///
-/// Constrains are applied after the update calls are
-/// completed. They can also be applied at any time by calling a [Node]'s
-/// [applyConstraints] method. It's possible to create custom constraints by
-/// overriding this class and implementing the [constrain] method.
-abstract class Constraint {
-  /// Called before the node's update method is called. This method can be
-  /// overridden to create setup work that needs to happen before the the
-  /// node is updated, e.g. to calculate the node's speed.
-  void preUpdate(Node node, double dt) {
-  }
-
-  /// Called after update is complete, if the constraint has been added to a
-  /// [Node]. Override this method to modify the node's property according to
-  /// the constraint.
-  void constrain(Node node, double dt);
-}
-
-double _dampenRotation(double src, double dst, double dampening) {
-  if (dampening == null)
-    return dst;
-
-  double delta = dst - src;
-  while (delta > 180.0) delta -= 360;
-  while (delta < -180) delta += 360;
-  delta *= dampening;
-
-  return src + delta;
-}
-
-/// A [Constraint] that aligns a nodes rotation to its movement.
-class ConstraintRotationToMovement extends Constraint {
-  /// Creates a new constraint the aligns a nodes rotation to its movement
-  /// vector. A [baseRotation] and [dampening] can optionally be set.
-  ConstraintRotationToMovement({this.baseRotation: 0.0, this.dampening});
-
-  /// The filter factor used when constraining the rotation of the node. Valid
-  /// values are in the range 0.0 to 1.0
-  final double dampening;
-
-  /// The base rotation will be added to a the movement vectors rotation.
-  final double baseRotation;
-
-  Point _lastPosition;
-
-  void preUpdate(Node node, double dt) {
-    _lastPosition = node.position;
-  }
-
-  void constrain(Node node, double dt) {
-    if (_lastPosition == null) return;
-    if (_lastPosition == node.position) return;
-
-    // Get the target angle
-    Offset offset = node.position - _lastPosition;
-    double target = degrees(GameMath.atan2(offset.dy, offset.dx)) + baseRotation;
-
-    node.rotation = _dampenRotation(node.rotation, target, dampening);
-  }
-}
-
-/// A [Constraint] that rotates a node to point towards another node. The target
-/// node is allowed to have a different parent, but they must be in the same
-/// [SpriteBox].
-class ConstraintRotationToNode extends Constraint {
-  /// Creates a new [Constraint] that rotates the node towards the [targetNode].
-  /// The [baseRotation] will be added to the nodes rotation, and [dampening]
-  /// can be used to ease the rotation.
-  ConstraintRotationToNode(this.targetNode, {this.baseRotation: 0.0, this.dampening});
-
-  /// The node to rotate towards.
-  final Node targetNode;
-
-  /// The base rotation will be added after the target rotation is calculated.
-  final double baseRotation;
-
-  /// The filter factor used when constraining the rotation of the node. Valid
-  /// values are in the range 0.0 to 1.0
-  final double dampening;
-
-  void constrain(Node node, double dt) {
-    Offset offset;
-
-    if (targetNode.spriteBox != node.spriteBox) {
-      // The target node is in another sprite box or has been removed
-      return;
-    }
-
-    if (targetNode.parent == node.parent) {
-      offset = targetNode.position - node.position;
-    } else {
-      offset = node.convertPointToBoxSpace(Point.origin)
-        - targetNode.convertPointToBoxSpace(Point.origin);
-    }
-
-    double target = degrees(GameMath.atan2(offset.dy, offset.dx)) + baseRotation;
-
-    node.rotation = _dampenRotation(node.rotation, target, dampening);
-  }
-}
-
-/// A [Constraint] that constrains the position of a node to equal the position
-/// of another node, optionally with dampening.
-class ConstraintPositionToNode extends Constraint {
-  /// Creates a new [Constraint] that constrains the poistion of a node to be
-  /// equal to the position of the [targetNode]. Optionally an [offset] can
-  /// be used and also [dampening]. The targetNode doesn't need to have the
-  /// same parent, but they need to be added to the same [SpriteBox].
-  ConstraintPositionToNode(this.targetNode, {this.dampening, this.offset: Offset.zero});
-
-  final Node targetNode;
-  final Offset offset;
-  final double dampening;
-
-  void constrain(Node node, double dt) {
-    Point targetPosition;
-
-    if (targetNode.spriteBox != node.spriteBox || node.parent == null) {
-      // The target node is in another sprite box or has been removed
-      return;
-    }
-
-    if (targetNode.parent == node.parent) {
-      targetPosition = targetNode.position;
-    } else {
-      targetPosition = node.parent.convertPointFromNode(Point.origin, targetNode);
-    }
-
-    if (offset != null)
-      targetPosition += offset;
-
-    if (dampening == null)
-      node.position = targetPosition;
-    else
-      node.position = GameMath.filterPoint(node.position, targetPosition, dampening);
-  }
-}
diff --git a/skysprites/lib/src/effect_line.dart b/skysprites/lib/src/effect_line.dart
deleted file mode 100644
index 34aef88..0000000
--- a/skysprites/lib/src/effect_line.dart
+++ /dev/null
@@ -1,208 +0,0 @@
-part of flutter_sprites;
-
-enum EffectLineWidthMode {
-  linear,
-  barrel,
-}
-
-enum EffectLineAnimationMode {
-  none,
-  scroll,
-  random,
-}
-
-class EffectLine extends Node {
-
-  EffectLine({
-    this.texture: null,
-    this.transferMode: ui.TransferMode.dstOver,
-    List<Point> points,
-    this.widthMode : EffectLineWidthMode.linear,
-    this.minWidth: 10.0,
-    this.maxWidth: 10.0,
-    this.widthGrowthSpeed: 0.0,
-    this.animationMode: EffectLineAnimationMode.none,
-    this.scrollSpeed: 0.1,
-    double scrollStart: 0.0,
-    this.fadeDuration: null,
-    this.fadeAfterDelay: null,
-    this.textureLoopLength: null,
-    this.simplify: true,
-    ColorSequence colorSequence
-  }) {
-    if (points == null)
-      this.points = <Point>[];
-    else
-      this.points = points;
-
-    _colorSequence = colorSequence;
-    if (_colorSequence == null) {
-      _colorSequence = new ColorSequence.fromStartAndEndColor(
-        new Color(0xffffffff),
-        new Color(0xffffffff)
-      );
-    }
-
-    _offset = scrollStart;
-
-    _painter = new TexturedLinePainter(points, _colors, _widths, texture);
-    _painter.textureLoopLength = textureLoopLength;
-  }
-
-  final Texture texture;
-
-  final ui.TransferMode transferMode;
-
-  final EffectLineWidthMode widthMode;
-  final double minWidth;
-  final double maxWidth;
-  final double widthGrowthSpeed;
-
-  final EffectLineAnimationMode animationMode;
-  final double scrollSpeed;
-  ColorSequence _colorSequence;
-  ColorSequence get colorSequence => _colorSequence;
-
-  List<Point> _points;
-
-  List<Point> get points => _points;
-
-  set points(List<Point> points) {
-    _points = points;
-    _pointAges = <double>[];
-    for (int i = 0; i < _points.length; i++) {
-      _pointAges.add(0.0);
-    }
-  }
-
-  List<double> _pointAges;
-  List<Color> _colors;
-  List<double> _widths;
-
-  final double fadeDuration;
-  final double fadeAfterDelay;
-
-  final double textureLoopLength;
-
-  final bool simplify;
-
-  TexturedLinePainter _painter;
-  double _offset = 0.0;
-
-  void update(double dt) {
-    // Update scrolling position
-    if (animationMode == EffectLineAnimationMode.scroll) {
-      _offset += dt * scrollSpeed;
-      _offset %= 1.0;
-    } else if (animationMode == EffectLineAnimationMode.random) {
-      _offset = randomDouble();
-    }
-
-    // Update age of line points and remove if neccesasry
-    if (fadeDuration != null && fadeAfterDelay != null) {
-      // Increase age of points
-      for (int i = _points.length - 1; i >= 0; i--) {
-        _pointAges[i] += dt;
-      }
-
-      // Check if the first/oldest point should be removed
-      while(_points.length > 0 && _pointAges[0] > (fadeDuration + fadeAfterDelay)) {
-        // Update scroll if it isn't the last and only point that is about to removed
-        if (_points.length > 1 && textureLoopLength != null) {
-          double dist = GameMath.distanceBetweenPoints(_points[0], _points[1]);
-          _offset = (_offset - (dist / textureLoopLength)) % 1.0;
-          if (_offset < 0.0) _offset += 1;
-        }
-
-        // Remove the point
-        _pointAges.removeAt(0);
-        _points.removeAt(0);
-      }
-    }
-  }
-
-  void paint(PaintingCanvas canvas) {
-    if (points.length < 2) return;
-
-    _painter.points = points;
-
-    // Calculate colors
-    List<double> stops = _painter.calculatedTextureStops;
-
-    List<Color> colors = <Color>[];
-    for (int i = 0; i < stops.length; i++) {
-      double stop = stops[i];
-      Color color = _colorSequence.colorAtPosition(stop);
-
-      if (fadeDuration != null && fadeAfterDelay != null) {
-        double age = _pointAges[i];
-        if (age > fadeAfterDelay) {
-          double fade = 1.0 - (age - fadeAfterDelay) / fadeDuration;
-          int alpha = (color.alpha * fade).toInt().clamp(0, 255);
-          color = new Color.fromARGB(alpha, color.red, color.green, color.blue);
-        }
-      }
-      colors.add(color);
-    }
-    _painter.colors = colors;
-
-    // Calculate widths
-    List<double> widths = <double>[];
-    for (int i = 0; i < stops.length; i++) {
-      double stop = stops[i];
-      double growth = math.max(widthGrowthSpeed * _pointAges[i], 0.0);
-      if (widthMode == EffectLineWidthMode.linear) {
-        double width = minWidth + (maxWidth - minWidth) * stop + growth;
-        widths.add(width);
-      } else if (widthMode == EffectLineWidthMode.barrel) {
-        double width = minWidth + math.sin(stop * math.PI) * (maxWidth - minWidth) + growth;
-        widths.add(width);
-      }
-    }
-    _painter.widths = widths;
-
-    _painter.textureStopOffset = _offset;
-
-    _painter.paint(canvas);
-  }
-
-  void addPoint(Point point) {
-    // Skip duplicate points
-    if (points.length > 0 && point.x == points[points.length - 1].x && point.y == points[points.length - 1].y)
-      return;
-
-    if (simplify && points.length >= 2 && GameMath.distanceBetweenPoints(point, points[points.length - 2]) < 10.0) {
-      // Check if we should remove last point before adding the new one
-
-      // Calculate the square distance from the middle point to the line of the
-      // new point and the second to last point
-      double dist2 = _distToSeqment2(
-        points[points.length - 1],
-        point,
-        points[points.length - 2]
-      );
-
-      // If the point is on the line, remove it
-      if (dist2 < 1.0) {
-        _points.removeAt(_points.length - 1);
-      }
-    }
-
-    // Add point and point's age
-    _points.add(point);
-    _pointAges.add(0.0);
-  }
-
-  double _sqr(double x) => x * x;
-
-  double _dist2(Point v, Point w) => _sqr(v.x - w.x) + _sqr(v.y - w.y);
-
-  double _distToSeqment2(Point p, Point v, Point w) {
-    double l2 = _dist2(v, w);
-    if (l2 == 0.0) return _dist2(p, v);
-    double t = ((p.x - v.x) * (w.x - v.x) + (p.y - v.y) * (w.y - v.y)) / l2;
-    if (t < 0) return _dist2(p, v);
-    if (t > 1) return _dist2(p, w);
-    return _dist2(p, new Point(v.x + t * (w.x - v.x), v.y + t * (w.y - v.y)));
-  }
-}
diff --git a/skysprites/lib/src/image_map.dart b/skysprites/lib/src/image_map.dart
deleted file mode 100644
index f72fe33..0000000
--- a/skysprites/lib/src/image_map.dart
+++ /dev/null
@@ -1,25 +0,0 @@
-// Copyright 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 flutter_sprites;
-
-class ImageMap {
-  ImageMap(AssetBundle bundle) : _bundle = bundle;
-
-  final AssetBundle _bundle;
-  final Map<String, ui.Image> _images = new Map<String, ui.Image>();
-
-  Future<List<ui.Image>> load(List<String> urls) {
-    return Future.wait(urls.map(_loadImage));
-  }
-
-  Future<ui.Image> _loadImage(String url) async {
-    ui.Image image = await _bundle.loadImage(url).first;
-    _images[url] = image;
-    return image;
-  }
-
-  ui.Image getImage(String url) => _images[url];
-  ui.Image operator [](String url) => _images[url];
-}
diff --git a/skysprites/lib/src/label.dart b/skysprites/lib/src/label.dart
deleted file mode 100644
index 510b8ee..0000000
--- a/skysprites/lib/src/label.dart
+++ /dev/null
@@ -1,62 +0,0 @@
-part of flutter_sprites;
-
-/// Labels are used to display a string of text in a the node tree. To align
-/// the label, the textAlign property of the [TextStyle] can be set.
-class Label extends Node {
-  /// Creates a new Label with the provided [_text] and [_textStyle].
-  Label(this._text, [this._textStyle]) {
-    if (_textStyle == null) {
-      _textStyle = new TextStyle();
-    }
-  }
-
-  String _text;
-
-  /// The text being drawn by the label.
-  String get text => _text;
-
-  set text(String text) {
-    _text = text;
-    _painter = null;
-  }
-
-  TextStyle _textStyle;
-
-  /// The style to draw the text in.
-  TextStyle get textStyle => _textStyle;
-
-  set textStyle(TextStyle textStyle) {
-    _textStyle = textStyle;
-    _painter = null;
-  }
-
-  TextPainter _painter;
-  double _width;
-
-  void paint(PaintingCanvas canvas) {
-    if (_painter == null) {
-      PlainTextSpan textSpan = new PlainTextSpan(_text);
-      StyledTextSpan styledTextSpan = new StyledTextSpan(_textStyle, <TextSpan>[textSpan]);
-      _painter = new TextPainter(styledTextSpan);
-
-      _painter.maxWidth = double.INFINITY;
-      _painter.minWidth = 0.0;
-      _painter.layout();
-
-      _width = _painter.maxIntrinsicWidth.ceil().toDouble();
-
-      _painter.maxWidth = _width;
-      _painter.minWidth = _width;
-      _painter.layout();
-    }
-
-    Offset offset = Offset.zero;
-    if (_textStyle.textAlign == TextAlign.center) {
-      offset = new Offset(-_width / 2.0, 0.0);
-    } else if (_textStyle.textAlign == TextAlign.right) {
-      offset = new Offset(-_width, 0.0);
-    }
-
-    _painter.paint(canvas, offset);
-  }
-}
diff --git a/skysprites/lib/src/layer.dart b/skysprites/lib/src/layer.dart
deleted file mode 100644
index dfd4585..0000000
--- a/skysprites/lib/src/layer.dart
+++ /dev/null
@@ -1,39 +0,0 @@
-part of flutter_sprites;
-
-/// A [Node] that provides an intermediate rendering surface in the sprite
-/// rendering tree. A [Layer] can be used to change the opacity, color, or to
-/// apply an effect to a set of nodes. All nodes that are children to the
-/// [Layer] will be rendered into the surface. If the area that is needed for
-/// the children to be drawn is know, the [layerRect] property should be set as
-/// this can enhance performance.
-class Layer extends Node with SpritePaint {
-
-  /// The area that the children of the [Layer] will occupy. This value is
-  /// treated as a hint to the rendering system and may in some cases be
-  /// ignored. If the area isn't known, the layerRect can be set to [null].
-  ///
-  ///     myLayer.layerRect = new Rect.fromLTRB(0.0, 0.0, 200.0, 100.0);
-  Rect layerRect;
-
-  /// Creates a new layer. The layerRect can optionally be passed as an argument
-  /// if it is known.
-  ///
-  ///     var myLayer = new Layer();
-  Layer([this.layerRect = null]);
-
-  Paint _cachedPaint = new Paint()
-    ..filterQuality = ui.FilterQuality.low
-    ..isAntiAlias = false;
-
-  void _prePaint(PaintingCanvas canvas, Matrix4 matrix) {
-    super._prePaint(canvas, matrix);
-
-    _updatePaint(_cachedPaint);
-    canvas.saveLayer(layerRect, _cachedPaint);
-  }
-
-  void _postPaint(PaintingCanvas canvas, Matrix4 totalMatrix) {
-    canvas.restore();
-    super._postPaint(canvas, totalMatrix);
-  }
-}
diff --git a/skysprites/lib/src/node.dart b/skysprites/lib/src/node.dart
deleted file mode 100644
index ecce1d2..0000000
--- a/skysprites/lib/src/node.dart
+++ /dev/null
@@ -1,811 +0,0 @@
-part of flutter_sprites;
-
-double convertDegrees2Radians(double degrees) => degrees * math.PI/180.8;
-
-double convertRadians2Degrees(double radians) => radians * 180.0/math.PI;
-
-/// A base class for all objects that can be added to the sprite node tree and rendered to screen using [SpriteBox] and
-/// [SpriteWidget].
-///
-/// The [Node] class itself doesn't render any content, but provides the basic functions of any type of node, such as
-/// handling transformations and user input. To render the node tree, a root node must be added to a [SpriteBox] or a
-/// [SpriteWidget]. Commonly used sub-classes of [Node] are [Sprite], [NodeWithSize], and many more upcoming subclasses.
-///
-/// Nodes form a hierarchical tree. Each node can have a number of children, and the transformation (positioning,
-/// rotation, and scaling) of a node also affects its children.
-class Node {
-
-  // Member variables
-
-  SpriteBox _spriteBox;
-  Node _parent;
-
-  Point _position = Point.origin;
-  double _rotation = 0.0;
-
-  Matrix4 _transformMatrix = new Matrix4.identity();
-  Matrix4 _transformMatrixInverse;
-  Matrix4 _transformMatrixNodeToBox;
-  Matrix4 _transformMatrixBoxToNode;
-
-  double _scaleX = 1.0;
-  double _scaleY = 1.0;
-
-  double _skewX = 0.0;
-  double _skewY = 0.0;
-
-  /// The visibility of this node and its children.
-  bool visible = true;
-
-  double _zPosition = 0.0;
-  int _addedOrder;
-  int _childrenLastAddedOrder = 0;
-  bool _childrenNeedSorting = false;
-  Matrix4 _savedTotalMatrix;
-
-  /// Decides if the node and its children is currently paused.
-  ///
-  /// A paused node will not receive any input events, update calls, or run any animations.
-  ///
-  ///     myNodeTree.paused = true;
-  bool paused = false;
-
-  bool _userInteractionEnabled = false;
-
-  /// If set to true the node will receive multiple pointers, otherwise it will only receive events the first pointer.
-  ///
-  /// This property is only meaningful if [userInteractionEnabled] is set to true. Default value is false.
-  ///
-  ///     class MyCustomNode extends Node {
-  ///       handleMultiplePointers = true;
-  ///     }
-  bool handleMultiplePointers = false;
-  int _handlingPointer;
-
-  List<Node> _children = <Node>[];
-
-  ActionController _actions;
-
-  /// The [ActionController] associated with this node.
-  ///
-  ///     myNode.actions.run(myAction);
-  ActionController get actions {
-    if (_actions == null) {
-      _actions = new ActionController();
-      if (_spriteBox != null) _spriteBox._actionControllers = null;
-    }
-    return _actions;
-  }
-
-  List<Constraint> _constraints;
-
-  /// A [List] of [Constraint]s that will be applied to the node.
-  /// The constraints are applied after the [update] method has been called.
-  List<Constraint> get constraints {
-    return _constraints;
-  }
-
-  set constraints(List<Constraint> constraints) {
-    _constraints = constraints;
-    if (_spriteBox != null) _spriteBox._constrainedNodes = null;
-  }
-
-  /// Called to apply the [constraints] to the node. Normally, this method is
-  /// called automatically by the [SpriteBox], but it can be called manually
-  /// if the constraints need to be applied immediately.
-  void applyConstraints(double dt) {
-    if (_constraints == null) return;
-
-    for (Constraint constraint in _constraints) {
-      constraint.constrain(this, dt);
-    }
-  }
-
-  // Constructors
-
-  /// Creates a new [Node] without any transformation.
-  ///
-  ///     Node myNode = new Node();
-  Node();
-
-  // Property setters and getters
-
-  /// The [SpriteBox] this node is added to, or null if it's not currently added to a [SpriteBox].
-  ///
-  /// For most applications it's not necessary to access the [SpriteBox] directly.
-  ///
-  ///     // Get the transformMode of the sprite box
-  ///     SpriteBoxTransformMode transformMode = myNode.spriteBox.transformMode;
-  SpriteBox get spriteBox => _spriteBox;
-
-  /// The parent of this node, or null if it doesn't have a parent.
-  ///
-  ///     // Hide the parent
-  ///     myNode.parent.visible = false;
-  Node get parent => _parent;
-
-  /// The rotation of this node in degrees.
-  ///
-  ///     myNode.rotation = 45.0;
-  double get rotation => _rotation;
-
-  void set rotation(double rotation) {
-    assert(rotation != null);
-
-    if (_physicsBody != null && (parent is PhysicsWorld || parent is PhysicsGroup)) {
-      _updatePhysicsRotation(physicsBody, rotation, parent);
-      return;
-    }
-
-    _rotation = rotation;
-    invalidateTransformMatrix();
-  }
-
-  void _updatePhysicsRotation(PhysicsBody body, double rotation, Node physicsParent) {
-    PhysicsWorld world = _physicsWorld(physicsParent);
-    if (world == null) return;
-    world._updateRotation(body, _rotationToPhysics(rotation, physicsParent));
-  }
-
-  PhysicsWorld _physicsWorld(Node parent) {
-    if (parent is PhysicsWorld) {
-      return parent;
-    }
-    else if (parent is PhysicsGroup) {
-      return _physicsWorld(parent.parent);
-    }
-    else {
-      assert(false);
-      return null;
-    }
-  }
-
-  double _rotationToPhysics(double rotation, Node physicsParent) {
-    if (physicsParent is PhysicsWorld) {
-      return rotation;
-    } else if (physicsParent is PhysicsGroup) {
-      return _rotationToPhysics(rotation + physicsParent.rotation, physicsParent.parent);
-    } else {
-      assert(false);
-      return null;
-    }
-  }
-
-  double _rotationFromPhysics(double rotation, Node physicsParent) {
-    if (physicsParent is PhysicsWorld) {
-      return rotation;
-    } else if (physicsParent is PhysicsGroup) {
-      return _rotationToPhysics(rotation - physicsParent.rotation, physicsParent.parent);
-    } else {
-      assert(false);
-      return null;
-    }
-  }
-
-  void _setRotationFromPhysics(double rotation, Node physicsParent) {
-    assert(rotation != null);
-    _rotation = _rotationFromPhysics(rotation, physicsParent);
-    invalidateTransformMatrix();
-  }
-
-  void teleportRotation(double rotation) {
-    assert(rotation != null);
-    if (_physicsBody != null && (parent is PhysicsWorld || parent is PhysicsGroup)) {
-      rotation = _rotationToPhysics(rotation, parent);
-      _physicsBody._body.setTransform(_physicsBody._body.position, radians(rotation));
-      _physicsBody._body.angularVelocity = 0.0;
-      _physicsBody._body.setType(box2d.BodyType.STATIC);
-    }
-    _setRotationFromPhysics(rotation, parent);
-  }
-
-  /// The position of this node relative to its parent.
-  ///
-  ///     myNode.position = new Point(42.0, 42.0);
-  Point get position => _position;
-
-  void set position(Point position) {
-    assert(position != null);
-
-    if (_physicsBody != null && (parent is PhysicsWorld || parent is PhysicsGroup)) {
-      _updatePhysicsPosition(this.physicsBody, position, parent);
-      return;
-    }
-
-    _position = position;
-    invalidateTransformMatrix();
-  }
-
-  void _updatePhysicsPosition(PhysicsBody body, Point position, Node physicsParent) {
-    PhysicsWorld world = _physicsWorld(physicsParent);
-    if (world == null) return;
-    world._updatePosition(body, _positionToPhysics(position, physicsParent));
-  }
-
-  Point _positionToPhysics(Point position, Node physicsParent) {
-    if (physicsParent is PhysicsWorld) {
-      return position;
-    } else if (physicsParent is PhysicsGroup) {
-      // Transform the position
-      Vector4 parentPos = physicsParent.transformMatrix.transform(new Vector4(position.x, position.y, 0.0, 1.0));
-      Point newPos = new Point(parentPos.x, parentPos.y);
-      return _positionToPhysics(newPos, physicsParent.parent);
-    } else {
-      assert(false);
-      return null;
-    }
-  }
-
-  void _setPositionFromPhysics(Point position, Node physicsParent) {
-    assert(position != null);
-    _position = _positionFromPhysics(position, physicsParent);
-    invalidateTransformMatrix();
-  }
-
-  Point _positionFromPhysics(Point position, Node physicsParent) {
-    if (physicsParent is PhysicsWorld) {
-      return position;
-    } else if (physicsParent is PhysicsGroup) {
-      // Transform the position
-      Vector4 parentPos = physicsParent._inverseMatrix().transform(new Vector4(position.x, position.y, 0.0, 1.0));
-      Point newPos = new Point(parentPos.x, parentPos.y);
-      return _positionToPhysics(newPos, physicsParent.parent);
-    } else {
-      assert(false);
-      return null;
-    }
-  }
-
-  void teleportPosition(Point position) {
-    assert(position != null);
-    PhysicsWorld world = _physicsWorld(parent);
-
-    if (_physicsBody != null && (parent is PhysicsWorld || parent is PhysicsGroup)) {
-      position = _positionToPhysics(position, parent);
-      _physicsBody._body.setTransform(
-        new Vector2(
-          position.x / world.b2WorldToNodeConversionFactor,
-          position.y / world.b2WorldToNodeConversionFactor
-        ),
-        _physicsBody._body.getAngle()
-      );
-      _physicsBody._body.linearVelocity = new Vector2.zero();
-      _physicsBody._body.setType(box2d.BodyType.STATIC);
-    }
-    _setPositionFromPhysics(position, parent);
-  }
-
-  /// The skew along the x-axis of this node in degrees.
-  ///
-  ///     myNode.skewX = 45.0;
-  double get skewX => _skewX;
-
-  void set skewX (double skewX) {
-    assert(skewX != null);
-    _skewX = skewX;
-    invalidateTransformMatrix();
-  }
-
-  /// The skew along the y-axis of this node in degrees.
-  ///
-  ///     myNode.skewY = 45.0;
-  double get skewY => _skewY;
-
-  void set skewY (double skewY) {
-    assert(skewY != null);
-    _skewY = skewY;
-    invalidateTransformMatrix();
-  }
-
-  /// The draw order of this node compared to its parent and its siblings.
-  ///
-  /// By default nodes are drawn in the order that they have been added to a parent. To override this behavior the
-  /// [zPosition] property can be used. A higher value of this property will force the node to be drawn in front of
-  /// siblings that have a lower value. If a negative value is used the node will be drawn behind its parent.
-  ///
-  ///     nodeInFront.zPosition = 1.0;
-  ///     nodeBehind.zPosition = -1.0;
-  double get zPosition => _zPosition;
-
-  void set zPosition(double zPosition) {
-    assert(zPosition != null);
-    _zPosition = zPosition;
-    if (_parent != null) {
-      _parent._childrenNeedSorting = true;
-    }
-  }
-
-  /// The scale of this node relative its parent.
-  ///
-  /// The [scale] property is only valid if [scaleX] and [scaleY] are equal values.
-  ///
-  ///     myNode.scale = 5.0;
-  double get scale {
-    assert(_scaleX == _scaleY);
-    return _scaleX;
-  }
-
-  void set scale(double scale) {
-    assert(scale != null);
-
-    if (_physicsBody != null && (parent is PhysicsWorld || parent is PhysicsGroup)) {
-      _updatePhysicsScale(physicsBody, scale, parent);
-    }
-
-    _scaleX = _scaleY = scale;
-    invalidateTransformMatrix();
-  }
-
-  void _updatePhysicsScale(PhysicsBody body, double scale, Node physicsParent) {
-    if (physicsParent == null) return;
-    _physicsWorld(physicsParent)._updateScale(body, _scaleToPhysics(scale, physicsParent));
-  }
-
-  double _scaleToPhysics(double scale, Node physicsParent) {
-    if (physicsParent is PhysicsWorld) {
-      return scale;
-    } else if (physicsParent is PhysicsGroup) {
-      return _scaleToPhysics(scale * physicsParent.scale, physicsParent.parent);
-    } else {
-      assert(false);
-      return null;
-    }
-  }
-
-  /// The horizontal scale of this node relative its parent.
-  ///
-  ///     myNode.scaleX = 5.0;
-  double get scaleX => _scaleX;
-
-  void set scaleX(double scaleX) {
-    assert(scaleX != null);
-    assert(physicsBody == null);
-
-    _scaleX = scaleX;
-    invalidateTransformMatrix();
-  }
-
-  /// The vertical scale of this node relative its parent.
-  ///
-  ///     myNode.scaleY = 5.0;
-  double get scaleY => _scaleY;
-
-  void set scaleY(double scaleY) {
-    assert(scaleY != null);
-    assert(physicsBody == null);
-
-    _scaleY = scaleY;
-    invalidateTransformMatrix();
-  }
-
-  /// A list of the children of this node.
-  ///
-  /// This list should only be modified by using the [addChild] and [removeChild] methods.
-  ///
-  ///     // Iterate over a nodes children
-  ///     for (Node child in myNode.children) {
-  ///       // Do something with the child
-  ///     }
-  List<Node> get children {
-    _sortChildren();
-    return _children;
-  }
-
-  // Adding and removing children
-
-  /// Adds a child to this node.
-  ///
-  /// The same node cannot be added to multiple nodes.
-  ///
-  ///     addChild(new Sprite(myImage));
-  void addChild(Node child) {
-    assert(child != null);
-    assert(child._parent == null);
-    assert(!(child is PhysicsGroup) || this is PhysicsGroup || this is PhysicsWorld);
-
-    _childrenNeedSorting = true;
-    _children.add(child);
-    child._parent = this;
-    child._spriteBox = this._spriteBox;
-    _childrenLastAddedOrder += 1;
-    child._addedOrder = _childrenLastAddedOrder;
-    if (_spriteBox != null) _spriteBox._registerNode(child);
-
-    if (child is PhysicsGroup) {
-      child._attachGroup(child, child._world);
-    }
-  }
-
-  /// Removes a child from this node.
-  ///
-  ///     removeChild(myChildNode);
-  void removeChild(Node child) {
-    assert(child != null);
-    if (_children.remove(child)) {
-      child._parent = null;
-      child._spriteBox = null;
-      if (_spriteBox != null) _spriteBox._deregisterNode(child);
-    }
-
-    if (child is PhysicsGroup) {
-      child._detachGroup(child);
-    }
-  }
-
-  /// Removes this node from its parent node.
-  ///
-  ///     removeFromParent();
-  void removeFromParent() {
-    assert(_parent != null);
-    _parent.removeChild(this);
-  }
-
-  /// Removes all children of this node.
-  ///
-  ///     removeAllChildren();
-  void removeAllChildren() {
-    for (Node child in _children) {
-      child._parent = null;
-      child._spriteBox = null;
-    }
-    _children = <Node>[];
-    _childrenNeedSorting = false;
-    if (_spriteBox != null) _spriteBox._deregisterNode(null);
-  }
-
-  void _sortChildren() {
-    // Sort children primarily by zPosition, secondarily by added order
-    if (_childrenNeedSorting) {
-      _children.sort((Node a, Node b) {
-        if (a._zPosition == b._zPosition) {
-          return a._addedOrder - b._addedOrder;
-        }
-        else if (a._zPosition > b._zPosition) {
-          return 1;
-        }
-        else {
-          return -1;
-        }
-      });
-      _childrenNeedSorting = false;
-    }
-  }
-
-  // Calculating the transformation matrix
-
-  /// The transformMatrix describes the transformation from the node's parent.
-  ///
-  /// You cannot set the transformMatrix directly, instead use the position, rotation and scale properties.
-  ///
-  ///     Matrix4 matrix = myNode.transformMatrix;
-  Matrix4 get transformMatrix {
-    if (_transformMatrix == null) {
-      _transformMatrix = computeTransformMatrix();
-    }
-    return _transformMatrix;
-  }
-
-  /// Computes the transformation matrix of this node. This method can be
-  /// overriden if a custom matrix is required. There is usually no reason to
-  /// call this method directly.
-  Matrix4 computeTransformMatrix() {
-    double cx, sx, cy, sy;
-
-    if (_rotation == 0.0) {
-      cx = 1.0;
-      sx = 0.0;
-      cy = 1.0;
-      sy = 0.0;
-    }
-    else {
-      double radiansX = convertDegrees2Radians(_rotation);
-      double radiansY = convertDegrees2Radians(_rotation);
-
-      cx = math.cos(radiansX);
-      sx = math.sin(radiansX);
-      cy = math.cos(radiansY);
-      sy = math.sin(radiansY);
-    }
-
-    // Create transformation matrix for scale, position and rotation
-    Matrix4 matrix = new Matrix4(cy * _scaleX, sy * _scaleX, 0.0, 0.0,
-               -sx * _scaleY, cx * _scaleY, 0.0, 0.0,
-               0.0, 0.0, 1.0, 0.0,
-              _position.x, _position.y, 0.0, 1.0);
-
-    if (_skewX != 0.0 || _skewY != 0.0) {
-      // Needs skew transform
-      Matrix4 skew = new Matrix4(1.0, math.tan(radians(_skewX)), 0.0, 0.0,
-                                 math.tan(radians(_skewY)), 1.0, 0.0, 0.0,
-                                 0.0, 0.0, 1.0, 0.0,
-                                 0.0, 0.0, 0.0, 1.0);
-      matrix.multiply(skew);
-    }
-
-    return matrix;
-  }
-
-  /// Invalidates the current transform matrix. If the [computeTransformMatrix]
-  /// method is overidden, this method should be called whenever a property
-  /// changes that affects the matrix.
-  void invalidateTransformMatrix() {
-    _transformMatrix = null;
-    _transformMatrixInverse = null;
-    _invalidateToBoxTransformMatrix();
-  }
-
-  void _invalidateToBoxTransformMatrix () {
-    _transformMatrixNodeToBox = null;
-    _transformMatrixBoxToNode = null;
-
-    for (Node child in children) {
-      child._invalidateToBoxTransformMatrix();
-    }
-  }
-
-  // Transforms to other nodes
-
-  Matrix4 _nodeToBoxMatrix() {
-    assert(_spriteBox != null);
-    if (_transformMatrixNodeToBox != null) {
-      return _transformMatrixNodeToBox;
-    }
-
-    if (_parent == null) {
-      // Base case, we are at the top
-      assert(this == _spriteBox.rootNode);
-      _transformMatrixNodeToBox = new Matrix4.copy(_spriteBox.transformMatrix).multiply(transformMatrix);
-    }
-    else {
-      _transformMatrixNodeToBox = new Matrix4.copy(_parent._nodeToBoxMatrix()).multiply(transformMatrix);
-    }
-    return _transformMatrixNodeToBox;
-  }
-
-  Matrix4 _boxToNodeMatrix() {
-    assert(_spriteBox != null);
-
-    if (_transformMatrixBoxToNode != null) {
-      return _transformMatrixBoxToNode;
-    }
-
-    _transformMatrixBoxToNode = new Matrix4.copy(_nodeToBoxMatrix());
-    _transformMatrixBoxToNode.invert();
-
-    return _transformMatrixBoxToNode;
-  }
-
-  Matrix4 _inverseMatrix() {
-    if (_transformMatrixInverse == null) {
-      _transformMatrixInverse = new Matrix4.copy(transformMatrix);
-      _transformMatrixInverse.invert();
-    }
-    return _transformMatrixInverse;
-  }
-
-  /// Converts a point from the coordinate system of the [SpriteBox] to the local coordinate system of the node.
-  ///
-  /// This method is particularly useful when handling pointer events and need the pointers position in a local
-  /// coordinate space.
-  ///
-  ///     Point localPoint = myNode.convertPointToNodeSpace(pointInBoxCoordinates);
-  Point convertPointToNodeSpace(Point boxPoint) {
-    assert(boxPoint != null);
-    assert(_spriteBox != null);
-
-    Vector4 v =_boxToNodeMatrix().transform(new Vector4(boxPoint.x, boxPoint.y, 0.0, 1.0));
-    return new Point(v[0], v[1]);
-  }
-
-  /// Converts a point from the local coordinate system of the node to the coordinate system of the [SpriteBox].
-  ///
-  ///     Point pointInBoxCoordinates = myNode.convertPointToBoxSpace(localPoint);
-  Point convertPointToBoxSpace(Point nodePoint) {
-    assert(nodePoint != null);
-    assert(_spriteBox != null);
-
-    Vector4 v =_nodeToBoxMatrix().transform(new Vector4(nodePoint.x, nodePoint.y, 0.0, 1.0));
-    return new Point(v[0], v[1]);
-  }
-
-  /// Converts a [point] from another [node]s coordinate system into the local coordinate system of this node.
-  ///
-  ///     Point pointInNodeASpace = nodeA.convertPointFromNode(pointInNodeBSpace, nodeB);
-  Point convertPointFromNode(Point point, Node node) {
-    assert(node != null);
-    assert(point != null);
-    assert(_spriteBox != null);
-    assert(_spriteBox == node._spriteBox);
-
-    Point boxPoint = node.convertPointToBoxSpace(point);
-    Point localPoint = convertPointToNodeSpace(boxPoint);
-
-    return localPoint;
-  }
-
-  // Hit test
-
-  /// Returns true if the [point] is inside the node, the [point] is in the local coordinate system of the node.
-  ///
-  ///     myNode.isPointInside(localPoint);
-  ///
-  /// [NodeWithSize] provides a basic bounding box check for this method, if you require a more detailed check this
-  /// method can be overridden.
-  ///
-  ///     bool isPointInside (Point nodePoint) {
-  ///       double minX = -size.width * pivot.x;
-  ///       double minY = -size.height * pivot.y;
-  ///       double maxX = minX + size.width;
-  ///       double maxY = minY + size.height;
-  ///       return (nodePoint.x >= minX && nodePoint.x < maxX &&
-  ///       nodePoint.y >= minY && nodePoint.y < maxY);
-  ///     }
-  bool isPointInside(Point point) {
-    assert(point != null);
-
-    return false;
-  }
-
-  // Rendering
-
-  void _visit(PaintingCanvas canvas, Matrix4 totalMatrix) {
-    assert(canvas != null);
-    if (!visible) return;
-
-    _prePaint(canvas, totalMatrix);
-    _visitChildren(canvas, totalMatrix);
-    _postPaint(canvas, totalMatrix);
-  }
-
-  void _prePaint(PaintingCanvas canvas, Matrix4 matrix) {
-    _savedTotalMatrix = new Matrix4.copy(matrix);
-
-    // Get the transformation matrix and apply transform
-    matrix.multiply(transformMatrix);
-  }
-
-  /// Paints this node to the canvas.
-  ///
-  /// Subclasses, such as [Sprite], override this method to do the actual painting of the node. To do custom
-  /// drawing override this method and make calls to the [canvas] object. All drawing is done in the node's local
-  /// coordinate system, relative to the node's position. If you want to make the drawing relative to the node's
-  /// bounding box's origin, override [NodeWithSize] and call the applyTransformForPivot method before making calls for
-  /// drawing.
-  ///
-  ///     void paint(PaintingCanvas canvas) {
-  ///       canvas.save();
-  ///       applyTransformForPivot(canvas);
-  ///
-  ///       // Do painting here
-  ///
-  ///       canvas.restore();
-  ///     }
-  void paint(PaintingCanvas canvas) {
-  }
-
-  void _visitChildren(PaintingCanvas canvas, Matrix4 totalMatrix) {
-    // Sort children if needed
-    _sortChildren();
-
-    int i = 0;
-
-    // Visit children behind this node
-    while (i < _children.length) {
-      Node child = _children[i];
-      if (child.zPosition >= 0.0) break;
-      child._visit(canvas, totalMatrix);
-      i++;
-    }
-
-    // Paint this node
-    canvas.setMatrix(totalMatrix.storage);
-    paint(canvas);
-
-    // Visit children in front of this node
-    while (i < _children.length) {
-      Node child = _children[i];
-      child._visit(canvas, totalMatrix);
-      i++;
-    }
-  }
-
-  void _postPaint(PaintingCanvas canvas, Matrix4 totalMatrix) {
-    totalMatrix.setFrom(_savedTotalMatrix);
-  }
-
-  // Receiving update calls
-
-  /// Called before a frame is drawn.
-  ///
-  /// Override this method to do any updates to the node or node tree before it's drawn to screen.
-  ///
-  ///     // Make the node rotate at a fixed speed
-  ///     void update(double dt) {
-  ///       rotation = rotation * 10.0 * dt;
-  ///     }
-  void update(double dt) {
-  }
-
-  /// Called whenever the [SpriteBox] is modified or resized, or if the device is rotated.
-  ///
-  /// Override this method to do any updates that may be necessary to correctly display the node or node tree with the
-  /// new layout of the [SpriteBox].
-  ///
-  ///     void spriteBoxPerformedLayout() {
-  ///       // Move some stuff around here
-  ///     }
-  void spriteBoxPerformedLayout() {
-  }
-
-  // Handling user interaction
-
-  /// The node will receive user interactions, such as pointer (touch or mouse) events.
-  ///
-  ///     class MyCustomNode extends NodeWithSize {
-  ///       userInteractionEnabled = true;
-  ///     }
-  bool get userInteractionEnabled => _userInteractionEnabled;
-
-  void set userInteractionEnabled(bool userInteractionEnabled) {
-    _userInteractionEnabled = userInteractionEnabled;
-    if (_spriteBox != null) _spriteBox._eventTargets = null;
-  }
-
-  /// Handles an event, such as a pointer (touch or mouse) event.
-  ///
-  /// Override this method to handle events. The node will only receive events if the [userInteractionEnabled] property
-  /// is set to true and the [isPointInside] method returns true for the position of the pointer down event (default
-  /// behavior provided by [NodeWithSize]). Unless [handleMultiplePointers] is set to true, the node will only receive
-  /// events for the first pointer that is down.
-  ///
-  /// Return true if the node has consumed the event, if an event is consumed it will not be passed on to nodes behind
-  /// the current node.
-  ///
-  ///     // MyTouchySprite gets transparent when we touch it
-  ///     class MyTouchySprite extends Sprite {
-  ///
-  ///       MyTouchySprite(Image img) : super (img) {
-  ///         userInteractionEnabled = true;
-  ///       }
-  ///
-  ///       bool handleEvent(SpriteBoxEvent event) {
-  ///         if (event.type == 'pointerdown) {
-  ///           opacity = 0.5;
-  ///         }
-  ///         else if (event.type == 'pointerup') {
-  ///           opacity = 1.0;
-  ///         }
-  ///         return true;
-  ///       }
-  ///     }
-  bool handleEvent(SpriteBoxEvent event) {
-    return false;
-  }
-
-  // Physics
-
-  PhysicsBody _physicsBody;
-
-  /// The physics body associated with this node. If a physics body is assigned,
-  /// and the node is a child of a [PhysicsWorld] or a [PhysicsGroup] the
-  /// node's position and rotation will be controlled by the body.
-  ///
-  ///     myNode.physicsBody = new PhysicsBody(
-  ///       new PhysicsShapeCircle(Point.zero, 20.0)
-  ///     );
-  PhysicsBody get physicsBody => _physicsBody;
-
-  set physicsBody(PhysicsBody physicsBody) {
-    if (parent != null) {
-      assert(parent is PhysicsWorld);
-
-      if (physicsBody == null) {
-        physicsBody._detach();
-      } else {
-        physicsBody._attach(parent, this);
-      }
-    }
-
-    _physicsBody = physicsBody;
-  }
-}
diff --git a/skysprites/lib/src/node3d.dart b/skysprites/lib/src/node3d.dart
deleted file mode 100644
index 40fb629..0000000
--- a/skysprites/lib/src/node3d.dart
+++ /dev/null
@@ -1,58 +0,0 @@
-part of flutter_sprites;
-
-/// An node that transforms its children using a 3D perspective projection. This
-/// node type can be used to create 3D flips and other similar effects.
-///
-///     var myNode3D = new Node3D();
-///     myNode3D.rotationY = 45.0;
-///     myNode3D.addChild(new Sprite(myTexture));
-class Node3D extends Node {
-
-  double _rotationX = 0.0;
-
-  /// The node's rotation around the x axis in degrees.
-  double get rotationX => _rotationX;
-
-  set rotationX(double rotationX) {
-    _rotationX = rotationX;
-    invalidateTransformMatrix();
-  }
-
-  double _rotationY = 0.0;
-
-  /// The node's rotation around the y axis in degrees.
-  double get rotationY => _rotationY;
-
-  set rotationY(double rotationY) {
-    _rotationY = rotationY;
-    invalidateTransformMatrix();
-  }
-
-  double _projectionDepth = 500.0;
-
-  /// The projection depth. Default value is 500.0.
-  double get projectionDepth => _projectionDepth;
-
-  set projectionDepth(double projectionDepth) {
-    _projectionDepth = projectionDepth;
-    invalidateTransformMatrix();
-  }
-
-  Matrix4 computeTransformMatrix() {
-    // Apply normal 2d transforms
-    Matrix4 matrix = super.computeTransformMatrix();
-
-    // Apply perspective projection
-    Matrix4 projection = new Matrix4(1.0, 0.0, 0.0, 0.0,
-                                     0.0, 1.0, 0.0, 0.0,
-                                     0.0, 0.0, 1.0, -1.0/_projectionDepth,
-                                     0.0, 0.0, 0.0, 1.0);
-    matrix = matrix.multiply(projection);
-
-    // Rotate around x and y axis
-    matrix.rotateY(radians(_rotationY));
-    matrix.rotateX(radians(_rotationX));
-
-    return matrix;
-  }
-}
diff --git a/skysprites/lib/src/node_with_size.dart b/skysprites/lib/src/node_with_size.dart
deleted file mode 100644
index 8a4a86d..0000000
--- a/skysprites/lib/src/node_with_size.dart
+++ /dev/null
@@ -1,61 +0,0 @@
-part of flutter_sprites;
-
-/// The super class of any [Node] that has a size.
-///
-/// NodeWithSize adds the ability for a node to have a size and a pivot point.
-class NodeWithSize extends Node {
-
-  /// Changing the size will affect the size of the rendering of the node.
-  ///
-  ///     myNode.size = new Size(1024.0, 1024.0);
-  Size size;
-
-  /// The normalized point which the node is transformed around.
-  ///
-  ///     // Position myNode from is middle top
-  ///     myNode.pivot = new Point(0.5, 0.0);
-  Point pivot;
-
-  /// Creates a new NodeWithSize.
-  ///
-  /// The default [size] is zero and the default [pivot] point is the origin. Subclasses may change the default values.
-  ///
-  ///     var myNodeWithSize = new NodeWithSize(new Size(1024.0, 1024.0));
-  NodeWithSize(this.size) {
-    if (size == null)
-      size = Size.zero;
-    pivot = Point.origin;
-  }
-
-  /// Call this method in your [paint] method if you want the origin of your drawing to be the top left corner of the
-  /// node's bounding box.
-  ///
-  /// If you use this method you will need to save and restore your canvas at the beginning and
-  /// end of your [paint] method.
-  ///
-  ///     void paint(PaintingCanvas canvas) {
-  ///       canvas.save();
-  ///       applyTransformForPivot(canvas);
-  ///
-  ///       // Do painting here
-  ///
-  ///       canvas.restore();
-  ///     }
-  void applyTransformForPivot(PaintingCanvas canvas) {
-    if (pivot.x != 0 || pivot.y != 0) {
-      double pivotInPointsX = size.width * pivot.x;
-      double pivotInPointsY = size.height * pivot.y;
-      canvas.translate(-pivotInPointsX, -pivotInPointsY);
-    }
-  }
-
-  bool isPointInside (Point nodePoint) {
-
-    double minX = -size.width * pivot.x;
-    double minY = -size.height * pivot.y;
-    double maxX = minX + size.width;
-    double maxY = minY + size.height;
-    return (nodePoint.x >= minX && nodePoint.x < maxX &&
-            nodePoint.y >= minY && nodePoint.y < maxY);
-  }
-}
diff --git a/skysprites/lib/src/particle_system.dart b/skysprites/lib/src/particle_system.dart
deleted file mode 100644
index 0eb740e..0000000
--- a/skysprites/lib/src/particle_system.dart
+++ /dev/null
@@ -1,446 +0,0 @@
-part of flutter_sprites;
-
-class _Particle {
-  Vector2 pos;
-  Vector2 startPos;
-
-  double colorPos = 0.0;
-  double deltaColorPos = 0.0;
-
-  double size = 0.0;
-  double deltaSize = 0.0;
-
-  double rotation = 0.0;
-  double deltaRotation = 0.0;
-
-  double timeToLive = 0.0;
-
-  Vector2 dir;
-
-  _ParticleAccelerations accelerations;
-
-  Float64List simpleColorSequence;
-
-  ColorSequence colorSequence;
-}
-
-class _ParticleAccelerations {
-  double radialAccel = 0.0;
-  double tangentialAccel = 0.0;
-}
-
-/// A particle system uses a large number of sprites to draw complex effects
-/// such as explosions, smoke, rain, or fire. There are a number of properties
-/// that can be set to control the look of the particle system. Most of the
-/// properties have a base value and a variance, these values are used when
-/// creating each individual particle. For instance, by setting the [life] to
-/// 1.0 and the [lifeVar] to 0.5, each particle will get a life time in the
-/// range of 0.5 to 1.5.
-///
-/// Particles are created and added to the system at [emissionRate], but the
-/// number of particles can never exceed the [maxParticles] limit.
-class ParticleSystem extends Node {
-
-  /// The texture used to draw each individual sprite.
-  Texture texture;
-
-  /// The time in seconds each particle will be alive.
-  double life;
-
-  /// Variance of the [life] property.
-  double lifeVar;
-
-  /// The variance of a particles initial position.
-  Point posVar;
-
-  /// The start scale of each individual particle.
-  double startSize;
-
-  /// Variance of the [startSize] property.
-  double startSizeVar;
-
-  /// The end scale of each individual particle.
-  double endSize;
-
-  /// Variance of the [endSize] property.
-  double endSizeVar;
-
-  /// The start rotation of each individual particle.
-  double startRotation;
-
-  /// Variance of the [startRotation] property.
-  double startRotationVar;
-
-  /// The end rotation of each individual particle.
-  double endRotation;
-
-  /// Variance of the [endRotation] property.
-  double endRotationVar;
-
-  /// If true, each particle will be rotated to the direction of the movement
-  /// of the particle. The calculated rotation will be added to the current
-  /// rotation as calculated by the [startRotation] and [endRotation]
-  /// properties.
-  bool rotateToMovement;
-
-  /// The direction in which each particle will be emitted in degrees.
-  double direction;
-
-  /// Variance of the [direction] property.
-  double directionVar;
-
-  /// The speed at which each particle will be emitted.
-  double speed;
-
-  /// Variance of the [direction] property.
-  double speedVar;
-
-  /// The radial acceleration of each induvidual particle.
-  double radialAcceleration;
-
-  /// Variance of the [radialAcceleration] property.
-  double radialAccelerationVar;
-
-  /// The tangential acceleration of each individual particle.
-  double tangentialAcceleration;
-
-  /// Variance of the [tangentialAcceleration] property.
-  double tangentialAccelerationVar;
-
-  /// The gravity vector of the particle system.
-  Vector2 gravity;
-
-  /// The maximum number of particles the system can display at a single time.
-  int maxParticles;
-
-  /// Total number of particles to emit, if the value is set to 0 the system
-  /// will continue to emit particles for an indifinte period of time.
-  int numParticlesToEmit;
-
-  /// The rate at which particles are emitted, defined in particles per second.
-  double emissionRate;
-
-  /// If set to true, the particle system will be automatically removed as soon
-  /// as there are no more particles left to draw.
-  bool autoRemoveOnFinish;
-
-  /// The [ColorSequence] used to animate the color of each individual particle
-  /// over the duration of its [life]. When applied to a particle the sequence's
-  /// color stops modified in accordance with the [alphaVar], [redVar],
-  /// [greenVar], and [blueVar] properties.
-  ColorSequence colorSequence;
-
-  /// Alpha varience of the [colorSequence] property.
-  int alphaVar;
-
-  /// Red varience of the [colorSequence] property.
-  int redVar;
-
-  /// Green varience of the [colorSequence] property.
-  int greenVar;
-
-  /// Blue varience of the [colorSequence] property.
-  int blueVar;
-
-  /// The transfer mode used to draw the particle system. Default is
-  /// [TransferMode.plus].
-  ui.TransferMode transferMode;
-
-  List<_Particle> _particles;
-
-  double _emitCounter;
-  int _numEmittedParticles = 0;
-
-  static Paint _paint = new Paint()
-    ..filterQuality = ui.FilterQuality.low
-    ..isAntiAlias = false;
-
-  ParticleSystem(this.texture,
-                 {this.life: 1.5,
-                  this.lifeVar: 1.0,
-                  this.posVar: Point.origin,
-                  this.startSize: 2.5,
-                  this.startSizeVar: 0.5,
-                  this.endSize: 0.0,
-                  this.endSizeVar: 0.0,
-                  this.startRotation: 0.0,
-                  this.startRotationVar: 0.0,
-                  this.endRotation: 0.0,
-                  this.endRotationVar: 0.0,
-                  this.rotateToMovement : false,
-                  this.direction: 0.0,
-                  this.directionVar: 360.0,
-                  this.speed: 100.0,
-                  this.speedVar: 50.0,
-                  this.radialAcceleration: 0.0,
-                  this.radialAccelerationVar: 0.0,
-                  this.tangentialAcceleration: 0.0,
-                  this.tangentialAccelerationVar: 0.0,
-                  this.gravity,
-                  this.maxParticles: 100,
-                  this.emissionRate: 50.0,
-                  this.colorSequence,
-                  this.alphaVar: 0,
-                  this.redVar: 0,
-                  this.greenVar: 0,
-                  this.blueVar: 0,
-                  this.transferMode: ui.TransferMode.plus,
-                  this.numParticlesToEmit: 0,
-                  this.autoRemoveOnFinish: true}) {
-    _particles = new List<_Particle>();
-    _emitCounter = 0.0;
-    // _elapsedTime = 0.0;
-    if (gravity == null) gravity = new Vector2.zero();
-    if (colorSequence == null) colorSequence = new ColorSequence.fromStartAndEndColor(new Color(0xffffffff), new Color(0x00ffffff));
-  }
-
-  void update(double dt) {
-    // TODO: Fix this (it's a temp fix for low framerates)
-    if (dt > 0.1) dt = 0.1;
-
-    // Create new particles
-    double rate = 1.0 / emissionRate;
-
-    if (_particles.length < maxParticles) {
-      _emitCounter += dt;
-    }
-
-    while(_particles.length < maxParticles
-       && _emitCounter > rate
-       && (numParticlesToEmit == 0 || _numEmittedParticles < numParticlesToEmit)) {
-      // Add a new particle
-      _addParticle();
-      _emitCounter -= rate;
-    }
-
-    // _elapsedTime += dt;
-
-    // Iterate over all particles
-    for (int i = _particles.length -1; i >= 0; i--) {
-      _Particle particle = _particles[i];
-
-      // Manage life time
-      particle.timeToLive -= dt;
-      if (particle.timeToLive <= 0) {
-        _particles.removeAt(i);
-        continue;
-      }
-
-      // Update the particle
-
-      if (particle.accelerations != null) {
-      // Radial acceleration
-      Vector2 radial;
-        if (particle.pos[0] != 0 || particle.pos[1] != 0) {
-          radial = new Vector2.copy(particle.pos).normalize();
-        } else {
-          radial = new Vector2.zero();
-        }
-        Vector2 tangential = new Vector2.copy(radial);
-        radial.scale(particle.accelerations.radialAccel);
-
-        // Tangential acceleration
-        double newY = tangential.x;
-        tangential.x = -tangential.y;
-        tangential.y = newY;
-        tangential.scale(particle.accelerations.tangentialAccel);
-
-        // (gravity + radial + tangential) * dt
-        Vector2 accel = (gravity + radial + tangential).scale(dt);
-        particle.dir += accel;
-      } else if (gravity[0] != 0.0 || gravity[1] != 0) {
-        // gravity
-        Vector2 accel = gravity.scale(dt);
-        particle.dir += accel;
-      }
-
-      // Update particle position
-      particle.pos[0] += particle.dir[0] * dt;
-      particle.pos[1] += particle.dir[1] * dt;
-
-      // Size
-      particle.size = math.max(particle.size + particle.deltaSize * dt, 0.0);
-
-      // Angle
-      particle.rotation += particle.deltaRotation * dt;
-
-      // Color
-      if (particle.simpleColorSequence != null) {
-        for (int i = 0; i < 4; i++) {
-          particle.simpleColorSequence[i] += particle.simpleColorSequence[i + 4] * dt;
-        }
-      } else {
-        particle.colorPos = math.min(particle.colorPos + particle.deltaColorPos * dt, 1.0);
-      }
-    }
-
-    if (autoRemoveOnFinish && _particles.length == 0 && _numEmittedParticles > 0) {
-      if (parent != null) removeFromParent();
-    }
-  }
-
-  void _addParticle() {
-
-    _Particle particle = new _Particle();
-
-    // Time to live
-    particle.timeToLive = math.max(life + lifeVar * randomSignedDouble(), 0.0);
-
-    // Position
-    Point srcPos = Point.origin;
-    particle.pos = new Vector2(srcPos.x + posVar.x * randomSignedDouble(),
-                               srcPos.y + posVar.y * randomSignedDouble());
-
-    // Size
-    particle.size = math.max(startSize + startSizeVar * randomSignedDouble(), 0.0);
-    double endSizeFinal = math.max(endSize + endSizeVar * randomSignedDouble(), 0.0);
-    particle.deltaSize = (endSizeFinal - particle.size) / particle.timeToLive;
-
-    // Rotation
-    particle.rotation = startRotation + startRotationVar * randomSignedDouble();
-    double endRotationFinal = endRotation + endRotationVar * randomSignedDouble();
-    particle.deltaRotation = (endRotationFinal - particle.rotation) / particle.timeToLive;
-
-    // Direction
-    double dirRadians = convertDegrees2Radians(direction + directionVar * randomSignedDouble());
-    Vector2 dirVector = new Vector2(math.cos(dirRadians), math.sin(dirRadians));
-    double speedFinal = speed + speedVar * randomSignedDouble();
-    particle.dir = dirVector.scale(speedFinal);
-
-    // Accelerations
-    if (radialAcceleration != 0.0 || radialAccelerationVar != 0.0 ||
-        tangentialAcceleration != 0.0 || tangentialAccelerationVar != 0.0) {
-      particle.accelerations = new _ParticleAccelerations();
-
-      // Radial acceleration
-      particle.accelerations.radialAccel = radialAcceleration + radialAccelerationVar * randomSignedDouble();
-
-      // Tangential acceleration
-      particle.accelerations.tangentialAccel = tangentialAcceleration + tangentialAccelerationVar * randomSignedDouble();
-    }
-
-    // Color
-    particle.colorPos = 0.0;
-    particle.deltaColorPos = 1.0 / particle.timeToLive;
-
-    if (alphaVar != 0 || redVar != 0 || greenVar != 0 || blueVar != 0) {
-      particle.colorSequence = _ColorSequenceUtil.copyWithVariance(colorSequence, alphaVar, redVar, greenVar, blueVar);
-    }
-
-    // Optimizes the case where there are only two colors in the sequence
-    if (colorSequence.colors.length == 2) {
-      Color startColor;
-      Color endColor;
-
-      if (particle.colorSequence != null) {
-        startColor = particle.colorSequence.colors[0];
-        endColor = particle.colorSequence.colors[1];
-      } else {
-        startColor = colorSequence.colors[0];
-        endColor = colorSequence.colors[1];
-      }
-
-      // First 4 elements are start ARGB, last 4 are delta ARGB
-      particle.simpleColorSequence = new Float64List(8);
-      particle.simpleColorSequence[0] = startColor.alpha.toDouble();
-      particle.simpleColorSequence[1] = startColor.red.toDouble();
-      particle.simpleColorSequence[2] = startColor.green.toDouble();
-      particle.simpleColorSequence[3] = startColor.blue.toDouble();
-
-      particle.simpleColorSequence[4] = (endColor.alpha.toDouble() - startColor.alpha.toDouble()) / particle.timeToLive;
-      particle.simpleColorSequence[5] = (endColor.red.toDouble() - startColor.red.toDouble()) / particle.timeToLive;
-      particle.simpleColorSequence[6] = (endColor.green.toDouble() - startColor.green.toDouble()) / particle.timeToLive;
-      particle.simpleColorSequence[7] = (endColor.blue.toDouble() - startColor.blue.toDouble()) / particle.timeToLive;
-    }
-
-    _particles.add(particle);
-    _numEmittedParticles++;
-  }
-
-  void paint(PaintingCanvas canvas) {
-
-    List<ui.RSTransform> transforms = <ui.RSTransform>[];
-    List<Rect> rects = <Rect>[];
-    List<Color> colors = <Color>[];
-
-    _paint.transferMode = transferMode;
-
-    for (_Particle particle in _particles) {
-      // Rect
-      Rect rect = texture.frame;
-      rects.add(rect);
-
-      // Transform
-      double scos;
-      double ssin;
-      if (rotateToMovement) {
-        double extraRotation = GameMath.atan2(particle.dir[1], particle.dir[0]);
-        scos = math.cos(convertDegrees2Radians(particle.rotation) + extraRotation) * particle.size;
-        ssin = math.sin(convertDegrees2Radians(particle.rotation) + extraRotation) * particle.size;
-      } else if (particle.rotation != 0.0) {
-        scos = math.cos(convertDegrees2Radians(particle.rotation)) * particle.size;
-        ssin = math.sin(convertDegrees2Radians(particle.rotation)) * particle.size;
-      } else {
-        scos = particle.size;
-        ssin = 0.0;
-      }
-      double ax = rect.width / 2;
-      double ay = rect.height / 2;
-      double tx = particle.pos[0] + -scos * ax + ssin * ay;
-      double ty = particle.pos[1] + -ssin * ax - scos * ay;
-      ui.RSTransform transform = new ui.RSTransform(scos, ssin, tx, ty);
-      transforms.add(transform);
-
-      // Color
-      if (particle.simpleColorSequence != null) {
-        Color particleColor = new Color.fromARGB(
-          particle.simpleColorSequence[0].toInt().clamp(0, 255),
-          particle.simpleColorSequence[1].toInt().clamp(0, 255),
-          particle.simpleColorSequence[2].toInt().clamp(0, 255),
-          particle.simpleColorSequence[3].toInt().clamp(0, 255));
-        colors.add(particleColor);
-      } else {
-        Color particleColor;
-        if (particle.colorSequence != null) {
-          particleColor = particle.colorSequence.colorAtPosition(particle.colorPos);
-        } else {
-          particleColor = colorSequence.colorAtPosition(particle.colorPos);
-        }
-        colors.add(particleColor);
-      }
-    }
-
-    canvas.drawAtlas(texture.image, transforms, rects, colors,
-      ui.TransferMode.modulate, null, _paint);
-  }
-}
-
-class _ColorSequenceUtil {
-  static ColorSequence copyWithVariance(
-    ColorSequence sequence,
-    int alphaVar,
-    int redVar,
-    int greenVar,
-    int blueVar
-  ) {
-    ColorSequence copy = new ColorSequence.copy(sequence);
-
-    int i = 0;
-    for (Color color in sequence.colors) {
-      int aDelta = ((randomDouble() * 2.0 - 1.0) * alphaVar).toInt();
-      int rDelta = ((randomDouble() * 2.0 - 1.0) * redVar).toInt();
-      int gDelta = ((randomDouble() * 2.0 - 1.0) * greenVar).toInt();
-      int bDelta = ((randomDouble() * 2.0 - 1.0) * blueVar).toInt();
-
-      int aNew = (color.alpha + aDelta).clamp(0, 255);
-      int rNew = (color.red + rDelta).clamp(0, 255);
-      int gNew = (color.green + gDelta).clamp(0, 255);
-      int bNew = (color.blue + bDelta).clamp(0, 255);
-
-      copy.colors[i] = new Color.fromARGB(aNew, rNew, gNew, bNew);
-      i++;
-    }
-
-    return copy;
-  }
-}
diff --git a/skysprites/lib/src/physics_body.dart b/skysprites/lib/src/physics_body.dart
deleted file mode 100644
index 9afed57..0000000
--- a/skysprites/lib/src/physics_body.dart
+++ /dev/null
@@ -1,549 +0,0 @@
-part of flutter_sprites;
-
-enum PhysicsBodyType {
-    static,
-    dynamic
-}
-
-/// A physics body can be assigned to any node to make it simulated by physics.
-/// The body has a shape, and physical properties such as density, friction,
-/// and velocity.
-///
-/// Bodies can be either dynamic or static. Dynamic bodies will move and rotate
-/// the nodes that are associated with it. Static bodies can be moved by moving
-/// or animating the node associated with them.
-///
-/// For a body to be simulated it needs to be associated with a [Node], through
-/// the node's physicsBody property. The node also need to be a child of either
-/// a [PhysicsWorld] or a [PhysicsGroup] (which in turn is a child of a
-/// [PhysicsWorld] or a [Physics Group]).
-class PhysicsBody {
-  PhysicsBody(this.shape, {
-    this.tag: null,
-    this.type: PhysicsBodyType.dynamic,
-    double density: 1.0,
-    double friction: 0.0,
-    double restitution: 0.0,
-    bool isSensor: false,
-    Offset linearVelocity: Offset.zero,
-    double angularVelocity: 0.0,
-    this.linearDampening: 0.0,
-    double angularDampening: 0.0,
-    bool allowSleep: true,
-    bool awake: true,
-    bool fixedRotation: false,
-    bool bullet: false,
-    bool active: true,
-    this.gravityScale: 1.0,
-    collisionCategory: "Default",
-    collisionMask: null
-  }) {
-    this.density = density;
-    this.friction = friction;
-    this.restitution = restitution;
-    this.isSensor = isSensor;
-
-    this.linearVelocity = linearVelocity;
-    this.angularVelocity = angularVelocity;
-    this.angularDampening = angularDampening;
-
-    this.allowSleep = allowSleep;
-    this.awake = awake;
-    this.fixedRotation = fixedRotation;
-    this.bullet = bullet;
-    this.active = active;
-
-    this.collisionCategory = collisionCategory;
-    this.collisionMask = collisionMask;
-  }
-
-  Vector2 _lastPosition;
-  double _lastRotation;
-  Vector2 _targetPosition;
-  double _targetAngle;
-
-  double _scale;
-
-  /// An object associated with this body, normally used for detecting
-  /// collisions.
-  ///
-  /// myBody.tag = "SpaceShip";
-  Object tag;
-
-  /// The shape of this physics body. The shape cannot be modified once the
-  /// body is created. If the shape is required to change, create a new body.
-  ///
-  ///     myShape = myBody.shape;
-  final PhysicsShape shape;
-
-  /// The type of the body. This is either [PhysicsBodyType.dynamic] or
-  /// [PhysicsBodyType.static]. Dynamic bodies are simulated by the physics,
-  /// static objects affect the physics but are not moved by the physics.
-  ///
-  ///     myBody.type = PhysicsBodyType.static;
-  PhysicsBodyType type;
-
-  double _density;
-
-  /// The density of the body, default value is 1.0. The density has no specific
-  /// unit, instead densities are relative to each other.
-  ///
-  ///     myBody.density = 0.5;
-  double get density => _density;
-
-  set density(double density) {
-    _density = density;
-
-    if (_body == null)
-      return;
-    for (box2d.Fixture f = _body.getFixtureList(); f != null; f = f.getNext()) {
-      f.setDensity(density);
-    }
-  }
-
-  double _friction;
-
-  /// The fricion of the body, the default is 0.0 and the value should be in
-  /// the range of 0.0 to 1.0.
-  ///
-  ///     myBody.friction = 0.4;
-  double get friction => _friction;
-
-  set friction(double friction) {
-    _friction = friction;
-
-    if (_body == null)
-      return;
-    for (box2d.Fixture f = _body.getFixtureList(); f != null; f = f.getNext()) {
-      f.setFriction(friction);
-    }
-  }
-
-  double _restitution;
-
-  double get restitution => _restitution;
-
-  /// The restitution of the body, the default is 0.0 and the value should be in
-  /// the range of 0.0 to 1.0.
-  ///
-  ///     myBody.restitution = 0.5;
-  set restitution(double restitution) {
-    _restitution = restitution;
-
-    if (_body == null)
-      return;
-    for (box2d.Fixture f = _body.getFixtureList(); f != null; f = f.getNext()) {
-      f.setRestitution(restitution);
-    }
-  }
-
-  bool _isSensor;
-
-  /// True if the body is a sensor. Sensors doesn't collide with other bodies,
-  /// but will return collision callbacks. Use a sensor body to detect if two
-  /// bodies are overlapping.
-  ///
-  ///     myBody.isSensor = true;
-  bool get isSensor => _isSensor;
-
-  set isSensor(bool isSensor) {
-    _isSensor = isSensor;
-
-    if (_body == null)
-      return;
-    for (box2d.Fixture f = _body.getFixtureList(); f != null; f = f.getNext()) {
-      f.setSensor(isSensor);
-    }
-  }
-
-  Offset _linearVelocity;
-
-  /// The current linear velocity of the body in points / second.
-  ///
-  ///     myBody.velocity = Offset.zero;
-  Offset get linearVelocity {
-    if (_body == null)
-      return _linearVelocity;
-    else {
-      double dx = _body.linearVelocity.x * _physicsWorld.b2WorldToNodeConversionFactor;
-      double dy = _body.linearVelocity.y * _physicsWorld.b2WorldToNodeConversionFactor;
-      return new Offset(dx, dy);
-    }
-  }
-
-  set linearVelocity(Offset linearVelocity) {
-    _linearVelocity = linearVelocity;
-
-    if (_body != null) {
-      Vector2 vec = new Vector2(
-        linearVelocity.dx / _physicsWorld.b2WorldToNodeConversionFactor,
-        linearVelocity.dy / _physicsWorld.b2WorldToNodeConversionFactor
-      );
-      _body.linearVelocity = vec;
-    }
-  }
-
-  double _angularVelocity;
-
-  /// The angular velocity of the body in degrees / second.
-  ///
-  ///     myBody.angularVelocity = 0.0;
-  double get angularVelocity {
-    if (_body == null)
-      return _angularVelocity;
-    else
-      return _body.angularVelocity;
-  }
-
-  set angularVelocity(double angularVelocity) {
-    _angularVelocity = angularVelocity;
-
-    if (_body != null) {
-      _body.angularVelocity = angularVelocity;
-    }
-  }
-
-  // TODO: Should this be editable in box2d.Body ?
-
-  /// Linear dampening, in the 0.0 to 1.0 range, default is 0.0.
-  ///
-  ///     double dampening = myBody.linearDampening;
-  final double linearDampening;
-
-  double _angularDampening;
-
-  /// Angular dampening, in the 0.0 to 1.0 range, default is 0.0.
-  ///
-  ///     myBody.angularDampening = 0.1;
-  double get angularDampening => _angularDampening;
-
-  set angularDampening(double angularDampening) {
-    _angularDampening = angularDampening;
-
-    if (_body != null)
-      _body.angularDamping = angularDampening;
-  }
-
-  bool _allowSleep;
-
-  /// Allows the body to sleep if it hasn't moved.
-  ///
-  ///     myBody.allowSleep = false;
-  bool get allowSleep => _allowSleep;
-
-  set allowSleep(bool allowSleep) {
-    _allowSleep = allowSleep;
-
-    if (_body != null)
-      _body.setSleepingAllowed(allowSleep);
-  }
-
-  bool _awake;
-
-  /// True if the body is currently awake.
-  ///
-  ///     bool isAwake = myBody.awake;
-  bool get awake {
-    if (_body != null)
-      return _body.isAwake();
-    else
-      return _awake;
-  }
-
-  set awake(bool awake) {
-    _awake = awake;
-
-    if (_body != null)
-      _body.setAwake(awake);
-  }
-
-  bool _fixedRotation;
-
-  /// If true, the body cannot be rotated by the physics simulation.
-  ///
-  ///     myBody.fixedRotation = true;
-  bool get fixedRotation => _fixedRotation;
-
-  set fixedRotation(bool fixedRotation) {
-    _fixedRotation = fixedRotation;
-
-    if (_body != null)
-      _body.setFixedRotation(fixedRotation);
-  }
-
-  bool _bullet;
-
-  bool get bullet => _bullet;
-
-  /// If true, the body cannot pass through other objects when moved at high
-  /// speed. Bullet bodies are slower to simulate, so only use this option
-  /// if neccessary.
-  ///
-  ///     myBody.bullet = true;
-  set bullet(bool bullet) {
-    _bullet = bullet;
-
-    if (_body != null) {
-      _body.setBullet(bullet);
-    }
-  }
-
-  bool _active;
-
-  /// An active body is used in the physics simulation. Set this to false if
-  /// you want to temporarily exclude a body from the simulation.
-  ///
-  ///     myBody.active = false;
-  bool get active {
-    if (_body != null)
-      return _body.isActive();
-    else
-      return _active;
-  }
-
-  set active(bool active) {
-    _active = active;
-
-    if (_body != null)
-      _body.setActive(active);
-  }
-
-  double gravityScale;
-
-  Object _collisionCategory = null;
-
-  /// The collision category assigned to this body. The default value is
-  /// "Default". The body will only collide with bodies that have the either
-  /// the [collisionMask] set to null or has the category in the mask.
-  ///
-  ///     myBody.collisionCategory = "Air";
-  Object get collisionCategory {
-    return _collisionCategory;
-  }
-
-  set collisionCategory(Object collisionCategory) {
-    _collisionCategory = collisionCategory;
-    _updateFilter();
-  }
-
-  List<Object> _collisionMask = null;
-
-  /// A list of collision categories that this object will collide with. If set
-  /// to null (the default value) the body will collide with all other bodies.
-  ///
-  ///     myBody.collisionMask = ["Air", "Ground"];
-  List<Object> get collisionMask => _collisionMask;
-
-  set collisionMask(List<Object> collisionMask) {
-    _collisionMask = collisionMask;
-    _updateFilter();
-  }
-
-  box2d.Filter get _b2Filter {
-    print("_physicsNode: $_physicsWorld groups: ${_physicsWorld._collisionGroups}");
-    box2d.Filter f = new box2d.Filter();
-    f.categoryBits = _physicsWorld._collisionGroups.getBitmaskForKeys([_collisionCategory]);
-    f.maskBits = _physicsWorld._collisionGroups.getBitmaskForKeys(_collisionMask);
-
-    print("Filter: $f category: ${f.categoryBits} mask: ${f.maskBits}");
-
-    return f;
-  }
-
-  void _updateFilter() {
-    if (_body != null) {
-      box2d.Filter filter = _b2Filter;
-      for (box2d.Fixture fixture = _body.getFixtureList(); fixture != null; fixture = fixture.getNext()) {
-        fixture.setFilterData(filter);
-      }
-    }
-  }
-
-  PhysicsWorld _physicsWorld;
-  Node _node;
-
-  box2d.Body _body;
-
-  List<PhysicsJoint> _joints = <PhysicsJoint>[];
-
-  bool _attached = false;
-
-  /// Applies a force to the body at the [worldPoint] position in world
-  /// cordinates.
-  ///
-  ///     myBody.applyForce(new Offset(0.0, 100.0), myNode.position);
-  void applyForce(Offset force, Point worldPoint) {
-    assert(_body != null);
-
-    Vector2 b2Force = new Vector2(
-      force.dx / _physicsWorld.b2WorldToNodeConversionFactor,
-      force.dy / _physicsWorld.b2WorldToNodeConversionFactor);
-
-    Vector2 b2Point = new Vector2(
-      worldPoint.x / _physicsWorld.b2WorldToNodeConversionFactor,
-      worldPoint.y / _physicsWorld.b2WorldToNodeConversionFactor
-    );
-
-    _body.applyForce(b2Force, b2Point);
-  }
-
-  /// Applice a force to the body at the its center of gravity.
-  ///
-  ///     myBody.applyForce(new Offset(0.0, 100.0));
-  void applyForceToCenter(Offset force) {
-    assert(_body != null);
-
-    Vector2 b2Force = new Vector2(
-      force.dx / _physicsWorld.b2WorldToNodeConversionFactor,
-      force.dy / _physicsWorld.b2WorldToNodeConversionFactor);
-
-    _body.applyForceToCenter(b2Force);
-  }
-
-  /// Applies a torque to the body.
-  ///
-  ///     myBody.applyTorque(10.0);
-  void applyTorque(double torque) {
-    assert(_body != null);
-
-    _body.applyTorque(torque / _physicsWorld.b2WorldToNodeConversionFactor);
-  }
-
-  /// Applies a linear impulse to the body at the [worldPoint] position in world
-  /// cordinates.
-  ///
-  ///     myBody.applyLinearImpulse(new Offset(0.0, 100.0), myNode.position);
-  void applyLinearImpulse(Offset impulse, Point worldPoint, [bool wake = true]) {
-    assert(_body != null);
-
-    Vector2 b2Impulse = new Vector2(
-      impulse.dx / _physicsWorld.b2WorldToNodeConversionFactor,
-      impulse.dy / _physicsWorld.b2WorldToNodeConversionFactor);
-
-    Vector2 b2Point = new Vector2(
-      worldPoint.x / _physicsWorld.b2WorldToNodeConversionFactor,
-      worldPoint.y / _physicsWorld.b2WorldToNodeConversionFactor
-    );
-
-    _body.applyLinearImpulse(b2Impulse, b2Point, wake);
-  }
-
-  /// Applies an angular impulse to the body.
-  ///
-  ///     myBody.applyAngularImpulse(20.0);
-  void applyAngularImpulse(double impulse) {
-    assert(_body != null);
-
-    _body.applyAngularImpulse(impulse / _physicsWorld.b2WorldToNodeConversionFactor);
-  }
-
-  void _attach(PhysicsWorld physicsNode, Node node) {
-    assert(_attached == false);
-
-    _physicsWorld = physicsNode;
-
-    // Account for physics groups
-    Point positionWorld = node._positionToPhysics(node.position, node.parent);
-    double rotationWorld = node._rotationToPhysics(node.rotation, node.parent);
-    double scaleWorld = node._scaleToPhysics(node.scale, node.parent);
-
-    // Update scale
-    _scale = scaleWorld;
-
-    // Create BodyDef
-    box2d.BodyDef bodyDef = new box2d.BodyDef();
-    bodyDef.linearVelocity = new Vector2(linearVelocity.dx, linearVelocity.dy);
-    bodyDef.angularVelocity = angularVelocity;
-    bodyDef.linearDamping = linearDampening;
-    bodyDef.angularDamping = angularDampening;
-    bodyDef.allowSleep = allowSleep;
-    bodyDef.awake = awake;
-    bodyDef.fixedRotation = fixedRotation;
-    bodyDef.bullet = bullet;
-    bodyDef.active = active;
-    bodyDef.gravityScale = gravityScale;
-    if (type == PhysicsBodyType.dynamic)
-      bodyDef.type = box2d.BodyType.DYNAMIC;
-    else
-      bodyDef.type = box2d.BodyType.STATIC;
-
-    // Convert to world coordinates and set position and angle
-    double conv = physicsNode.b2WorldToNodeConversionFactor;
-    bodyDef.position = new Vector2(positionWorld.x / conv, positionWorld.y / conv);
-    bodyDef.angle = radians(rotationWorld);
-
-    // Create Body
-    _body = physicsNode.b2World.createBody(bodyDef);
-
-    _createFixtures(physicsNode);
-
-    _body.userData = this;
-
-    _node = node;
-
-    _attached = true;
-
-    // Attach any joints
-    for (PhysicsJoint joint in _joints) {
-      if (joint.bodyA._attached && joint.bodyB._attached) {
-        joint._attach(physicsNode);
-      }
-    }
-  }
-
-  void _createFixtures(PhysicsWorld physicsNode) {
-    // Create FixtureDef
-    box2d.FixtureDef fixtureDef = new box2d.FixtureDef();
-    fixtureDef.friction = friction;
-    fixtureDef.restitution = restitution;
-    fixtureDef.density = density;
-    fixtureDef.isSensor = isSensor;
-    fixtureDef.filter = _b2Filter;
-
-    // Get shapes
-    List<box2d.Shape> b2Shapes = <box2d.Shape>[];
-    List<PhysicsShape> physicsShapes = <PhysicsShape>[];
-    _addB2Shapes(physicsNode, shape, b2Shapes, physicsShapes);
-
-    // Create fixtures
-    for (int i = 0; i < b2Shapes.length; i++) {
-      box2d.Shape b2Shape = b2Shapes[i];
-      PhysicsShape physicsShape = physicsShapes[i];
-
-      fixtureDef.shape = b2Shape;
-      box2d.Fixture fixture = _body.createFixtureFromFixtureDef(fixtureDef);
-      fixture.userData = physicsShape;
-    }
-  }
-
-  void _detach() {
-    if (_attached) {
-      _physicsWorld._bodiesScheduledForDestruction.add(_body);
-      _attached = false;
-    }
-  }
-
-  void _updateScale(PhysicsWorld physicsNode) {
-    // Destroy old fixtures
-    for (box2d.Fixture fixture = _body.getFixtureList(); fixture != null; fixture = fixture.getNext()) {
-      _body.destroyFixture(fixture);
-    }
-
-    // Make sure we create new b2Shapes
-    shape._invalidate();
-
-    // Create new fixtures
-    _createFixtures(physicsNode);
-  }
-
-  void _addB2Shapes(PhysicsWorld physicsNode, PhysicsShape shape, List<box2d.Shape> b2Shapes, List<PhysicsShape> physicsShapes) {
-    if (shape is PhysicsShapeGroup) {
-      for (PhysicsShape child in shape.shapes) {
-        _addB2Shapes(physicsNode, child, b2Shapes, physicsShapes);
-      }
-    } else {
-      b2Shapes.add(shape.getB2Shape(physicsNode, _scale));
-      physicsShapes.add(shape);
-    }
-  }
-}
diff --git a/skysprites/lib/src/physics_collision_groups.dart b/skysprites/lib/src/physics_collision_groups.dart
deleted file mode 100644
index 234f1c4..0000000
--- a/skysprites/lib/src/physics_collision_groups.dart
+++ /dev/null
@@ -1,40 +0,0 @@
-part of flutter_sprites;
-
-class _PhysicsCollisionGroups {
-
-  _PhysicsCollisionGroups() {
-    // Make sure there is a default entry in the groups
-    getBitmaskForKeys(["Default"]);
-  }
-
-  Map<Object,int> keyLookup = <Object,int>{};
-
-  List<Object> getKeysForBitmask(int bitmask) {
-    List<Object> keys = [];
-    keyLookup.forEach((Object key, int value) {
-      if (value & bitmask != 0) {
-        keys.add(key);
-      }
-    });
-    return keys;
-  }
-
-  int getBitmaskForKeys(List<Object> keys) {
-    if (keys == null) {
-      return 0xffff;
-    }
-
-    int bitmask = 0;
-
-    for (Object key in keys) {
-      int value = keyLookup[key];
-      if (value == null) {
-        assert(keyLookup.length < 16);
-        value = 1 << keyLookup.length;
-        keyLookup[key] = value;
-      }
-      bitmask |= value;
-    }
-    return bitmask;
-  }
-}
diff --git a/skysprites/lib/src/physics_debug.dart b/skysprites/lib/src/physics_debug.dart
deleted file mode 100644
index cb766b8..0000000
--- a/skysprites/lib/src/physics_debug.dart
+++ /dev/null
@@ -1,104 +0,0 @@
-part of flutter_sprites;
-
-class _PhysicsDebugDraw extends box2d.DebugDraw {
-  _PhysicsDebugDraw(
-    box2d.ViewportTransform transform,
-    this.physicsWorld
-  ) : super(transform) {
-    appendFlags(
-      box2d.DebugDraw.JOINT_BIT |
-      box2d.DebugDraw.CENTER_OF_MASS_BIT |
-      box2d.DebugDraw.WIREFRAME_DRAWING_BIT
-    );
-  }
-
-  PhysicsWorld physicsWorld;
-
-  PaintingCanvas canvas;
-
-  void drawSegment(Vector2 p1, Vector2 p2, box2d.Color3i color) {
-    Paint paint = new Paint()
-      ..color = _toColor(color)
-      ..strokeWidth = 1.0;
-    canvas.drawLine(_toPoint(p1), _toPoint(p2), paint);
-  }
-
-  void drawSolidPolygon(
-    List<Vector2> vertices,
-    int vertexCount,
-    box2d.Color3i color
-  ) {
-    Path path = new Path();
-    Point pt = _toPoint(vertices[0]);
-    path.moveTo(pt.x, pt.y);
-    for (int i = 1; i < vertexCount; i++) {
-      pt = _toPoint(vertices[i]);
-      path.lineTo(pt.x, pt.y);
-    }
-
-    Paint paint = new Paint()..color = _toColor(color);
-    canvas.drawPath(path, paint);
-  }
-
-  void drawCircle(Vector2 center, num radius, box2d.Color3i color, [Vector2 axis]) {
-    Paint paint = new Paint()
-      ..color = _toColor(color)
-      ..style = ui.PaintingStyle.stroke
-      ..strokeWidth = 1.0;
-
-    canvas.drawCircle(_toPoint(center), _scale(radius), paint);
-  }
-
-  void drawSolidCircle(Vector2 center, num radius, Vector2 axis, box2d.Color3i color) {
-    Paint paint = new Paint()
-      ..color = _toColor(color);
-
-    canvas.drawCircle(_toPoint(center), _scale(radius), paint);
-  }
-
-  void drawPoint(Vector2 point, num radiusOnScreen, box2d.Color3i color) {
-    drawSolidCircle(point, radiusOnScreen, null, color);
-  }
-
-  void drawParticles(
-    List<Vector2> centers,
-    double radius,
-    List<box2d.ParticleColor> colors,
-    int count
-  ) {
-    // TODO: Implement
-  }
-
-  void drawParticlesWireframe(
-    List<Vector2> centers,
-    double radius,
-    List<box2d.ParticleColor> colors,
-    int count
-  ) {
-    // TODO: Implement
-  }
-
-  void drawTransform(box2d.Transform xf, box2d.Color3i color) {
-    drawCircle(xf.p, 0.1, color);
-    // TODO: Improve
-  }
-
-  void drawStringXY(num x, num y, String s, box2d.Color3i color) {
-    // TODO: Implement
-  }
-
-  Color _toColor(box2d.Color3i color) {
-    return new Color.fromARGB(255, color.x, color.y, color.z);
-  }
-
-  Point _toPoint(Vector2 vec) {
-    return new Point(
-      vec.x * physicsWorld.b2WorldToNodeConversionFactor,
-      vec.y * physicsWorld.b2WorldToNodeConversionFactor
-    );
-  }
-
-  double _scale(double value) {
-    return value * physicsWorld.b2WorldToNodeConversionFactor;
-  }
-}
diff --git a/skysprites/lib/src/physics_group.dart b/skysprites/lib/src/physics_group.dart
deleted file mode 100644
index a78b0d5..0000000
--- a/skysprites/lib/src/physics_group.dart
+++ /dev/null
@@ -1,114 +0,0 @@
-part of flutter_sprites;
-
-/// A [Node] that acts as a middle layer between a [PhysicsWorld] and a node
-/// with an assigned [PhysicsBody]. The group's transformations are limited to
-/// [position], [rotation], and uniform [scale].
-///
-///     PhysicsGroup group = new PhysicsGroup();
-///     myWorld.addChild(group);
-///     group.addChild(myNode);
-class PhysicsGroup extends Node {
-
-  set scaleX(double scaleX) {
-    assert(false);
-  }
-
-  set scaleY(double scaleX) {
-    assert(false);
-  }
-
-  set skewX(double scaleX) {
-    assert(false);
-  }
-
-  set skewY(double scaleX) {
-    assert(false);
-  }
-
-  set physicsBody(PhysicsBody body) {
-    assert(false);
-  }
-
-  set position(Point position) {
-    super.position = position;
-    _invalidatePhysicsBodies(this);
-  }
-
-  set rotation(double rotation) {
-    super.rotation = rotation;
-    _invalidatePhysicsBodies(this);
-  }
-
-  set scale(double scale) {
-    super.scale = scale;
-    _invalidatePhysicsBodies(this);
-  }
-
-  void _invalidatePhysicsBodies(Node node) {
-    if (_world == null) return;
-
-    if (node.physicsBody != null) {
-      // TODO: Add to list
-      _world._bodiesScheduledForUpdate.add(node.physicsBody);
-    }
-
-    for (Node child in node.children) {
-      _invalidatePhysicsBodies(child);
-    }
-  }
-
-  void addChild(Node node) {
-    super.addChild(node);
-
-    PhysicsWorld world = _world;
-    if (node.physicsBody != null && world != null) {
-      node.physicsBody._attach(world, node);
-    }
-
-    if (node is PhysicsGroup) {
-      _attachGroup(this, world);
-    }
-  }
-
-  void _attachGroup(PhysicsGroup group, PhysicsWorld world) {
-    for (Node child in group.children) {
-      if (child is PhysicsGroup) {
-        _attachGroup(child, world);
-      } else if (child.physicsBody != null) {
-        child.physicsBody._attach(world, child);
-      }
-    }
-  }
-
-  void removeChild(Node node) {
-    super.removeChild(node);
-
-    if (node.physicsBody != null) {
-      node.physicsBody._detach();
-    }
-
-    if (node is PhysicsGroup) {
-      _detachGroup(this);
-    }
-  }
-
-  void _detachGroup(PhysicsGroup group) {
-    for (Node child in group.children) {
-      if (child is PhysicsGroup) {
-        _detachGroup(child);
-      } else if (child.physicsBody != null) {
-        child.physicsBody._detach();
-      }
-    }
-  }
-
-  PhysicsWorld get _world {
-    if (this.parent is PhysicsWorld)
-      return this.parent;
-    if (this.parent is PhysicsGroup) {
-      PhysicsGroup group = this.parent;
-      return group._world;
-    }
-    return null;
-  }
-}
diff --git a/skysprites/lib/src/physics_joint.dart b/skysprites/lib/src/physics_joint.dart
deleted file mode 100644
index d5a0eef..0000000
--- a/skysprites/lib/src/physics_joint.dart
+++ /dev/null
@@ -1,584 +0,0 @@
-part of flutter_sprites;
-
-typedef void PhysicsJointBreakCallback(PhysicsJoint joint);
-
-/// A joint connects two physics bodies and restricts their movements. Some
-/// types of joints also support motors that adds forces to the connected
-/// bodies.
-abstract class PhysicsJoint {
-  PhysicsJoint(this._bodyA, this._bodyB, this.breakingForce, this.breakCallback) {
-    bodyA._joints.add(this);
-    bodyB._joints.add(this);
-  }
-
-  PhysicsBody _bodyA;
-
-  /// The first body connected to the joint.
-  ///
-  ///     PhysicsBody body = myJoint.bodyA;
-  PhysicsBody get bodyA => _bodyA;
-
-  PhysicsBody _bodyB;
-
-  /// The second body connected to the joint.
-  ///
-  ///     PhysicsBody body = myJoint.bodyB;
-  PhysicsBody get bodyB => _bodyB;
-
-  /// The maximum force the joint can handle before it breaks. If set to null,
-  /// the joint will never break.
-  final double breakingForce;
-
-  final PhysicsJointBreakCallback breakCallback;
-
-  bool _active = true;
-  box2d.Joint _joint;
-
-  PhysicsWorld _physicsWorld;
-
-  void _completeCreation() {
-    if (bodyA._attached && bodyB._attached) {
-      _attach(bodyA._physicsWorld);
-    }
-  }
-
-  void _attach(PhysicsWorld physicsNode) {
-    if (_joint == null) {
-      _physicsWorld = physicsNode;
-      _joint = _createB2Joint(physicsNode);
-      _physicsWorld._joints.add(this);
-    }
-  }
-
-  void _detach() {
-    if (_joint != null && _active) {
-      _physicsWorld.b2World.destroyJoint(_joint);
-      _joint = null;
-      _physicsWorld._joints.remove(this);
-    }
-    _active = false;
-  }
-
-  box2d.Joint _createB2Joint(PhysicsWorld physicsNode);
-
-  /// If the joint is no longer needed, call the the [destroy] method to detach
-  /// if from its connected bodies.
-  void destroy() {
-    _detach();
-  }
-
-  void _checkBreakingForce(double dt) {
-    if (breakingForce == null) return;
-
-    if (_joint != null && _active) {
-      Vector2 reactionForce = new Vector2.zero();
-      _joint.getReactionForce(1.0 / dt, reactionForce);
-
-      if (breakingForce * breakingForce < reactionForce.length2) {
-        // Destroy the joint
-        destroy();
-
-        // Notify any observer
-        if (breakCallback != null)
-          breakCallback(this);
-      }
-    }
-  }
-}
-
-/// The revolute joint can be thought of as a hinge, a pin, or an axle.
-/// An anchor point is defined in global space.
-///
-/// Revolute joints can be given limits so that the bodies can rotate only to a
-/// certain point using [lowerAngle], [upperAngle], and [enableLimit].
-/// They can also be given a motor using [enableMotore] together with
-/// [motorSpeed] and [maxMotorTorque] so that the bodies will try
-/// to rotate at a given speed, with a given torque.
-///
-/// Common uses for revolute joints include:
-/// - wheels or rollers
-/// - chains or swingbridges (using multiple revolute joints)
-/// - rag-doll joints
-/// - rotating doors, catapults, levers
-///
-///     new PhysicsJointRevolute(
-///       nodeA.physicsBody,
-///       nodeB.physicsBody,
-///       nodeB.position
-///     );
-class PhysicsJointRevolute extends PhysicsJoint {
-  PhysicsJointRevolute(
-    PhysicsBody bodyA,
-    PhysicsBody bodyB,
-    this._worldAnchor, {
-      this.lowerAngle: 0.0,
-      this.upperAngle: 0.0,
-      this.enableLimit: false,
-      PhysicsJointBreakCallback breakCallback,
-      double breakingForce,
-      bool enableMotor: false,
-      double motorSpeed: 0.0,
-      double maxMotorTorque: 0.0
-    }) : super(bodyA, bodyB, breakingForce, breakCallback) {
-    _enableMotor = enableMotor;
-    _motorSpeed = motorSpeed;
-    _maxMotorTorque = maxMotorTorque;
-    _completeCreation();
-  }
-
-  final Point _worldAnchor;
-
-  /// The lower angle of the limits of this joint, only used if [enableLimit]
-  /// is set to true.
-  final double lowerAngle;
-
-  /// The upper angle of the limits of this joint, only used if [enableLimit]
-  /// is set to true.
-  final double upperAngle;
-
-  /// If set to true, the rotation will be limited to a value between
-  /// [lowerAngle] and [upperAngle].
-  final bool enableLimit;
-
-  bool _enableMotor;
-
-  /// By setting enableMotor to true, the joint will automatically rotate, e.g.
-  /// this can be used for creating an engine for a wheel. For this to be
-  /// useful you also need to set [motorSpeed] and [maxMotorTorque].
-  bool get enableMotor => _enableMotor;
-
-  set enableMotor(bool enableMotor) {
-    _enableMotor = enableMotor;
-    if (_joint != null) {
-      box2d.RevoluteJoint revoluteJoint = _joint;
-      revoluteJoint.enableMotor(enableMotor);
-    }
-  }
-
-  double _motorSpeed;
-
-  /// Sets the motor speed of this joint, will only work if [enableMotor] is
-  /// set to true and [maxMotorTorque] is set to a non zero value.
-  double get motorSpeed => _motorSpeed;
-
-  set motorSpeed(double motorSpeed) {
-    _motorSpeed = motorSpeed;
-    if (_joint != null) {
-      box2d.RevoluteJoint revoluteJoint = _joint;
-      revoluteJoint.setMotorSpeed(radians(motorSpeed));
-    }
-  }
-
-  double _maxMotorTorque;
-
-  double get maxMotorTorque => _maxMotorTorque;
-
-  /// Sets the motor torque of this joint, will only work if [enableMotor] is
-  /// set to true and [motorSpeed] is set to a non zero value.
-  set maxMotorTorque(double maxMotorTorque) {
-    _maxMotorTorque = maxMotorTorque;
-    if (_joint != null) {
-      box2d.RevoluteJoint revoluteJoint = _joint;
-      revoluteJoint.setMaxMotorTorque(maxMotorTorque);
-    }
-  }
-
-  box2d.Joint _createB2Joint(PhysicsWorld physicsNode) {
-    // Create Joint Definition
-    Vector2 vecAnchor = new Vector2(
-      _worldAnchor.x / physicsNode.b2WorldToNodeConversionFactor,
-      _worldAnchor.y / physicsNode.b2WorldToNodeConversionFactor
-    );
-
-    box2d.RevoluteJointDef b2Def = new box2d.RevoluteJointDef();
-    b2Def.initialize(bodyA._body, bodyB._body, vecAnchor);
-    b2Def.enableLimit = enableLimit;
-    b2Def.lowerAngle = lowerAngle;
-    b2Def.upperAngle = upperAngle;
-
-    b2Def.enableMotor = _enableMotor;
-    b2Def.motorSpeed = _motorSpeed;
-    b2Def.maxMotorTorque = _maxMotorTorque;
-
-    // Create joint
-    return physicsNode.b2World.createJoint(b2Def);
-  }
-}
-
-/// The prismatic joint is probably more commonly known as a slider joint.
-/// The two joined bodies have their rotation held fixed relative to each
-/// other, and they can only move along a specified axis.
-///
-/// Prismatic joints can be given limits so that the bodies can only move
-/// along the axis within a specific range. They can also be given a motor so
-/// that the bodies will try to move at a given speed, with a given force.
-///
-/// Common uses for prismatic joints include:
-/// - elevators
-/// - moving platforms
-/// - sliding doors
-/// - pistons
-///
-///     new PhysicsJointPrismatic(
-///       nodeA.physicsBody,
-///       nodeB.physicsBody,
-///       new Offset(0.0, 1.0)
-///     );
-class PhysicsJointPrismatic extends PhysicsJoint {
-  PhysicsJointPrismatic(
-    PhysicsBody bodyA,
-    PhysicsBody bodyB,
-    this.axis, {
-      double breakingForce,
-      PhysicsJointBreakCallback breakCallback,
-      bool enableMotor: false,
-      double motorSpeed: 0.0,
-      double maxMotorForce: 0.0
-    }
-  ) : super(bodyA, bodyB, breakingForce, breakCallback) {
-    _enableMotor = enableMotor;
-    _motorSpeed = motorSpeed;
-    _maxMotorForce = maxMotorForce;
-    _completeCreation();
-  }
-
-  /// Axis that the movement is restricted to (in global space at the time of
-  /// creation)
-  final Offset axis;
-
-  bool _enableMotor;
-
-  /// For the motor to be effective you also need to set [motorSpeed] and
-  /// [maxMotorForce].
-  bool get enableMotor => _enableMotor;
-
-  set enableMotor(bool enableMotor) {
-    _enableMotor = enableMotor;
-    if (_joint != null) {
-      box2d.PrismaticJoint prismaticJoint = _joint;
-      prismaticJoint.enableMotor(enableMotor);
-    }
-  }
-
-  double _motorSpeed;
-
-  /// Sets the motor speed of this joint, will only work if [enableMotor] is
-  /// set to true and [maxMotorForce] is set to a non zero value.
-  double get motorSpeed => _motorSpeed;
-
-  set motorSpeed(double motorSpeed) {
-    _motorSpeed = motorSpeed;
-    if (_joint != null) {
-      box2d.PrismaticJoint prismaticJoint = _joint;
-      prismaticJoint.setMotorSpeed(motorSpeed / _physicsWorld.b2WorldToNodeConversionFactor);
-    }
-  }
-
-  double _maxMotorForce;
-
-  /// Sets the motor force of this joint, will only work if [enableMotor] is
-  /// set to true and [motorSpeed] is set to a non zero value.
-  double get maxMotorForce => _maxMotorForce;
-
-  set maxMotorForce(double maxMotorForce) {
-    _maxMotorForce = maxMotorForce;
-    if (_joint != null) {
-      box2d.PrismaticJoint prismaticJoint = _joint;
-      prismaticJoint.setMaxMotorForce(maxMotorForce / _physicsWorld.b2WorldToNodeConversionFactor);
-    }
-  }
-
-  box2d.Joint _createB2Joint(PhysicsWorld physicsNode) {
-    box2d.PrismaticJointDef b2Def = new box2d.PrismaticJointDef();
-    b2Def.initialize(bodyA._body, bodyB._body, bodyA._body.position, new Vector2(axis.dx, axis.dy));
-    b2Def.enableMotor = _enableMotor;
-    b2Def.motorSpeed = _motorSpeed;
-    b2Def.maxMotorForce = _maxMotorForce;
-
-    return physicsNode.b2World.createJoint(b2Def);
-  }
-}
-
-/// The weld joint attempts to constrain all relative motion between two bodies.
-///
-///     new PhysicsJointWeld(bodyA.physicsJoint, bodyB.physicsJoint)
-class PhysicsJointWeld extends PhysicsJoint {
-  PhysicsJointWeld(
-    PhysicsBody bodyA,
-    PhysicsBody bodyB, {
-      double breakingForce,
-      PhysicsJointBreakCallback breakCallback,
-      this.dampening: 0.0,
-      this.frequency: 0.0
-    }
-  ) : super(bodyA, bodyB, breakingForce, breakCallback) {
-    _completeCreation();
-  }
-
-  final double dampening;
-  final double frequency;
-
-  box2d.Joint _createB2Joint(PhysicsWorld physicsNode) {
-    box2d.WeldJointDef b2Def = new box2d.WeldJointDef();
-    Vector2 middle = new Vector2(
-      (bodyA._body.position.x + bodyB._body.position.x) / 2.0,
-      (bodyA._body.position.y + bodyB._body.position.y) / 2.0
-    );
-    b2Def.initialize(bodyA._body, bodyB._body, middle);
-    b2Def.dampingRatio = dampening;
-    b2Def.frequencyHz = frequency;
-    return physicsNode.b2World.createJoint(b2Def);
-  }
-}
-
-/// A pulley is used to create an idealized pulley. The pulley connects two
-/// bodies to ground and to each other. As one body goes up, the other goes
-/// down.
-///
-/// The total length of the pulley rope is conserved according to the initial
-/// configuration.
-///
-///     new PhysicsJointPulley(
-///       nodeA.physicsBody,
-///       nodeB.physicsBody,
-///       new Point(0.0, 100.0),
-///       new Point(100.0, 100.0),
-///       nodeA.position,
-///       nodeB.position,
-///       1.0
-///     );
-class PhysicsJointPulley extends PhysicsJoint {
-  PhysicsJointPulley(
-    PhysicsBody bodyA,
-    PhysicsBody bodyB,
-    this.groundAnchorA,
-    this.groundAnchorB,
-    this.anchorA,
-    this.anchorB,
-    this.ratio, {
-      double breakingForce,
-      PhysicsJointBreakCallback breakCallback
-    }
-  ) : super(bodyA, bodyB, breakingForce, breakCallback) {
-    _completeCreation();
-  }
-
-  final Point groundAnchorA;
-  final Point groundAnchorB;
-  final Point anchorA;
-  final Point anchorB;
-  final double ratio;
-
-  box2d.Joint _createB2Joint(PhysicsWorld physicsNode) {
-    box2d.PulleyJointDef b2Def = new box2d.PulleyJointDef();
-    b2Def.initialize(
-      bodyA._body,
-      bodyB._body,
-      _convertPosToVec(groundAnchorA, physicsNode),
-      _convertPosToVec(groundAnchorB, physicsNode),
-      _convertPosToVec(anchorA, physicsNode),
-      _convertPosToVec(anchorB, physicsNode),
-      ratio
-    );
-    return physicsNode.b2World.createJoint(b2Def);
-  }
-}
-
-/// The gear joint can only connect revolute and/or prismatic joints.
-///
-/// Like the pulley ratio, you can specify a gear ratio. However, in this case
-/// the gear ratio can be negative. Also keep in mind that when one joint is a
-/// revolute joint (angular) and the other joint is prismatic (translation),
-/// and then the gear ratio will have units of length or one over length.
-///
-///     new PhysicsJointGear(nodeA.physicsBody, nodeB.physicsBody);
-class PhysicsJointGear extends PhysicsJoint {
-  PhysicsJointGear(
-    PhysicsBody bodyA,
-    PhysicsBody bodyB, {
-      double breakingForce,
-      PhysicsJointBreakCallback breakCallback,
-      this.ratio: 1.0
-    }
-  ) : super(bodyA, bodyB, breakingForce, breakCallback) {
-    _completeCreation();
-  }
-
-  /// The ratio of the rotation for bodyA relative bodyB.
-  final double ratio;
-
-  box2d.Joint _createB2Joint(PhysicsWorld physicsNode) {
-    box2d.GearJointDef b2Def = new box2d.GearJointDef();
-    b2Def.bodyA = bodyA._body;
-    b2Def.bodyB = bodyB._body;
-    b2Def.ratio = ratio;
-
-    return physicsNode.b2World.createJoint(b2Def);
-  }
-}
-
-/// Keeps a fixed distance between two bodies, [anchorA] and [anchorB] are
-/// defined in world coordinates.
-class PhysicsJointDistance extends PhysicsJoint {
-  PhysicsJointDistance(
-    PhysicsBody bodyA,
-    PhysicsBody bodyB,
-    this.anchorA,
-    this.anchorB, {
-      double breakingForce,
-      PhysicsJointBreakCallback breakCallback,
-      this.length,
-      this.dampening: 0.0,
-      this.frequency: 0.0
-    }
-  ) : super(bodyA, bodyB, breakingForce, breakCallback) {
-    _completeCreation();
-  }
-
-  /// The anchor of bodyA in world coordinates at the time of creation.
-  final Point anchorA;
-
-  /// The anchor of bodyB in world coordinates at the time of creation.
-  final Point anchorB;
-
-  /// The desired distance between the joints, if not passed in at creation
-  /// it will be set automatically to the distance between the anchors at the
-  /// time of creation.
-  final double length;
-
-  /// Dampening factor.
-  final double dampening;
-
-  /// Dampening frequency.
-  final double frequency;
-
-  box2d.Joint _createB2Joint(PhysicsWorld physicsNode) {
-    box2d.DistanceJointDef b2Def = new box2d.DistanceJointDef();
-    b2Def.initialize(
-      bodyA._body,
-      bodyB._body,
-      _convertPosToVec(anchorA, physicsNode),
-      _convertPosToVec(anchorB, physicsNode)
-    );
-    b2Def.dampingRatio = dampening;
-    b2Def.frequencyHz = frequency;
-    if (length != null)
-      b2Def.length = length / physicsNode.b2WorldToNodeConversionFactor;
-
-    return physicsNode.b2World.createJoint(b2Def);
-  }
-}
-
-/// The wheel joint restricts a point on bodyB to a line on bodyA. The wheel
-/// joint also optionally provides a suspension spring.
-class PhysicsJointWheel extends PhysicsJoint {
-  PhysicsJointWheel(
-    PhysicsBody bodyA,
-    PhysicsBody bodyB,
-    this.anchor,
-    this.axis, {
-      double breakingForce,
-      PhysicsJointBreakCallback breakCallback,
-      this.dampening: 0.0,
-      this.frequency: 0.0
-    }
-  ) : super(bodyA, bodyB, breakingForce, breakCallback) {
-    _completeCreation();
-  }
-
-  /// The rotational point in global space at the time of creation.
-  final Point anchor;
-
-  /// The axis which to restrict the movement to.
-  final Offset axis;
-
-  /// Dampening factor.
-  final double dampening;
-
-  /// Dampening frequency.
-  final double frequency;
-
-  box2d.Joint _createB2Joint(PhysicsWorld physicsNode) {
-    box2d.WheelJointDef b2Def = new box2d.WheelJointDef();
-    b2Def.initialize(
-      bodyA._body,
-      bodyB._body,
-      _convertPosToVec(anchor, physicsNode),
-      new Vector2(axis.dx, axis.dy)
-    );
-    b2Def.dampingRatio = dampening;
-    b2Def.frequencyHz = frequency;
-
-    return physicsNode.b2World.createJoint(b2Def);
-  }
-}
-
-/// The friction joint is used for top-down friction. The joint provides 2D
-/// translational friction and angular friction.
-class PhysicsJointFriction extends PhysicsJoint {
-  PhysicsJointFriction(
-    PhysicsBody bodyA,
-    PhysicsBody bodyB,
-    this.anchor, {
-      double breakingForce,
-      PhysicsJointBreakCallback breakCallback,
-      this.maxForce: 0.0,
-      this.maxTorque: 0.0
-    }
-  ) : super(bodyA, bodyB, breakingForce, breakCallback) {
-    _completeCreation();
-  }
-
-  final Point anchor;
-  final double maxForce;
-  final double maxTorque;
-
-  box2d.Joint _createB2Joint(PhysicsWorld physicsNode) {
-    box2d.FrictionJointDef b2Def = new box2d.FrictionJointDef();
-    b2Def.initialize(
-      bodyA._body,
-      bodyB._body,
-      _convertPosToVec(anchor, physicsNode)
-    );
-    b2Def.maxForce = maxForce / physicsNode.b2WorldToNodeConversionFactor;
-    b2Def.maxTorque = maxTorque / physicsNode.b2WorldToNodeConversionFactor;
-    return physicsNode.b2World.createJoint(b2Def);
-  }
-}
-
-class PhysicsJointConstantVolume extends PhysicsJoint {
-  PhysicsJointConstantVolume(
-    this.bodies, {
-      double breakingForce,
-      PhysicsJointBreakCallback breakCallback,
-      this.dampening,
-      this.frequency
-    }
-  ) : super(null, null, breakingForce, breakCallback) {
-    assert(bodies.length > 2);
-    _bodyA = bodies[0];
-    _bodyB = bodies[1];
-    _completeCreation();
-  }
-
-  final List<PhysicsBody> bodies;
-  final double dampening;
-  final double frequency;
-
-  box2d.Joint _createB2Joint(PhysicsWorld physicsNode) {
-    box2d.ConstantVolumeJointDef b2Def = new box2d.ConstantVolumeJointDef();
-    for (PhysicsBody body in bodies) {
-      b2Def.addBody(body._body);
-    }
-    b2Def.dampingRatio = dampening;
-    b2Def.frequencyHz = frequency;
-    return physicsNode.b2World.createJoint(b2Def);
-  }
-}
-
-Vector2 _convertPosToVec(Point pt, PhysicsWorld physicsNode) {
-  return new Vector2(
-    pt.x / physicsNode.b2WorldToNodeConversionFactor,
-    pt.y / physicsNode.b2WorldToNodeConversionFactor
-  );
-}
diff --git a/skysprites/lib/src/physics_shape.dart b/skysprites/lib/src/physics_shape.dart
deleted file mode 100644
index 8f7eef9..0000000
--- a/skysprites/lib/src/physics_shape.dart
+++ /dev/null
@@ -1,184 +0,0 @@
-part of flutter_sprites;
-
-/// Defines the shape of a  [PhysicsBody].
-abstract class PhysicsShape {
-
-  box2d.Shape _b2Shape;
-
-  Object userObject;
-
-  box2d.Shape getB2Shape(PhysicsWorld node, double scale) {
-    if (_b2Shape == null) {
-      _b2Shape = _createB2Shape(node, scale);
-    }
-    return _b2Shape;
-  }
-
-  box2d.Shape _createB2Shape(PhysicsWorld node, double scale);
-
-  void _invalidate() {
-    _b2Shape = null;
-  }
-}
-
-/// Defines a circle shape with a given center [point] and [radius].
-///
-///     var shape = PhysicsShapeCircle(Point.origin, 20.0);
-class PhysicsShapeCircle extends PhysicsShape {
-  PhysicsShapeCircle(this.point, this.radius);
-
-  final Point point;
-  final double radius;
-
-  box2d.Shape _createB2Shape(PhysicsWorld node, double scale) {
-    box2d.CircleShape shape = new box2d.CircleShape();
-    shape.p.x = scale * point.x / node.b2WorldToNodeConversionFactor;
-    shape.p.y = scale * point.y / node.b2WorldToNodeConversionFactor;
-    shape.radius = scale * radius / node.b2WorldToNodeConversionFactor;
-    return shape;
-  }
-}
-
-/// Defines a polygon shape from a list of [points];
-///
-///     var points = [
-///       new Point(-10.0, 0.0),
-///       new Point(0.0, 10.0),
-///       new Point(10.0, 0.0)
-///     ];
-///     var shape = new PhysicsShapePolygon(points);
-class PhysicsShapePolygon extends PhysicsShape {
-  PhysicsShapePolygon(this.points);
-
-  final List<Point> points;
-
-  box2d.Shape _createB2Shape(PhysicsWorld node, double scale) {
-    List<Vector2> vectors = <Vector2>[];
-    for (Point point in points) {
-      Vector2 vec = new Vector2(
-        scale * point.x / node.b2WorldToNodeConversionFactor,
-        scale * point.y / node.b2WorldToNodeConversionFactor
-      );
-      vectors.add(vec);
-    }
-
-    box2d.PolygonShape shape = new box2d.PolygonShape();
-    shape.set(vectors, vectors.length);
-    return shape;
-  }
-}
-
-/// Defines a box shape from a [width] and [height].
-///
-/// var shape = new PhysicsShapeBox(50.0, 100.0);
-class PhysicsShapeBox extends PhysicsShape {
-  PhysicsShapeBox(
-    this.width,
-    this.height, [
-      this.center = Point.origin,
-      this.rotation = 0.0
-  ]);
-
-  final double width;
-  final double height;
-  final Point center;
-  final double rotation;
-
-  box2d.Shape _createB2Shape(PhysicsWorld node, double scale) {
-    box2d.PolygonShape shape = new box2d.PolygonShape();
-    shape.setAsBox(
-      scale * width / node.b2WorldToNodeConversionFactor,
-      scale * height / node.b2WorldToNodeConversionFactor,
-      new Vector2(
-        scale * center.x / node.b2WorldToNodeConversionFactor,
-        scale * center.y / node.b2WorldToNodeConversionFactor
-      ),
-      radians(rotation)
-    );
-    return shape;
-  }
-}
-
-/// Defines a chain shape from a set of [points]. This can be used to create
-/// a continuous chain of edges or, if [loop] is set to true, concave polygons.
-///
-///     var points = [
-///       new Point(-10.0, 0.0),
-///       new Point(0.0, 10.0),
-///       new Point(10.0, 0.0)
-///     ];
-///     var shape = new PhysicsShapeChain(points);
-class PhysicsShapeChain extends PhysicsShape {
-  PhysicsShapeChain(this.points, [this.loop=false]);
-
-  final List<Point> points;
-  final bool loop;
-
-  box2d.Shape _createB2Shape(PhysicsWorld node, double scale) {
-    List<Vector2> vectors = <Vector2>[];
-    for (Point point in points) {
-      Vector2 vec = new Vector2(
-        scale * point.x / node.b2WorldToNodeConversionFactor,
-        scale * point.y / node.b2WorldToNodeConversionFactor
-      );
-      vectors.add(vec);
-    }
-
-    box2d.ChainShape shape = new box2d.ChainShape();
-    if (loop)
-      shape.createLoop(vectors, vectors.length);
-    else
-      shape.createChain(vectors, vectors.length);
-    return shape;
-  }
-}
-
-/// Defines a single edge line shape from [pointA] to [pointB].
-///
-///     var shape = new PhysicsShapeEdge(
-///       new Point(20.0, 20.0),
-///       new Point(50.0, 20.0)
-///     );
-class PhysicsShapeEdge extends PhysicsShape {
-  PhysicsShapeEdge(this.pointA, this.pointB);
-
-  final Point pointA;
-  final Point pointB;
-
-  box2d.Shape _createB2Shape(PhysicsWorld node, double scale) {
-    box2d.EdgeShape shape = new box2d.EdgeShape();
-    shape.set(
-      new Vector2(
-        scale * pointA.x / node.b2WorldToNodeConversionFactor,
-        scale * pointA.y / node.b2WorldToNodeConversionFactor
-      ),
-      new Vector2(
-        scale * pointB.x / node.b2WorldToNodeConversionFactor,
-        scale * pointB.y / node.b2WorldToNodeConversionFactor
-      )
-    );
-    return shape;
-  }
-}
-
-/// A group combines several [shapes] into a single shape.
-///
-///     var s0 = new PhysicsShapeCircle(new Point(-10.0, 0.0), 20.0);
-///     var s1 = new PhysicsShapeCircle(new Point(10.0, 0.0), 20.0);
-///     var shape = new PhysicsShapeGroup([s0, s1]);
-class PhysicsShapeGroup extends PhysicsShape {
-
-  PhysicsShapeGroup(this.shapes);
-
-  final List<PhysicsShape> shapes;
-
-  box2d.Shape _createB2Shape(PhysicsWorld node, double scale) {
-    return null;
-  }
-
-  void _invalidate() {
-    for (PhysicsShape shape in shapes) {
-      shape._invalidate();
-    }
-  }
-}
diff --git a/skysprites/lib/src/physics_world.dart b/skysprites/lib/src/physics_world.dart
deleted file mode 100644
index 5e7ba72..0000000
--- a/skysprites/lib/src/physics_world.dart
+++ /dev/null
@@ -1,440 +0,0 @@
-part of flutter_sprites;
-
-enum PhysicsContactType {
-  preSolve,
-  postSolve,
-  begin,
-  end
-}
-
-typedef void PhysicsContactCallback(PhysicsContactType type, PhysicsContact contact);
-
-/// A [Node] that performs a 2D physics simulation on any children with a
-/// [PhysicsBody] attached. To simulate grand children, they need to be placed
-/// in a [PhysicsGroup].
-///
-/// The PhysicsWorld uses Box2D.dart to perform the actual simulation, but
-/// wraps its behavior in a way that is more integrated with the sprite node
-/// tree. If needed, you can still access the Box2D world through the [b2World]
-/// property.
-class PhysicsWorld extends Node {
-  PhysicsWorld(Offset gravity) {
-    b2World = new box2d.World.withGravity(
-      new Vector2(
-        gravity.dx / b2WorldToNodeConversionFactor,
-        gravity.dy / b2WorldToNodeConversionFactor));
-    _init();
-  }
-
-  PhysicsWorld.fromB2World(this.b2World, this.b2WorldToNodeConversionFactor) {
-    _init();
-  }
-
-  void _init() {
-    _contactHandler = new _ContactHandler(this);
-    b2World.setContactListener(_contactHandler);
-
-    box2d.ViewportTransform transform = new box2d.ViewportTransform(
-      new Vector2.zero(),
-      new Vector2.zero(),
-      1.0
-    );
-    _debugDraw = new _PhysicsDebugDraw(transform, this);
-    b2World.debugDraw = _debugDraw;
-  }
-
-  /// The Box2D world used to perform the physics simulations.
-  box2d.World b2World;
-
-  _ContactHandler _contactHandler;
-
-  _PhysicsCollisionGroups _collisionGroups = new _PhysicsCollisionGroups();
-
-  List<PhysicsJoint> _joints = <PhysicsJoint>[];
-
-  List<box2d.Body> _bodiesScheduledForDestruction = <box2d.Body>[];
-
-  List<PhysicsBody> _bodiesScheduledForUpdate = <PhysicsBody>[];
-
-  /// If set to true, a debug image of all physics shapes and joints will
-  /// be drawn on top of the [SpriteBox].
-  bool drawDebug = false;
-
-  Matrix4 _debugDrawTransform ;
-
-  _PhysicsDebugDraw _debugDraw;
-
-  /// The conversion factor that is used to convert points in the physics world
-  /// node to points in the Box2D physics simulation.
-  double b2WorldToNodeConversionFactor = 10.0;
-
-  /// The gravity vector used in the simulation.
-  Offset get gravity {
-    Vector2 g = b2World.getGravity();
-    return new Offset(g.x, g.y);
-  }
-
-  set gravity(Offset gravity) {
-    // Convert from points/s^2 to m/s^2
-    b2World.setGravity(new Vector2(gravity.dx / b2WorldToNodeConversionFactor,
-      gravity.dy / b2WorldToNodeConversionFactor));
-  }
-
-  /// If set to true, objects can fall asleep if the haven't moved in a while.
-  bool get allowSleep => b2World.isAllowSleep();
-
-  set allowSleep(bool allowSleep) {
-    b2World.setAllowSleep(allowSleep);
-  }
-
-  /// True if sub stepping should be used in the simulation.
-  bool get subStepping => b2World.isSubStepping();
-
-  set subStepping(bool subStepping) {
-    b2World.setSubStepping(subStepping);
-  }
-
-  void _stepPhysics(double dt) {
-    // Update transformations of bodies whose groups have moved
-    for (PhysicsBody body in _bodiesScheduledForUpdate) {
-      Node node = body._node;
-      node._updatePhysicsPosition(body, node.position, node.parent);
-      node._updatePhysicsRotation(body, node.rotation, node.parent);
-    }
-    _bodiesScheduledForUpdate.clear();
-
-    // Remove bodies that were marked for destruction during the update phase
-    _removeBodiesScheduledForDestruction();
-
-    // Assign velocities and momentum to static and kinetic bodies
-    for (box2d.Body b2Body = b2World.bodyList; b2Body != null; b2Body = b2Body.getNext()) {
-      // Fetch body
-      PhysicsBody body = b2Body.userData;
-
-      // Skip all dynamic bodies
-      if (b2Body.getType() == box2d.BodyType.DYNAMIC) {
-        body._lastPosition = null;
-        body._lastRotation = null;
-        continue;
-      }
-
-      // Update linear velocity
-      if (body._lastPosition == null || body._targetPosition == null) {
-        b2Body.linearVelocity.setZero();
-      } else {
-        Vector2 velocity = (body._targetPosition - body._lastPosition) / dt;
-        b2Body.linearVelocity = velocity;
-        body._lastPosition = null;
-      }
-
-      // Update angular velocity
-      if (body._lastRotation == null || body._targetAngle == null) {
-        b2Body.angularVelocity = 0.0;
-      } else {
-        double angularVelocity = (body._targetAngle - body._lastRotation) / dt;
-        b2Body.angularVelocity = angularVelocity;
-        body._lastRotation = 0.0;
-      }
-    }
-
-    // Calculate a step in the simulation
-    b2World.stepDt(dt, 10, 10);
-
-    // Iterate over the bodies
-    for (box2d.Body b2Body = b2World.bodyList; b2Body != null; b2Body = b2Body.getNext()) {
-      // Update visual position and rotation
-      PhysicsBody body = b2Body.userData;
-
-      if (b2Body.getType() == box2d.BodyType.KINEMATIC) {
-        body._targetPosition = null;
-        body._targetAngle = null;
-      }
-
-      // Update visual position and rotation
-      if (body.type == PhysicsBodyType.dynamic) {
-        body._node._setPositionFromPhysics(
-          new Point(
-            b2Body.position.x * b2WorldToNodeConversionFactor,
-            b2Body.position.y * b2WorldToNodeConversionFactor
-          ),
-          body._node.parent
-        );
-
-        body._node._setRotationFromPhysics(
-          degrees(b2Body.getAngle()),
-          body._node.parent
-        );
-      }
-    }
-
-    // Break joints
-    for (PhysicsJoint joint in _joints) {
-      joint._checkBreakingForce(dt);
-    }
-
-    // Remove bodies that were marked for destruction during the simulation
-    _removeBodiesScheduledForDestruction();
-  }
-
-  void _removeBodiesScheduledForDestruction() {
-    for (box2d.Body b2Body in _bodiesScheduledForDestruction) {
-      // Destroy any joints before destroying the body
-      PhysicsBody body = b2Body.userData;
-      for (PhysicsJoint joint in body._joints) {
-        joint._detach();
-      }
-
-      // Destroy the body
-      b2World.destroyBody(b2Body);
-    }
-    _bodiesScheduledForDestruction.clear();
-  }
-
-  void _updatePosition(PhysicsBody body, Point position) {
-    if (body._lastPosition == null && body.type == PhysicsBodyType.static) {
-      body._lastPosition = new Vector2.copy(body._body.position);
-      body._body.setType(box2d.BodyType.KINEMATIC);
-    }
-
-    Vector2 newPos = new Vector2(
-      position.x / b2WorldToNodeConversionFactor,
-      position.y / b2WorldToNodeConversionFactor
-    );
-    double angle = body._body.getAngle();
-
-    if (body.type == PhysicsBodyType.dynamic) {
-      body._body.setTransform(newPos, angle);
-    } else {
-      body._targetPosition = newPos;
-      body._targetAngle = angle;
-    }
-    body._body.setAwake(true);
-  }
-
-  void _updateRotation(PhysicsBody body, double rotation) {
-    if (body._lastRotation == null)
-      body._lastRotation = body._body.getAngle();
-
-    Vector2 pos = body._body.position;
-    double newAngle = radians(rotation);
-    body._body.setTransform(pos, newAngle);
-    body._body.setAwake(true);
-  }
-
-  void _updateScale(PhysicsBody body, double scale) {
-    body._scale = scale;
-
-    if (body._attached) {
-      body._updateScale(this);
-    }
-  }
-
-  void addChild(Node node) {
-    super.addChild(node);
-    if (node.physicsBody != null) {
-      node.physicsBody._attach(this, node);
-    }
-  }
-
-  void removeChild(Node node) {
-    super.removeChild(node);
-    if (node.physicsBody != null) {
-      node.physicsBody._detach();
-    }
-  }
-
-  /// Adds a contact callback, the callback will be invoked when bodies collide
-  /// in the world.
-  ///
-  /// To match specific sets bodies, use the [tagA] and [tagB]
-  /// which will be matched to the tag property that is set on the
-  /// [PhysicsBody]. If [tagA] or [tagB] is set to null, it will match any
-  /// body.
-  ///
-  /// By default, callbacks are made at four different times during a
-  /// collision; preSolve, postSolve, begin, and end. If you are only interested
-  /// in one of these events you can pass in a [type].
-  ///
-  ///     myWorld.addContactCallback(
-  ///       (PhysicsContactType type, PhysicsContact contact) {
-  ///         print("Collision between ship and asteroid");
-  ///       },
-  ///       "Ship",
-  ///       "Asteroid",
-  ///       PhysicsContactType.begin
-  ///     );
-  void addContactCallback(PhysicsContactCallback callback, Object tagA, Object tagB, [PhysicsContactType type]) {
-    _contactHandler.addContactCallback(callback, tagA, tagB, type);
-  }
-
-  void paint(PaintingCanvas canvas) {
-    if (drawDebug) {
-      _debugDrawTransform = new Matrix4.fromFloat64List(canvas.getTotalMatrix());
-    }
-    super.paint(canvas);
-  }
-
-  /// Draws the debug data of the physics world, normally this method isn't
-  /// invoked directly. Instead, set the [drawDebug] property to true.
-  void paintDebug(PaintingCanvas canvas) {
-    _debugDraw.canvas = canvas;
-    b2World.drawDebugData();
-  }
-}
-
-/// Contains information about a physics collision and is normally passed back
-/// in callbacks from the [PhysicsWorld].
-///
-///     void myCallback(PhysicsContactType type, PhysicsContact contact) {
-///       if (contact.isTouching)
-///         print("Bodies are touching");
-///     }
-class PhysicsContact {
-  PhysicsContact(
-    this.nodeA,
-    this.nodeB,
-    this.shapeA,
-    this.shapeB,
-    this.isTouching,
-    this.isEnabled,
-    this.touchingPoints,
-    this.touchingNormal
-  );
-
-  /// The first node as matched in the rules set when adding the callback.
-  final Node nodeA;
-
-  /// The second node as matched in the rules set when adding the callback.
-  final Node nodeB;
-
-  /// The first shape as matched in the rules set when adding the callback.
-  final PhysicsShape shapeA;
-
-  /// The second shape as matched in the rules set when adding the callback.
-  final PhysicsShape shapeB;
-
-  /// True if the two nodes are touching.
-  final isTouching;
-
-  /// To ignore the collision to take place, you can set isEnabled to false
-  /// during the preSolve phase.
-  bool isEnabled;
-
-  /// List of points that are touching, in world coordinates.
-  final List<Point> touchingPoints;
-
-  /// The normal from [shapeA] to [shapeB] at the touchingPoint.
-  final Offset touchingNormal;
-}
-
-class _ContactCallbackInfo {
-  _ContactCallbackInfo(this.callback, this.tagA, this.tagB, this.type);
-
-  PhysicsContactCallback callback;
-  Object tagA;
-  Object tagB;
-  PhysicsContactType type;
-}
-
-class _ContactHandler extends box2d.ContactListener {
-  _ContactHandler(this.physicsNode);
-
-  PhysicsWorld physicsNode;
-
-  List<_ContactCallbackInfo> callbackInfos = <_ContactCallbackInfo>[];
-
-  void addContactCallback(PhysicsContactCallback callback, Object tagA, Object tagB, PhysicsContactType type) {
-    callbackInfos.add(new _ContactCallbackInfo(callback, tagA, tagB, type));
-  }
-
-  void handleCallback(PhysicsContactType type, box2d.Contact b2Contact, box2d.Manifold oldManifold, box2d.ContactImpulse impulse) {
-    // Get info about the contact
-    PhysicsBody bodyA = b2Contact.fixtureA.getBody().userData;
-    PhysicsBody bodyB = b2Contact.fixtureB.getBody().userData;
-    box2d.Fixture fixtureA = b2Contact.fixtureA;
-    box2d.Fixture fixtureB = b2Contact.fixtureB;
-
-    // Match callback with added callbacks
-    for (_ContactCallbackInfo info in callbackInfos) {
-      // Check that type is matching
-      if (info.type != null && info.type != type)
-        continue;
-
-      // Check if there is a match
-      bool matchA = (info.tagA == null) || info.tagA == bodyA.tag;
-      bool matchB = (info.tagB == null) || info.tagB == bodyB.tag;
-
-      bool match = (matchA && matchB);
-      if (!match) {
-        // Check if there is a match if we swap a & b
-        bool matchA = (info.tagA == null) || info.tagA == bodyB.tag;
-        bool matchB = (info.tagB == null) || info.tagB == bodyA.tag;
-
-        match = (matchA && matchB);
-        if (match) {
-          // Swap a & b
-          PhysicsBody tempBody = bodyA;
-          bodyA = bodyB;
-          bodyB = tempBody;
-
-          box2d.Fixture tempFixture = fixtureA;
-          fixtureA = fixtureB;
-          fixtureB = tempFixture;
-        }
-      }
-
-      if (match) {
-        // We have contact and a matched callback, setup contact info
-        List<Point> touchingPoints = null;
-        Offset touchingNormal = null;
-
-        // Fetch touching points, if any
-        if (b2Contact.isTouching()) {
-          box2d.WorldManifold manifold = new box2d.WorldManifold();
-          b2Contact.getWorldManifold(manifold);
-          touchingNormal = new Offset(manifold.normal.x, manifold.normal.y);
-          touchingPoints = <Point>[];
-          for (Vector2 vec in manifold.points) {
-            touchingPoints.add(new Point(
-              vec.x * physicsNode.b2WorldToNodeConversionFactor,
-              vec.y * physicsNode.b2WorldToNodeConversionFactor
-            ));
-          }
-        }
-
-        // Create the contact
-        PhysicsContact contact = new PhysicsContact(
-          bodyA._node,
-          bodyB._node,
-          fixtureA.userData,
-          fixtureB.userData,
-          b2Contact.isTouching(),
-          b2Contact.isEnabled(),
-          touchingPoints,
-          touchingNormal
-        );
-
-        // Make callback
-        info.callback(type, contact);
-
-        // Update Box2D contact
-        b2Contact.setEnabled(contact.isEnabled);
-      }
-    }
-  }
-
-  void beginContact(box2d.Contact contact) {
-    handleCallback(PhysicsContactType.begin, contact, null, null);
-  }
-
-  void endContact(box2d.Contact contact) {
-    handleCallback(PhysicsContactType.end, contact, null, null);
-  }
-
-  void preSolve(box2d.Contact contact, box2d.Manifold oldManifold) {
-    handleCallback(PhysicsContactType.preSolve, contact, oldManifold, null);
-  }
-  void postSolve(box2d.Contact contact, box2d.ContactImpulse impulse) {
-    handleCallback(PhysicsContactType.postSolve, contact, null, impulse);
-  }
-}
diff --git a/skysprites/lib/src/sound.dart b/skysprites/lib/src/sound.dart
deleted file mode 100644
index aadf317..0000000
--- a/skysprites/lib/src/sound.dart
+++ /dev/null
@@ -1,209 +0,0 @@
-part of flutter_sprites;
-
-// TODO: The sound effects should probably use Android's SoundPool instead of
-// MediaPlayer as it is more efficient and flexible for playing back sound effects
-
-typedef void SoundEffectStreamCallback(SoundEffectStream);
-
-class SoundEffect {
-  SoundEffect(this._pipeFuture);
-
-  // TODO: Remove load method from SoundEffect
-  Future load() async {
-    _data = await _pipeFuture;
-  }
-
-  Future<MojoDataPipeConsumer> _pipeFuture;
-  MojoDataPipeConsumer _data;
-}
-
-class SoundEffectStream {
-  SoundEffectStream(
-    this.sound,
-    this.loop,
-    this.volume,
-    this.pitch,
-    this.pan,
-    this.onSoundComplete
-  );
-
-  // TODO: Make these properties work
-  SoundEffect sound;
-  bool playing = false;
-  bool loop = false;
-  double volume = 1.0;
-  double pitch = 1.0;
-  double pan = 0.0;
-
-  // TODO: Implement completion callback. On completion, sounds should
-  // also be removed from the list of playing sounds.
-  SoundEffectStreamCallback onSoundComplete;
-
-  MediaPlayerProxy _player;
-}
-
-SoundEffectPlayer _sharedSoundEffectPlayer;
-
-class SoundEffectPlayer {
-
-  static SoundEffectPlayer sharedInstance() {
-    if (_sharedSoundEffectPlayer == null) {
-      _sharedSoundEffectPlayer = new SoundEffectPlayer();
-    }
-    return _sharedSoundEffectPlayer;
-  }
-
-  SoundEffectPlayer() {
-    _mediaService = new MediaServiceProxy.unbound();
-    shell.connectToService(null, _mediaService);
-  }
-
-  MediaServiceProxy _mediaService;
-  List<SoundEffectStream> _soundEffectStreams = <SoundEffectStream>[];
-
-  // TODO: This should no longer be needed when moving to SoundPool backing
-  Map<SoundEffect,MediaPlayerProxy> _mediaPlayers = <SoundEffect, MediaPlayerProxy>{};
-
-  Future _prepare(SoundEffectStream playingSound) async {
-    await playingSound._player.ptr.prepare(playingSound.sound._data);
-  }
-
-  // TODO: Move sound loading here
-  // TODO: Support loading sounds from bundles
-  // Future<SoundEffect> load(url) async {
-  //   ...
-  // }
-
-  // TODO: Add sound unloader
-  // unload(SoundEffect effect) {
-  //   ...
-  // }
-
-  // TODO: Add paused property (should pause playback of all sounds)
-  bool paused;
-
-  SoundEffectStream play(
-    SoundEffect sound,
-    [bool loop = false,
-      double volume = 1.0,
-      double pitch = 1.0,
-      double pan = 0.0,
-      SoundEffectStreamCallback callback = null]) {
-
-    // Create new PlayingSound object
-    SoundEffectStream playingSound = new SoundEffectStream(
-      sound,
-      loop,
-      volume,
-      pitch,
-      pan,
-      callback
-    );
-
-    // TODO: Replace this with calls to SoundPool
-    if (_mediaPlayers[sound] == null) {
-      // Create player
-      playingSound._player = new MediaPlayerProxy.unbound();
-      _mediaService.ptr.createPlayer(playingSound._player);
-
-      // Prepare sound, then play it
-      _prepare(playingSound).then((_) {
-        playingSound._player.ptr.seekTo(0);
-        playingSound._player.ptr.start();
-      });
-
-      _soundEffectStreams.add(playingSound);
-      _mediaPlayers[sound] = playingSound._player;
-    } else {
-      // Reuse player
-      playingSound._player = _mediaPlayers[sound];
-      playingSound._player.ptr.seekTo(0);
-      playingSound._player.ptr.start();
-    }
-
-    return playingSound;
-  }
-
-  void stop(SoundEffectStream stream) {
-    stream._player.ptr.pause();
-    _soundEffectStreams.remove(stream);
-  }
-
-  void stopAll() {
-    for (SoundEffectStream playingSound in _soundEffectStreams) {
-      playingSound._player.ptr.pause();
-    }
-    _soundEffectStreams = <SoundEffectStream>[];
-  }
-}
-
-typedef void SoundTrackCallback(SoundTrack);
-typedef void SoundTrackBufferingCallback(SoundTrack, int);
-
-class SoundTrack {
-  MediaPlayerProxy _player;
-
-  SoundTrackCallback onSoundComplete;
-  SoundTrackCallback onSeekComplete;
-  SoundTrackBufferingCallback onBufferingUpdate;
-  bool loop;
-  double time;
-  double volume;
-}
-
-SoundTrackPlayer _sharedSoundTrackPlayer;
-
-class SoundTrackPlayer {
-  List<SoundTrack> _soundTracks = <SoundTrack>[];
-
-  static sharedInstance() {
-    if (_sharedSoundTrackPlayer == null) {
-      _sharedSoundTrackPlayer = new SoundTrackPlayer();
-    }
-    return _sharedSoundTrackPlayer;
-  }
-
-  SoundTrackPlayer() {
-    _mediaService = new MediaServiceProxy.unbound();
-    shell.connectToService(null, _mediaService);
-  }
-
-  MediaServiceProxy _mediaService;
-
-  Future<SoundTrack> load(Future<MojoDataPipeConsumer> pipe) async {
-    // Create media player
-    SoundTrack soundTrack = new SoundTrack();
-    soundTrack._player = new MediaPlayerProxy.unbound();
-    _mediaService.ptr.createPlayer(soundTrack._player);
-
-    await soundTrack._player.ptr.prepare(await pipe);
-    return soundTrack;
-  }
-
-  void unload(SoundTrack soundTrack) {
-    stop(soundTrack);
-    _soundTracks.remove(soundTrack);
-  }
-
-  void play(
-    SoundTrack soundTrack,
-    [bool loop = false,
-      double volume,
-      double startTime = 0.0]) {
-    // TODO: Implement looping & volume
-    // soundTrack._player.ptr.setLooping(loop);
-    // soundTrack._player.ptr.setVolume(volume);
-    soundTrack._player.ptr.seekTo((startTime * 1000.0).toInt());
-    soundTrack._player.ptr.start();
-  }
-
-  void stop(SoundTrack track) {
-    track._player.ptr.pause();
-  }
-
-  void stopAll() {
-    for (SoundTrack soundTrack in _soundTracks) {
-      soundTrack._player.ptr.pause();
-    }
-  }
-}
diff --git a/skysprites/lib/src/sound_manager.dart b/skysprites/lib/src/sound_manager.dart
deleted file mode 100644
index 3246cfa..0000000
--- a/skysprites/lib/src/sound_manager.dart
+++ /dev/null
@@ -1,236 +0,0 @@
-part of flutter_sprites;
-
-enum SoundFadeMode {
-  crossFade,
-  fadeOutThenPlay,
-  fadeOutThenFadeIn,
-}
-
-enum SoundEventSimultaneousPolicy {
-  dontPlay,
-  stopOldest,
-}
-
-enum SoundEventMinimumOverlapPolicy {
-  dontPlay,
-  delay,
-}
-
-class SoundEvent {
-  SoundEvent(SoundEffect effect) {
-    effects = <SoundEffect>[effect];
-  }
-
-  SoundEvent.withList(this.effects);
-
-  List<SoundEffect> effects;
-  double pitchVariance = 0.0;
-  double volumeVariance = 0.0;
-  double panVariance = 0.0;
-
-  SoundEventSimultaneousPolicy simultaneousLimitPolicy = SoundEventSimultaneousPolicy.stopOldest;
-  int simultaneousLimit = 0;
-
-  SoundEventMinimumOverlapPolicy minimumOverlapPolicy = SoundEventMinimumOverlapPolicy.dontPlay;
-  double minimumOverlap = 0.0;
-}
-
-class _PlayingSoundEvent {
-  SoundEvent event;
-  SoundEffectStream stream;
-  int startTime;
-}
-
-SoundManager _sharedSoundManager;
-
-class SoundManager {
-
-  static SoundManager sharedInstance() {
-    if (_sharedSoundManager == null) {
-      _sharedSoundManager = new SoundManager();
-    }
-    return _sharedSoundManager;
-  }
-
-  static void purgeSharedInstance() {
-    if (_sharedSoundManager == null) return;
-    _sharedSoundManager = null;
-  }
-
-  SoundManager() {
-    new Timer.periodic(new Duration(milliseconds:10), _update);
-  }
-
-  Map<SoundEvent, List<_PlayingSoundEvent>> _playingEvents = <SoundEvent, List<_PlayingSoundEvent>>{};
-  SoundTrack _backgroundMusicTrack;
-
-  SoundEffectPlayer _effectPlayer = SoundEffectPlayer.sharedInstance();
-  SoundTrackPlayer _trackPlayer = SoundTrackPlayer.sharedInstance();
-  ActionController actions = new ActionController();
-
-  bool enableBackgroundMusic;
-  bool enableSoundEffects;
-
-  int _lastTimeStamp;
-
-  void playEvent(SoundEvent evt, [double volume = 1.0, double pitch = 1.0, double pan = 0.0]) {
-    List<_PlayingSoundEvent> playingList = _playingEvents[evt];
-    if (playingList == null) playingList = <_PlayingSoundEvent>[];
-
-    // Check simultaneousLimit
-    if (evt.simultaneousLimit != 0 && evt.simultaneousLimit >= playingList.length) {
-      // We have too many sounds playing
-      if (evt.simultaneousLimitPolicy == SoundEventSimultaneousPolicy.dontPlay) {
-        // Skip this sound event
-        return;
-      } else {
-        // Stop the oldest sound
-        _effectPlayer.stop(playingList[0].stream);
-      }
-    }
-
-    // Check for overlap
-    int playTime = new DateTime.now().millisecondsSinceEpoch;
-
-    if (evt.minimumOverlap != 0.0 && playingList.length > 0) {
-      int overlap = playTime - playingList.last.startTime;
-      if (overlap.toDouble() / 1000.0 < evt.minimumOverlap) {
-        // Sounds are overlapping
-        if (evt.minimumOverlapPolicy == SoundEventMinimumOverlapPolicy.dontPlay) {
-          return;
-        } else {
-          // TODO: try to play the sound a little bit later
-          return;
-        }
-      }
-    }
-
-    // Create a new entry for the event
-    _PlayingSoundEvent newPlaying = new _PlayingSoundEvent();
-    newPlaying.startTime = playTime;
-    newPlaying.event = evt;
-
-    // Pick a sound effect to play
-    SoundEffect effect = evt.effects.elementAt(randomInt(evt.effects.length));
-
-    // Add the entry
-    playingList.add(newPlaying);
-
-    // Play the event
-    newPlaying.stream = _effectPlayer.play(
-      effect,
-      false,
-      (volume + evt.volumeVariance * randomSignedDouble()).clamp(0.0, 2.0),
-      (pitch + evt.pitchVariance * randomSignedDouble()).clamp(0.5, 2.0),
-      (pan + evt.panVariance * randomSignedDouble()).clamp(-1.0, 1.0),
-      (SoundEffectStream s) {
-        // Completion callback - remove the entry
-        playingList.remove(newPlaying);
-      }
-    );
-  }
-
-  void stopAllEvents([double fadeDuration]) {
-    for (List<_PlayingSoundEvent> playingList in _playingEvents.values) {
-      for (_PlayingSoundEvent playing in playingList) {
-        if (fadeDuration > 0.0) {
-          // Fade out and stop
-          ActionTween fadeOut = new ActionTween((a) => playing.stream.volume = a, playing.stream.volume, 0.0, fadeDuration);
-          ActionCallFunction stop = new ActionCallFunction(() { _effectPlayer.stop(playing.stream); });
-          ActionSequence seq = new ActionSequence(<Action>[fadeOut, stop]);
-          actions.run(seq);
-        }
-        else {
-          // Stop right away
-          _effectPlayer.stop(playing.stream);
-        }
-      }
-    }
-  }
-
-  void playBackgroundMusic(SoundTrack track, [double fadeDuration = 0.0, SoundFadeMode fadeMode = SoundFadeMode.fadeOutThenPlay]) {
-    double fadeInDuration = 0.0;
-    double fadeInDelay = 0.0;
-    double fadeOutDuration = 0.0;
-
-    // Calculate durations
-    if (fadeDuration > 0.0) {
-      if (fadeMode == SoundFadeMode.crossFade) {
-        fadeOutDuration = fadeDuration;
-        fadeInDuration = fadeDuration;
-      } else if (fadeMode == SoundFadeMode.fadeOutThenPlay) {
-        fadeOutDuration = fadeDuration;
-        fadeInDelay = fadeDuration;
-      } else if (fadeMode == SoundFadeMode.fadeOutThenFadeIn) {
-        fadeOutDuration = fadeDuration / 2.0;
-        fadeInDuration = fadeDuration / 2.0;
-        fadeInDelay = fadeDuration / 2.0;
-      }
-    }
-
-    if (_backgroundMusicTrack != null) {
-      // Stop the current track
-      if (fadeOutDuration == 0.0) {
-        _trackPlayer.stop(_backgroundMusicTrack);
-      } else {
-        ActionTween fadeOut = new ActionTween((a) => _backgroundMusicTrack.volume = a, _backgroundMusicTrack.volume, 0.0, fadeOutDuration);
-        ActionCallFunction stop = new ActionCallFunction(() { _trackPlayer.stop(_backgroundMusicTrack); });
-        ActionSequence seq = new ActionSequence(<Action>[fadeOut, stop]);
-        actions.run(seq);
-      }
-    } else {
-      fadeInDelay = 0.0;
-    }
-
-    // Fade in new sound
-    if (fadeInDelay == 0.0) {
-      _fadeInTrack(track, fadeInDuration);
-    } else {
-      ActionDelay delay = new ActionDelay(fadeInDelay);
-      ActionCallFunction fadeInCall = new ActionCallFunction(() {
-        _fadeInTrack(track, fadeInDuration);
-      });
-      ActionSequence seq = new ActionSequence(<Action>[delay, fadeInCall]);
-      actions.run(seq);
-    }
-  }
-
-  void _fadeInTrack(SoundTrack track, double duration) {
-    _backgroundMusicTrack = track;
-
-    if (duration == 0.0) {
-      _trackPlayer.play(track);
-    } else {
-      _trackPlayer.play(track, true, 0.0);
-      actions.run(new ActionTween((a) => track.volume = a, 0.0, 1.0, duration));
-    }
-  }
-
-  void stopBackgroundMusic([double fadeDuration = 0.0]) {
-    if (fadeDuration == 0.0) {
-      _trackPlayer.stop(_backgroundMusicTrack);
-    } else {
-      ActionTween fadeOut = new ActionTween(
-        (a) => _backgroundMusicTrack.volume = a,
-        _backgroundMusicTrack.volume, 0.0, fadeDuration);
-      ActionCallFunction stopCall = new ActionCallFunction(() {
-        _trackPlayer.stop(_backgroundMusicTrack);
-      });
-      ActionSequence seq = new ActionSequence(<Action>[fadeOut, stopCall]);
-      actions.run(seq);
-    }
-
-    _backgroundMusicTrack = null;
-  }
-
-  void _update(Timer timer) {
-    int delta = 0;
-    int timestamp = new DateTime.now().millisecondsSinceEpoch;
-    if (_lastTimeStamp != null) {
-      delta = timestamp - _lastTimeStamp;
-    }
-    _lastTimeStamp = timestamp;
-
-    actions.step(delta / 1000.0);
-  }
-}
diff --git a/skysprites/lib/src/sprite.dart b/skysprites/lib/src/sprite.dart
deleted file mode 100644
index 1bc818a..0000000
--- a/skysprites/lib/src/sprite.dart
+++ /dev/null
@@ -1,123 +0,0 @@
-part of flutter_sprites;
-
-/// A Sprite is a [Node] that renders a bitmap image to the screen.
-class Sprite extends NodeWithSize with SpritePaint {
-
-  /// The texture that the sprite will render to screen.
-  ///
-  /// If the texture is null, the sprite will be rendered as a red square
-  /// marking the bounds of the sprite.
-  ///
-  ///     mySprite.texture = myTexture;
-  Texture texture;
-
-  /// If true, constrains the proportions of the image by scaling it down, if its proportions doesn't match the [size].
-  ///
-  ///     mySprite.constrainProportions = true;
-  bool constrainProportions = false;
-
-  Paint _cachedPaint = new Paint()
-    ..filterQuality = ui.FilterQuality.low
-    ..isAntiAlias = false;
-
-  /// Creates a new sprite from the provided [texture].
-  ///
-  ///     var mySprite = new Sprite(myTexture)
-  Sprite([this.texture]) : super(Size.zero) {
-    if (texture != null) {
-      size = texture.size;
-      pivot = texture.pivot;
-    } else {
-      pivot = new Point(0.5, 0.5);
-    }
-  }
-
-  /// Creates a new sprite from the provided [image].
-  ///
-  /// var mySprite = new Sprite.fromImage(myImage);
-  Sprite.fromImage(ui.Image image) : super(Size.zero) {
-    assert(image != null);
-
-    texture = new Texture(image);
-    size = texture.size;
-
-    pivot = new Point(0.5, 0.5);
-  }
-
-  void paint(PaintingCanvas canvas) {
-    // Account for pivot point
-    applyTransformForPivot(canvas);
-
-    if (texture != null) {
-      double w = texture.size.width;
-      double h = texture.size.height;
-
-      if (w <= 0 || h <= 0) return;
-
-      double scaleX = size.width / w;
-      double scaleY = size.height / h;
-
-      if (constrainProportions) {
-        // Constrain proportions, using the smallest scale and by centering the image
-        if (scaleX < scaleY) {
-          canvas.translate(0.0, (size.height - scaleX * h) / 2.0);
-          scaleY = scaleX;
-        } else {
-          canvas.translate((size.width - scaleY * w) / 2.0, 0.0);
-          scaleX = scaleY;
-        }
-      }
-
-      canvas.scale(scaleX, scaleY);
-
-      // Setup paint object for opacity and transfer mode
-      _updatePaint(_cachedPaint);
-
-      // Do actual drawing of the sprite
-      texture.drawTexture(canvas, Point.origin, _cachedPaint);
-    } else {
-      // Paint a red square for missing texture
-      canvas.drawRect(new Rect.fromLTRB(0.0, 0.0, size.width, size.height),
-      new Paint()..color = new Color.fromARGB(255, 255, 0, 0));
-    }
-  }
-}
-
-abstract class SpritePaint {
-  double _opacity = 1.0;
-
-  /// The opacity of the sprite in the range 0.0 to 1.0.
-  ///
-  ///     mySprite.opacity = 0.5;
-  double get opacity => _opacity;
-
-  void set opacity(double opacity) {
-    assert(opacity != null);
-    assert(opacity >= 0.0 && opacity <= 1.0);
-    _opacity = opacity;
-  }
-
-  /// The color to draw on top of the sprite, null if no color overlay is used.
-  ///
-  ///     // Color the sprite red
-  ///     mySprite.colorOverlay = new Color(0x77ff0000);
-  Color colorOverlay;
-
-  /// The transfer mode used when drawing the sprite to screen.
-  ///
-  ///     // Add the colors of the sprite with the colors of the background
-  ///     mySprite.transferMode = TransferMode.plusMode;
-  ui.TransferMode transferMode;
-
-  void _updatePaint(Paint paint) {
-    paint.color = new Color.fromARGB((255.0*_opacity).toInt(), 255, 255, 255);
-
-    if (colorOverlay != null) {
-      paint.colorFilter = new ColorFilter.mode(colorOverlay, ui.TransferMode.srcATop);
-    }
-
-    if (transferMode != null) {
-      paint.transferMode = transferMode;
-    }
-  }
-}
diff --git a/skysprites/lib/src/sprite_box.dart b/skysprites/lib/src/sprite_box.dart
deleted file mode 100644
index 8817629..0000000
--- a/skysprites/lib/src/sprite_box.dart
+++ /dev/null
@@ -1,553 +0,0 @@
-part of flutter_sprites;
-
-/// Options for setting up a [SpriteBox].
-///
-///  * [nativePoints], use the same points as the parent [Widget].
-///  * [letterbox], use the size of the root node for the coordinate system, constrain the aspect ratio and trim off
-///  areas that end up outside the screen.
-///  * [stretch], use the size of the root node for the coordinate system, scale it to fit the size of the box.
-///  * [scaleToFit], similar to the letterbox option, but instead of trimming areas the sprite system will be scaled
-///  down to fit the box.
-///  * [fixedWidth], uses the width of the root node to set the size of the coordinate system, this option will change
-///  the height of the root node to fit the box.
-///  * [fixedHeight], uses the height of the root node to set the size of the coordinate system, this option will change
-///  the width of the root node to fit the box.
-enum SpriteBoxTransformMode {
-  nativePoints,
-  letterbox,
-  stretch,
-  scaleToFit,
-  fixedWidth,
-  fixedHeight,
-}
-
-class SpriteBox extends RenderBox {
-
-  // Member variables
-
-  // Root node for drawing
-  NodeWithSize _rootNode;
-
-  void set rootNode (NodeWithSize value) {
-    if (value == _rootNode) return;
-
-    // Ensure that the root node has a size
-    assert(_transformMode == SpriteBoxTransformMode.nativePoints
-      || value.size.width > 0);
-    assert(_transformMode == SpriteBoxTransformMode.nativePoints
-      || value.size.height > 0);
-
-    // Remove sprite box references
-    if (_rootNode != null) _removeSpriteBoxReference(_rootNode);
-
-    // Update the value
-    _rootNode = value;
-
-    // Add new references
-    _addSpriteBoxReference(_rootNode);
-    markNeedsLayout();
-  }
-
-  // Tracking of frame rate and updates
-  Duration _lastTimeStamp;
-  double _frameRate = 0.0;
-
-  double get frameRate => _frameRate;
-
-  // Transformation mode
-  SpriteBoxTransformMode _transformMode;
-
-  void set transformMode (SpriteBoxTransformMode value) {
-    if (value == _transformMode)
-      return;
-    _transformMode = value;
-
-    // Invalidate stuff
-    markNeedsLayout();
-  }
-
-  /// The transform mode used by the [SpriteBox].
-  SpriteBoxTransformMode get transformMode => _transformMode;
-
-  // Cached transformation matrix
-  Matrix4 _transformMatrix;
-
-  List<Node> _eventTargets;
-
-  List<ActionController> _actionControllers;
-
-  List<Node> _constrainedNodes;
-
-  List<PhysicsWorld> _physicsNodes;
-
-  Rect _visibleArea;
-
-  Rect get visibleArea {
-    if (_visibleArea == null)
-      _calcTransformMatrix();
-    return _visibleArea;
-  }
-
-  bool _initialized = false;
-
-  // Setup
-
-  /// Creates a new SpriteBox with a node as its content, by default uses letterboxing.
-  ///
-  /// The [rootNode] provides the content of the node tree, typically it's a custom subclass of [NodeWithSize]. The
-  /// [mode] provides different ways to scale the content to best fit it to the screen. In most cases it's preferred to
-  /// use a [SpriteWidget] that automatically wraps the SpriteBox.
-  ///
-  ///     var spriteBox = new SpriteBox(myNode, SpriteBoxTransformMode.fixedHeight);
-  SpriteBox(NodeWithSize rootNode, [SpriteBoxTransformMode mode = SpriteBoxTransformMode.letterbox]) {
-    assert(rootNode != null);
-    assert(rootNode._spriteBox == null);
-
-    // Setup transform mode
-    this.transformMode = mode;
-
-    // Setup root node
-    this.rootNode = rootNode;
-  }
-
-  void _removeSpriteBoxReference(Node node) {
-    node._spriteBox = null;
-    for (Node child in node._children) {
-      _removeSpriteBoxReference(child);
-    }
-  }
-
-  void _addSpriteBoxReference(Node node) {
-    node._spriteBox = this;
-    for (Node child in node._children) {
-      _addSpriteBoxReference(child);
-    }
-  }
-
-  void attach() {
-    super.attach();
-    _scheduleTick();
-  }
-
-  // Properties
-
-  /// The root node of the node tree that is rendered by this box.
-  ///
-  ///     var rootNode = mySpriteBox.rootNode;
-  NodeWithSize get rootNode => _rootNode;
-
-  void performLayout() {
-    size = constraints.biggest;
-    _invalidateTransformMatrix();
-    _callSpriteBoxPerformedLayout(_rootNode);
-    _initialized = true;
-  }
-
-  // Adding and removing nodes
-
-  void _registerNode(Node node) {
-    _actionControllers = null;
-    _eventTargets = null;
-    _physicsNodes = null;
-    if (node == null || node.constraints != null) _constrainedNodes = null;
-  }
-
-  void _deregisterNode(Node node) {
-    _actionControllers = null;
-    _eventTargets = null;
-    _physicsNodes = null;
-    if (node == null || node.constraints != null) _constrainedNodes = null;
-  }
-
-  // Event handling
-
-  void _addEventTargets(Node node, List<Node> eventTargets) {
-    List children = node.children;
-    int i = 0;
-
-    // Add childrens that are behind this node
-    while (i < children.length) {
-      Node child = children[i];
-      if (child.zPosition >= 0.0)
-        break;
-      _addEventTargets(child, eventTargets);
-      i++;
-    }
-
-    // Add this node
-    if (node.userInteractionEnabled) {
-      eventTargets.add(node);
-    }
-
-    // Add children in front of this node
-    while (i < children.length) {
-      Node child = children[i];
-      _addEventTargets(child, eventTargets);
-      i++;
-    }
-  }
-
-  void handleEvent(InputEvent event, _SpriteBoxHitTestEntry entry) {
-    if (!attached)
-      return;
-
-    if (event is PointerInputEvent) {
-
-      if (event.type == 'pointerdown') {
-        // Build list of event targets
-        if (_eventTargets == null) {
-          _eventTargets = <Node>[];
-          _addEventTargets(_rootNode, _eventTargets);
-        }
-
-        // Find the once that are hit by the pointer
-        List<Node> nodeTargets = <Node>[];
-        for (int i = _eventTargets.length - 1; i >= 0; i--) {
-          Node node = _eventTargets[i];
-
-          // Check if the node is ready to handle a pointer
-          if (node.handleMultiplePointers || node._handlingPointer == null) {
-            // Do the hit test
-            Point posInNodeSpace = node.convertPointToNodeSpace(entry.localPosition);
-            if (node.isPointInside(posInNodeSpace)) {
-              nodeTargets.add(node);
-              node._handlingPointer = event.pointer;
-            }
-          }
-        }
-
-        entry.nodeTargets = nodeTargets;
-      }
-
-      // Pass the event down to nodes that were hit by the pointerdown
-      List<Node> targets = entry.nodeTargets;
-      for (Node node in targets) {
-        // Check if this event should be dispatched
-        if (node.handleMultiplePointers || event.pointer == node._handlingPointer) {
-          // Dispatch event
-          bool consumedEvent = node.handleEvent(new SpriteBoxEvent(new Point(event.x, event.y), event.type, event.pointer));
-          if (consumedEvent == null || consumedEvent)
-            break;
-        }
-      }
-
-      // De-register pointer for nodes that doesn't handle multiple pointers
-      for (Node node in targets) {
-        if (event.type == 'pointerup' || event.type == 'pointercancel') {
-          node._handlingPointer = null;
-        }
-      }
-    }
-  }
-
-  bool hitTest(HitTestResult result, { Point position }) {
-    result.add(new _SpriteBoxHitTestEntry(this, position));
-    return true;
-  }
-
-  // Rendering
-
-  /// The transformation matrix used to transform the root node to the space of the box.
-  ///
-  /// It's uncommon to need access to this property.
-  ///
-  ///     var matrix = mySpriteBox.transformMatrix;
-  Matrix4 get transformMatrix {
-    // Get cached matrix if available
-    if (_transformMatrix == null) {
-      _calcTransformMatrix();
-    }
-    return _transformMatrix;
-  }
-
-  void _calcTransformMatrix() {
-    _transformMatrix = new Matrix4.identity();
-
-    // Calculate matrix
-    double scaleX = 1.0;
-    double scaleY = 1.0;
-    double offsetX = 0.0;
-    double offsetY = 0.0;
-
-    double systemWidth = rootNode.size.width;
-    double systemHeight = rootNode.size.height;
-
-    switch(_transformMode) {
-      case SpriteBoxTransformMode.stretch:
-        scaleX = size.width/systemWidth;
-        scaleY = size.height/systemHeight;
-        break;
-      case SpriteBoxTransformMode.letterbox:
-        scaleX = size.width/systemWidth;
-        scaleY = size.height/systemHeight;
-        if (scaleX > scaleY) {
-          scaleY = scaleX;
-          offsetY = (size.height - scaleY * systemHeight)/2.0;
-        } else {
-          scaleX = scaleY;
-          offsetX = (size.width - scaleX * systemWidth)/2.0;
-        }
-        break;
-      case SpriteBoxTransformMode.scaleToFit:
-        scaleX = size.width/systemWidth;
-        scaleY = size.height/systemHeight;
-        if (scaleX < scaleY) {
-          scaleY = scaleX;
-          offsetY = (size.height - scaleY * systemHeight)/2.0;
-        } else {
-          scaleX = scaleY;
-          offsetX = (size.width - scaleX * systemWidth)/2.0;
-        }
-        break;
-      case SpriteBoxTransformMode.fixedWidth:
-        scaleX = size.width/systemWidth;
-        scaleY = scaleX;
-        systemHeight = size.height/scaleX;
-        rootNode.size = new Size(systemWidth, systemHeight);
-        break;
-      case SpriteBoxTransformMode.fixedHeight:
-        scaleY = size.height/systemHeight;
-        scaleX = scaleY;
-        systemWidth = size.width/scaleY;
-        rootNode.size = new Size(systemWidth, systemHeight);
-        break;
-      case SpriteBoxTransformMode.nativePoints:
-        systemWidth = size.width;
-        systemHeight = size.height;
-        break;
-      default:
-        assert(false);
-        break;
-    }
-
-    _visibleArea = new Rect.fromLTRB(-offsetX / scaleX,
-                                     -offsetY / scaleY,
-                                     systemWidth + offsetX / scaleX,
-                                     systemHeight + offsetY / scaleY);
-
-    _transformMatrix.translate(offsetX, offsetY);
-    _transformMatrix.scale(scaleX, scaleY);
-  }
-
-  void _invalidateTransformMatrix() {
-    _visibleArea = null;
-    _transformMatrix = null;
-    _rootNode._invalidateToBoxTransformMatrix();
-  }
-
-  void paint(PaintingContext context, Offset offset) {
-    final PaintingCanvas canvas = context.canvas;
-    canvas.save();
-
-    // Move to correct coordinate space before drawing
-    canvas.translate(offset.dx, offset.dy);
-    canvas.concat(transformMatrix.storage);
-
-    // Draw the sprite tree
-    Matrix4 totalMatrix = new Matrix4.fromFloat64List(canvas.getTotalMatrix());
-    _rootNode._visit(canvas, totalMatrix);
-
-    // Draw physics debug
-    for (PhysicsWorld world in _physicsNodes) {
-      if (world.drawDebug) {
-        canvas.setMatrix(world._debugDrawTransform.storage);
-        world.paintDebug(canvas);
-      }
-    }
-
-    canvas.restore();
-  }
-
-  // Updates
-
-  void _scheduleTick() {
-    scheduler.requestAnimationFrame(_tick);
-  }
-
-  void _tick(Duration timeStamp) {
-    if (!attached)
-      return;
-
-    // Calculate delta and frame rate
-    if (_lastTimeStamp == null)
-      _lastTimeStamp = timeStamp;
-    double delta = (timeStamp - _lastTimeStamp).inMicroseconds.toDouble() / Duration.MICROSECONDS_PER_SECOND;
-    _lastTimeStamp = timeStamp;
-
-    _frameRate = 1.0/delta;
-
-    if (_initialized) {
-      _callConstraintsPreUpdate(delta);
-      _runActions(delta);
-      _callUpdate(_rootNode, delta);
-      _callStepPhysics(delta);
-      _callConstraintsConstrain(delta);
-    }
-
-    // Schedule next update
-    _scheduleTick();
-
-    // Make sure the node graph is redrawn
-    markNeedsPaint();
-  }
-
-  void _runActions(double dt) {
-    if (_actionControllers == null) {
-      _rebuildActionControllersAndPhysicsNodes();
-    }
-    for (ActionController actions in _actionControllers) {
-      actions.step(dt);
-    }
-  }
-
-  void _rebuildActionControllersAndPhysicsNodes() {
-    _actionControllers = <ActionController>[];
-    _physicsNodes = <PhysicsWorld>[];
-    _addActionControllersAndPhysicsNodes(_rootNode);
-  }
-
-  void _addActionControllersAndPhysicsNodes(Node node) {
-    if (node._actions != null) _actionControllers.add(node._actions);
-    if (node is PhysicsWorld) _physicsNodes.add(node);
-
-    for (int i = node.children.length - 1; i >= 0; i--) {
-      Node child = node.children[i];
-      _addActionControllersAndPhysicsNodes(child);
-    }
-  }
-
-  void _callUpdate(Node node, double dt) {
-    node.update(dt);
-    for (int i = node.children.length - 1; i >= 0; i--) {
-      Node child = node.children[i];
-      if (!child.paused) {
-        _callUpdate(child, dt);
-      }
-    }
-  }
-
-  void _callStepPhysics(double dt) {
-    if (_physicsNodes == null)
-      _rebuildActionControllersAndPhysicsNodes();
-
-    for (PhysicsWorld physicsNode in _physicsNodes) {
-      physicsNode._stepPhysics(dt);
-    }
-  }
-
-  void _callConstraintsPreUpdate(double dt) {
-    if (_constrainedNodes == null) {
-      _constrainedNodes = <Node>[];
-      _addConstrainedNodes(_rootNode, _constrainedNodes);
-    }
-
-    for (Node node in _constrainedNodes) {
-      for (Constraint constraint in node.constraints) {
-        constraint.preUpdate(node, dt);
-      }
-    }
-  }
-
-  void _callConstraintsConstrain(double dt) {
-    if (_constrainedNodes == null) {
-      _constrainedNodes = <Node>[];
-      _addConstrainedNodes(_rootNode, _constrainedNodes);
-    }
-
-    for (Node node in _constrainedNodes) {
-      for (Constraint constraint in node.constraints) {
-        constraint.constrain(node, dt);
-      }
-    }
-  }
-
-  void _addConstrainedNodes(Node node, List<Node> nodes) {
-    if (node._constraints != null && node._constraints.length > 0) {
-      nodes.add(node);
-    }
-
-    for (Node child in node.children) {
-      _addConstrainedNodes(child, nodes);
-    }
-  }
-
-  void _callSpriteBoxPerformedLayout(Node node) {
-    node.spriteBoxPerformedLayout();
-    for (Node child in node.children) {
-      _callSpriteBoxPerformedLayout(child);
-    }
-  }
-
-  // Hit tests
-
-  /// Finds all nodes at a position defined in the box's coordinates.
-  ///
-  /// Use this method with caution. It searches the complete node tree to locate the nodes, which can be slow if the
-  /// node tree is large.
-  ///
-  ///     List nodes = mySpriteBox.findNodesAtPosition(new Point(50.0, 50.0));
-  List<Node> findNodesAtPosition(Point position) {
-    assert(position != null);
-
-    List<Node> nodes = <Node>[];
-
-    // Traverse the render tree and find objects at the position
-    _addNodesAtPosition(_rootNode, position, nodes);
-
-    return nodes;
-  }
-
-  _addNodesAtPosition(Node node, Point position, List<Node> list) {
-    // Visit children first
-    for (Node child in node.children) {
-      _addNodesAtPosition(child, position, list);
-    }
-    // Do the hit test
-    Point posInNodeSpace = node.convertPointToNodeSpace(position);
-    if (node.isPointInside(posInNodeSpace)) {
-      list.add(node);
-    }
-  }
-}
-
-class _SpriteBoxHitTestEntry extends BoxHitTestEntry {
-  List<Node> nodeTargets;
-  _SpriteBoxHitTestEntry(RenderBox target, Point localPosition) : super(target, localPosition);
-}
-
-/// An event that is passed down the node tree when pointer events occur. The SpriteBoxEvent is typically handled in
-/// the handleEvent method of [Node].
-class SpriteBoxEvent {
-
-  /// The position of the event in box coordinates.
-  ///
-  /// You can use the convertPointToNodeSpace of [Node] to convert the position to local coordinates.
-  ///
-  ///     bool handleEvent(SpriteBoxEvent event) {
-  ///       Point localPosition = convertPointToNodeSpace(event.boxPosition);
-  ///       if (event.type == 'pointerdown') {
-  ///         // Do something!
-  ///       }
-  ///     }
-  final Point boxPosition;
-
-  /// The type of event, there are currently four valid types, 'pointerdown', 'pointermoved', 'pointerup', and
-  /// 'pointercancel'.
-  ///
-  ///     if (event.type == 'pointerdown') {
-  ///       // Do something!
-  ///     }
-  final String type;
-
-  /// The id of the pointer. Each pointer on the screen will have a unique pointer id.
-  ///
-  ///     if (event.pointer == firstPointerId) {
-  ///       // Do something
-  ///     }
-  final int pointer;
-
-  /// Creates a new SpriteBoxEvent, typically this is done internally inside the SpriteBox.
-  ///
-  ///     var event = new SpriteBoxEvent(new Point(50.0, 50.0), 'pointerdown', 0);
-  SpriteBoxEvent(this.boxPosition, this.type, this.pointer);
-}
diff --git a/skysprites/lib/src/sprite_widget.dart b/skysprites/lib/src/sprite_widget.dart
deleted file mode 100644
index 4c71605..0000000
--- a/skysprites/lib/src/sprite_widget.dart
+++ /dev/null
@@ -1,33 +0,0 @@
-part of flutter_sprites;
-
-/// A widget that uses a [SpriteBox] to render a sprite node tree to the screen.
-class SpriteWidget extends OneChildRenderObjectWidget {
-
-  /// The rootNode of the sprite node tree.
-  ///
-  ///     var node = mySpriteWidget.rootNode;
-  final NodeWithSize rootNode;
-
-  /// The transform mode used to fit the sprite node tree to the size of the widget.
-  final SpriteBoxTransformMode transformMode;
-
-  /// Creates a new sprite widget with [rootNode] as its content.
-  ///
-  /// The widget will setup the coordinate space for the sprite node tree using the size of the [rootNode] in
-  /// combination with the supplied [transformMode]. By default the letterbox transform mode is used. See
-  /// [SpriteBoxTransformMode] for more details on the different modes.
-  ///
-  /// The most common way to setup the sprite node graph is to subclass [NodeWithSize] and pass it to the sprite widget.
-  /// In the custom subclass it's possible to build the node graph, do animations and handle user events.
-  ///
-  ///     var mySpriteTree = new MyCustomNodeWithSize();
-  ///     var mySpriteWidget = new SpriteWidget(mySpriteTree, SpriteBoxTransformMode.fixedHeight);
-  SpriteWidget(this.rootNode, [this.transformMode = SpriteBoxTransformMode.letterbox]);
-
-  SpriteBox createRenderObject() => new SpriteBox(rootNode, transformMode);
-
-  void updateRenderObject(SpriteBox renderObject, SpriteWidget oldWidget) {
-    renderObject.rootNode = rootNode;
-    renderObject.transformMode = transformMode;
-  }
-}
diff --git a/skysprites/lib/src/spritesheet.dart b/skysprites/lib/src/spritesheet.dart
deleted file mode 100644
index a428502..0000000
--- a/skysprites/lib/src/spritesheet.dart
+++ /dev/null
@@ -1,74 +0,0 @@
-part of flutter_sprites;
-
-/// A sprite sheet packs a number of smaller images into a single large image.
-///
-/// The placement of the smaller images are defined by a json file. The larger image and json file is typically created
-/// by a tool such as TexturePacker. The [SpriteSheet] class will take a reference to a larger image and a json string.
-/// From the image and the string the [SpriteSheet] creates a number of [Texture] objects. The names of the frames in
-/// the sprite sheet definition are used to reference the different textures.
-class SpriteSheet {
-
-  ui.Image _image;
-  Map<String, Texture> _textures = new Map<String, Texture>();
-
-  /// Creates a new sprite sheet from an [_image] and a sprite sheet [jsonDefinition].
-  ///
-  ///     var mySpriteSheet = new SpriteSheet(myImage, jsonString);
-  SpriteSheet(this._image, String jsonDefinition) {
-    assert(_image != null);
-    assert(jsonDefinition != null);
-
-    JsonDecoder decoder = new JsonDecoder();
-    Map file = decoder.convert(jsonDefinition);
-    assert(file != null);
-
-    List frames = file["frames"];
-
-    for (Map frameInfo in frames) {
-      String fileName = frameInfo["filename"];
-      Rect frame = _readJsonRect(frameInfo["frame"]);
-      bool rotated = frameInfo["rotated"];
-      bool trimmed = frameInfo["trimmed"];
-      Rect spriteSourceSize = _readJsonRect(frameInfo["spriteSourceSize"]);
-      Size sourceSize = _readJsonSize(frameInfo["sourceSize"]);
-      Point pivot = _readJsonPoint(frameInfo["pivot"]);
-
-      var texture = new Texture._fromSpriteFrame(_image, fileName, sourceSize, rotated, trimmed, frame,
-        spriteSourceSize, pivot);
-      _textures[fileName] = texture;
-    }
-  }
-
-  Rect _readJsonRect(Map data) {
-    num x = data["x"];
-    num y = data["y"];
-    num w = data["w"];
-    num h = data["h"];
-
-    return new Rect.fromLTRB(x.toDouble(), y.toDouble(), (x + w).toDouble(), (y + h).toDouble());
-  }
-
-  Size _readJsonSize(Map data) {
-    num w = data["w"];
-    num h = data["h"];
-
-    return new Size(w.toDouble(), h.toDouble());
-  }
-
-  Point _readJsonPoint(Map data) {
-    num x = data["x"];
-    num y = data["y"];
-
-    return new Point(x.toDouble(), y.toDouble());
-  }
-
-  /// The image used by the sprite sheet.
-  ///
-  ///     var spriteSheetImage = mySpriteSheet.image;
-  ui.Image get image => _image;
-
-  /// Returns a texture by its name.
-  ///
-  ///     var myTexture = mySpriteSheet["example.png"];
-  Texture operator [](String fileName) => _textures[fileName];
-}
diff --git a/skysprites/lib/src/texture.dart b/skysprites/lib/src/texture.dart
deleted file mode 100644
index e5c53a8..0000000
--- a/skysprites/lib/src/texture.dart
+++ /dev/null
@@ -1,112 +0,0 @@
-part of flutter_sprites;
-
-/// A texture represents a rectangular area of an image and is typically used to draw a sprite to the screen.
-///
-/// Normally you get a reference to a texture from a [SpriteSheet], but you can also create one from an [Image].
-class Texture {
-
-  /// Creates a new texture from an [Image] object.
-  ///
-  ///     var myTexture = new Texture(myImage);
-  Texture(ui.Image image) :
-    size = new Size(image.width.toDouble(), image.height.toDouble()),
-    image = image,
-    trimmed = false,
-    rotated = false,
-    frame = new Rect.fromLTRB(0.0, 0.0, image.width.toDouble(), image.height.toDouble()),
-    spriteSourceSize = new Rect.fromLTRB(0.0, 0.0, image.width.toDouble(), image.height.toDouble()),
-    pivot = new Point(0.5, 0.5);
-
-
-  Texture._fromSpriteFrame(this.image, this.name, this.size, this.rotated, this.trimmed, this.frame,
-                           this.spriteSourceSize, this.pivot);
-
-  /// The image that this texture is a part of.
-  ///
-  ///     var textureImage = myTexture.image;
-  final ui.Image image;
-
-  /// The logical size of the texture, before being trimmed by the texture packer.
-  ///
-  ///     var textureSize = myTexture.size;
-  final Size size;
-
-  /// The name of the image acts as a tag when acquiring a reference to it.
-  ///
-  ///     myTexture.name = "new_texture_name";
-  String name;
-
-  /// The texture was rotated 90 degrees when being packed into a sprite sheet.
-  ///
-  ///     if (myTexture.rotated) drawRotated();
-  final bool rotated;
-
-  /// The texture was trimmed when being packed into a sprite sheet.
-  ///
-  ///     bool trimmed = myTexture.trimmed
-  final bool trimmed;
-
-  /// The frame of the trimmed texture inside the image.
-  ///
-  ///     Rect frame = myTexture.frame;
-  final Rect frame;
-
-  /// The offset and size of the trimmed texture inside the image.
-  ///
-  /// Position represents the offset from the logical [size], the size of the rect represents the size of the trimmed
-  /// texture.
-  ///
-  ///     Rect spriteSourceSize = myTexture.spriteSourceSize;
-  final Rect spriteSourceSize;
-
-  /// The default pivot point for this texture. When creating a [Sprite] from the texture, this is the pivot point that
-  /// will be used.
-  ///
-  ///     myTexture.pivot = new Point(0.5, 0.5);
-  Point pivot;
-
-  Texture textureFromRect(Rect rect, [String name = null]) {
-    assert(rect != null);
-    assert(!rotated);
-    Rect srcFrame = new Rect.fromLTWH(rect.left + frame.left, rect.top + frame.top, rect.size.width, rect.size.height);
-    Rect dstFrame = new Rect.fromLTWH(0.0, 0.0, rect.size.width, rect.size.height);
-    return new Texture._fromSpriteFrame(image, name, rect.size, false, false, srcFrame, dstFrame, new Point(0.5, 0.5));
-  }
-
-  void drawTexture(PaintingCanvas canvas, Point position, Paint paint) {
-    // Get drawing position
-    double x = position.x;
-    double y = position.y;
-
-    // Draw the texture
-    if (rotated) {
-      // Account for position
-      bool translate = (x != 0 || y != 0);
-      if (translate) {
-        canvas.translate(x, y);
-      }
-
-      // Calculate the rotated frame and spriteSourceSize
-      Size originalFrameSize = frame.size;
-      Rect rotatedFrame = frame.topLeft & new Size(originalFrameSize.height, originalFrameSize.width);
-      Point rotatedSpriteSourcePoint = new Point(
-          -spriteSourceSize.top - (spriteSourceSize.bottom - spriteSourceSize.top),
-          spriteSourceSize.left);
-      Rect rotatedSpriteSourceSize = rotatedSpriteSourcePoint & new Size(originalFrameSize.height, originalFrameSize.width);
-
-      // Draw the rotated sprite
-      canvas.rotate(-math.PI/2.0);
-      canvas.drawImageRect(image, rotatedFrame, rotatedSpriteSourceSize, paint);
-      canvas.rotate(math.PI/2.0);
-
-      // Translate back
-      if (translate) {
-        canvas.translate(-x, -y);
-      }
-    } else {
-      // Draw the sprite
-      Rect dstRect = new Rect.fromLTWH(x + spriteSourceSize.left, y + spriteSourceSize.top, spriteSourceSize.width, spriteSourceSize.height);
-      canvas.drawImageRect(image, frame, dstRect, paint);
-    }
-  }
-}
diff --git a/skysprites/lib/src/textured_line.dart b/skysprites/lib/src/textured_line.dart
deleted file mode 100644
index 26c7309..0000000
--- a/skysprites/lib/src/textured_line.dart
+++ /dev/null
@@ -1,299 +0,0 @@
-part of flutter_sprites;
-
-class TexturedLine extends Node {
-  TexturedLine(List<Point> points, List<Color> colors, List<double> widths, [Texture texture, List<double> textureStops]) {
-    painter = new TexturedLinePainter(points, colors, widths, texture, textureStops);
-  }
-
-  TexturedLinePainter painter;
-
-  void paint(PaintingCanvas canvas) {
-    painter.paint(canvas);
-  }
-}
-
-class TexturedLinePainter {
-  TexturedLinePainter(this._points, this.colors, this.widths, [Texture texture, this.textureStops]) {
-    this.texture = texture;
-  }
-
-  List<Point> _points;
-
-  List<Point> get points => _points;
-
-  set points(List<Point> points) {
-    _points = points;
-    _calculatedTextureStops = null;
-  }
-
-  List<Color> colors;
-  List<double> widths;
-  Texture _texture;
-
-  Texture get texture => _texture;
-
-  set texture(Texture texture) {
-    _texture = texture;
-    if (texture == null) {
-      _cachedPaint = new Paint();
-    } else {
-      Matrix4 matrix = new Matrix4.identity();
-      ui.ImageShader shader = new ui.ImageShader(texture.image,
-        ui.TileMode.repeated, ui.TileMode.repeated, matrix.storage);
-
-      _cachedPaint = new Paint()
-        ..shader = shader;
-    }
-  }
-
-  List<double> textureStops;
-
-  List<double> _calculatedTextureStops;
-
-  List<double> get calculatedTextureStops {
-    if (_calculatedTextureStops == null)
-      _calculateTextureStops();
-    return _calculatedTextureStops;
-  }
-
-  double _length;
-
-  double get length {
-    if (_calculatedTextureStops == null)
-      _calculateTextureStops();
-    return _length;
-  }
-
-  double textureStopOffset = 0.0;
-
-  double _textureLoopLength;
-
-  get textureLoopLength => textureLoopLength;
-
-  set textureLoopLength(double textureLoopLength) {
-    _textureLoopLength = textureLoopLength;
-    _calculatedTextureStops = null;
-  }
-
-  bool removeArtifacts = true;
-
-  ui.TransferMode transferMode = ui.TransferMode.srcOver;
-
-  Paint _cachedPaint = new Paint();
-
-  void paint(PaintingCanvas canvas) {
-    // Check input values
-    assert(_points != null);
-    if (_points.length < 2) return;
-
-    assert(_points.length == colors.length);
-    assert(_points.length == widths.length);
-
-    _cachedPaint.transferMode = transferMode;
-
-    // Calculate normals
-    List<Vector2> vectors = <Vector2>[];
-    for (Point pt in _points) {
-      vectors.add(new Vector2(pt.x, pt.y));
-    }
-    List<Vector2> miters = _computeMiterList(vectors, false);
-
-    List<Point> vertices = <Point>[];
-    List<int> indicies = <int>[];
-    List<Color> verticeColors = <Color>[];
-    List<Point> textureCoordinates;
-    double textureTop;
-    double textureBottom;
-    List<double> stops;
-
-    // Add first point
-    Point lastPoint = _points[0];
-    Vector2 lastMiter = miters[0];
-
-    // Add vertices and colors
-    _addVerticesForPoint(vertices, lastPoint, lastMiter, widths[0]);
-    verticeColors.add(colors[0]);
-    verticeColors.add(colors[0]);
-
-    if (texture != null) {
-      assert(texture.rotated == false);
-
-      // Setup for calculating texture coordinates
-      textureTop = texture.frame.top;
-      textureBottom = texture.frame.bottom;
-      textureCoordinates = <Point>[];
-
-      // Use correct stops
-      if (textureStops != null) {
-        assert(_points.length == textureStops.length);
-        stops = textureStops;
-      } else {
-        if (_calculatedTextureStops == null) _calculateTextureStops();
-        stops = _calculatedTextureStops;
-      }
-
-      // Texture coordinate points
-      double xPos = _xPosForStop(stops[0]);
-      textureCoordinates.add(new Point(xPos, textureTop));
-      textureCoordinates.add(new Point(xPos, textureBottom));
-    }
-
-    // Add the rest of the points
-    for (int i = 1; i < _points.length; i++) {
-      // Add vertices
-      Point currentPoint = _points[i];
-      Vector2 currentMiter = miters[i];
-      _addVerticesForPoint(vertices, currentPoint, currentMiter, widths[i]);
-
-      // Add references to the triangles
-      int lastIndex0 = (i - 1) * 2;
-      int lastIndex1 = (i - 1) * 2 + 1;
-      int currentIndex0 = i * 2;
-      int currentIndex1 = i * 2 + 1;
-      indicies.addAll(<int>[lastIndex0, lastIndex1, currentIndex0]);
-      indicies.addAll(<int>[lastIndex1, currentIndex1, currentIndex0]);
-
-      // Add colors
-      verticeColors.add(colors[i]);
-      verticeColors.add(colors[i]);
-
-      if (texture != null) {
-        // Texture coordinate points
-        double xPos = _xPosForStop(stops[i]);
-        textureCoordinates.add(new Point(xPos, textureTop));
-        textureCoordinates.add(new Point(xPos, textureBottom));
-      }
-
-      // Update last values
-      lastPoint = currentPoint;
-      lastMiter = currentMiter;
-    }
-
-    canvas.drawVertices(ui.VertexMode.triangles, vertices, textureCoordinates, verticeColors, ui.TransferMode.modulate, indicies, _cachedPaint);
-  }
-
-  double _xPosForStop(double stop) {
-    if (_textureLoopLength == null) {
-      return texture.frame.left + texture.frame.width * (stop - textureStopOffset);
-    } else {
-      return texture.frame.left + texture.frame.width * (stop - textureStopOffset * (_textureLoopLength / length)) * (length / _textureLoopLength);
-    }
-  }
-
-  void _addVerticesForPoint(List<Point> vertices, Point point, Vector2 miter, double width) {
-    double halfWidth = width / 2.0;
-
-    Offset offset0 = new Offset(miter[0] * halfWidth, miter[1] * halfWidth);
-    Offset offset1 = new Offset(-miter[0] * halfWidth, -miter[1] * halfWidth);
-
-    Point vertex0 = point + offset0;
-    Point vertex1 = point + offset1;
-
-    int vertexCount = vertices.length;
-    if (removeArtifacts && vertexCount >= 2) {
-      Point oldVertex0 = vertices[vertexCount - 2];
-      Point oldVertex1 = vertices[vertexCount - 1];
-
-      Point intersection = GameMath.lineIntersection(oldVertex0, oldVertex1, vertex0, vertex1);
-      if (intersection != null) {
-        if (GameMath.distanceBetweenPoints(vertex0, intersection) < GameMath.distanceBetweenPoints(vertex1, intersection)) {
-          vertex0 = oldVertex0;
-        } else {
-          vertex1 = oldVertex1;
-        }
-      }
-    }
-
-    vertices.add(vertex0);
-    vertices.add(vertex1);
-  }
-
-  void _calculateTextureStops() {
-    List<double> stops = <double>[];
-    double length = 0.0;
-
-    // Add first stop
-    stops.add(0.0);
-
-    // Calculate distance to each point from the first point along the line
-    for (int i = 1; i < _points.length; i++) {
-      Point lastPoint = _points[i - 1];
-      Point currentPoint = _points[i];
-
-      double dist = GameMath.distanceBetweenPoints(lastPoint, currentPoint);
-      length += dist;
-      stops.add(length);
-    }
-
-    // Normalize the values in the range [0.0, 1.0]
-    for (int i = 1; i < points.length; i++) {
-      stops[i] = stops[i] / length;
-      new Point(512.0, 512.0);
-    }
-
-    _calculatedTextureStops = stops;
-    _length = length;
-  }
-}
-
-Vector2 _computeMiter(Vector2 lineA, Vector2 lineB) {
-  Vector2 miter = new Vector2(- (lineA[1] + lineB[1]), lineA[0] + lineB[0]);
-  miter.normalize();
-
-  double dot = dot2(miter, new Vector2(-lineA[1], lineA[0]));
-  if (dot.abs() < 0.1) {
-    miter = _vectorNormal(lineA).normalize();
-    return miter;
-  }
-
-  double miterLength = 1.0 / dot;
-  miter = miter.scale(miterLength);
-
-  return miter;
-}
-
-Vector2 _vectorNormal(Vector2 v) {
-  return new Vector2(-v[1], v[0]);
-}
-
-Vector2 _vectorDirection(Vector2 a, Vector2 b) {
-  Vector2 result = a - b;
-  return result.normalize();
-}
-
-List<Vector2> _computeMiterList(List<Vector2> points, bool closed) {
-  List<Vector2> out = <Vector2>[];
-  Vector2 curNormal = null;
-
-  if (closed) {
-    points = new List<Vector2>.from(points);
-    points.add(points[0]);
-  }
-
-  int total = points.length;
-  for (int i = 1; i < total; i++) {
-    Vector2 last = points[i - 1];
-    Vector2 cur = points[i];
-    Vector2 next = (i < total - 1) ? points[i + 1] : null;
-
-    Vector2 lineA = _vectorDirection(cur, last);
-    if (curNormal == null) {
-      curNormal = _vectorNormal(lineA);
-    }
-
-    if (i == 1) {
-      out.add(curNormal);
-    }
-
-    if (next == null) {
-      curNormal = _vectorNormal(lineA);
-      out.add(curNormal);
-    } else {
-      Vector2 lineB = _vectorDirection(next, cur);
-      Vector2 miter = _computeMiter(lineA, lineB);
-      out.add(miter);
-    }
-  }
-
-  return out;
-}
diff --git a/skysprites/lib/src/util.dart b/skysprites/lib/src/util.dart
deleted file mode 100644
index 5dbd940..0000000
--- a/skysprites/lib/src/util.dart
+++ /dev/null
@@ -1,149 +0,0 @@
-part of flutter_sprites;
-
-
-math.Random _random = new math.Random();
-
-// Random methods
-
-/// Returns a random [double] in the range of 0.0 to 1.0.
-double randomDouble() {
-  return _random.nextDouble();
-}
-
-/// Returns a random [double] in the range of -1.0 to 1.0.
-double randomSignedDouble() {
-  return _random.nextDouble() * 2.0 - 1.0;
-}
-
-/// Returns a random [int] from 0 to max - 1.
-int randomInt(int max) {
-  return _random.nextInt(max);
-}
-
-/// Returns either [true] or [false] in a most random fashion.
-bool randomBool() {
-  return _random.nextDouble() < 0.5;
-}
-
-// atan2
-
-class _Atan2Constants {
-
-  _Atan2Constants() {
-    for (int i = 0; i <= size; i++) {
-      double f = i.toDouble() / size.toDouble();
-      ppy[i] = math.atan(f) * stretch / math.PI;
-      ppx[i] = stretch * 0.5 - ppy[i];
-      pny[i] = -ppy[i];
-      pnx[i] = ppy[i] - stretch * 0.5;
-      npy[i] = stretch - ppy[i];
-      npx[i] = ppy[i] + stretch * 0.5;
-      nny[i] = ppy[i] - stretch;
-      nnx[i] = -stretch * 0.5 - ppy[i];
-    }
-  }
-
-  static const int size = 1024;
-  static const double stretch = math.PI;
-
-  static const int ezis = -size;
-
-  final Float64List ppy = new Float64List(size + 1);
-  final Float64List ppx = new Float64List(size + 1);
-  final Float64List pny = new Float64List(size + 1);
-  final Float64List pnx = new Float64List(size + 1);
-  final Float64List npy = new Float64List(size + 1);
-  final Float64List npx = new Float64List(size + 1);
-  final Float64List nny = new Float64List(size + 1);
-  final Float64List nnx = new Float64List(size + 1);
-}
-
-/// Provides convenience methods for calculations often carried out in graphics.
-/// Some of the methods are returning approximations.
-class GameMath {
-  static final _Atan2Constants _atan2 = new _Atan2Constants();
-
-  /// Returns the angle of two vector components. The result is less acurate
-  /// than the standard atan2 function in the math package.
-  static double atan2(double y, double x) {
-    if (x >= 0) {
-      if (y >= 0) {
-        if (x >= y)
-          return _atan2.ppy[(_Atan2Constants.size * y / x + 0.5).toInt()];
-        else
-          return _atan2.ppx[(_Atan2Constants.size * x / y + 0.5).toInt()];
-      } else {
-        if (x >= -y)
-          return _atan2.pny[(_Atan2Constants.ezis * y / x + 0.5).toInt()];
-        else
-          return _atan2.pnx[(_Atan2Constants.ezis * x / y + 0.5).toInt()];
-      }
-    } else {
-      if (y >= 0) {
-        if (-x >= y)
-          return _atan2.npy[(_Atan2Constants.ezis * y / x + 0.5).toInt()];
-        else
-          return _atan2.npx[(_Atan2Constants.ezis * x / y + 0.5).toInt()];
-      } else {
-        if (x <= y)
-          return _atan2.nny[(_Atan2Constants.size * y / x + 0.5).toInt()];
-        else
-          return _atan2.nnx[(_Atan2Constants.size * x / y + 0.5).toInt()];
-      }
-    }
-  }
-
-  /// Approximates the distance between two points. The returned value can be
-  /// up to 6% wrong in the worst case.
-  static double distanceBetweenPoints(Point a, Point b) {
-    double dx = a.x - b.x;
-    double dy = a.y - b.y;
-    if (dx < 0.0) dx = -dx;
-    if (dy < 0.0) dy = -dy;
-    if (dx > dy) {
-      return dx + dy/2.0;
-    }
-    else {
-      return dy + dx/2.0;
-    }
-  }
-
-  /// Interpolates a [double] between [a] and [b] according to the
-  /// [filterFactor], which should be in the range of 0.0 to 1.0.
-  static double filter (double a, double b, double filterFactor) {
-      return (a * (1-filterFactor)) + b * filterFactor;
-  }
-
-  /// Interpolates a [Point] between [a] and [b] according to the
-  /// [filterFactor], which should be in the range of 0.0 to 1.0.
-  static Point filterPoint(Point a, Point b, double filterFactor) {
-    return new Point(filter(a.x, b.x, filterFactor), filter(a.y, b.y, filterFactor));
-  }
-
-  /// Returns the intersection between two line segmentss defined by p0, p1 and
-  /// q0, q1. If the lines are not intersecting null is returned.
-  static Point lineIntersection(Point p0, Point p1, Point q0, Point q1) {
-    double epsilon = 1e-10;
-
-    Vector2 r = new Vector2(p1.x - p0.x, p1.y - p0.y);
-    Vector2 s = new Vector2(q1.x - q0.x, q1.y - q0.y);
-    Vector2 qp = new Vector2(q0.x - p0.x, q0.y - p0.y);
-
-    double rxs = cross2(r, s);
-
-    if (rxs.abs() < epsilon) {
-      // The lines are linear or collinear
-      return null;
-    }
-
-    double t = cross2(qp, s) / rxs;
-    double u = cross2(qp, r) / rxs;
-
-    if ((0.0 <= t && t <= 1.0) && (0.0 <= u && u <= 1.0)) {
-      return new Point(p0.x + t * r.x, p0.y + t * r.y);
-    }
-
-    // No intersection between the lines
-    return null;
-  }
-}
diff --git a/skysprites/lib/src/virtual_joystick.dart b/skysprites/lib/src/virtual_joystick.dart
deleted file mode 100644
index db010b1..0000000
--- a/skysprites/lib/src/virtual_joystick.dart
+++ /dev/null
@@ -1,62 +0,0 @@
-part of flutter_sprites;
-
-class VirtualJoystick extends NodeWithSize {
-  VirtualJoystick() : super(new Size(160.0, 160.0)) {
-    userInteractionEnabled = true;
-    handleMultiplePointers = false;
-    position = new Point(160.0, -20.0);
-    pivot = new Point(0.5, 1.0);
-    _center = new Point(size.width / 2.0, size.height / 2.0);
-    _handlePos = _center;
-
-    _paintHandle = new Paint()
-      ..color=new Color(0xffffffff);
-    _paintControl = new Paint()
-      ..color=new Color(0xffffffff)
-      ..strokeWidth = 1.0
-      ..style = ui.PaintingStyle.stroke;
-  }
-
-  Point _value = Point.origin;
-  Point get value => _value;
-
-  bool _isDown = false;
-  bool get isDown => _isDown;
-
-  Point _pointerDownAt;
-  Point _center;
-  Point _handlePos;
-
-  Paint _paintHandle;
-  Paint _paintControl;
-
-  bool handleEvent(SpriteBoxEvent event) {
-    if (event.type == "pointerdown") {
-      _pointerDownAt = event.boxPosition;
-      actions.stopAll();
-      _isDown = true;
-    }
-    else if (event.type == "pointerup" || event.type == "pointercancel") {
-      _pointerDownAt = null;
-      _value = Point.origin;
-      ActionTween moveToCenter = new ActionTween((a) => _handlePos = a, _handlePos, _center, 0.4, Curves.elasticOut);
-      actions.run(moveToCenter);
-      _isDown = false;
-    } else if (event.type == "pointermove") {
-      Offset movedDist = event.boxPosition - _pointerDownAt;
-
-      _value = new Point(
-        (movedDist.dx / 80.0).clamp(-1.0, 1.0),
-        (movedDist.dy / 80.0).clamp(-1.0, 1.0));
-
-        _handlePos = _center + new Offset(_value.x * 40.0, _value.y * 40.0);
-    }
-    return true;
-  }
-
-  void paint(PaintingCanvas canvas) {
-    applyTransformForPivot(canvas);
-    canvas.drawCircle(_handlePos, 25.0, _paintHandle);
-    canvas.drawCircle(_center, 40.0, _paintControl);
-  }
-}
diff --git a/skysprites/pubspec.yaml b/skysprites/pubspec.yaml
deleted file mode 100644
index 137113c..0000000
--- a/skysprites/pubspec.yaml
+++ /dev/null
@@ -1,9 +0,0 @@
-name: flutter_sprites
-description: A sprite toolkit built on top of Flutter
-version: 0.0.15
-author: Flutter Authors <flutter-dev@googlegroups.com>
-homepage: http://flutter.io
-dependencies:
-  flutter: 
-    '0.0.18'
-  box2d: ">=0.2.0 <0.3.0"