diff --git a/examples/raw/pubspec.yaml b/examples/raw/pubspec.yaml
index 02ca8c1..0443125 100644
--- a/examples/raw/pubspec.yaml
+++ b/examples/raw/pubspec.yaml
@@ -1,4 +1,4 @@
-name: raw
+name: sky_raw_examples
 dependencies:
   flutter: ">=0.0.3 <0.1.0"
   sky_tools: any
diff --git a/examples/rendering/lib/sector_layout.dart b/examples/rendering/lib/sector_layout.dart
new file mode 100644
index 0000000..8944c5f
--- /dev/null
+++ b/examples/rendering/lib/sector_layout.dart
@@ -0,0 +1,527 @@
+// 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';
+
+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(ui.Event 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/pubspec.yaml b/examples/rendering/pubspec.yaml
index 0eb70a3..5158fb4 100644
--- a/examples/rendering/pubspec.yaml
+++ b/examples/rendering/pubspec.yaml
@@ -1,4 +1,4 @@
-name: rendering
+name: flutter_rendering_examples
 dependencies:
   flutter: ">=0.0.3 <0.1.0"
   sky_tools: any
diff --git a/examples/rendering/sector_layout.dart b/examples/rendering/sector_layout.dart
index 912127a..ac3fc46 100644
--- a/examples/rendering/sector_layout.dart
+++ b/examples/rendering/sector_layout.dart
@@ -2,539 +2,9 @@
 // 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:async';
 import 'package:flutter/rendering.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();
-  }
-
-  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 }) {
-    assert(parentData is SectorParentData);
-    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) {
-      assert(child.parentData is SectorChildListParentData);
-      if (child.hitTest(result, radius: radius, theta: theta))
-        return;
-      child = child.parentData.previousSibling;
-    }
-  }
-
-  void visitChildren(RenderObjectVisitor visitor) {
-    RenderSector child = lastChild;
-    while (child != null) {
-      visitor(child);
-      child = child.parentData.previousSibling;
-    }
-  }
-}
-
-class RenderSectorRing extends RenderSectorWithChildren {
-  // lays out RenderSector children in a ring
-
-  RenderSectorRing({
-    BoxDecoration decoration,
-    double deltaRadius: double.INFINITY,
-    double padding: 0.0
-  }) : super(decoration), _padding = padding, _desiredDeltaRadius = deltaRadius;
-
-  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;
-      assert(child.parentData is SectorChildListParentData);
-      child = child.parentData.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;
-      assert(child.parentData is SectorChildListParentData);
-      child = child.parentData.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) {
-      assert(child.parentData is SectorChildListParentData);
-      context.paintChild(child, offset.toPoint());
-      child = child.parentData.nextSibling;
-    }
-  }
-
-}
-
-class RenderSectorSlice extends RenderSectorWithChildren {
-  // lays out RenderSector children in a stack
-
-  RenderSectorSlice({
-    BoxDecoration decoration,
-    double deltaTheta: kTwoPi,
-    double padding: 0.0
-  }) : super(decoration), _padding = padding, _desiredDeltaTheta = deltaTheta;
-
-  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;
-      assert(child.parentData is SectorChildListParentData);
-      child = child.parentData.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;
-      assert(child.parentData is SectorChildListParentData);
-      child = child.parentData.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());
-      child = child.parentData.nextSibling;
-    }
-  }
-
-}
-
-class RenderBoxToRenderSectorAdapter extends RenderBox {
-
-  RenderBoxToRenderSectorAdapter({ double innerRadius: 0.0, RenderSector child }) :
-    _innerRadius = innerRadius {
-    _child = child;
-    adoptChild(_child);
-  }
-
-  double _innerRadius;
-  double get innerRadius => _innerRadius;
-  void set innerRadius(double value) {
-    _innerRadius = value;
-    markNeedsLayout();
-  }
-
-  RenderSector _child;
-  RenderSector get child => _child;
-  void set child(RenderSector value) {
-    if (_child != null)
-      dropChild(_child);
-    _child = value;
-    adoptChild(_child);
-    markNeedsLayout();
-  }
-
-  void setupParentData(RenderObject child) {
-    if (child.parentData is! SectorParentData)
-      child.parentData = new SectorParentData();
-  }
-
-  void visitChildren(RenderObjectVisitor visitor) {
-    visitor(_child);
-  }
-
-  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 }) {
-    double x = position.x;
-    double y = position.y;
-    if (child == null)
-      return false;
-    // 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(ui.Event event, HitTestEntry entry) {
-    if (event.type == 'pointerdown')
-      decoration = new BoxDecoration(backgroundColor: const Color(0xFFFF0000));
-    else if (event.type == 'pointerup')
-      decoration = new BoxDecoration(backgroundColor: backgroundColor);
-  }
-}
+import 'lib/sector_layout.dart';
 
 RenderBox buildSectorExample() {
   RenderSectorRing rootCircle = new RenderSectorRing(padding: 20.0);
diff --git a/examples/widgets/pubspec.yaml b/examples/widgets/pubspec.yaml
index 1a48361..8cc7e8c 100644
--- a/examples/widgets/pubspec.yaml
+++ b/examples/widgets/pubspec.yaml
@@ -1,9 +1,12 @@
-name: widgets
+name: sky_widgets_examples
 dependencies:
   flutter: ">=0.0.3 <0.1.0"
   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/sector.dart.old b/examples/widgets/sector.dart
similarity index 76%
rename from examples/widgets/sector.dart.old
rename to examples/widgets/sector.dart
index 0b78121..38bf742 100644
--- a/examples/widgets/sector.dart.old
+++ b/examples/widgets/sector.dart
@@ -7,7 +7,7 @@
 import 'package:flutter/material.dart';
 import 'package:flutter/rendering.dart';
 
-import '../rendering/sector_layout.dart';
+import 'package:flutter_rendering_examples/sector_layout.dart';
 
 RenderBox initCircle() {
   return new RenderBoxToRenderSectorAdapter(
@@ -16,10 +16,14 @@
   );
 }
 
-class SectorApp extends MaterialApp {
+class SectorApp extends StatefulComponent {
+  SectorAppState createState() => new SectorAppState();
+}
 
-  RenderBoxToRenderSectorAdapter sectors = initCircle();
-  math.Random rand = new math.Random(1);
+class SectorAppState extends State<SectorApp> {
+
+  final RenderBoxToRenderSectorAdapter sectors = initCircle();
+  final math.Random rand = new math.Random(1);
 
   void addSector() {
     double deltaTheta;
@@ -52,27 +56,27 @@
   RenderBoxToRenderSectorAdapter sectorAddIcon = initSector(const Color(0xFF00DD00));
   RenderBoxToRenderSectorAdapter sectorRemoveIcon = initSector(const Color(0xFFDD0000));
 
-  bool enabledAdd = true;
-  bool enabledRemove = false;
+  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;
+      _enabledAdd = currentSize.deltaTheta < kTwoPi;
+      _enabledRemove = ring.firstChild != null;
     });
   }
 
   Widget buildBody() {
     return new Material(
-      child: new Column([
+      child: new Column(<Widget>[
           new Container(
             padding: new EdgeDims.symmetric(horizontal: 8.0, vertical: 25.0),
-            child: new Row([
+            child: new Row(<Widget>[
                 new RaisedButton(
-                  enabled: enabledAdd,
+                  enabled: _enabledAdd,
                   child: new IntrinsicWidth(
-                    child: new Row([
+                    child: new Row(<Widget>[
                       new Container(
                         padding: new EdgeDims.all(4.0),
                         margin: new EdgeDims.only(right: 10.0),
@@ -84,9 +88,9 @@
                   onPressed: addSector
                 ),
                 new RaisedButton(
-                  enabled: enabledRemove,
+                  enabled: _enabledRemove,
                   child: new IntrinsicWidth(
-                    child: new Row([
+                    child: new Row(<Widget>[
                       new Container(
                         padding: new EdgeDims.all(4.0),
                         margin: new EdgeDims.only(right: 10.0),
@@ -117,18 +121,20 @@
     );
   }
 
-  Widget build() {
-    return new Theme(
-      data: new ThemeData.light(),
-      child: new Title(
-        title: 'Sector Layout',
-        child: new Scaffold(
-          toolBar: new ToolBar(
-            center: new Text('Sector Layout in a Widget Tree')
-          ),
-          body: buildBody()
-        )
-      )
+  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()
+          );
+        }
+      }
     );
   }
 }
diff --git a/packages/flutter/lib/src/rendering/box.dart b/packages/flutter/lib/src/rendering/box.dart
index cfc9cd2..25bb5d8 100644
--- a/packages/flutter/lib/src/rendering/box.dart
+++ b/packages/flutter/lib/src/rendering/box.dart
@@ -633,7 +633,7 @@
     }
   }
 
-  String debugDescribeSettings(String prefix) => '${super.debugDescribeSettings(prefix)}${prefix}size: $size\n';
+  String debugDescribeSettings(String prefix) => '${super.debugDescribeSettings(prefix)}${prefix}size: ${ hasSize ? size : "MISSING" }\n';
 }
 
 /// A mixin that provides useful default behaviors for boxes with children
diff --git a/packages/flutter/lib/src/widgets/basic.dart b/packages/flutter/lib/src/widgets/basic.dart
index f4f3d1c..346a418 100644
--- a/packages/flutter/lib/src/widgets/basic.dart
+++ b/packages/flutter/lib/src/widgets/basic.dart
@@ -961,6 +961,22 @@
   }
 }
 
+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
 
